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 =>
142
142
}
143
143
144
144
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
146
155
147
156
override def transformSelect (tree : Select )(implicit ctx : Context ): Tree =
148
157
if (tree.isType) toTypeTree(tree) else constToLiteral(tree)
@@ -154,7 +163,9 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
154
163
constToLiteral(foldCondition(tree))
155
164
156
165
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
158
169
159
170
override def transformBlock (tree : Block )(implicit ctx : Context ): Tree =
160
171
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