-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve GADT reasoning for pattern alternatives #23205
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
base: main
Are you sure you want to change the base?
Conversation
Previously it fails, but now it is ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refines GADT constraint handling for pattern alternatives by collecting constraints from each case and using their common, necessary constraint instead of discarding all GADT reasoning.
- Collects GADT constraints per alternative in
Typer.scala
and restores the weakest common constraint if it exists. - Adds
necessaryGadtConstraint
inTypeComparer.scala
to compute a constraint subsumed by all alternatives. - Updates existing positive and negative tests to reflect the new behavior.
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
tests/pos/gadt-alt-doc1.scala | Adds a positive test demonstrating a disallowed alternative now errors. |
tests/neg/gadt-alternatives.scala & various gadt-alt-expr*.scala | Updates negative tests to expect new accept/reject behavior. |
compiler/src/dotty/tools/dotc/typer/Typer.scala | Collects and aggregates GADT constraints instead of discarding them. |
compiler/src/dotty/tools/dotc/core/TypeComparer.scala | Introduces necessaryGadtConstraint and related import updates. |
Comments suppressed due to low confidence (1)
compiler/src/dotty/tools/dotc/core/TypeComparer.scala:28
- [nitpick] The combined import
import scala.util.boundary, boundary.break
may importboundary.break
from the wrong package; preferimport scala.util.boundary.break
or separate the imports to ensure the correct symbol is brought into scope.
import scala.util.boundary, boundary.break
val trees1 = tree.trees.mapconserve: t => | ||
nestedCtx.gadtState.restore(preGadt) | ||
val res = typed(t, pt)(using nestedCtx) | ||
gadtConstrs += ctx.gadt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recording ctx.gadt
likely captures the outer context rather than the updated nested context; it should use nestedCtx.gadt
to collect the actual constraints produced by each alternative.
gadtConstrs += ctx.gadt | |
gadtConstrs += nestedCtx.gadt |
Copilot uses AI. Check for mistakes.
fixes #22882.
Previously, for a pattern alternative:
we ignore GADT constraints derived from it, which is too restrictive. Now we try to find a GADT constraint that is subsumed by all and use it, and only ignore GADT constraints when such a constraint cannot be found.