summaryrefslogtreecommitdiff
path: root/test/files/neg/t6260b.check
Commit message (Collapse)AuthorAgeFilesLines
* SI-6260 Avoid double-def error with lambdas over value classesJason Zaugg2014-02-101-7/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Post-erasure of value classs in method signatures to the underlying type wreaks havoc when the erased signature overlaps with the generic signature from an overriden method. There just isn't room for both. But we *really* need both; callers to the interface method will be passing boxed values that the bridge needs to unbox and pass to the specific method that accepts unboxed values. This most commonly turns up with value classes that erase to Object that are used as the parameter or the return type of an anonymous function. This was thought to have been intractable, unless we chose a different name for the unboxed, specific method in the subclass. But that sounds like a big task that would require call-site rewriting, ala specialization. But there is an important special case in which we don't need to rewrite call sites. If the class defining the method is anonymous, there is actually no need for the unboxed method; it will *only* ever be called via the generic method. I came to this realisation when looking at how Java 8 lambdas are handled. I was expecting bridge methods, but found none. The lambda body is placed directly in a method exactly matching the generic signature. This commit detects the clash between bridge and target, and recovers for anonymous classes by mangling the name of the target method's symbol. This is used as the bytecode name. The generic bridge forward to that, as before, with the requisite box/unbox operations.
* SI-6385 Avoid bridges to identical signatures over value classesJason Zaugg2013-10-281-0/+7
As Paul noted in the comments to SI-6260 (from which I mined some test cases) "there is no possible basis for conflict here": scala> class C[A](val a: Any) extends AnyVal defined class C scala> class B { def x[A](ca: C[A]) = () } defined class B scala> class D extends B { override def x[A](ca: C[A]) = () } <console>:8: error: bridge generated for member method x: [A](ca: C[A])Unit in class D which overrides method x: [A](ca: C[A])Unit in class B clashes with definition of the member itself; both have erased type (ca: Object)Unit class D extends B { override def x[A](ca: C[A]) = () } ^ What was happening? Bridge computation compares `B#x` and `D#x` exitingErasure, which results in comparing: ErasedValueType(C[A(in B#x)]) =:= ErasedValueType(C[A(in D#x)]) These types were considered distinct (on the grounds of the unique type hash consing), even though they have the same erasure and involve the same value class. That triggered creation of an bridge. After post-erasure eliminates the `ErasedValuedType`s, we find that this marvel of enginineering is bridges `(Object)Unit` right back onto itself. The previous resolution of SI-6385 (d435f72e5fb7fe) was a test case that confirmed that we detected the zero-length bridge and reported it nicely, which happened after related work in SI-6260. But we can simply avoid creating in it in the first place. That's what this commit does. It does so by reducing the amount of information carried in `ErasedValueType` to the bare minimum needed during the erasure -> posterasure transition. We need to know: 1. which value class wraps the value, so we can box and unbox as needed 2. the erasure of the underlying value, which will replace this type in post-erasure. This construction means that the bridge above computation now compares: ErasedValueType(C, Any) =:= ErasedValueType(C, Any]) I have included a test to show that: - we don't incur any linkage or other runtime errors in the reported case (run/t6385.scala) - a similar case compiles when the signatures align (pos/t6260a.scala), but does *not* compile when the just erasures align (neg/t6260c.scala) - polymorphic value classes continue to erase to the instantiated type of the unbox: (run/t6260b.scala) - other cases in SI-6260 remains unsolved and indeed unsolvable without an overhaul of value classes: (neg/t6260b.scala) In my travels I spotted a bug in corner case of null, asInstanceOf and value classes, which I have described in a pending test.