Skip to content

Commit dd37f07

Browse files
authored
Fix ctx implicits under case unapplySeq (scala#21748)
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
2 parents ede1261 + 69f5f73 commit dd37f07

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
22012201
/** Type a case. */
22022202
def typedCase(tree: untpd.CaseDef, sel: Tree, wideSelType: Type, pt: Type)(using Context): CaseDef = {
22032203
val originalCtx = ctx
2204-
val gadtCtx: Context = ctx.fresh.setFreshGADTBounds.setNewScope
2204+
val gadtCtx: Context = ctx.fresh.setFreshGADTBounds
22052205

22062206
def caseRest(pat: Tree)(using Context) = {
22072207
val pt1 = instantiateMatchTypeProto(pat, pt) match {
@@ -2231,7 +2231,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
22312231
val pat1 = typedPattern(tree.pat, wideSelType)(using gadtCtx)
22322232
caseRest(pat1)(
22332233
using Nullables.caseContext(sel, pat1)(
2234-
using gadtCtx))
2234+
using gadtCtx.fresh.setNewScope))
22352235
}
22362236

22372237
def typedLabeled(tree: untpd.Labeled)(using Context): Labeled = {

tests/pos/i21742.1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
case class C(n: Int, ds: Double*)
2+
class Test:
3+
def m(using n: Int): Int = n + 1
4+
def t(): Unit =
5+
C(1, 2, 3, 4) match { case C(given Int, ds*) => m }

tests/pos/i21742.2.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
case class C(n: Int, ds: Seq[Double])
2+
class Test:
3+
def m(using n: Int): Int = n + 1
4+
def t(): Unit =
5+
C(1, Seq(2, 3, 4)) match { case C(given Int, ds) => m }

0 commit comments

Comments
 (0)