Incorrect bytecode generated for StringBuilder.max · Issue #4214 · scala/bug (original) (raw)

=== Background ===
While trying to weave a simple AspectJ aspect is a Scala compiler jar,
we got a puzzling error that fails the AspectJ weaver if we use
Scala version 2.8.1 or 2.9.0-SNAPSHOT, but not 2.8.0.
Upon closer inspection (see below) there appears to be a problem
due to inconsistent bytecode generated by the Scala compiler.
This not only fails with AspectJ, but also
crashes the Eclipse compiler in a plain (non-AspectJ) Java project.

Here is the analysis based on input from AspectJ project lead Andy Clement.

The issue is with StringBuilder.max (with 2.8.1)

=== What steps will reproduce the problem ? ===
Here is the bytecode generated by the Scala compiler:

public java.lang.Object max(scala.math.Ordering); Code: Stack=2, Locals=2, Args_size=2 0: aload_0 1: aload_1 2: invokestatic SI-1024; //Method scala/collection/TraversableOnce$$class.max:(Lscala/collection/TraversableOnce;Lscala/math/Ordering;)Ljava/lang/Object; 5: areturn Signature: length = 0x2 03 FFFFFFFD

So it calls another method then finishes with an ARETURN (i.e.
returning an object, not a primitive). Now it is generic so we can
lookup the original signature using that attribute, the generic
signature is:

<B:Ljava/lang/Object;>(Lscala/math/Ordering<TB;>;)C;

and that says that the method returns a char (the trailing C), so it
should have been declared 'char max(Ordering)' and finish with an
IRETURN.

Now, the compiler may be being clever and looking for the boxing to a
Character, but it seems odd that the generic signature disagrees
with the bytecode signature in that way.

In Scala 2.8.0 it was not a generic method so there is no mismatch in
signatures.

=== Seeing the problem without involving AspectJ ===
If you want to see the Eclipse compiler crashing, create a pure java project,
give it a dependency on the 2.8.1 scala library then try to compile
this:

import scala.collection.mutable.StringBuilder;

public class CC { public void m() { StringBuilder sb = new StringBuilder(); } }

Eclipse throws up an error message (an Internal compiler error)

Internal compiler error: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:944) CC.java /scala-library-bug/src/bug line 0

I can attach the project if you wish, but as you can see,
there isn't much needed to get the Eclipse compiler to crash.

=== What versions of the following are you using? ===