Skip to content

Commit d70ce95

Browse files
committed
Make singleton typecase patterns and type checks consistent
1 parent 964792d commit d70ce95

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
144144
}
145145

146146
override def transformIdent(tree: Ident)(implicit ctx: Context): Tree =
147-
if (tree.isType) toTypeTree(tree) else constToLiteral(tree)
147+
if (tree.isType) {
148+
toTypeTree(tree)
149+
} else if (tree.name != nme.WILDCARD) {
150+
// Constant-foldable wildcards can occur in patterns, for instance as `case _: "a"`
151+
// we avoid constant-folding those as doing so would change the meaning of the pattern
152+
constToLiteral(tree)
153+
} else tree
148154

149155
override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
150156
if (tree.isType) toTypeTree(tree) else constToLiteral(tree)
@@ -156,7 +162,9 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
156162
constToLiteral(foldCondition(tree))
157163

158164
override def transformTyped(tree: Typed)(implicit ctx: Context): Tree =
159-
constToLiteral(tree)
165+
// Singleton type cases (such as `case _: "a"`) are constant-foldable
166+
// we avoid constant-folding those as doing so would change the meaning of the pattern
167+
if (!ctx.mode.is(Mode.Pattern)) constToLiteral(tree) else tree
160168

161169
override def transformBlock(tree: Block)(implicit ctx: Context): Tree =
162170
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)