File tree Expand file tree Collapse file tree 3 files changed +30
-2
lines changed
compiler/src/dotty/tools/dotc/transform Expand file tree Collapse file tree 3 files changed +30
-2
lines changed Original file line number Diff line number Diff line change @@ -142,7 +142,16 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
142142 }
143143
144144 override def transformIdent (tree : Ident )(implicit ctx : Context ): Tree =
145- if (tree.isType) toTypeTree(tree) else constToLiteral(tree)
145+ if (tree.isType) {
146+ toTypeTree(tree)
147+ } else if (tree.name != nme.WILDCARD ) {
148+ // We constant-fold all idents except wildcards.
149+ // AFAIK, constant-foldable wildcard idents can only occur in patterns, for instance as `case _: "a"`.
150+ // Constant-folding that would result in `case "a": "a"`, which changes the meaning of the pattern.
151+ // Note that we _do_ want to constant-fold idents in patterns that _aren't_ wildcards -
152+ // for example, @switch annotation needs to see inlined literals and not indirect references.
153+ constToLiteral(tree)
154+ } else tree
146155
147156 override def transformSelect (tree : Select )(implicit ctx : Context ): Tree =
148157 if (tree.isType) toTypeTree(tree) else constToLiteral(tree)
@@ -154,7 +163,9 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
154163 constToLiteral(foldCondition(tree))
155164
156165 override def transformTyped (tree : Typed )(implicit ctx : Context ): Tree =
157- constToLiteral(tree)
166+ // Singleton type cases (such as `case _: "a"`) are constant-foldable.
167+ // We avoid constant-folding those as doing so would change the meaning of the pattern (see transformIdent).
168+ if (! ctx.mode.is(Mode .Pattern )) constToLiteral(tree) else tree
158169
159170 override def transformBlock (tree : Block )(implicit ctx : Context ): Tree =
160171 constToLiteral(tree)
Original file line number Diff line number Diff line change 1+ an `a`
2+ false
3+ not `a`
Original file line number Diff line number Diff line change 1+ object Test {
2+
3+ def isAType (arg : String ): Unit = arg match {
4+ case _ : " a" => println(" an `a`" )
5+ case _ => println(" not `a`" )
6+ }
7+
8+ def main (args : Array [String ]): Unit = {
9+ isAType(" a" )
10+ println(new String (" a" ).isInstanceOf [" a" ])
11+ isAType(new String (" a" ))
12+ }
13+
14+ }
You can’t perform that action at this time.
0 commit comments