From e9bfa33c1eef822eb9d3d0f471f4bbbe390e1e65 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Wed, 25 Mar 2015 19:26:36 +0100 Subject: SI-9239 fix java generic signature when traits extend classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given the following code: class C1[T] trait T1[T] extends C1[T] class C2[T] extends T1[T] The generic signature of C2 changed after ced3ca8 from "C1[T], T1[T]" to "Object, T1[T]", even though C1 was still marked as a superclass in the bytecode... C1 was removed because a subclass (T1) appeared later on, and it was possible for a trait to cause a class to be evicted. It turns out that if a class A appears in "parents", it *always* has to stay in the signature: if a trait later in the list inherits from some class, that class has to be a superclass of A (per SLS ยง5.1), or A itself, so in any case, the most specific superclass is A, so A should stay in the signature. Thus minimizeParents now only allows traits/interfaces to be removed from the list (the refactoring in 7552739, moving from mixinClasses to parents, makes this much easier to fix). This didn't happen for non-generic signatures because there are two separate fields in the classfile for this (one for the superclass, one for interfaces), so interfaces were processed on their own. Thus non-parametrized classes were not affected. Anything that used erased types at runtime was also fine (like isInstanceOf checks), and anything that used ScalaSignature was also unaffected. Maybethat's why so few things broke... See the test for how this affects Java (hint: badly). This changes very few things when building scala itself, and the changes seem sensible: --- sandbox/lib/scala-library.jar#!scala/runtime/NonLocalReturnControl.class +++ build/pack/lib/scala-library.jar#!scala/runtime/NonLocalReturnControl.class - Generic Signature: Ljava/lang/Object;Lscala/util/control/ControlThrowable; + Generic Signature: Ljava/lang/Throwable;Lscala/util/control/ControlThrowable; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/QueueProxy$$anon$1.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/QueueProxy$$anon$1.class - Generic Signature: Ljava/lang/Object;Lscala/collection/mutable/QueueProxy; + Generic Signature: Lscala/collection/mutable/Queue;Lscala/collection/mutable/QueueProxy; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/collection/immutable/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/immutable/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/collection/immutable/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/immutable/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/throws.class +++ build/pack/lib/scala-library.jar#!scala/throws.class - Generic Signature: Ljava/lang/Object;Lscala/annotation/StaticAnnotation; + Generic Signature: Lscala/annotation/Annotation;Lscala/annotation/StaticAnnotation; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/StackProxy$$anon$1.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/StackProxy$$anon$1.class - Generic Signature: Ljava/lang/Object;Lscala/collection/mutable/StackProxy; + Generic Signature: Lscala/collection/mutable/Stack;Lscala/collection/mutable/StackProxy; --- sandbox/lib/scala-library.jar#!scala/collection/convert/Wrappers$IterableWrapper.class +++ build/pack/lib/scala-library.jar#!scala/collection/convert/Wrappers$IterableWrapper.class - Generic Signature: Ljava/lang/Object;Lscala/collection/convert/Wrappers$IterableWrapperTrait;Lscala/Product;Lscala/Serializable; + Generic Signature: Ljava/util/AbstractCollection;Lscala/collection/convert/Wrappers$IterableWrapperTrait;Lscala/Product;Lscala/Serializable; --- sandbox/lib/scala-library.jar#!scala/collection/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/collection/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory; + Generic Signature: Lscala/collection/generic/GenTraversableFactory;Lscala/collection/generic/TraversableFactory; --- sandbox/lib/scala-library.jar#!scala/collection/parallel/AdaptiveWorkStealingForkJoinTasks$WrappedTask.class +++ build/pack/lib/scala-library.jar#!scala/collection/parallel/AdaptiveWorkStealingForkJoinTasks$WrappedTask.class - Generic Signature: Ljava/lang/Object;Lscala/collection/parallel/ForkJoinTasks$WrappedTask;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask; + Generic Signature: Lscala/concurrent/forkjoin/RecursiveAction;Lscala/collection/parallel/ForkJoinTasks$WrappedTask;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask; --- test/files/pos/t9239/Declaration.scala | 3 +++ test/files/pos/t9239/Usage.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/files/pos/t9239/Declaration.scala create mode 100644 test/files/pos/t9239/Usage.java (limited to 'test') diff --git a/test/files/pos/t9239/Declaration.scala b/test/files/pos/t9239/Declaration.scala new file mode 100644 index 0000000000..452dcc1e77 --- /dev/null +++ b/test/files/pos/t9239/Declaration.scala @@ -0,0 +1,3 @@ +class Foo[A] +trait Bar[A] extends Foo[A] +class Baz[A] extends Bar[A] diff --git a/test/files/pos/t9239/Usage.java b/test/files/pos/t9239/Usage.java new file mode 100644 index 0000000000..d1e3fb0c3e --- /dev/null +++ b/test/files/pos/t9239/Usage.java @@ -0,0 +1,15 @@ +/** + * Used to fail with: + * + * Usage.java:5: error: incompatible types: Baz cannot be converted to Foo + * foo(f); + * ^ + */ +public class Usage { + public Usage() { + Baz f = null; + foo(f); + } + + public void foo(Foo f) { }; +} -- cgit v1.2.3