8000 SI-9630 Fix spurious warning related to same-named case accessors · scala/scala@79a52e6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 79a52e6

Browse files
committed
SI-9630 Fix spurious warning related to same-named case accessors
Hash consing of trees within pattern match analysis was broken, and considered `x1.foo#1` to be the same tree as `x1.foo#2`, even though the two `foo`-s referred to different symbols. The hash consing was based on `Tree#correspondsStructure`, but the predicate in that function cannot veto correspondance, it can only supplement the default structural comparison. I've instead created a custom tree comparison method for use in the pattern matcher that handles the tree shapes that we use.
1 parent bbd890b commit 79a52e6

File tree

11 files changed

+112
-7
lines changed

11 files changed

+112
-7
lines changed

src/compiler/scala/tools/nsc/transform/patmat/Logic.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis {
691691
// if X is mutable.
692692
freshExistentialSubtype(t.tpe)
693693
}
694-
else trees find (a => a.correspondsStructure(t)(sameValue)) match {
694+
else trees find (a => equivalentTree(a, t)) match {
695695
case Some(orig) =>
696696
debug.patmat("unique tp for tree: " + ((orig, orig.tpe)))
697697
orig.tpe

src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,15 @@ trait TreeAndTypeAnalysis extends Debugging {
8484
tp <:< tpImpliedNormalizedToAny
8585
}
8686

87-
// TODO: improve, e.g., for constants
88-
def sameValue(a: Tree, b: Tree): Boolean = (a eq b) || ((a, b) match {
89-
case (_ : Ident, _ : Ident) => a.symbol eq b.symbol
90-
case _ => false
91-
})
87+
def equivalentTree(a: Tree, b: Tree): Boolean = (a, b) match {
88+
case (Select(qual1, _), Select(qual2, _)) => equivalentTree(qual1, qual2) && a.symbol == b.symbol
89+
case (Ident(_), Ident(_)) => a.symbol == b.symbol
90+
case (Literal(c1), Literal(c2)) => c1 == c2
91+
case (This(_), This(_)) => a.symbol == b.symbol
92+
case (Apply(fun1, args1), Apply(fun2, args2)) => equivalentTree(fun1, fun2) && args1.corresponds(args2)(equivalentTree)
93+
// Those are the only cases we need to handle in the pattern matcher
94+
case _ => false
95+
}
9296

9397
trait CheckableTreeAndTypeAnalysis {
9498
val typer: Typer
@@ -276,7 +280,7 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
276280

277281
// hashconsing trees (modulo value-equality)
278282
def unique(t: Tree, tpOverride: Type = NoType): Tree =
279-
trees find (a => a.correspondsStructure(t)(sameValue)) match {
283+
trees find (a => equivalentTree(a, t)) match {
280284
case Some(orig) =>
281285
// debug.patmat("unique: "+ (t eq orig, orig))
282286
orig

test/files/pos/t9399.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xfatal-warnings

test/files/pos/t9399.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
sealed abstract class TA
2+
sealed abstract class TB extends TA
3+
case object A extends TA
4+
case object B extends TB
5+
6+
sealed trait C
7+
case class CTA(id: Int, da: TA) extends C
8+
case class CTB(id: Int, da: TB) extends C
9+
10+
class Test {
11+
def test(c: C): Unit = c match {
12+
case CTA(_, A) =>
13+
case CTA(_, B) =>
14+
case CTB(_, B) =>
15+
}
16+
}
17+

test/files/pos/t9411a.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xfatal-warnings

test/files/pos/t9411a.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
object OhNoes {
2+
3+
sealed trait F
4+
sealed abstract class FA extends F
5+
sealed abstract class FB extends F
6+
7+
case object FA1 extends FA
8+
case object FB1 extends FB
9+
case object FB2 extends FB
10+
11+
sealed trait G
12+
case object G1 extends G
13+
case object G2 extends G
14+
15+
sealed trait H
16+
case class H1(a: FB, b: G) extends H
17+
case class H2(a: F) extends H
18+
19+
val demo: H => Unit = {
20+
case H1(FB1, G1) =>
21+
case H1(FB2, G2) =>
22+
case H2(_: FB) =>
23+
case H2(_: FA) =>
24+
case H1(FB1, G2) =>
25+
case H1(FB2, G1) =>
26+
}
27+
}

test/files/pos/t9411b.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xfatal-warnings

test/files/pos/t9411b.scala

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
object OhNoes {
2+
3+
sealed trait F
4+
sealed abstract class FA extends F
5+
sealed abstract class FB extends F
6+
7+
case object FA1 extends FA
8+
case object FB1 extends FB
9+
case object FB2 extends FB
10+
11+
sealed trait G
12+
case object G1 extends G
13+
case object G2 extends G
14+
15+
sealed trait H
16+
case class H1(a: FB, b: G) extends H
17+
case class H2(b: F) extends H
18+
19+
val demo: H => Unit = {
20+
case H1(FB1, G1) =>
21+
case H1(FB2, G2) =>
22+
case H2(_: FB) =>
23+
case H2(_: FA) =>
24+
case H1(FB1, G2) =>
25+
case H1(FB2, G1) =>
26+
}
27+
28+
val demo2: H => Unit = {
29+
case H2(_: FA) =>
30+
case H2(_: FB) =>
31+
case H1(FB1, G1) =>
32+
case H1(FB2, G1) =>
33+
case H1(FB1, G2) =>
34+
case H1(FB2, G2) =>
35+
}
36+
}

test/files/pos/t9630.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xfatal-warnings

test/files/pos/t9630/t9630a.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
sealed trait Base
3+
final case class Base_1(sameName: Some[Any]) extends Base
4+
final case class Base_2(sameName: Nested) extends Base
5+
6+
sealed trait Nested
7+
final case class Nested_1(x: Any) extends Nested
8+
final case class Nested_2(y: Any) extends Nested
9+

0 commit comments

Comments
 (0)
0