summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-01-27 19:01:25 +1000
committerAdriaan Moors <adriaan@lightbend.com>2016-12-21 16:53:28 -0800
commitda986839d17dbbd41877df809e3efed8d63deb4e (patch)
treee198a85516c67b8381ac1f45e64e4cb26daa6bb7 /src/compiler/scala/tools/nsc/transform
parent80ce23103ca72762ced87e5cb97e8ae34b434edd (diff)
downloadscala-da986839d17dbbd41877df809e3efed8d63deb4e.tar.gz
scala-da986839d17dbbd41877df809e3efed8d63deb4e.tar.bz2
scala-da986839d17dbbd41877df809e3efed8d63deb4e.zip
SI-9630 Fix spurious warning related to same-named case accessors [backport]
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. (cherry picked from commit 79a52e6807d2797dee12bab1730765441a0e222d)
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform')
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala16
2 files changed, 11 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index 91777b34d5..40fcceb0bf 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
@@ -691,7 +691,7 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis {
// if X is mutable.
freshExistentialSubtype(t.tpe)
}
- else trees find (a => a.correspondsStructure(t)(sameValue)) match {
+ else trees find (a => equivalentTree(a, t)) match {
case Some(orig) =>
debug.patmat("unique tp for tree: " + ((orig, orig.tpe)))
orig.tpe
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index 1331eb6993..c71299b893 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -85,11 +85,15 @@ trait TreeAndTypeAnalysis extends Debugging {
tp <:< tpImpliedNormalizedToAny
}
- // TODO: improve, e.g., for constants
- def sameValue(a: Tree, b: Tree): Boolean = (a eq b) || ((a, b) match {
- case (_ : Ident, _ : Ident) => a.symbol eq b.symbol
- case _ => false
- })
+ def equivalentTree(a: Tree, b: Tree): Boolean = (a, b) match {
+ case (Select(qual1, _), Select(qual2, _)) => equivalentTree(qual1, qual2) && a.symbol == b.symbol
+ case (Ident(_), Ident(_)) => a.symbol == b.symbol
+ case (Literal(c1), Literal(c2)) => c1 == c2
+ case (This(_), This(_)) => a.symbol == b.symbol
+ case (Apply(fun1, args1), Apply(fun2, args2)) => equivalentTree(fun1, fun2) && args1.corresponds(args2)(equivalentTree)
+ // Those are the only cases we need to handle in the pattern matcher
+ case _ => false
+ }
trait CheckableTreeAndTypeAnalysis {
val typer: Typer
@@ -277,7 +281,7 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
// hashconsing trees (modulo value-equality)
def unique(t: Tree, tpOverride: Type = NoType): Tree =
- trees find (a => a.correspondsStructure(t)(sameValue)) match {
+ trees find (a => equivalentTree(a, t)) match {
case Some(orig) =>
// debug.patmat("unique: "+ (t eq orig, orig))
orig