-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Rework unification of Object and Any in Java/Scala interop #7966
Conversation
def removeAll(x$1: java.util.Collection[_]): Boolean = ??? | ||
def retainAll(x$1: java.util.Collection[_]): Boolean = ??? | ||
def size(): Int = ??? | ||
def toArray[T](x$1: Array[T with Object]): Array[T with Object] = ??? | ||
def toArray[T <: Object](x$1: Array[T]): Array[T] = ??? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting change here. Needs to look at this more to decide if its a re- or pro-gression...
3426455
to
565be77
Compare
Chatted about this with @odersky and @adriaanm. A slightly cleaner way to express this might be to make |
d83faca
to
81a7e77
Compare
References to `j.l.Object` from Java sources or classfiles use `definitions.ObjectTpeJava`, which behaves like `ObjectTpe` but is slackened to `AnyTpe` during `=:=` and `<:<` when this can help yield positive results. This subsumes two prior mechanisms (usages of `obj2Any` and `MethodType.isJava`)
Dropping 81a7e77, adding another 11469 test to the first commit. |
Running community build: https://scala-ci.typesafe.com/job/scala-2.13.x-integrate-community-build/2084/console (using compiler built from previous sha, but only diff is tests) |
scala-js says /cc @sjrd
|
That looks problematic. The file package java.lang
import java.util.Iterator
trait Iterable[T] {
def iterator(): Iterator[T]
} It doesn't seem like this pattern is particularly Scala.js-specific. It's a straightforward mention of a Java interface with a Scala type parameter. |
So you don't do any weird tricks to rewire the info of the type param to use |
Sorry, scratch that. I thought I was looking at the source of |
OMG no. I don't touch the typer. I don't even touch |
Haha ok phew 😅 Still weird, as this PR's standard scalac compiles this source file without problem. |
Looks like a dbuild-specific issue. I cannot reproduce the issue locally with
I hate dbuild-specific issues 😫 |
Bizarre. Dbuild is actually using |
Same outcome: works fine locally. |
Thanks. Well, I guess I'm in for some fun dbuild debugging :-) |
Well, at least it fixed the issue with jackson-module-scala -- it built fine with my workaround reverted |
Scala sha after merging scala/scala#7966
[EDIT]: the akka testkit breakage was not due to this PR, scala/bug#11523 Seems like this did break something in akka testkit -- haven't looked beyond copy pasting the error from https://scala-ci.typesafe.com/job/scala-2.13.x-integrate-community-build/2087/consoleText:
|
/cc @anatoliykmetyuk this would be a good candidate to forward port to dotc. Note the follow-up PR, which makes the special ObjectJavaTpe truly unique. |
#8049 is a followup to this |
@adriaanm Is this likely to get backported too? If it resolves jdk11 migration issues like scala/bug#10418 for 2.11/12. |
as far as I know a backport is unlikely given the tricky nature of the changes made. |
This PR description says:
But as far as I can tell, % scalac test/files/pos/t11469_2/Test_1.java test/files/pos/t11469_2/Test_2.scala
test/files/pos/t11469_2/Test_2.scala:5: error: name clash between defined and inherited member:
def m(a: java.util.Optional[_]): Unit in class B and
override def m(a: java.util.Optional[_ <: Object]): Unit at line 5
have same type after erasure: (a: java.util.Optional)Unit
override def m(a: java.util.Optional[_ <: Object]): Unit = { }
^
one error found Is this intentional ? |
The change to |
In Java unlike Scala, `Object` is the top type, this leads to various usability problems when attempting to call or override a Java method from Scala. So far, we relied mainly on one mechanism to improve the situation: in the ClassfileParser, some references to `Object` in signatures were replaced by `Any` (cf `objToAny`). But this had several shortcomings: - To compensate for this substitution, `TypeComparer#matchingMethodParams` had to special case Any in Java methods and treat it like Object - There were various situation were this substitution was not applied, notably when using varargs (`Object... args`) or when jointly compiling .java sources since this is handled by JavaParser and not ClassfileParser. This commit replaces all of this by a more systematic solution: all references to `Object` in Java definitions (both in classfiles and .java source files) are replaced by a special type `FromJavaObject` which is a type alias of `Object` with one extra subtyping rule: tp <:< FromJavaObject is equivalent to: tp <:< Any See the documentation of `FromJavaObjectSymbol` for details on why this makes sense. This solution is very much inspired by scala/scala#7966 (which was refined in scala/scala#8049 and scala/scala#8638) with two main differences: - We use a type with its own symbol and name distinct from `java.lang.Object`, because this type can show up in inferred types and therefore needs to be preserved when pickling so that unpickled trees pass `-Ycheck`. - Unlike in Scala 2, we cannot get rid of `JavaMethodType` because when calling `Type#signature` we need to know whether we're in a Java method or not, because signatures are based on erased types and erasure differs between Scala and Java (we cannot ignore this and always base signatures on the Scala erasure, because signatures are used to distinguish between overloads and overrides so they must agree with the actual JVM bytecode signature). Fixes scala#7467, scala#7963, scala#8588, scala#8977.
In Java unlike Scala, `Object` is the top type, this leads to various usability problems when attempting to call or override a Java method from Scala. So far, we relied mainly on one mechanism to improve the situation: in the ClassfileParser, some references to `Object` in signatures were replaced by `Any` (cf `objToAny`). But this had several shortcomings: - To compensate for this substitution, `TypeComparer#matchingMethodParams` had to special case Any in Java methods and treat it like Object - There were various situation were this substitution was not applied, notably when using varargs (`Object... args`) or when jointly compiling .java sources since this is handled by JavaParser and not ClassfileParser. This commit replaces all of this by a more systematic solution: all references to `Object` in Java definitions (both in classfiles and .java source files) are replaced by a special type `FromJavaObject` which is a type alias of `Object` with one extra subtyping rule: tp <:< FromJavaObject is equivalent to: tp <:< Any See the documentation of `FromJavaObjectSymbol` for details on why this makes sense. This solution is very much inspired by scala/scala#7966 (which was refined in scala/scala#8049 and scala/scala#8638) with two main differences: - We use a type with its own symbol and name distinct from `java.lang.Object`, because this type can show up in inferred types and therefore needs to be preserved when pickling so that unpickled trees pass `-Ycheck`. - Unlike in Scala 2, we cannot get rid of `JavaMethodType` because when calling `Type#signature` we need to know whether we're in a Java method or not, because signatures are based on erased types and erasure differs between Scala and Java (we cannot ignore this and always base signatures on the Scala erasure, because signatures are used to distinguish between overloads and overrides so they must agree with the actual JVM bytecode signature). Fixes scala#7467, scala#7963, scala#8588, scala#8977.
References to
j.l.Object
from Java sources or classfiles usedefinitions.ObjectTpeJava
, which behaves likeObjectTpe
but isslackened to
AnyTpe
during=:=
and<:<
when this can help yieldpositive results.
This subsumes two prior mechanisms (usages of
obj2Any
andMethodType.isJava
)Fixes scala/bug#10418
Fixes scala/bug#11469