Skip to content

Fix #1747: Tweak for <:< between method types #1926

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

Closed
wants to merge 2 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Feb 1, 2017

If one of two method types originates from Java, the two
types might match yet have different parameter signatures,
because of the way Array[T] is handled differently in Java
and Scala. The tweak takes this pecularity into account.

Review by @nicolasstucki

If one of two method types originates from Java, the two
types might match yet have different parameter signatures,
because of the way Array[T] is handled differently in Java
and Scala. The tweak takes this pecularity into account.
@@ -0,0 +1,3 @@
abstract class Coll[E] extends java.util.Collection[E] {
def toArray[T](a: Array[T]): Array[T] = ???
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably be a good idea to make this a run test to make sure that the erased signatures are also consistent in the bytecode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolasstucki Yes, I agree. Can I ask you to add this? Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that its sound to treat them as equivalent. You can't safely provide a generic Scala Array to Java:

scala> def foo[T](al: java.util.ArrayList[T], a: Array[T]) = al.toArray(a)
<console>:12: error: type mismatch;
 found   : Array[T]
 required: Array[? with Object]
Note: T >: ? with Object, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ? with Object`. (SLS 3.2.10)
       def foo[T](al: java.util.ArrayList[T], a: Array[T]) = al.toArray(a)
                                                                        ^

You need to bound things to:

scala> def foo[T <: AnyRef](al: java.util.ArrayList[T], a: Array[T]) = al.toArray(a)
foo: [T <: AnyRef](al: java.util.ArrayList[T], a: Array[T])Array[T with Object]

The overriding method can't add a bound to the type parameter, but can express the restriction as:

abstract class C[E] extends java.util.Collection[E] {
   override def toArray[T](a: Array[T with Object]): Array[T with Object] = ???
}

We also can't add bridges to paper over the difference because of the mutability of arrays.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, the pos test is not testing anything as it is an abstract class and it could be defining new abstract members.

abstract class Coll[E] extends java.util.Collection[E] {
  def toArray[T](a: Array[T]): Array[T] = ???
}

This is in fact generating the following method in the bytecode.

public Object toArray(Object a) { ... }

I added run tests that reproduce the issue (the CI will fail).

@odersky
Copy link
Contributor Author

odersky commented Feb 13, 2017

In light of @retronym's comments it seems we should reject this PR and close #1747, or change it to demand a better error message. Everyone agreed?

@nicolasstucki
Copy link
Contributor

Yes

@odersky odersky closed this Feb 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants