From 045508cf4b970e42a7ab4a79fc577cf008f2ff82 Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Tue, 20 Feb 2018 18:07:09 +0100 Subject: [PATCH] fix #3200: bind var for singleton pattern get scrutinee type Related issues: https://issues.scala-lang.org/browse/SI-1503 https://github.com/lampepfl/dotty/issues/1463 --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 7 ++++++- tests/neg/i3200.scala | 6 ++++++ tests/neg/i3200b.scala | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i3200.scala create mode 100644 tests/neg/i3200b.scala 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 + } +}