-
Notifications
You must be signed in to change notification settings - Fork 1.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
An alternative feature to UnsafeNulls: UnsafeJavaReturn #15096
Conversation
What is the correct way to make an annotation more sticky to a type? I tried to create an annotation extending |
Do you have minimized example of source code for which this is needed (i.e. where the annotation is lost)? That might help to determine the most practical solution. |
If an annotation is a normal static annotation, it will be stripped when we use Suppose Update: I end up adding a special rule for |
757edc0
to
300bf40
Compare
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.
This now LGTM, but I would like @odersky to approve particularly the fact that CanEqualNull
is a RefiningAnnotation
and the change in TypeComparer
that makes it a special RefiningAnnotation
.
While I was fixing the errors, I found a bug in It seems the |
Seems it doesn't work for the following minimized case: import scala.language.unsafeJavaReturn
val s = "foo"
val methods: Array[java.lang.reflect.Method] = s.getClass.getMethods
|
bee0ac2
to
b037a49
Compare
Here's another bug I came across in the community build: import language.unsafeJavaReturn
import java.math.MathContext, MathContext._
val x: MathContext = DECIMAL32 // Error
val y: MathContext = MathContext.DECIMAL32 // OK I'd expect both to be OK. |
And another bug from the community build: import language.unsafeJavaReturn
val zids: java.util.Set[String] = java.time.ZoneId.getAvailableZoneIds
val zarr: Array[String] = java.time.ZoneId.getAvailableZoneIds.toArray(Array.empty[String]) Without
Not sure if that's a bug in this PR or a limitation of the feature implemented by the PR. |
b037a49
to
adcfda4
Compare
Since we don't modify the parameter types, the arguments should be nullable:
Fixed |
The contents of the PR now LGTM, but I'm concerned about merging it into main. This is an experimental feature and the PR introduces a language import and a change to the standard library (CanEqualNull). Both of these would be hard to remove if we change our minds about how to do this. We want to merge it so we can experiment with it on the compiler itself and on the community build; would it be possible to merge it not into main but into a branch like the cc-experiment branch? |
If we add a language import and something to the standard library we have to make them experimental. I.e. import language.experimental.unsafeJavaReturn
@experimental
final class CanEqualNull... |
98a4f42
to
056a0ad
Compare
@odersky I have moved the new language feature inside the experimental object, but the CI test
Do I need to change some configration? |
I think the person who knows best would be @dwijnand. In your place I would just add the filters that were suggested to the MiMa excludes file. |
056a0ad
to
a874a9c
Compare
Yeah, you can either add the filters or annotate it with the |
I'm happy with this now to be merged, but I would still like approval from @odersky even though it's now all experimental. |
@noti0na1 I'm assuming you were still waiting on a review here? If so, are you able to rebase and I can try to get you a review? |
This PR introduces a new language feature for explicit nulls,
unsafeJavaReturn
. It is similar tounsafeNulls
, but less aggresive. This is an experiment to address the pain point 2 in #14622.Under
unsafeJavaReturn
, all| Null
in Java methods' return types and members are replced by a new annotation@CanEqualNull
. For example, a Java methoddef f(x: String | Null): Array[String | Null] | Null
becomesdef f(x: String | Null): Array[String @CanEqualNull] @CanEqualNull
.String @CanEqualNull
is a same type asString
. But when a reference type has this annotation, its values can be compared withnull
.This feature is very useful when working with Java methods with long chain calling. For example,
"aaab".substring(2).trim().length()
. The null safety is only weakened for Java methods. Other part of code is not affect. Without this feature, we have add.nn
everywhere, or useunsafeNulls
to weaken the null safety in the whole scope.A longer example: