Skip to content

Suppress type constructors in java generic signatures #4337

@scabug

Description

@scabug
// compiles
interface J1 extends scala.collection.Traversable { }

interface J2<A> extends scala.collection.Traversable<A> { }
// J.java:4: types scala.collection.Traversable<A> and scala.collection.Traversable<A> are incompatible; both define newBuilder(), but with unrelated return types
// interface J2<A> extends scala.collection.Traversable<A> { }
// ^
interface J3 extends scala.collection.Traversable<Object> { }
//
// J.java:6: types scala.collection.Traversable<java.lang.Object> and scala.collection.Traversable<java.lang.Object> are incompatible; both define newBuilder(), but with unrelated return types
// interface J3 extends scala.collection.Traversable<Object> { }
// ^

The signatures of the inherited newBuilder() interface methods differ only in a type parameter.

const SI-14 = Asciz	()Lscala/collection/mutable/Builder;;
const SI-15 = Asciz	()Lscala/collection/mutable/Builder<TA;TRepr;>;;
const SI-16 = Asciz	()Lscala/collection/mutable/Builder;;
const SI-17 = Asciz	()Lscala/collection/mutable/Builder<TA;TCC;>;;

If one tries to do the same thing in java, it is disallowed:

import java.util.*;

interface J1<A, CC> { public Map<A, CC> foo(); }
interface J2<A, CC> { public Map<A, CC> foo(); }

abstract class J3 implements J1<String, List>, J2<String, Map> { }
// J1.java:6: types J2<java.lang.String,java.util.Map> and J1<java.lang.String,java.util.List> are incompatible; both define foo(), but with unrelated return types
// abstract class J3 implements J1<String, List>, J2<String, Map> { }
//          ^
// 1 error  

I thought perhaps overriding in Traversable would solve it by generating a signature there. It does generate a signature, but the failure remains.

trait Traversable[+A] extends TraversableLike[A, Traversable[A]] 
                         with GenericTraversableTemplate[A, Traversable] {
  def companion: GenericCompanion[Traversable] = Traversable
  override protected[this] def newBuilder: Builder[A, Traversable[A]] = companion.newBuilder[A]
  [...]  
}
// javap
//
// const SI-7 = Asciz newBuilder;
// const SI-8 = Asciz ()Lscala/collection/mutable/Builder;;
// const SI-9 = Asciz ()Lscala/collection/mutable/Builder<TA;Lscala/collection/Traversable<TA;>;>;;

% javac -cp /scala/trunk/build/quick/classes/library J.java 
// J.java:4: types scala.collection.Traversable<A> and scala.collection.Traversable<A> are incompatible; both define newBuilder(), but with unrelated return types
// interface J2<A> extends scala.collection.Traversable<A> { }
// ^
// J.java:8: types scala.collection.Traversable<java.lang.Object> and scala.collection.Traversable<java.lang.Object> are incompatible; both define newBuilder(), but with unrelated return types
// interface J3 extends scala.collection.Traversable<Object> { }
// ^
// 2 errors

Any thoughts? I don't know how big a deal this is, but it seems like a bad thing.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions