File tree Expand file tree Collapse file tree 7 files changed +117
-0
lines changed Expand file tree Collapse file tree 7 files changed +117
-0
lines changed Original file line number Diff line number Diff line change
1
+
2
+ // Test that nullability is correctly detected
3
+ // in the presence of a type alias.
4
+ class Base {
5
+ type T >: Null <: AnyRef | Null
6
+ }
7
+
8
+ object foo {
9
+ class Foo {
10
+ val length : Int = 42
11
+ def doFoo (): Unit = ()
12
+ }
13
+ }
14
+
15
+ class Derived extends Base {
16
+ type Nullable [X ] = X | Null
17
+ type Foo = Nullable [foo.Foo ]
18
+
19
+ def fun (foo : Foo ): Unit = {
20
+ foo.length // error: foo is nullable
21
+ foo.doFoo() // error: foo is nullable
22
+ }
23
+ }
24
+
Original file line number Diff line number Diff line change
1
+
2
+ class Foo {
3
+ val x : String = null // error: String is non-nullable
4
+
5
+ def foo (x : String ): String = " x"
6
+
7
+ val y = foo(null ) // error: String argument is non-nullable
8
+
9
+ val z : String = foo(" hello" )
10
+
11
+ class Bar
12
+ val b : Bar = null // error: user-created classes are also non-nullable
13
+ }
Original file line number Diff line number Diff line change
1
+ // Test what can be compared for equality against null.
2
+ class Foo {
3
+ // Null itself
4
+ val x0 : Null = null
5
+ x0 == null
6
+ null == x0
7
+ null == null
8
+
9
+ // Nullable types: OK
10
+ val x1 : String | Null = null
11
+ x1 == null
12
+ null == x1
13
+
14
+ // Reference types, even non-nullable ones: OK.
15
+ // Allowed as an escape hatch.
16
+ val x2 : String = " hello"
17
+ x2 != null
18
+ x2 == null
19
+ null == x2
20
+
21
+ // Value types: not allowed.
22
+ 1 == null // error
23
+ null == 1 // error
24
+ true == null // error
25
+ null == true // error
26
+ }
Original file line number Diff line number Diff line change
1
+
2
+ // Test that we can't compare for equality `null` and
3
+ // classes that derive from AnyVal.
4
+ class Foo (x : Int ) extends AnyVal
5
+
6
+ class Bar {
7
+ val foo : Foo = new Foo (15 )
8
+ if (foo == null ) {} // error
9
+ if (null == foo) {} // error
10
+
11
+ // To test against null, make the type nullable.
12
+ val foo2 : Foo | Null = foo
13
+ if (foo2 == null ) {}
14
+ if (null == foo2) {}
15
+ }
Original file line number Diff line number Diff line change
1
+
2
+ class Foo {
3
+
4
+ class B1
5
+ class B2
6
+
7
+ val x : (Null | String ) | Null | (B1 | (Null | B2 )) = ???
8
+ if (x != null ) {
9
+ val x2 : String | B1 | B2 = x // ok: can remove all nullable unions
10
+ }
11
+
12
+ val x2 : (Null | String ) & (Null | B1 ) = ???
13
+ if (x2 != null ) {
14
+ val x3 : String & B1 = x2 // error: can't remove null from embedded intersection
15
+ }
16
+ }
Original file line number Diff line number Diff line change
1
+
2
+ // Test that reference types being non-nullable
3
+ // is checked when lower bound of a type argument
4
+ // is Null.
5
+ object Test {
6
+ type Untyped = Null
7
+ class TreeInstances [T >: Untyped ]
8
+ class Type
9
+
10
+ object untpd extends TreeInstances [Null ]
11
+ // There are two errors reported for the line below (don't know why).
12
+ object tpd extends TreeInstances [Type ] // error // error
13
+ }
Original file line number Diff line number Diff line change
1
+
2
+ // Test that is fixed when explicit nulls are enabled.
3
+ // https://github.com/lampepfl/dotty/issues/6247
4
+
5
+ class Foo {
6
+ val x1 : String | Null = null
7
+ x1.nn.length
8
+ val x2 : String = x1.nn
9
+ x1.nn.length
10
+ }
You can’t perform that action at this time.
0 commit comments