-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
3.2.0 regression around match types #15926
Comments
Bisect points to 02f775f |
Expected reduction: Sum[Minus[Succ[Zero]], Minus[Succ[Zero]]]
Minus[NatSum[Succ[Zero], Succ[Zero]]]
Minus[NatSum[Succ[Succ[Zero]], Zero]]
Minus[Succ[Succ[Zero]]] Apparent reduction: Sum[Minus[Succ[Zero]], Minus[Succ[Zero]]]
Minus[NatSum[Succ[Zero], Succ[Zero]]]
Minus[NatSum[Succ[Succ[Zero]], NatT]] |
This issue was picked for the Issue Spree No. 22 of 18 October 2022 which takes place in a week from now. @dwijnand, @nmcb, @markehammons, @mbovel, @SethTisue will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
notes on the minimization:
type NatSum[X <: NatT, Y <: NatT] <: NatT = Y match
case Zero => X
case Succ[y] => NatSum[Succ[X], y]
type Sum[X <: IntT, Y <: IntT] <: IntT = Y match
case Minus[y] => X match
case Minus[x] => Minus[NatSum[x, y]] here's a little script for verifying the pos/neg status on four relevant Scala versions: scala-cli compile -S 3.1.2 . || echo "it failed on 3.1.2"
scala-cli compile -S 3.1.3 . && echo "it compiled on 3.1.3"
scala-cli compile -S 3.2.0-RC1 . || echo "it failed on 3.2.0-RC1"
scala-cli compile -S 3.nightly . || echo "it failed on 3.nightly" |
and sadly, the bug only reproduces if you go through the first reduction step first. if you just write the second reduction step directly: summon[Minus[NatSum[Succ[Zero], Succ[Zero]]] =:= Minus[NatSum[Succ[Succ[Zero]], Zero]]] then it compiles in all four Scala versions 😭 |
We hope to find some connection with type avoidance, since that's the subject of the reverted PR Wojciech identified (#15341 reverted #13780). Dale observes that in this code: type Sum[X <: IntT, Y <: IntT] <: IntT = Y match
case Minus[y] => X match
case Minus[x] => Minus[NatSum[x, y]] perhaps type avoidance is inappropriately kicking in thinking that |
The story of changes to type avoidance in the compiler has become convoluted. Wojciech's bisect points to #15341 which partially reverted Olivier's #13780. But this is part of a larger story summarized at #15373. Along the way, Guillaume's big type avoidance PR #14026 was first merged, then reverted, but not completely — the code was kept, but put behind a flag. More recent development is Martin's level-checking PR, #15746, and another PR by Martin, #15423. (I hope I haven't misrepresented the story. At minimum, these are relevant issue and PR numbers.) |
I failed to find any further useful minimizations, but I'm also not sure I tried every possible avenue :-/ |
After thought having played around with the issue - changing the match of
|
We ruled out type avoidance (turning it off completely doesn't make a difference), the issue does go away if canWidenAbstract is set to false in https://github.com/lampepfl/dotty/blob/96d4ccdcfc3e0ff4d62e969374b92b6db590ccd3/compiler/src/dotty/tools/dotc/core/TypeComparer.scala#L3139 |
Extracting the inner match makes the code compile: type Sum[X <: IntT, Y <: IntT] <: IntT = Y match
case Zero => X
case Minus[y] => Sum1[X, y]
case _ => X match
case Minus[x] => NatDif[Y, x]
case _ => NatSum[X, Y]
type Sum1[X <: IntT, y <: IntT] <: IntT = X match
case Minus[x] => Minus[NatSum[x, y]]
case _ => NatDif[X, y] |
That would also solves this issue: diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index 8eb6a490010..dbe89ec385e 100644
- else if matches(canWidenAbstract = true) then
+ else if !caseLambda.exists && matches(canWidenAbstract = true) then But make these 2 It's really about the heuristics of when to widen abstract types and when not to. |
We purposely backed out an overly restricting change because of the code that failed to compile because of it. So there was one patch version where it compiled and then not. So not a "regression" as I see it. |
Refine criterion when to widen types in match type reduction. We now do not widen if the compared-against type contains variant named type parameters. This is intended to fix the soundness problem in scala#17149. Fixes scala#17149 Fixes scala#15926 Todos: - [ ] Check & fix neg test failures - [ ] Add more tests - [ ] Also consider approximating abstract types to lower bounds. This is completely missing so far. There are neither tests nor an implementation. - [ ] Update the docs on match types to explain what goes on here.
Refine criterion when to widen types in match type reduction. We now do not widen if the compared-against type contains variant named type parameters. This is intended to fix the soundness problem in scala#17149. Fixes scala#17149 Fixes scala#15926 Todos: - [ ] Check & fix neg test failures - [ ] Add more tests - [ ] Also consider approximating abstract types to lower bounds. This is completely missing so far. There are neither tests nor an implementation. - [ ] Update the docs on match types to explain what goes on here.
Compiler version
3.2-RC1, 3.2-RC2, 3.2-RC3, 3.2-RC4
Minimized code
Output
Expectation
Code should compile, as in Scala 3.1.3.
The text was updated successfully, but these errors were encountered: