-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Missing variance checks in rhs of type aliases leads to unsoudness #1252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
/cc @sstucki |
Just had a discussion on this with @sstucki who made a very good observation, the type Foo[+X] <: X // OK
type Foo[+X] = X // OK
type Foo[+X] >: X // error: covariant type X occurs in contravariant position Since @sstucki suggested that whether we are in a lower or upper-bound should not affect the variance check, because: type Bar[+X] >: One[X] <: Two[X] is really: type Bar >: [+X] => One[X] <: [+X] => One[X] So |
Do we have examples where this causes a ClassCastException? If not, I would follow @sstucki's reasoning and recommend to close. |
My initial example causes a ClassCastException in dotty, @sstucki's reasoning does not mean that we shouldn't check anything but that whether something is lower- or upper-bounded does not affect the check, doing this check in my initial example will prevent it from compiling as expected. I can prepare a PR for that. |
Here's a related issue, which doesn't involve variance annotations: trait A { type L[Y <: Int] >: Int }
trait B { type L[Y <: String] >: String }
trait C extends A with B { type L[Y <: Any] >: Any } The compiler reports
the problem is that, when the compiler checks that bounds of Concretely, here we want all the lambdas to have the (wider) kind [Y <: String] => String has kind (Y <: String) -> *
[Y <: String] => Any has kind (Y <: String) -> *
[Y] => Any has kind (Y <: Any) -> * sub-kind of (Y <: String) -> *
[Y] => Any has kind (Y <: Any) -> * sub-kind of (Y <: String) -> * so all the bounds are well-kinded and their kinds conform to the signature in the parent class. Then we need to check that the definitions of the lambdas agree in this kind, which they do: /* Lower bounds are checked contravariantly: */
String <: Any forall Y <: String, so [Y <: String] => String <: [Y <: Any ] => Any
/* Upper bounds are checked covariantly: */
Any <: Any forall Y <: String, so [Y <: Any ] => Any <: [Y <: String] => Any I'm not sure whether this should be reported in a separate issue. The two issues are definitely related because in both cases kind-checking and subtyping are mixed up. |
940f517 added these checks but missed the case where a TypeLambdaTree type is a TypeBounds, this commit just adds the missing case as well as an explanatory comment in TypeLambdaTree.
Fix #1252: Fix variance checking for parameterized typedefs
940f517 added these checks but missed the case where a TypeLambdaTree type is a TypeBounds, this commit just adds the missing case as well as an explanatory comment in TypeLambdaTree.
This shouldn't compile because
X
appears covariantly in the rhs oftype Id[-X] = X
:scalac
doesn't allowtype Id[-X] = X
andtype Id[-X] <: X
but allowstype Id[-X] >: X
, I haven't thought enough about it to know if that makes sense.The text was updated successfully, but these errors were encountered: