Skip to content

Changed type constraint behaviour when pattern matching with unions #22882

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
WojciechMazur opened this issue Mar 28, 2025 · 3 comments · May be fixed by #23205
Open

Changed type constraint behaviour when pattern matching with unions #22882

WojciechMazur opened this issue Mar 28, 2025 · 3 comments · May be fixed by #23205
Assignees
Labels
area:pattern-matching area:typer itype:bug regression This worked in a previous version but doesn't anymore

Comments

@WojciechMazur
Copy link
Contributor

Based on OpenCB failure in in outr/lightdb

Compiler version

Last good release: 3.7.1-RC1-bin-20250323-451fdcd-NIGHTLY
First bad release: 3.7.1-RC1-bin-20250325-701fa8a-NIGHTLY

Bisect points to either 451fdcd or 701fa8a (most likekly)

Minimized code

trait Document[Doc <: Document[Doc]]
sealed trait Conversion[Doc, V]

object Conversion {
  case class Doc[Doc <: Document[Doc]]() extends Conversion[Doc, Doc]
  case class Converted[Doc <: Document[Doc], T](f: Doc => T) extends Conversion[Doc, T]
}

def Test[Doc <: Document[Doc], V](conversion: Conversion[Doc, V]) = 
  val fails = conversion match 
    case Conversion.Doc() | Conversion.Converted(_) => ??? // error
  val works = conversion match 
    case Conversion.Doc() => ???
    case Conversion.Converted(_) => ???

Output

-- [E057] Type Mismatch Error: /Users/wmazur/projects/scala/sandbox/test.scala:12:9 ---------------------------------------------------------------------------------------------------------
12 |    case Conversion.Doc() | Conversion.Converted(_) => ??? // error
   |         ^
   |         Type argument V does not conform to upper bound Document[V]
   |
   | longer explanation available when compiling with `-explain`

Expectation

Should probably compile without error or fail in both cases

@WojciechMazur WojciechMazur added area:pattern-matching area:typer itype:bug regression This worked in a previous version but doesn't anymore labels Mar 28, 2025
@mbovel
Copy link
Member

mbovel commented May 19, 2025

Further minimized:

trait Document[Doc <: Document[Doc]]
sealed trait Conversion[Doc, V]

case class C[Doc <: Document[Doc]]() extends Conversion[Doc, Doc]

def Test[Doc <: Document[Doc], V](conversion: Conversion[Doc, V]) =
  conversion match
    case C() | C() => ??? // error

It type-checks without the union:

trait Document[Doc <: Document[Doc]]
sealed trait Conversion[Doc, V]

case class C[Doc <: Document[Doc]]() extends Conversion[Doc, Doc]

def Test[Doc <: Document[Doc], V](conversion: Conversion[Doc, V]) =
  conversion match
    case C() => ??? // error

I haven't found out yet what differs between the two. The following calls and constraints are the same in both cases:

checkBounds: C.unapply [Doc <: Document[Doc]](x$1: C[Doc]): (true : Boolean)
boundsViolations([V], [ <: Document[Doc]], <notype>)
checkOverlapsBounds(V, V, V,  <: Document[Doc])
check(V, Document[V], upper, Document[V])
 constrained types = 
 bounds = 
 coDeps = ()
 contraDeps = ()
check(Nothing, V, lower, Nothing)
 constrained types = 
 bounds = 
 coDeps = ()
 contraDeps = ()

@mbovel
Copy link
Member

mbovel commented May 19, 2025

I confirm the culprit is #22853; commenting

nestedCtx.gadtState.restore(savedGadt) // Disable GADT reasoning for pattern alternatives
allows the test to pass.

@mbovel
Copy link
Member

mbovel commented May 19, 2025

@Linyxus I will need your help on this one. Could we have a look together one of these days?

@mbovel mbovel assigned Linyxus and unassigned mbovel May 19, 2025
@Linyxus Linyxus linked a pull request May 20, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:pattern-matching area:typer itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants