Skip to content

Commit 5c389c6

Browse files
authored
Merge pull request #8415 from dotty-staging/fix-#8407
Fix #8407: Survive nonsensical patterns
2 parents 14066d6 + 9bbae12 commit 5c389c6

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,8 +1552,9 @@ class Typer extends Namer
15521552
}
15531553

15541554
def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Tree = {
1555-
val pt1 = fullyDefinedType(pt, "pattern variable", tree.span)
1556-
val body1 = typed(tree.body, pt1)
1555+
if !isFullyDefined(pt, ForceDegree.all) then
1556+
return errorTree(tree, i"expected type of $tree is not fully defined")
1557+
val body1 = typed(tree.body, pt)
15571558
body1 match {
15581559
case UnApply(fn, Nil, arg :: Nil)
15591560
if fn.symbol.exists && fn.symbol.owner == defn.ClassTagClass && !body1.tpe.isError =>
@@ -1573,21 +1574,21 @@ class Typer extends Namer
15731574
// for a singleton pattern like `x @ Nil`, `x` should get the type from the scrutinee
15741575
// see tests/neg/i3200b.scala and SI-1503
15751576
val symTp =
1576-
if body1.tpe.isInstanceOf[TermRef] then pt1
1577+
if body1.tpe.isInstanceOf[TermRef] then pt
15771578
else if isWildcardStarArg(body1)
1578-
|| pt1 == defn.ImplicitScrutineeTypeRef
1579+
|| pt == defn.ImplicitScrutineeTypeRef
15791580
|| body1.tpe <:< pt // There is some strange interaction with gadt matching.
15801581
// and implicit scopes.
15811582
// run/t2755.scala fails to compile if this subtype test is omitted
1582-
// and the else clause is changed to `body1.tpe & pt1`. What
1583+
// and the else clause is changed to `body1.tpe & pt`. What
15831584
// happens is that we get either an Array[Float] or an Array[T]
15841585
// where T is GADT constrained to := Float. But the case body
15851586
// compiles only if the bound variable is Array[Float]. If
15861587
// it is Array[T] we get an implicit not found. To avoid fragility
15871588
// wrt to operand order for `&`, we include the explicit subtype test here.
15881589
// See also #5649.
15891590
then body1.tpe
1590-
else pt1 & body1.tpe
1591+
else pt & body1.tpe
15911592
val sym = ctx.newPatternBoundSymbol(name, symTp, tree.span)
15921593
if (pt == defn.ImplicitScrutineeTypeRef || tree.mods.is(Given)) sym.setFlag(Given)
15931594
if (ctx.mode.is(Mode.InPatternAlternative))

tests/neg/i8407.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test:
2+
val xs = List(1, 2, 3, 4, 5)
3+
xs match {
4+
case List(1, 2, xs1 @ xs2: _*) => println(xs2) // error // error
5+
case _ => ()
6+
}

0 commit comments

Comments
 (0)