-
Notifications
You must be signed in to change notification settings - Fork 1.1k
GADT type unification chain length limitation #11682
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
|
@Kordyjan are you sure? The only example with |
@smarter: Now I see I misunderstood the sample. It indeed seems to be a problem with GADTs constraints. |
@smarter I guess this issue doesn't remind you of anything similar in type inference? I'd be somewhat surprised if there was anything specific to the GADT logic that would make us handle correctly instantiation chains of length 3, but not of length 4, so my intuition is that there's something in constraint handling to blame. Ofc, it's entirely possible that I'm (still) misusing constraint handling. |
No, this doesn't ring a bell, I thought it might be a deep subtype issue but running with |
Ok, I took a look and it indeed seems like the problem is in ConstraintHandling. The traces are here: https://gist.github.com/abgruszecki/b6cc78b3f38aeec04f9d8d7160a6ee3b It seems that for the case that works, when we initially add the constraints, we have:
And for the case that doesn't work, we have:
Note that |
…arams `order` takes `current` as input and returns a constraint set that subsumes both `current` and `param1 <: param2`, but it's an instance method because it relies on `this` to determine if `current` is used linearly such that we can reuse its backing arrays instead of copying them. However, the implementation of `order` mistakenly returned `this` and called methods on `this` instead of `current`. This lead to issues like scala#11682 but that was compensated by logic inserted in ConstraintHandling#addToConstraint which we can now remove. Fixing this also required fixing an unrelated issue in avoidLambdaParams to prevent a regression in tests/pos/i9676.scala: we shouldn't avoid a lambda param under its own binder even if it is in `comparedTypeLambdas`, the sequence of operations where this happens is: [A] =>> List[A] <:< [A] =>> G[A] // comparedTypeLambdas ++= ([A] =>> List[A], [A] =>> G[A]) List[A] <:< G[A] [A] =>> List[A] <:< G // previously, avoidLambdaParams([A] =>> List[A]) = [A] =>> List[Any], // now it leaves the type lambda alone. We end up checking `[A] =>> List[A] <:< G` instead of just `List <:< G` because of `ensureLambdaSub` in `compareAppliedTypeParamRef`. I'm not sure if this is actually needed, but I decided to not disturb that code too much for now.
…arams `order` takes `current` as input and returns a constraint set that subsumes both `current` and `param1 <: param2`, but it's an instance method because it relies on `this` to determine if `current` is used linearly such that we can reuse its backing arrays instead of copying them. However, the implementation of `order` mistakenly returned `this` and called methods on `this` instead of `current`. This lead to issues like scala#11682 but that was compensated by logic inserted in ConstraintHandling#addToConstraint which we can now remove. Fixing this also required fixing an unrelated issue in avoidLambdaParams to prevent a regression in tests/pos/i9676.scala: we shouldn't avoid a lambda param under its own binder even if it is in `comparedTypeLambdas`, the sequence of operations where this happens is: [A] =>> List[A] <:< [A] =>> G[A] // comparedTypeLambdas ++= ([A] =>> List[A], [A] =>> G[A]) List[A] <:< G[A] [A] =>> List[A] <:< G // previously, avoidLambdaParams([A] =>> List[A]) = [A] =>> List[Any], // now it leaves the type lambda alone. We end up checking `[A] =>> List[A] <:< G` instead of just `List <:< G` because of `ensureLambdaSub` in `compareAppliedTypeParamRef`. I'm not sure if this is actually needed, but I decided to not disturb that code too much for now.
Compiler version
3.0.0-M4-bin-SNAPSHOT
,3.0.0-RC1
Minimized code
Output
Expectation
It should infer the constraint
T = X = Y = Z = Int
.@abgruszecki
The text was updated successfully, but these errors were encountered: