diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 8c2cfab986c4..2a5937b42571 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1320,7 +1320,12 @@ class Typer extends Namer case _ => if (tree.name == nme.WILDCARD) body1 else { - val sym = ctx.newPatternBoundSymbol(tree.name, body1.tpe.underlyingIfRepeated(isJava = false), tree.pos) + // for a singleton pattern like `x @ Nil`, `x` should get the type from the scrutinee + // see tests/neg/i3200b.scala and SI-1503 + val symTp = + if (body1.tpe.isInstanceOf[TermRef]) pt1 + else body1.tpe.underlyingIfRepeated(isJava = false) + val sym = ctx.newPatternBoundSymbol(tree.name, symTp, tree.pos) if (ctx.mode.is(Mode.InPatternAlternative)) ctx.error(i"Illegal variable ${sym.name} in pattern alternative", tree.pos) assignType(cpy.Bind(tree)(tree.name, body1), sym) diff --git a/tests/neg/i3200.scala b/tests/neg/i3200.scala new file mode 100644 index 000000000000..7d905810b6ab --- /dev/null +++ b/tests/neg/i3200.scala @@ -0,0 +1,6 @@ +object Test { + case object Bob { override def equals(other: Any) = true } + def main(args: Array[String]): Unit = { + val m : Bob.type = (5: Any) match { case x @ Bob => x } // error + } +} diff --git a/tests/neg/i3200b.scala b/tests/neg/i3200b.scala new file mode 100644 index 000000000000..522f4e3d63ea --- /dev/null +++ b/tests/neg/i3200b.scala @@ -0,0 +1,5 @@ +object Test { + def main(args: Array[String]): Unit = { + val a : Nil.type = (Vector(): Any) match { case n @ Nil => n } // error + } +}