| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
Also eliminates the warning when a mixin forwarder cannot be implemented
because the target method is a java-defined default method in an
interface that is not a direct parent of the class.
The test t5148 is moved to neg, as expected: It was moved to pos when
disabling mixin forwarders in 33e7106. Same for the changed error
message in t4749.
|
|
|
|
|
|
|
|
| |
In most cases when a class inherits a concrete method from a trait we
don't need to generate a forwarder to the default method in the class.
t5148 is moved to pos as it compiles without error now. the error
message ("missing or invalid dependency") is still tested by t6440b.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[Parts of this patch and some of the commentary are from @paulp]
This took me so long to figure out I can't even tell you. Partly because
there were two different bugs, one which only arose for trait forwarders
and one for mirror class forwarders, and every time I'd make one set
of tests work another set would start failing. The runtime failures
associated with these bugs were fairly well hidden because you usually
have to go through java to encounter them: scala doesn't pay that much
attention to generic signatures, so they can be wrong and scala might still
generate correct code. But java is not so lucky.
Bug #1)
During mixin composition, classes which extend traits receive forwarders
to the implementations. An attempt was made to give these the correct
info (in method "cloneBeforeErasure") but it was prone to giving
the wrong answer, because: the key attribute which the forwarder
must capture is what the underlying method will erase to *where the
implementation is*, not how it appears to the class which contains it.
That means the signature of the forwarder must be no more precise than
the signature of the inherited implementation unless additional measures
will be taken.
This subtle difference will put on an unsubtle show for you in test
run/t3452.scala.
trait C[T]
trait Search[M] { def search(input: M): C[Int] = null }
object StringSearch extends Search[String] { }
StringSearch.search("test"); // java
// java.lang.NoSuchMethodError: StringSearch.search(Ljava/lang/String;)LC;
The principled thing to do here would be to create a pair of
methods in the host class: a mixin forwarder with the erased
signature `(String)C[Int]`, and a bridge method with the same
erased signature as the trait interface facet.
But, this turns out to be pretty hard to retrofit onto the
current setup of Mixin and Erasure, mostly due to the fact
that mixin happens after erasure which has already taken
care of bridging.
For a future, release, we should try to move all bridging
after mixin, and pursue this approach. But for now, what can
we do about `LinkageError`s for Java clients?
This commit simply checks if the pre-erasure method signature
that we generate for the trait forward erases identically to
that of the interface method. If so, we can be precise. If not,
we emit the erased signature as the generic signature.
Bug #2) The same principle is at work, at a different location.
During genjvm, objects without declared companion classes
are given static forwarders in the corresponding class, e.g.
object Foo { def bar = 5 }
which creates these classes (taking minor liberties):
class Foo$ { static val MODULE$ = new Foo$ ; def bar = 5 }
class Foo { static def bar = Foo$.MODULE$.bar }
In generating these, genjvm circumvented the usual process whereby one
creates a symbol and gives it an info, preferring to target the bytecode
directly. However generic signatures are calculated from symbol info
(in this case reusing the info from the module class.) Lacking even the
attempt which was being made in mixin to "clone before erasure", we
would have runtime failures of this kind:
abstract class Foo {
type T
def f(x: T): List[T] = List()
}
object Bar extends Foo { type T = String }
Bar.f(""); // java
// java.lang.NoSuchMethodError: Bar.f(Ljava/lang/String;)Lscala/collection/immutable/List;
Before/after this commit:
< signature f (Ljava/lang/String;)Lscala/collection/immutable/List<Ljava/lang/String;>;
---
> signature f (Ljava/lang/Object;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
This takes the warning count for compiling collections under
`-Ycheck:jvm` from 1521 to 26.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
One last flurry with the broom before I leave you slobs to code
in your own filth. Eliminated all the trailing whitespace I
could manage, with special prejudice reserved for the test cases
which depended on the preservation of trailing whitespace.
Was reminded I cannot figure out how to eliminate the trailing
space on the "scala> " prompt in repl transcripts. At least
reduced the number of such empty prompts by trimming transcript
code on the way in.
Routed ConsoleReporter's "printMessage" through a trailing
whitespace stripping method which might help futureproof
against the future of whitespace diseases. Deleted the up-to-40
lines of trailing whitespace found in various library files.
It seems like only yesterday we performed whitespace surgery
on the whole repo. Clearly it doesn't stick very well. I suggest
it would work better to enforce a few requirements on the way in.
|
|
|
|
|
|
|
| |
Instead of changing warnings to errors mid-stream, at the end of
a run I check for condition "no errors, some warnings, and fatal
warnings" and then generate an error at that point. This is
necessary to test for some warnings which come from later stages.
|
|
Now notices most things which look like main methods and says
something useful if they aren't usable as entry points.
Closes SI-4749.
|