Skip to content

Commit

Permalink
Fix ctx implicits under case unapplySeq (scala#21748)
Browse files Browse the repository at this point in the history
A case class with a varargs has a unapplySeq extractor instead of
unapply.  When we type an unapply, in typedUnapply, we first look for
unapply methods before unapplySeq methods.  But when searching for
unapply, if a class method isn't found, then an extension method is
looked for, which causes context implicits to be cached.  The bindings
from a pattern (such as from an unapply or unapplySeq extractor) are
added to the context in indexPattern.  But Context's `implicitCache`
doesn't account for the scope changing.

I opted for giving the body its own scope context, rather than making
indexPattern reset the context implicits cache.

Fixes scala#21742
  • Loading branch information
odersky authored Oct 27, 2024
2 parents ede1261 + 69f5f73 commit dd37f07
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2201,7 +2201,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
/** Type a case. */
def typedCase(tree: untpd.CaseDef, sel: Tree, wideSelType: Type, pt: Type)(using Context): CaseDef = {
val originalCtx = ctx
val gadtCtx: Context = ctx.fresh.setFreshGADTBounds.setNewScope
val gadtCtx: Context = ctx.fresh.setFreshGADTBounds

def caseRest(pat: Tree)(using Context) = {
val pt1 = instantiateMatchTypeProto(pat, pt) match {
Expand Down Expand Up @@ -2231,7 +2231,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val pat1 = typedPattern(tree.pat, wideSelType)(using gadtCtx)
caseRest(pat1)(
using Nullables.caseContext(sel, pat1)(
using gadtCtx))
using gadtCtx.fresh.setNewScope))
}

def typedLabeled(tree: untpd.Labeled)(using Context): Labeled = {
Expand Down
5 changes: 5 additions & 0 deletions tests/pos/i21742.1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
case class C(n: Int, ds: Double*)
class Test:
def m(using n: Int): Int = n + 1
def t(): Unit =
C(1, 2, 3, 4) match { case C(given Int, ds*) => m }
5 changes: 5 additions & 0 deletions tests/pos/i21742.2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
case class C(n: Int, ds: Seq[Double])
class Test:
def m(using n: Int): Int = n + 1
def t(): Unit =
C(1, Seq(2, 3, 4)) match { case C(given Int, ds) => m }

0 comments on commit dd37f07

Please sign in to comment.