summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-01-29 14:00:05 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-01-29 14:00:05 +1000
commit6f9c65d784ddc0df3accf8ca821c7f9e081110f0 (patch)
tree2c5a5312d1c37aa1a5f71e127ddc7a860e421227 /src/compiler
parent8a761a313bfe3d79afefed1622b69a850636d732 (diff)
parent136c5ed872d518eba327813c97e92111093e5a0a (diff)
downloadscala-6f9c65d784ddc0df3accf8ca821c7f9e081110f0.tar.gz
scala-6f9c65d784ddc0df3accf8ca821c7f9e081110f0.tar.bz2
scala-6f9c65d784ddc0df3accf8ca821c7f9e081110f0.zip
Merge pull request #4919 from retronym/ticket/9630
Pattern Matching analysis improvements
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Parsers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
4 files changed, 16 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
index f4584f3627..cc3f01e53b 100644
--- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
@@ -16,8 +16,9 @@ trait Parsers {
val tree = gen.mkTreeOrBlock(parser.parseStatsOrPackages())
sreporter.infos.foreach {
case sreporter.Info(pos, msg, sreporter.ERROR) => throw ParseException(pos, msg)
+ case _ =>
}
tree
} finally global.reporter = oldReporter
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index 1a4df9973e..8b2e09495f 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 affbcf9ec8..ab3b25e76b 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -84,11 +84,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
@@ -172,6 +176,8 @@ trait TreeAndTypeAnalysis extends Debugging {
filterChildren(subclasses)
})
}
+ case sym if sym.isCase =>
+ List(List(tp))
case sym =>
debug.patmat("enum unsealed "+ ((tp, sym, sym.isSealed, isPrimitiveValueClass(sym))))
@@ -276,7 +282,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
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 84af9233e1..bf64ed9baa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1860,7 +1860,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
clazz.annotations.map(_.completeInfo())
if (templ.symbol == NoSymbol)
templ setSymbol clazz.newLocalDummy(templ.pos)
- val self1 = templ.self match {
+ val self1 = (templ.self: @unchecked) match {
case vd @ ValDef(_, _, tpt, EmptyTree) =>
val tpt1 = checkNoEscaping.privates(
clazz.thisSym,