Reputation: 9952
In my project, I have a constellation like this:
trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x
Trait X
has a type parameter with an upper bound of F
. From my understanding, the types X[_]
and X[_ <: F]
should be equivalent. But scalac
2.12.5 complains that one is not assignable to the other.
$ scalac -Xscript test test.scala
test.scala:5: error: type mismatch;
found : this.X[_$1] where type _$1
required: this.X[_ <: this.F]
def test(x: X[_]): X[_ <: F] = x
^
I cannot think of a situation where this assignment is making a sound program unsound. What are the reasons that this assignment is rejected? Is there a way that allowing such an assignment (maybe in a more complex example) is problematic?
Upvotes: 3
Views: 346
Reputation: 726
i might be wrong, but it's enough to look at the definition of the function itself:
def test(x: X[_]): X[_ <: F] = x
the only information existential type gives is that there exists something. and with this signature you try to "narrow" the function result
put it in a practical way with an example. let's say you have smth like this:
def test(x: Option[_]): Option[_ <: String]
and then you call it passing inside Option[Int]
. would you expect this assignment to be correct?
val result: Option[_ <: String] = test(Some(1): Option[_])
Upvotes: 0
Reputation: 44992
This assignment isn't really problematic, and the compiler even kind-of knows this, because the following implementation compiles without problems:
trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x match { case q: X[t] => q }
If you give the type checker some slack by allowing it to infer more precise bounds for the type variable t
, it will eventually figure out that t
must be subtype of F
, and then allow you to return the value q
(which is the same as x
) without complaining. It doesn't do this by default for some counter-intuitive reasons that probably have something to do with Java-wildcard interoperability.
(Undeleted again; My original guess didn't seem too far off, and given Dmytro Mitin's link, it doesn't even seem all that vague by comparison.)
Upvotes: 2