You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@tu lazyvalClassCastExceptionClass_stringConstructor:TermSymbol=ClassCastExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match {
@tu lazyvalArithmeticExceptionClass_stringConstructor:TermSymbol=ArithmeticExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match {
Copy file name to clipboardExpand all lines: docs/docs/internals/explicit-nulls.md
+4-6
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ title: "Explicit Nulls"
5
5
6
6
The explicit nulls feature (enabled via a flag) changes the Scala type hierarchy
7
7
so that reference types (e.g. `String`) are non-nullable. We can still express nullability
8
-
with union types: e.g. `val x: String|Null = null`.
8
+
with union types: e.g. `val x: String | Null = null`.
9
9
10
10
The implementation of the feature in dotty can be conceptually divided in several parts:
11
11
1. changes to the type hierarchy so that `Null` is only a subtype of `Any`
@@ -27,15 +27,13 @@ We change the type hierarchy so that `Null` is only a subtype of `Any` by:
27
27
28
28
## Working with Nullable Unions
29
29
30
-
There are some utility functions for nullable types in `NullOpsDecorator.scala` . They are extension methods for `Type`; hence we can use them in this way: `tp.f(...)`.
30
+
There are some utility functions for nullable types in `NullOpsDecorator.scala`.
31
+
They are extension methods for `Type`; hence we can use them in this way: `tp.f(...)`.
31
32
32
-
-`stripNull` syntactically strips all `Null` types in the union:
33
+
-`stripNullWhenExplicit` syntactically strips all `Null` types in the union:
33
34
e.g. `String|Null => String`.
34
-
-`stripAllNullS` collapses all `Null` unions within this type, and not just the outermost
35
-
ones (as `stripNull` does).
36
35
-`isNullableUnion` determines whether `this` is a nullable union.
37
36
-`isNullableAfterErasure` determines whether `this` type can have `null` value after erasure.
38
-
-`isUnsafelyConvertible` determines whether we can convert `this` type to `pt` unsafely if we ignore `Null` type.
39
37
40
38
Within `Types.scala`, we also defined an extractor `OrNull` to extract the non-nullable part of a nullable unions .
Copy file name to clipboardExpand all lines: docs/docs/reference/other-new-features/explicit-nulls.md
+34-7
Original file line number
Diff line number
Diff line change
@@ -55,6 +55,12 @@ So far, we have found the following useful:
55
55
56
56
Don't use `.nn` on mutable variables directly, because it may introduce an unknown typeinto the typeof the variable.
57
57
58
+
-An `unsafeNulls` language feature
59
+
60
+
When imported, `T | Null` can be used as `T`, similar to regular Scala (without explicit nulls).
61
+
62
+
SeeUnsafeNulls section for more details.
63
+
58
64
##Unsoundness
59
65
60
66
Thenewtypesystem is unsound with respect to `null`. This means there are still instances where an expression has a non-nullable typelike `String`, but its value is actually `null`.
@@ -439,17 +445,38 @@ We don't support:
439
445
440
446
### UnsafeNulls
441
447
442
-
It is difficult to work with nullable values, we introduce a language feature `unsafeNulls`. Inside this "unsafe" scope, all `T | Null` values can be used as `T`, and `Null` type keeps being a subtype of `Any`.
448
+
It is difficult to work with many nullable values, we introduce a language feature `unsafeNulls`.
449
+
Inside this "unsafe" scope, all `T | Null` values can be used as `T`.
443
450
444
-
Users can import `scala.language.unsafeNulls` to create such scopes, or use `-language:unsafeNulls` to enable this feature globally. The following unsafe null operations will apply to all nullable types:
445
-
1. select member of `T` on `T | Null` object
446
-
2. call extension methods of `T` on `T | Null`
447
-
3. convert `T1` to `T2` if `T1.stripAllNulls <:< T2.stripAllNulls` or `T1` is `Null` and `T2` has null value after erasure
448
-
4. allow equality check between `T` and `T | Null`
451
+
Users can import `scala.language.unsafeNulls` to create such scopes, or use `-language:unsafeNulls` to enable this feature globally (for migration purpose only).
452
+
453
+
Assume `T` is a reference type (a subtype of `AnyRef`), the following unsafe operation rules are
454
+
applied in this unsafe-nulls scope:
455
+
1. the members of `T` can be found on `T | Null`
456
+
2. a value with type `T` can be compared with `T | Null` and `Null`
457
+
3. suppose `T1` is not a subtype of `T2` using explicit-nulls subtyping (where `Null` is a direct
458
+
subtype of Any), extension methods and implicit conversions designed for `T2` can be used for
459
+
`T1` if `T1` is a subtype of `T2` using regular subtyping rules (where `Null` is a subtype of every
460
+
reference type)
461
+
4. suppose `T1` is not a subtype of `T2` using explicit-nulls subtyping, a value with type `T1`
462
+
can be used as `T2` if `T1` is a subtype of `T2` using regular subtyping rules
449
463
450
464
Addtionally, `null` can be used as `AnyRef` (`Object`), which means you can select `.eq` or `.toString` on it.
451
465
452
-
The intention of this `unsafeNulls` is to give users a better migration path for explicit nulls. Projects for Scala 2 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 fact of `Null <:< AnyRef`). To migrate to full explicit nulls in the future, `-language:unsafeNulls` can be dropped and add `import scala.language.unsafeNulls` only when needed.
466
+
The program in `unsafeNulls` will have a **similar** semantic as regular Scala, but not **equivalent**.
467
+
468
+
For example, the following code cannot be compiled even using unsafe nulls. Because of the
469
+
Java interoperation, the type of the get method becomes `T | Null`.
470
+
471
+
```Scala
472
+
def head[T](xs: java.util.List[T]): T = xs.get(0) // error
473
+
```
474
+
475
+
Since the compiler doesn’t know whether `T` is a reference type, it is unable to cast `T | Null`
476
+
to `T`. A `.nn` need to be inserted after `xs.get(0)` by user manually to fix the error, which
477
+
strips the `Nul`l from its type.
478
+
479
+
The intention of this `unsafeNulls` is to give users a better migration path for explicit nulls. Projects for Scala 2 or regular dotty can try this by adding `-Yexplicit-nulls -language:unsafeNulls` to the compile options. A small number of manual modifications are expected. To migrate to full explicit nulls in the future, `-language:unsafeNulls` can be dropped and add `import scala.language.unsafeNulls` only when needed.
0 commit comments