summaryrefslogtreecommitdiff
path: root/test/files/run/t3425.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-05-20 21:56:14 -0700
committerPaul Phillips <paulp@improving.org>2013-05-21 01:18:20 -0700
commita2ad291acd159ed299eb30305e42a0bace95f02a (patch)
tree63dc189dea7b1096232da0a4e0d0edfdf676578f /test/files/run/t3425.scala
parent085b4d9bdb7ba9f9fe00c63e998e93278a34b161 (diff)
downloadscala-a2ad291acd159ed299eb30305e42a0bace95f02a.tar.gz
scala-a2ad291acd159ed299eb30305e42a0bace95f02a.tar.bz2
scala-a2ad291acd159ed299eb30305e42a0bace95f02a.zip
SI-3425 erasure crash with refinement members.
Checking that a refinement class symbol does not override any symbols does mean it will have to be invoke reflectively; but the converse is not true. It can override other symbols and still have to be called reflectively, because the overridden symbols may also be defined in refinement classes. scala> class Foo { type R1 <: { def x: Any } ; type R2 <: R1 { def x: Int } } defined class Foo scala> typeOf[Foo].member(TypeName("R2")).info.member("x": TermName).overrideChain res1: List[$r.intp.global.Symbol] = List(method x, method x) scala> res1 filterNot (_.owner.isRefinementClass) res2: List[$r.intp.global.Symbol] = List() And checking that "owner.info decl name == this" only works if name is not overloaded. So the logic is all in "isOnlyRefinementMember" now, and let's hope that suffices for a while.
Diffstat (limited to 'test/files/run/t3425.scala')
-rw-r--r--test/files/run/t3425.scala40
1 files changed, 40 insertions, 0 deletions
diff --git a/test/files/run/t3425.scala b/test/files/run/t3425.scala
new file mode 100644
index 0000000000..6505ee6e24
--- /dev/null
+++ b/test/files/run/t3425.scala
@@ -0,0 +1,40 @@
+object Other {
+ abstract class Foo {
+ type R1 <: { def x: Any }
+ type R2 <: R1 { def x: Int }
+
+ def f(x: R2) = x.x
+ }
+
+ abstract class Bar {
+ trait R0 { def x: Any }
+ type R1 <: R0 { def x: AnyVal }
+ type R2 <: R1 { def x: Int }
+
+ def f(x: R2) = x.x
+ }
+}
+object Test {
+ trait A
+ trait B
+ def x(a: (A { val y: Int }) with B { val y: Int }) = a.y
+
+ class C extends A with B {
+ val y = 456
+ }
+
+ class Bippy { def x: Int = 789 }
+
+ def main(args: Array[String]): Unit = {
+ println(x(new A with B { val y = 123 }))
+ println(x(new C))
+
+ { val foo = new Other.Foo { type R1 = Bippy ; type R2 = Bippy }
+ println(foo.f(new Bippy))
+ }
+ { val bar = new Other.Bar { type R1 = Bippy with R0 ; type R2 = R1 }
+ println(bar.f(new Bippy with bar.R0))
+ }
+ }
+}
+