summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-01-29 16:01:32 +1000
committerJason Zaugg <jzaugg@gmail.com>2015-01-29 17:07:24 +1000
commit9735108e9bb13b7b5a48bd2a051a5ec3e8a2f2ac (patch)
tree4dc1b7d09ccabe0d82ebeccb03b3e17514ac098e
parent7b5998a0592ee707c02a13859fe1520687c76c38 (diff)
downloadscala-9735108e9bb13b7b5a48bd2a051a5ec3e8a2f2ac.tar.gz
scala-9735108e9bb13b7b5a48bd2a051a5ec3e8a2f2ac.tar.bz2
scala-9735108e9bb13b7b5a48bd2a051a5ec3e8a2f2ac.zip
SI-9123 More coherent trees with patmat, dependent types
The pattern matcher needs to substitute references to bound variables with references to either a) synthetic temporary vals, or to b) selections. The latter occurs under -optimize to avoid to be frugal with local variable slots. For instance: ``` def test(s: Some[String]) = s match { case Some(elem) => elem.length } ``` Is translated to: ``` def test(s: Some[String]): Int = { case <synthetic> val x1: Some[String] = s; case4(){ if (x1.ne(null)) matchEnd3(x1.x.length()) else case5() }; case5(){ matchEnd3(throw new MatchError(x1)) }; matchEnd3(x: Int){ x } } ``` However, for a long time this translation failed to consider references to the binder in types. #4122 tried to address this by either using standard substitution facilities where available (references to temp vals), and by expanding the patmat's home grown substitution to handle the more complex case of referencing a selection. However, this left the tree in an incoherent state; while it patched up the `.tpe` field of `Tree`s, it failed to modify the info of `Symbol`-s. This led to a crash in the later uncurry phase under `-Ydelambdafy:method`. This commit modifies the info of such symbols to get rid of stray refeferences to the pattern binder symbols.
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala5
-rw-r--r--test/files/pos/t9123.flags1
-rw-r--r--test/files/pos/t9123.scala10
3 files changed, 16 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
index d35aad964d..b2f2516b5b 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
@@ -239,6 +239,11 @@ trait Interface extends ast.TreeDSL {
case Ident(_) => subst(from, to)
case _ => super.transform(tree)
}
+ tree1 match {
+ case _: DefTree =>
+ tree1.symbol.modifyInfo(_.substituteTypes(from, toTypes))
+ case _ =>
+ }
tree1.modifyType(_.substituteTypes(from, toTypes))
}
}
diff --git a/test/files/pos/t9123.flags b/test/files/pos/t9123.flags
new file mode 100644
index 0000000000..c16e2f71dc
--- /dev/null
+++ b/test/files/pos/t9123.flags
@@ -0,0 +1 @@
+-optimize -Ydelambdafy:method
diff --git a/test/files/pos/t9123.scala b/test/files/pos/t9123.scala
new file mode 100644
index 0000000000..22d55b4351
--- /dev/null
+++ b/test/files/pos/t9123.scala
@@ -0,0 +1,10 @@
+trait Setting {
+ type T
+ def value: T
+}
+
+object Test {
+ def test(x: Some[Setting]) = x match {
+ case Some(dep) => Some(dep.value) map (_ => true)
+ }
+}