Closed noti0na1 closed 4 years ago
I rewrote the widenUnion
as below:
case tp @ OrType(lhs, rhs) =>
tp match {
case OrNull(tp1) =>
// Don't widen `T|Null`, since otherwise we wouldn't be able to infer nullable unions.
val tp1Widen = tp1.widenUnion
if (tp1Widen.isRef(defn.AnyClass)) tp1Widen
else tp.derivedOrType(tp1Widen, defn.NullType)
case _ =>
ctx.typeComparer.lub(lhs.widenUnion, rhs.widenUnion, canConstrain = true) match {
case union: OrType => union.join
case res => res
}
}
Because the original implementation will infer incorrect type for this case:
class A
class B
val x: (A | Null) | B = ???
val y = x // the lub for A and B is AnyRef, but Any | Null is inferrred
Also, I don't think using stripNull
is very expensive here, and this is more readable.
@abeln
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:9:8 -----------------------------------------------
9 | x1.ne(1)
| ^
| Found: Int(1)
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:10:8 ----------------------------------------------
10 | x1.eq(null)
| ^^^^
| Found: Null
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:11:8 ----------------------------------------------
11 | x1.ne(null)
| ^^^^
| Found: Null
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:12:8 ----------------------------------------------
12 | x1.eq(1) // ok: implicit conversion from int to Integer
| ^
| Found: Int(1)
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:13:8 ----------------------------------------------
13 | x1.ne(1) // ok: ditto
| ^
| Found: Int(1)
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:14:8 ----------------------------------------------
14 | x1.eq(x2)
| ^^
| Found: (String | Null)(Test.this.x2)
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/pos/ref-eq.scala:15:8 ----------------------------------------------
15 | x1.ne(x2)
| ^^
| Found: (String | Null)(Test.this.x2)
| Required: Object
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:18:7 -------------------------------------------
18 | null.eq("hello")
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:19:7 -------------------------------------------
19 | null.ne("hello")
| ^^^^^^^
| value ne is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:20:7 -------------------------------------------
20 | null.eq(null)
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:21:7 -------------------------------------------
21 | null.ne(null)
| ^^^^^^^
| value ne is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:22:7 -------------------------------------------
22 | null.eq(x2)
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:23:7 -------------------------------------------
23 | null.ne(x2)
| ^^^^^^^
| value ne is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:25:5 -------------------------------------------
25 | x2.eq(null)
| ^^^^^
| value eq is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:26:5 -------------------------------------------
26 | x2.ne(null)
| ^^^^^
| value ne is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:27:5 -------------------------------------------
27 | x2.eq(x1)
| ^^^^^
| value eq is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:28:5 -------------------------------------------
28 | x2.ne(x1)
| ^^^^^
| value ne is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:29:5 -------------------------------------------
29 | x2.eq(x2)
| ^^^^^
| value eq is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/pos/ref-eq.scala:30:5 -------------------------------------------
30 | x2.ne(x2)
| ^^^^^
| value ne is not a member of String | Null
Compilation failed for: 'tests/explicit-nulls/pos/ref-eq.scala'
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:5:16 --------------------------------------
5 | assert(null.eq(null))
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:6:17 --------------------------------------
6 | assert(!null.ne(null))
| ^^^^^^^
| value ne is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:8:17 --------------------------------------
8 | assert(!null.eq("hello"))
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:9:16 --------------------------------------
9 | assert(null.ne("hello"))
| ^^^^^^^
| value ne is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:11:17 -------------------------------------
11 | assert(!null.eq(4))
| ^^^^^^^
| value eq is not a member of Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:12:16 -------------------------------------
12 | assert(null.ne(4))
| ^^^^^^^
| value ne is not a member of Null
-- [E007] Type Mismatch Error: tests/explicit-nulls/run/subtype-any.scala:14:23 ----------------------------------------
14 | assert(!"hello".eq(null))
| ^^^^
| Found: Null
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/run/subtype-any.scala:15:22 ----------------------------------------
15 | assert("hello".ne(null))
| ^^^^
| Found: Null
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/run/subtype-any.scala:17:17 ----------------------------------------
17 | assert(!4.eq(null))
| ^^^^
| Found: Null
| Required: Object
-- [E007] Type Mismatch Error: tests/explicit-nulls/run/subtype-any.scala:18:16 ----------------------------------------
18 | assert(4.ne(null))
| ^^^^
| Found: Null
| Required: Object
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:21:13 -------------------------------------
21 | assert(x.eq(null))
| ^^^^
| value eq is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:22:14 -------------------------------------
22 | assert(!x.ne(null))
| ^^^^
| value ne is not a member of String | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:25:15 -------------------------------------
25 | assert(!x2.eq(null))
| ^^^^^
| value eq is not a member of AnyRef | Null
-- [E008] Member Not Found Error: tests/explicit-nulls/run/subtype-any.scala:26:14 -------------------------------------
26 | assert(x2.ne(null))
| ^^^^^
| value ne is not a member of AnyRef | Null
Compilation failed for: 'tests/explicit-nulls/run/subtype-any.scala'
Changes according to #7546
Merge Nullability Analysis
nullable.scala
; it requires implementingnotNull
Others
Types.widenUnion