diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index 971aa33f3163..27f505c21df9 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -144,7 +144,16 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => } override def transformIdent(tree: Ident)(implicit ctx: Context): Tree = - if (tree.isType) toTypeTree(tree) else constToLiteral(tree) + if (tree.isType) { + toTypeTree(tree) + } else if (tree.name != nme.WILDCARD) { + // We constant-fold all idents except wildcards. + // AFAIK, constant-foldable wildcard idents can only occur in patterns, for instance as `case _: "a"`. + // Constant-folding that would result in `case "a": "a"`, which changes the meaning of the pattern. + // Note that we _do_ want to constant-fold idents in patterns that _aren't_ wildcards - + // for example, @switch annotation needs to see inlined literals and not indirect references. + constToLiteral(tree) + } else tree override def transformSelect(tree: Select)(implicit ctx: Context): Tree = if (tree.isType) toTypeTree(tree) else constToLiteral(tree) @@ -156,7 +165,9 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase => constToLiteral(foldCondition(tree)) override def transformTyped(tree: Typed)(implicit ctx: Context): Tree = - constToLiteral(tree) + // Singleton type cases (such as `case _: "a"`) are constant-foldable. + // We avoid constant-folding those as doing so would change the meaning of the pattern (see transformIdent). + if (!ctx.mode.is(Mode.Pattern)) constToLiteral(tree) else tree override def transformBlock(tree: Block)(implicit ctx: Context): Tree = constToLiteral(tree) diff --git a/tests/run/i6996.check b/tests/run/i6996.check new file mode 100644 index 000000000000..a4387987de57 --- /dev/null +++ b/tests/run/i6996.check @@ -0,0 +1,3 @@ +an `a` +false +not `a` diff --git a/tests/run/i6996.scala b/tests/run/i6996.scala new file mode 100644 index 000000000000..9314727c5437 --- /dev/null +++ b/tests/run/i6996.scala @@ -0,0 +1,14 @@ +object Test { + + def isAType(arg: String): Unit = arg match { + case _ : "a" => println("an `a`") + case _ => println("not `a`") + } + + def main(args: Array[String]): Unit = { + isAType("a") + println(new String("a").isInstanceOf["a"]) + isAType(new String("a")) + } + +}