Skip to content

Commit 69f5f73

Browse files
committed
Fix ctx implicits under case unapplySeq
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.
1 parent 3408ed7 commit 69f5f73

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Typer.scala

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

22032203
def caseRest(pat: Tree)(using Context) = {
22042204
val pt1 = instantiateMatchTypeProto(pat, pt) match {
@@ -2228,7 +2228,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
22282228
val pat1 = typedPattern(tree.pat, wideSelType)(using gadtCtx)
22292229
caseRest(pat1)(
22302230
using Nullables.caseContext(sel, pat1)(
2231-
using gadtCtx))
2231+
using gadtCtx.fresh.setNewScope))
22322232
}
22332233

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

Diff for: 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 }

Diff for: 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)