That isn’t how type inference in Scala works; your mental model is too simple. Types aren’t inferred in a vacuum, they’re inferred w/r/t some expected type bounds, and those bounds come from context.
Consider the following interaction:
scala 2.13.1> trait SomeTrait
defined trait SomeTrait
scala 2.13.1> val a: SomeTrait = Option("foo").getOrElse("bar")
error: type mismatch;
found : String("bar")
Look at the error closely and note where the caret is pointing. It isn’t saying the result of
getOrElse is the wrong type, it’s saying
"bar" is the wrong type! What’s happening here? Well, when the
getOrElse call is being typechecked, the expected type of the call is
SomeTrait — that’s coming from the left-hand-side. The only way that’s going to work is if
B is some type compatible with
SomeTrait — perhaps
SomeTrait itself. So the typechecker says to itself, “B now has an upper bound of SomeTrait”. With that information in mind, tries to type check the argument to
getOrElse. That argument doesn’t conform to
B's bounds, hence the error above.
I worked through this simpler example because it shows what I mean by an “expected type” guiding type inference, and proves that it’s happening, because if it weren’t, the error would be different.
OK, that’s enough for one post. I haven’t actually worked out where
Object is coming from in your full example. I may have accidentally given the impression that I have the answer all worked out already. But I don’t, I’m exploring this with you and Luis a piece at time.