diff options
author | Antoine Gourlay <antoine@gourlay.fr> | 2015-03-25 19:26:36 +0100 |
---|---|---|
committer | Antoine Gourlay <antoine@gourlay.fr> | 2015-03-25 20:49:53 +0100 |
commit | e9bfa33c1eef822eb9d3d0f471f4bbbe390e1e65 (patch) | |
tree | 8aa2544f4751871a3e59bd22d563fdea17ab7166 /test | |
parent | 2dc40cc7d7d956a510a9278ab236014f3fb564bc (diff) | |
download | scala-e9bfa33c1eef822eb9d3d0f471f4bbbe390e1e65.tar.gz scala-e9bfa33c1eef822eb9d3d0f471f4bbbe390e1e65.tar.bz2 scala-e9bfa33c1eef822eb9d3d0f471f4bbbe390e1e65.zip |
SI-9239 fix java generic signature when traits extend classes
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: <T:Ljava/lang/Object;>Ljava/lang/Object;Lscala/util/control/ControlThrowable;
+ Generic Signature: <T:Ljava/lang/Object;>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<TA;>;
+ Generic Signature: Lscala/collection/mutable/Queue<TA;>;Lscala/collection/mutable/QueueProxy<TA;>;
--- 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<Lscala/collection/mutable/Iterable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/mutable/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Iterable;>;
--- 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<Lscala/collection/immutable/Traversable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/immutable/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Traversable;>;
--- 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<Lscala/collection/immutable/Iterable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/immutable/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Iterable;>;
--- 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<Lscala/collection/mutable/Traversable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/mutable/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Traversable;>;
--- sandbox/lib/scala-library.jar#!scala/throws.class
+++ build/pack/lib/scala-library.jar#!scala/throws.class
- Generic Signature: <T:Ljava/lang/Throwable;>Ljava/lang/Object;Lscala/annotation/StaticAnnotation;
+ Generic Signature: <T:Ljava/lang/Throwable;>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<TA;>;
+ Generic Signature: Lscala/collection/mutable/Stack<TA;>;Lscala/collection/mutable/StackProxy<TA;>;
--- 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: <A:Ljava/lang/Object;>Ljava/lang/Object;Lscala/collection/convert/Wrappers$IterableWrapperTrait<TA;>;Lscala/Product;Lscala/Serializable;
+ Generic Signature: <A:Ljava/lang/Object;>Ljava/util/AbstractCollection<TA;>;Lscala/collection/convert/Wrappers$IterableWrapperTrait<TA;>;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<Lscala/collection/Iterable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/Iterable;>;
--- 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<Lscala/collection/Traversable;>;
+ Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/Traversable;>;
--- 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: <R:Ljava/lang/Object;Tp:Ljava/lang/Object;>Ljava/lang/Object;Lscala/collection/parallel/ForkJoinTasks$WrappedTask<TR;TTp;>;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask<TR;TTp;>;
+ Generic Signature: <R:Ljava/lang/Object;Tp:Ljava/lang/Object;>Lscala/concurrent/forkjoin/RecursiveAction;Lscala/collection/parallel/ForkJoinTasks$WrappedTask<TR;TTp;>;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask<TR;TTp;>;
Diffstat (limited to 'test')
-rw-r--r-- | test/files/pos/t9239/Declaration.scala | 3 | ||||
-rw-r--r-- | test/files/pos/t9239/Usage.java | 15 |
2 files changed, 18 insertions, 0 deletions
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<String> cannot be converted to Foo<String> + * foo(f); + * ^ + */ +public class Usage { + public Usage() { + Baz<String> f = null; + foo(f); + } + + public void foo(Foo<String> f) { }; +} |