Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static methods in objects extending an abstract class, or classes with covariant-overriding mxins, get inconsistent java generics signature #3452

Closed
scabug opened this issue May 19, 2010 · 36 comments

Comments

@scabug
Copy link

@scabug scabug commented May 19, 2010

See this [http://scala-programming-language.1934581.n4.nabble.com/valid-code-throws-NoSuchMethodError-at-runtime-td2222685.html#a2222685 thread]

Compiling this with scalac (tested 2.8.0.RC2):

abstract class BulkSearch {
       type R   <: Row
       type Rel <: Relation [R]
       type Corr <: Correspondence[R]

       def searchFor(input: Rel): Mapping[Corr] = null
}

object BulkSearchInstance extends BulkSearch {
       type R   = UpRow
       type Rel = UpRelation
       type Corr = UpCorrespondence
}

class Row
class UpRow extends Row

class Relation [R <: Row]
class UpRelation extends Relation [UpRow]

class Correspondence [R <: Row]
class UpCorrespondence extends Correspondence [UpRow]

class Mapping[MC <: Correspondence[_]]

and compiling this with javac:

public class JavaApp {
       public static void main(String[] args) {
               BulkSearchInstance.searchFor(new UpRelation());
       }
}

produces no compile-time errors but a runtime error later on:

Exception in thread "main" java.lang.NoSuchMethodError: bugs.BulkSearchInstance.searchFor(Lbugs/UpRelation;)Lbugs/Mapping;
       at bugs.JavaApp.main(JavaApp.java:15)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)

After some analysis, I found out that is probably due to an inconsistent generic signature being generated for the static method delegate in BulkSearchInstance.class.

Scalac generates these signatures for BulkSearchInstance.searchFor:

method_info.descriptor (see � 4.3 JVM spec): (LRelation;)LMapping;
attribute 'Signature' (see JSR 014): (LUpRelation;)LMapping<LUpCorrespondence;>;

When javac sees that, it produces something strange (i.e. not matching the descriptor found in BulkSearchInstance.class):

invokestatic    SI-4; //Method BulkSearchInstance.searchFor:(LUpRelation;)LMapping;

which looks like the erasure of the generic signature. However, JVM's linker looks for the exact descriptor when looking for methods. I think the solution should be

  1. Always generate consistent descriptor and generic signature
  2. At least, in the case of the static delegator method in the object class, generate the most specific type possible. The method can't be overridden anyways.

Workaround: use a trait instead of an abstract class

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 19, 2010

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 26, 2010

@dragos said:
(In r22043) Closes #3452, inconsistency between method descriptors and java signature for static forwarders. Review by extempore.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 27, 2011

@paulp said:
Well, I guess I'm 10 months behind on my reviews. (More even.) There was no test case checked in, and as far as I can tell the behavior never changed. The example given in this ticket fails at runtime with scala 2.8.0 and r24603.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 21, 2012

@jrudolph said:
I've further simplified the example to

trait Search[M] {
    def search(input: M): C[Int] = null
}

object StringSearch extends Search[String]

trait C[T]

and

public class JavaApp {
       public static void main(String[] args) {
               StringSearch.search("test");
       }
}

In a strange way the error depends on the return value being an applied type (strange because the error appears in the parameter position). The problem is actually catched using the -Ycheck:genjvm flag:

src/main/scala/Test.scala:5: warning: compiler bug: created generic signature for method search in StringSearch that does not conform to its erasure
signature: (Ljava/lang/String;)LC<Ljava/lang/Object;>;
original type: (input: String)C[Int]
normalized type: (input: String)C[Object]
erasure type: (input: Object)C
if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
object StringSearch extends Search[String]
       ^
one warning found
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 22, 2012

DaveScala (davescala) said:
Another report of this bug
see:
http://groups.google.com/group/scala-user/browse_thread/thread/35fa02126594bfa4

package types
trait IStringPair[T] { 
  def a : String 
  def b : String 
  def build(a : String, b : String) : T 
  def cat(that : IStringPair[T]) = build(this.a + that.a, this.b + that.b) 
  override def toString = a + b 
} 

