Skip to content

Commit 6261ed2

Browse files
authored
Merge pull request #7027 from dotty-staging/i6996
Make singleton typecase patterns and type checks consistent
2 parents ff6427e + 4b64f0b commit 6261ed2

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

compiler/src/dotty/tools/dotc/transform/FirstTransform.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff 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)

tests/run/i6996.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
an `a`
2+
false
3+
not `a`

tests/run/i6996.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
}

0 commit comments

Comments
 (0)