Skip to content

Conversation

@SolalPirelli
Copy link
Contributor

@SolalPirelli SolalPirelli commented Jan 14, 2026

Fixes #24435

makePatDef was quite hard to understand and also wrong in edge cases related to types and `@unchecked conversions.

I rewrote it with (1) detailed comments of what the optimizations are, (2) support for more patterns such as Typed(Tuple(_), _), and (3) a printing test that enshrines what we expect from these optimizations.

@SolalPirelli SolalPirelli changed the title Take typed identifiers into account when optimizing matches [WIP] Take typed identifiers into account when optimizing matches Jan 14, 2026
@SolalPirelli SolalPirelli force-pushed the solal/tuple-of-literals-deconstruct branch 2 times, most recently from 1296cdb to 495187a Compare January 16, 2026 09:55
@SolalPirelli SolalPirelli force-pushed the solal/tuple-of-literals-deconstruct branch from c4103a3 to 39116e9 Compare January 16, 2026 15:20
sel
end match

case class TuplePatternInfo(arity: Int, varNum: Int, wildcardNum: Int)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review in split diff, this is a rewrite

def makeLambda(gen: GenFrom, body: Tree): Tree = gen.pat match {
case IdPattern(named, tpt) if gen.checkMode != GenCheckMode.FilterAlways =>
Function(derivedValDef(gen.pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case IdPattern(named, tpt) if named.name != nme.WILDCARD && gen.checkMode != GenCheckMode.FilterAlways =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it quite confusing that IdPattern ignored wildcards, and in my case I wanted "any (un)typed ID, even a wildcard", so I moved the check to the existing uses and removed it from IdPattern

case _ => Modifiers()
makePatDef(valeq, mods, defpat, rhs)
val pdefs = valeqs.lazyZip(defpats).map { case (valeq @ GenAlias(_, rhs), defpat) =>
makePatDef(defpat, rhs, valeq.span, givenPatternsAllowed = true)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No behavior change here (hopefully), just cleaning up some rather messy maps and zips

case _ => Modifiers()
makePatDef(valeq, mods, defpat, rhs)
val pdefs = valeqs.map { case valeq @ GenAlias(pat, rhs) =>
makePatDef(makeIdPat(pat)._1, rhs, valeq.span, givenPatternsAllowed = true)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@@ -1,3 +1,3 @@
object Foo {
val (A, B) = () // error // error
val (A, B) = () // error
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure why there were 2 errors before but I think 1 is quite enough :)

def test =
val (x: "x", y: "y") = (("x", "y"): ("x", "y"))
println(x)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the original test from the issue this PR is fixing


def test =
val (x: List[B @unchecked], y: List[C @unchecked]) = foo(): @unchecked
bar(x, y)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a simplified version of code in Typer.scala that failed to compile in my initial attempt at fixing this

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.

Compiler error when deconstructing tuple of literals

1 participant