class StringPair(val a : String, val b : String) extends IStringPair[StringPair] { 
  def build(a : String, b : String) = new StringPair(a, b) 
  def len = a.length + b.length 
} 
C:\scala-2.10.0-M2\examples\testjava>scalac -Ycheck:genjvm types.scala
types.scala:10: warning: compiler bug: created generic signature for method cat
in types.StringPair that does not conform to its erasure
signature: (Ltypes/IStringPair<Ltypes/StringPair;>;)Ltypes/StringPair;
original type: (that: types.IStringPair)types.StringPair
normalized type: (that: types.IStringPair)types.StringPair
erasure type: (that: types.IStringPair)Object
if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
class StringPair(val a : String, val b : String) extends IStringPair[StringPair]
 {
      ^
one warning found
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 23, 2012

@paulp said:
What version of scala is that? I can't reproduce it with any version.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 23, 2012

@paulp said:
OK, I can reproduce the breakage (which is the important part) as outlined at that thread, but I don't get the warning.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 24, 2012

DaveScala (davescala) said:
I could reproduce it in scala-2.10.0-M2 with compiler option -Ycheck:genjvm which generates the warning and seems to fix the signature erasure too.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 30, 2012

@jrudolph said:
Yes, you need the -Ycheck:genjvm to generate the warning. Looking at the code there's a return after generating the warning which circumvents the generation of the broken signature. This would explain why using the flag makes the runtime error disappear.

It may be sensible to enable this flag/code path by default if this can't be fixed soon or is still likely to be broken in some cases. That would mean that a) you can use these methods at all from Java even if the compiler still has a bug when generating them b) you are loosing generic type info at the Java side because the generic type is missing. Compare that to the current situation where although Java can compile against the generic type, the call fails at runtime.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 30, 2012

@paulp said:
I spent most of the last two days on this bug. It's a multiway battle of a bunch of tests where one passing leads to another failing. Still unresolved.

BTW I don't see the warning regardless of -Ycheck, I don't know why. I know it's generating the bad signatures.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 30, 2012

@jrudolph said:
I see. For the original case one simple (naive?) solution would have been to use the checking code to generate the method descriptor from the generic signature. This should work for the static forwarders for objects.

For the new case Dave gave this is obviously not working because the important part is that the method descriptor actually implements the Java interface correctly. So, the generation of the generic signature has to be fixed in this case to match the descriptor. Maybe in this case we should just copy the overwritten method's signature over to the method implementing the method.

It's strange that you're not seeing the warning, it's there in the code, isn't it?. Dave seemed to be working with Scala 2.10.0-M2, right? In my unorderly ways I'm often on some version, where in this case it was f987afe which is master from two weeks ago.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 30, 2012

@paulp said:
Oh, wonderful. I wasn't seeing the warning because the check looking for the string "genjvm" which is not actually the name of the phase. I, having catlike reflexes with respect to the phase names, was entering it as "-Ycheck:jvm" which is what it is supposed to be. You guys were smart enough to enter the string it was looking for.

  • NOTICE! I'M FIXING IT! **

That means it's -Ycheck:jvm, and -Ycheck:genjvm refers to a non-existent phase. The options which take a phase argument should probably fail on mystery strings, but right now they silently ignore. Still, you know if it checked by examining the output: it will always say "[Now checking: jvm]" if it understood you, and it will be silent if it did not.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Mar 30, 2012

@paulp said:
The reason I only warn rather than fixing it at the signature generation point is that detecting it depends on sun internal classes and I don't want to add one more mystery by having it work some places and not others. It would not be rocket science to write our own signature parser, but it's not something I have time for at the moment (even though I've already done it, more than once in fact...) if anyone wants to bring up to date some of the parsers in here, it'd be so appreciated.

https://github.com/paulp/awesome

Look how beautiful:

https://github.com/paulp/awesome/blob/master/src/main/scala/awesome/jvm/SignatureParser.scala

This one is especially compelling given that that's all the necessary logic:

https://github.com/paulp/awesome/blob/master/src/main/scala/awesome/jvm/DescriptorParser.scala

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 19, 2012

@Blaisorblade said:
Paul, I wanted to start hacking on the compiler by addressing this bug, since writing a signature verifier sounded easy enough. However, the task seems to have become irrelevant by now, and maybe to have always been irrelevant for this bug. Hence I collected the pieces together to reintroduce support for -Xverify and to enable the proposed workaround.

More in detail:
(1) the signature parser does not seem to be needed for this warning - in fact, it is currently not used at all, but was used when you wrote this message* for a different warning. You removed this part of the implementation of -Xverify 4 days ago (scala/scala@317a105#diff-18).
(2) I made the extra checking unconditional, since the only obstacle you mentioned (dependency on Sun classes) does not apply.
(3) By now, an ASM-based signature parsing is integrated and used by the GenASM backend - I understand that now ASM is already included in the compiler. This warning has no dependencies on the rest of the ASM backend. Therefore, I readded an implementation of that warning based on ASM, by intelligently merging the old code with the GenASM code. The warning code seems to run correctly (reporting no warning here), but I'd like to have some testcase.

In a moment I'll create a pull request which will reference this comment.

  • I chose some commit around the date of your last post, 30 Mar 2012 (commit 88bc33301a1d1994a7a60f91ff7603c8e902b6a8 from the scala/scala tree). At that time there are two independent warnings, and one relies on Sun's SigParser (triggered by -Xverify) while the other is the one triggered here (triggered by -Ycheck:jvm).
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 19, 2012

@Blaisorblade said:
I just submitted pull request scala/scala#584. I'm running the test suite now, and I'll run 'ant dist' later to be totally sure I didn't break anything (since ant is managing incremental compilation, that looks required).

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@Blaisorblade said:
Jenkins claims that my pull request passes all tests:
https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/130

However, the number of times the warning triggers (for instance when compiling the standard library) is scary:
https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/130/console
After all, the pattern eliciting the problem does not seem to be unusual, and scalac would probably ignore the erased signature and only consider the generic one, hence this amount of warning is not necessarily wrong (also, I did not modify the warning itself, I only enabled it by default).

Moreover, it is somewhat interesting that tests pass, since on my local machine I get errors (mostly OOM) while running the test suite, both with and without my changes (I'm comparing the results).

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@paulp said:
Your errors are probably just ant not having enough memory.

It's easy for the tests to pass and all the warnings to be valid, because scalac ignores the generic signatures completely. To see the breakage caused by this bug, you generally have to involve java so that something will be miscompiled based on the inaccurate signature.

Signature verification wasn't on by default for performance reasons, so you will probably want to measure the asm impact.

The underlying issue is fairly hairy (and there is more than one.) I have it fairly well outlined and fixed for some approximation of fixed, but I have recently lost my taste for this brand of completely thankless work. If you want I can clean up that branch and hand it over if you'd like to go for the finish line.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@paulp said (edited on May 20, 2012 2:51:34 AM UTC):
Here it is: https://github.com/paulp/scala/commit/11c11f0efc

Another reason I stopped there is that I thought my time would be better spent rewriting the backend not to generate wrong signatures, rather than spending any more of my life chasing bugs which could be made impossible with decent engineering. But that's another thing I've lost enthusiasm for.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@Blaisorblade said:
Paul, given my experience as user and bug reporter of Scalac, I would like to thank you for all the work you do; I can also understand your frustration (not that I really understand scalac's internals yet).

I'm taking a look at this. After reading the commit message, I'm not totally sure what's missing there, so I'll have to give a closer look - I'd greatly appreciate any specific hints.

Meanwhile, I'll try testing the results. I've merged your commit and I'm running the testsuite again to verify that no warning is produced, this time with enough memory for ant.

Do you know if Jenkins will recompile my pull request if I push again?
Also, should I use some other channel rather than the bug tracker for these stupid questions of a first-time developer?

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@retronym said:
Currently build bot only builds each PR once; that might be changed:

https://groups.google.com/d/topic/scala-internals/VCGsivMKtoY/discussion

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 20, 2012

@paulp said:

I'm taking a look at this. After reading the commit message, I'm not totally sure what's missing there, so I'll have to give a closer look - I'd greatly appreciate any specific hints.

Take a look at the diff from the two failing tests (assuming it still acts the way I've described; since I've rebased it I can't guarantee it.) It will point you in the direction of the problem. The change in mixin overshoots the target.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 21, 2012

@Blaisorblade said:
Aah I see, I had completely misunderstood the message. I tested the commit on top of my pull request, so the tests don't fail but there are still warnings, like the following confusing one for instance.

strap.comp:
[scalacfork] Compiling 5 files to /Users/pgiarrusso/Documents/Research/Sorgenti/scala/build/strap/classes/compiler
[scalacfork] /Users/pgiarrusso/Documents/Research/Sorgenti/scala/src/compiler/scala/tools/nsc/transform/Erasure.scala:14: warning: compiler bug: created generic signature for method mkTypeCompleter in scala.tools.nsc.transform.Erasure that does not conform to its erasure
[scalacfork] signature: (Lscala/reflect/api/Trees$Tree;Lscala/Function1<Lscala/reflect/internal/Symbols$Symbol;Lscala/runtime/BoxedUnit;>;)Lscala/tools/nsc/typechecker/Namers$TypeCompleter;
[scalacfork] original type: (t: scala.reflect.api.Trees$Tree, c: Function1)Namers.this.Namers$TypeCompleter with Namers.this.Namers$LockingTypeCompleter
[scalacfork] normalized type: (t: scala.reflect.api.Trees$Tree, c: Function1)Namers.this.Namers$TypeCompleter with Namers.this.Namers$LockingTypeCompleter
[scalacfork] erasure type: (t: scala.reflect.api.Trees$Tree, c: Function1)scala.tools.nsc.typechecker.Namers$LockingTypeCompleter
[scalacfork] if this is reproducible, please report bug at https://issues.scala-lang.org/
[scalacfork] abstract class Erasure extends AddInterfaces

The problem is in the return type, Namers.this.Namers$TypeCompleter with Namers.this.Namers$LockingTypeCompleter, which makes little sense since LockingTypeCompleter <: TypeCompleter (I complained somewhere else that intersection types are not always properly simplified- XXX-I'll have to find where!). In addition to making little sense, this intersection type is transformed in different ways - erased to the most specific type of the two (LockingTypeCompleter), which looks good; instead the generic signature contains simply the first component of the intersection; i.e., A with B becomes A in the generic signature even if B <: A).

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 21, 2012

@Blaisorblade said:
About intersection types not being simplified, I'll quote src/compiler/scala/reflect/internal/Types.scala:

/**** This implementation to merge parents was checked in in commented-out
      form and has languished unaltered for five years.  I think we should
      use it or lose it.

Moreover, as far as I see (mostly) from comments, there's no attempt to simplify the intersection of a class with its parents in method Types.intersectionType.
Anyway. I shall continue investigations later.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 21, 2012

@paulp said:

In addition to making little sense, this intersection type is transformed in different ways - erased to the most specific type of the two (LockingTypeCompleter), which looks good; instead the generic signature contains simply the first component of the intersection; i.e., A with B becomes A in the generic signature even if B <: A).

No, I don't think this quite captures the problem. Given this situation:

abstract class A
trait B extends A

In scala B <: A, but that relationship is only known to scala and can't be expressed in the method descriptor. If the descriptor says "B", scala is attempting to say "some unknown class which extends A and implements B" but all java is going to hear is "B", which does not include A. So it is not clear that B is the most specific type, at least not usefully so.

abstract class Foo

trait Bar1
trait Bar2 extends Foo
trait Bar3 { self: Foo => }

class Test {
  def f1 = new Foo { }
  def f2 = new Foo with Bar1 { }
  def f3 = new Foo with Bar2 { }
  def f4 = new Foo with Bar3 { }

  // descriptors:
  // public Foo f1();
  // public Foo f2();
  // public Bar2 f3();
  // public Foo f4();
}
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 22, 2012

@Blaisorblade said (edited on May 26, 2012 11:11:13 PM UTC):
Paul, this semantic issue is most interesting. I also find interesting that you didn't point me to a specification about these issues, and I see why you complained before.

I'm not sure I get you fully, but I do see that things are not so simple as I thought. But does your example support your point? In our case, the relevant descriptor is the one for f3, which is declared to return Bar2, which corresponds to B in your discussion. That is, the erasure algorithm works as I would have expected. Generic signatures are instead computed in a different way: there Foo with Bar2 erases to Foo, and even Bar2 erases to Foo, as shown in the testcase below!

However, the erasure algorithm does what I considered obvious, and I would keep that unchanged for binary compatibility, since there might be existing Java code calling into Scala using erased descriptors (I wrote some myself, even if it was an horrible experience since the Scala interface was much more fancy).
Instead, the generic signatures we produce currently cannot be used if they don't match the descriptors, so we can change them to match more the descriptors without breaking binary compatibility so much - especially before the release of 2.10.

Do you agree about changing that algorithm?

Example

The above example has no generic signatures, but adding type parameters produces a reduced version of the problem in Erasure:

//Other definitions like above, I only changed Test.
class Test {
  def f1 = new Foo { }
  def f2 = new Foo with Bar1 { }
  def f3 = new Foo with Bar2 { }
  def f4 = new Foo with Bar3 { }
  def f5 = new Bar2 { }
  def f6[T](t: T) = new Foo with Bar2 { }
  def f7[T](t: T) = new Bar2 { }

  // descriptors:
  // public Foo f1();
  // public Foo f2();
  // public Bar2 f3();
  // public Foo f4();
  // public Bar2 f5();
  // public Bar2 f6(Object);
  // public Bar2 f7(Object);
  // Both f6 and f7 have generic signature:
  // <T:Ljava/lang/Object;>(TT;)LFoo;
  // which means <T extends Object> Foo methodName(T);
}

Of course, the generic signature is only emitted by a mainline Scala compiler, with the warning disabled. The generic signature warning (that is, -Ycheck:jvm or my pull request) reports the following warnings and omits generic signatures:

SI-3452/DescriptorExample.scala:13: warning: compiler bug: created generic signature for method f6 in Test that does not conform to its erasure
signature: <T:Ljava/lang/Object;>(TT;)LFoo;
original type: [T >: ? <: ?](t: Object)Foo with Bar2
normalized type: [T >: ? <: ?](t: Object)Foo with Bar2
erasure type: (t: Object)Bar2
if this is reproducible, please report bug at https://issues.scala-lang.org/
  def f6[T](t: T) = new Foo with Bar2 { }
      ^
SI-3452/DescriptorExample.scala:14: warning: compiler bug: created generic signature for method f7 in Test that does not conform to its erasure
signature: <T:Ljava/lang/Object;>(TT;)LFoo;
original type: [T >: ? <: ?](t: Object)Foo with Bar2
normalized type: [T >: ? <: ?](t: Object)Foo with Bar2
erasure type: (t: Object)Bar2
if this is reproducible, please report bug at https://issues.scala-lang.org/
  def f7[T](t: T) = new Bar2 { }
      ^
two warnings found

Notice, in particular, that the algorithm producing generic signatures transforms not only Foo with Bar2 into Foo, but also Bar2 into Foo (see f7). This shows nicely another source of mismatch between generic signatures and erased types.

Back to encoding Bar2 with Foo, Java does have some kind of intersection types, at least in type bounds, which might be useful; I did not look into it because I'm sure somebody smarter already tried and failed. For instance, given Java method <T extends Foo & Bar2> T foo(), probably type inference would not infer a type argument for T.

Other remaining bugs

I categorized warnings on the library (which are simpler). Here's a list of what is left there:

  • tons of Nothing-vs-Nothing$ mismatches:
[scalacfork] signature: (TB;)Lscala/runtime/Nothing$;
[scalacfork] original type: (x$1: Object)Nothing
[scalacfork] normalized type: (x$1: Object)scala.runtime.Nothing$
[scalacfork] erasure type: (x$1: Object)Nothing

The documentation of Nothing$ claims that Nothing should erase to Nothing$; this one sounds easiest to fix, so I'll take a look at it first - I might actually be able to fix this.

  • parsers seems to show the same problem with intersection types again;
  • classes extending AnyVal are erased correctly, but not in generic signatures:
[scalacfork] signature: <A:Ljava/lang/Object;>(TA;)Lscala/Predef$ArrowAssoc<TA;>;
[scalacfork] original type: [A >: ? <: ?](x: Object)Predef$ArrowAssoc[A]
[scalacfork] normalized type: [A >: ? <: ?](x: Object)Predef$ArrowAssoc[A]
[scalacfork] erasure type: (x: Object)Object
[scalacfork] if this is reproducible, please report bug at https://issues.scala-lang.org/
[scalacfork]   @inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)

(same problem on any2Ensuring)

  • This warnings I don't get yet - what is the '...'?
[scalacfork] /Users/pgiarrusso/Documents/Research/Sorgenti/scala/src/library/scala/collection/parallel/mutable/ParHashMap.scala:192: warning: compiler bug: created generic signature for object table$1 in scala.collection.parallel.mutable.ParHashMapCombiner that does not conform to its erasure
[scalacfork] signature: ()Lscala/collection/parallel/mutable/ParHashMapCombiner$table$2$;
[scalacfork] original type: ()...
[scalacfork] normalized type: ()...
[scalacfork] erasure type: (table$module$1: scala.runtime.VolatileObjectRef)...
[scalacfork] if this is reproducible, please report bug at https://issues.scala-lang.org/
[scalacfork]     object table extends HashTable[K, DefaultEntry[K, V]] {
  • More crazy stuff, note @annotation.unspecialized:
[scalacfork] /Users/pgiarrusso/Documents/Research/Sorgenti/scala/src/library/scala/runtime/AbstractPartialFunction.scala:64: warning: compiler bug: created generic signature for method applyOrElse$mcZD$sp in scala.runtime.AbstractTotalFunction that does not conform to its erasure
[scalacfork] signature: <A1:Ljava/lang/Object;B1:Ljava/lang/Object;>(TA1;Lscala/Function1<TA1;TB1;>;)TB1;
[scalacfork] original type: [A1 >: ? <: ?, B1 >: ? <: ?](x: Double, default: Function1)B1
[scalacfork] normalized type: [A1 >: ? <: ?, B1 >: ? <: ?](x: Object, default: Function1)B1
[scalacfork] erasure type: (x: Double, default: Function1)Object
[scalacfork] if this is reproducible, please report bug at https://issues.scala-lang.org/
[scalacfork]   @annotation.unspecialized override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x)
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 23, 2012

@paulp said:
"..." is what it (rather opaquely) prints when it hits the maximum recursion depth trying to print the type.

This is exceeding the complexity of conversation I want to have in the useless jira comment interface. Could I talk you into starting a thread on scala-language? Also that way we might get some assistance.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 24, 2012

@Blaisorblade said:
I also prefer email - I also have some code changes which make sense enough, I plan to refine & send the changes + an update over the situation on the weekend.
For analogy with
https://github.com/scala/scala/wiki/Pull-Request-Policy, I plan to send the stuff to scala-internals. Of course you're free to start earlier (CCing me, p (dot) giarrusso (at) gmail (dot) com), but before sending my first email there I'll have to do my "homework".

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented May 28, 2012

@Blaisorblade said:
The bird has left the nest—repeat—the bird has left the nest :-).
There's my email:
https://groups.google.com/d/topic/scala-internals/K2dELqajQbg/discussion

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 11, 2012

@adriaanm said:
Assigning to community as a proxy for Paolo.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jun 19, 2012

@Blaisorblade said:
Thanks for the assignment. I just submitted a new pull request (scala/scala#747) with a partial solution.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 3, 2012

@retronym said (edited on Jul 3, 2012 9:50:45 PM UTC):
Paul, commenting just now on a ticket two thousand notches younger than this one (#1459):

Interesting, I didn't realize it at the time but it sounds from my description above that this is intimately related to SI-3452.
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 9, 2012

@paulp said:
And going two thousand and more notches in the other direction, see also #6050.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Sep 22, 2012

@paulp said:
See also #6414 .

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Sep 22, 2012

@Blaisorblade said:
It seems too late for a proper fix in 2.10.0... would it be worth to resubmit just the part which checks generic signatures and omits the erroneous ones?

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Feb 9, 2014

@retronym said:
I'm considering this approach:

scala/scala#3493

The key dilemna is what to do about mixin signatures. We should really add bridges. But that has proved really tough to implement. So as a stopgap measure, I'm weakening the as-seen-from the subclass generic signature if it doesn't erase to the same signature as the trait forwarder.

By doing this conditionally, I can at least maintain backwards compatibility with code that didn't previously result in a LinkageError.

@scabug scabug closed this Feb 16, 2014
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Feb 16, 2014

@retronym said (edited on Feb 16, 2014 1:58:01 PM UTC):
Closing as the problems with trait forwarders and static forwarders has been fixed in 2.11.0, by emitting weaker signatures if the exact one won't be coherent with the erasure.

I'm hopeful we'll find a more refined approach in the future. I've outlined the ideas for that: #8293

If I have missed any residual signature issues that weren't related to forwarders, please open a new ticket and link it to this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.