-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[Draft] A New UnsafeNulls Language Feature for Explicit Nulls #9231
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
Conversation
Can you confirm that the changes to overriding of Java methods apply even without the language import? (From the code, it appears they do, and I think they should, because whether an overriding is legal is a non-local property.) If so, then perhaps the PR could be split to separate the overriding changes from the unsafe operations changes, but I'll let @odersky comment on that. We talked earlier of having, in addition to the language import, a second language import that applies the 3 unsafe operations only when the term with the T|Null type is a call to a Java-defined method. Is that still planned for later, or did you decide against it? I see that some of the unsafe-* tests are duplicated in pos/ and neg/, with the only difference that the pos/ version of the test has a language import. Would it make sense to avoid duplication by having an unsafe/ directory that is run twice, once with the language flag and once without? Some of the changes (especially in the tests) appear to be whitespace-only changes. These should be reverted. |
Yes, the overriding rules apply even without the
Is it enough to just check the method sym is
Yes, I think these tests can be combined. We are also thinking about making I am also doing same experiment on this. It seems I need to modify the codegen part. |
Yes, I think so. You apply rules 1, 2, and 3 (from your description of this PR) only when the tree whose type is nullable is a call to a Java method, so presumably an Apply whose fun has a symbol that is JavaDefined.
I think it's worth experimenting with, though in a separate PR. |
aa6e0ed
to
de903f4
Compare
ed4454b
to
9efa940
Compare
9efa940
to
d0d8853
Compare
I will close this PR, because I moved the source branch to dotty-staging. |
This PR removes the
UncheckedNull
type, and adds a new language featureunsafeNulls
to explicit nulls, which allows unsafe null operations in a certain scope. In addition, a relaxed overriding rule is implemented for overriding Java classes.Description
In the original explicit nulls design,
UncheckedNull
was introduced to allow member selections on nullable objects from Java code (with typeT | UncheckedNull
). We could defineUncheckedNull
as a type alias ofNull
or a true subtype ofNull
; however, we find it is difficult to implement in both ways. See #7828 for more discussion.We decided to create a new language feature, called
unsafeNulls
. Inside this "unsafe" scope, allT | Null
objects can be used asT
, andNull
keeps being a subtype ofAny
.User can import
scala.language.unsafeNulls
to create such scope, or use-language:unsafeNulls
to enable this feature globally. The following unsafe null operations will apply to all nullable types:T
onT | Null
objectT
onT | Null
T1
toT2
ifT1.stripAllNulls <:< T2.stripAllNulls
orT1
isNull
andT2
has null value after erasureThe intention of this
unsafeNulls
is to give users a better migration path for explicit nulls. TheUncheckedNull
is only limited to unsafe member selections. We think this approach can do more thanUncheckedNull
and in a better way.Projects for Scala2 or regular dotty can try this by adding
-Yexplicit-nulls -language:unsafeNulls
to the compile options. A small number of manual modifications are expected (for example, some code relies on the facts ofNull <:< AnyRef
). To migrate to full explicit nulls in the future,-language:unsafeNulls
can be dropped and addimport scala.language.unsafeNulls
only when needed.Examples
All the examples are under
-Yexplicit-nulls
flag.Without the
unsafeNulls
, all these unsafe operations will not be compiled.unsafeNulls
also works for extension methods and implicit search.See more examples about
unsafeNulls
intests/explicit-nulls/pos/unsafe-*.scala
.An example for relaxed overriding:
See more examples about overriding in
tests/explicit-nulls/pos/override-*
./cc @odersky @olhotak