Skip to content

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Linyxus
Copy link
Contributor

@Linyxus Linyxus commented May 20, 2025

fixes #22882.

Previously, for a pattern alternative:

scrutinee match
  case P1(...) | P2(...) => ...

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.

@Linyxus Linyxus requested a review from mbovel May 20, 2025 14:42
@Linyxus Linyxus requested a review from Copilot May 20, 2025 15:40
Copy link

@Copilot Copilot AI left a 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 in TypeComparer.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 import boundary.break from the wrong package; prefer import 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
Copy link
Preview

Copilot AI May 20, 2025

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.

Suggested change
gadtConstrs += ctx.gadt
gadtConstrs += nestedCtx.gadt

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changed type constraint behaviour when pattern matching with unions
2 participants