I think you’re talking about two different things. Your last example is not related to the example that you link in the SO question. Let’s tackle the discrepancy first.
sumFunc with no type parameters is inferred to be
Nothing and then the implicit search is triggered for whatever type you’re looking for, in this case
Holder. If the implicit
Holder[Nothing] did not exist in your example, then
sumFunc with no type parameter would fail, as shown by the following REPL session:
➜ Code scala
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_172).
Type in expressions for evaluation. Or try :help.
scala> class Holder[T]
defined class Holder
scala> def sumFunc[T: Holder]: T = ???
sumFunc: [T](implicit evidence$1: Holder[T])T
<console>:13: error: could not find implicit value for evidence parameter of type Holder[T]
When you add
implicit def holderNothing: Holder[Nothing] = ??? and try again,
sumFunc succeeds because it’s inferred to be
sumFunc[Nothing] and there exists an implicit
So, coming back to your initial example with
TypeTag (which I haven’t fully understood, but I’ll use the example in the SO question as a reference), what you seem to want is to avoid a definition type to be inferred to
Nothing. For example, in
val person = find("Joe"),
person is typed as
Nothing because the type in
find is not set at the call-site and the return type is the same polymorphic type
T, with no further type restrictions. This is the expected behavior of the code.
The Scala way of avoiding
Nothing to be inferred is to create your own type class and then restrict the return type the function will return by using implicits at the definition site of
sumFunc in your previous case). So long as you don’t define the implicit for
Nothing, the code
find("Joe") will fail to compile if you implement something like the answer in the SO question.