diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-05-07 23:29:02 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-11-14 22:19:49 +1000 |
commit | 5b8327b807c40cab867065cf695191a36c9210ee (patch) | |
tree | 8e3964382814439fe2436fa37941610179a92781 /test/files/run | |
parent | b431a4bd83d3bfb2b95d0426d2905b34ce1265ad (diff) | |
download | scala-5b8327b807c40cab867065cf695191a36c9210ee.tar.gz scala-5b8327b807c40cab867065cf695191a36c9210ee.tar.bz2 scala-5b8327b807c40cab867065cf695191a36c9210ee.zip |
SI-7459 Handle pattern binders used as prefixes in TypeTrees.
Match translation was incorrect for:
case t => new t.C
case D(t) => new d.C
We would end up with Types in TypeTrees referring to the wrong
symbols, e.g:
// t7459a.scala
((x0$1: this.LM) => {
case <synthetic> val x1: this.LM = x0$1;
case4(){
matchEnd3(new tttt.Node[Any]())
};
matchEnd3(x: Any){
x
}
Or:
// t7459b.scala
((x0$1: CC) => {
case <synthetic> val x1: CC = x0$1;
case4(){
if (x1.ne(null))
matchEnd3(new tttt.Node[Any]())
else
case5()
};
This commit:
- Changes `bindSubPats` to traverse types, as well as terms,
in search of references to bound symbols
- Changes `Substitution` to reuse `Tree#substituteSymbols` rather
than the home-brew substitution from `Tree`s to `Tree`s, if the
`to` trees are all `Ident`s
- extends `substIdentsForTrees` to substitute selections like
`x1.caseField` into types.
I had to dance around the awkward handling of "swatches" (exception
handlers that can be implemented with JVM native type switches) by
duplicating trees to avoid seeing the results of `substituteSymbols`
in `caseDefs` after we abandon that approach if we detect the
patterns are too complex late in the game.
I also had to add an escape hatch for the "type selection from
volatile type" check in the type checker. Without this, the
translation of `pos/t7459c.scala`:
case <synthetic> val x1: _$1 = (null: Test.Mirror[_]).universe;
case5(){
if (x1.isInstanceOf[Test.JavaUniverse])
{
<synthetic> val x2: _$1 with Test.JavaUniverse = (x1.asInstanceOf[_$1 with Test.JavaUniverse]: _$1 with Test.JavaUniverse);
matchEnd4({
val ju1: Test.JavaUniverse = x2;
val f: () => x2.Type = (() => (null: x2.TypeTag[Nothing]).tpe);
.. triggers that error at `x2.TypeTag`.
Diffstat (limited to 'test/files/run')
-rw-r--r-- | test/files/run/t7459a.scala | 14 | ||||
-rw-r--r-- | test/files/run/t7459b-optimize.flags | 1 | ||||
-rw-r--r-- | test/files/run/t7459b-optimize.scala | 21 | ||||
-rw-r--r-- | test/files/run/t7459b.scala | 21 | ||||
-rw-r--r-- | test/files/run/t7459c.scala | 16 | ||||
-rw-r--r-- | test/files/run/t7459d.scala | 15 | ||||
-rw-r--r-- | test/files/run/t7459f.scala | 12 |
7 files changed, 100 insertions, 0 deletions
diff --git a/test/files/run/t7459a.scala b/test/files/run/t7459a.scala new file mode 100644 index 0000000000..e9653c6e79 --- /dev/null +++ b/test/files/run/t7459a.scala @@ -0,0 +1,14 @@ +class LM { + class Node[B1] + case class CC(n: LM) + + // crash + val f: (LM => Any) = { + case tttt => + new tttt.Node[Any]() + } +} + +object Test extends App { + new LM().f(new LM()) +} diff --git a/test/files/run/t7459b-optimize.flags b/test/files/run/t7459b-optimize.flags new file mode 100644 index 0000000000..49d036a887 --- /dev/null +++ b/test/files/run/t7459b-optimize.flags @@ -0,0 +1 @@ +-optimize diff --git a/test/files/run/t7459b-optimize.scala b/test/files/run/t7459b-optimize.scala new file mode 100644 index 0000000000..605890962c --- /dev/null +++ b/test/files/run/t7459b-optimize.scala @@ -0,0 +1,21 @@ +class LM { + class Node[B1] + + // crash + val g: (CC => Any) = { + case CC(tttt) => + new tttt.Node[Any]() + } + + val h: (Some[CC] => Any) = { + case Some(CC(tttt)) => + new tttt.Node[Any]() + } +} + +object Test extends App { + new LM().g(new CC(new LM())) + new LM().h(Some(new CC(new LM()))) +} +case class CC(n: LM) + diff --git a/test/files/run/t7459b.scala b/test/files/run/t7459b.scala new file mode 100644 index 0000000000..605890962c --- /dev/null +++ b/test/files/run/t7459b.scala @@ -0,0 +1,21 @@ +class LM { + class Node[B1] + + // crash + val g: (CC => Any) = { + case CC(tttt) => + new tttt.Node[Any]() + } + + val h: (Some[CC] => Any) = { + case Some(CC(tttt)) => + new tttt.Node[Any]() + } +} + +object Test extends App { + new LM().g(new CC(new LM())) + new LM().h(Some(new CC(new LM()))) +} +case class CC(n: LM) + diff --git a/test/files/run/t7459c.scala b/test/files/run/t7459c.scala new file mode 100644 index 0000000000..144c5d793b --- /dev/null +++ b/test/files/run/t7459c.scala @@ -0,0 +1,16 @@ +class LM { + class Node[B1] + + // crash + val g: (CC => Any) = { + case CC(tttt) => + tttt.## // no crash + new tttt.Node[Any]() + } +} + +object Test extends App { + new LM().g(new CC(new LM())) +} +case class CC(n: LM) + diff --git a/test/files/run/t7459d.scala b/test/files/run/t7459d.scala new file mode 100644 index 0000000000..3263701f9d --- /dev/null +++ b/test/files/run/t7459d.scala @@ -0,0 +1,15 @@ +class LM { + class Node[B1] + case class CC(n: LM) + + // crash + val f: (LM => Any) = { + case tttt => + val uuuu: (tttt.type, Any) = (tttt, 0) + new uuuu._1.Node[Any]() + } +} + +object Test extends App { + new LM().f(new LM()) +} diff --git a/test/files/run/t7459f.scala b/test/files/run/t7459f.scala new file mode 100644 index 0000000000..63e2109560 --- /dev/null +++ b/test/files/run/t7459f.scala @@ -0,0 +1,12 @@ +object Test extends App { + class C + + case class FooSeq(x: Int, y: String, z: C*) + + FooSeq(1, "a", new C()) match { + case FooSeq(1, "a", x@_* ) => + //println(x.toList) + x.asInstanceOf[x.type] + assert(x.isInstanceOf[x.type]) + } +} |