From 75c411c85115d7907f8e2cbe0fb16bd5618ba8a5 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 21 May 2014 09:40:33 +0200 Subject: SI-8607 Fix erasure for value class inheriting from private class The fix for SI-4283 added a pre-emptive cast of the qualifier of a selection `qual.a` to avoid later casting to the owner of `a` if that owner might be inaccessible at the call site. This fixed a `LinkageError`. In the enclosed test, this cast led to the following diff in the tree shapes (with respect to a version with a public base class). [erasure] - new p1.C.(c.$asInstanceOf[scala.this.Int]()).a(); + new p1.C.(new p1.C.(c.$asInstanceOf[scala.this.Int]()).$asInstanceOf[ErasedValueType( class C, scala.this.Int)]().$asInstanceOf[scala.this.Int]()).a(); [posterasure] - new p1.C.(c).a(); + new p1.C.(new p1.C.(c).$asInstanceOf[scala.this.Int]().$asInstanceOf[scala.this.Int]()) .a(); () What we really wanted to end up with is: new p1.C.(c).$asInstanceOf[C]().a(); The stray cast leads to the crash: error: should have been unboxed by erasure: new p1.C.(c).$asInstanceOf[scala.this.Int]() Rather than trying to fix this in erasure/posterasure, this commit instead relies on the fact the owner of `a` cannot be Java defined if `qual`s type is a derived value class. This follows from the restrictions we place on value classes. With this knowledge, we elide the cast altogether in this case. --- test/files/run/t8607.scala | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/files/run/t8607.scala (limited to 'test') diff --git a/test/files/run/t8607.scala b/test/files/run/t8607.scala new file mode 100644 index 0000000000..1b8ef9bbd0 --- /dev/null +++ b/test/files/run/t8607.scala @@ -0,0 +1,36 @@ +package p1 { + private[p1] trait B extends Any { + def a: Any = "" + } + + class C(val value: Int) extends AnyVal with B { + // def b = "" + } +} + +object Test { + def main(args: Array[String]) { + val c = new p1.C(42) + c.a + /* + new p1.C.( + c.$asInstanceOf[scala.this.Int]() + ).a(); + + + new p1.C.( + new p1.C.( + c.$asInstanceOf[scala.this.Int]() + ).$asInstanceOf[ErasedValueType(class C, scala.this.Int)]() + .$asInstanceOf[scala.this.Int]() + ).a(); + + new p1.C.( + new p1.C.(c) + .$asInstanceOf[scala.this.Int]() + .$asInstanceOf[scala.this.Int]() + ).a(); + + */ + } +} -- cgit v1.2.3