Skip to content

Commit 0a319be

Browse files
committed
Consider cases with Nothing type
1 parent 273c867 commit 0a319be

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Typer.scala

+16-8
Original file line numberDiff line numberDiff line change
@@ -1543,9 +1543,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
15431543
def thenPathInfo = cond1.notNullInfoIf(true).seq(result.thenp.notNullInfo)
15441544
def elsePathInfo = cond1.notNullInfoIf(false).seq(result.elsep.notNullInfo)
15451545
result.withNotNullInfo(
1546-
if result.thenp.tpe.isRef(defn.NothingClass) then
1546+
if result.thenp.tpe.isNothingType then
15471547
elsePathInfo.withRetracted(thenPathInfo)
1548-
else if result.elsep.tpe.isRef(defn.NothingClass) then
1548+
else if result.elsep.tpe.isNothingType then
15491549
thenPathInfo.withRetracted(elsePathInfo)
15501550
else thenPathInfo.alt(elsePathInfo)
15511551
)
@@ -2134,20 +2134,28 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
21342134
case1
21352135
}
21362136
.asInstanceOf[List[CaseDef]]
2137-
var nni = sel.notNullInfo
2138-
if cases1.nonEmpty then nni = nni.seq(cases1.map(_.notNullInfo).reduce(_.alt(_)))
2139-
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).cast(pt).withNotNullInfo(nni)
2137+
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).cast(pt)
2138+
.withNotNullInfo(notNullInfoFromCases(sel.notNullInfo, cases1))
21402139
}
21412140

21422141
// Overridden in InlineTyper for inline matches
21432142
def typedMatchFinish(tree: untpd.Match, sel: Tree, wideSelType: Type, cases: List[untpd.CaseDef], pt: Type)(using Context): Tree = {
21442143
val cases1 = harmonic(harmonize, pt)(typedCases(cases, sel, wideSelType, pt.dropIfProto))
21452144
.asInstanceOf[List[CaseDef]]
2146-
var nnInfo = sel.notNullInfo
2147-
if cases1.nonEmpty then nnInfo = nnInfo.seq(cases1.map(_.notNullInfo).reduce(_.alt(_)))
2148-
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).withNotNullInfo(nnInfo)
2145+
assignType(cpy.Match(tree)(sel, cases1), sel, cases1)
2146+
.withNotNullInfo(notNullInfoFromCases(sel.notNullInfo, cases1))
21492147
}
21502148

2149+
private def notNullInfoFromCases(initInfo: NotNullInfo, cases: List[CaseDef])(using Context): NotNullInfo =
2150+
var nnInfo = initInfo
2151+
if cases.nonEmpty then
2152+
val (nothingCases, normalCases) = cases.partition(_.body.tpe.isNothingType)
2153+
nnInfo = nothingCases.foldLeft(nnInfo):
2154+
(nni, c) => nni.withRetracted(c.notNullInfo)
2155+
if normalCases.nonEmpty then
2156+
nnInfo = nnInfo.seq(normalCases.map(_.notNullInfo).reduce(_.alt(_)))
2157+
nnInfo
2158+
21512159
def typedCases(cases: List[untpd.CaseDef], sel: Tree, wideSelType0: Type, pt: Type)(using Context): List[CaseDef] =
21522160
var caseCtx = ctx
21532161
var wideSelType = wideSelType0

Diff for: tests/explicit-nulls/neg/i21380b.scala

+18
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,22 @@ def test3(i: Int) =
1818
i match
1919
case 1 if x != null => ()
2020
case _ => x = " "
21+
x.trim() // ok
22+
23+
def test4(i: Int) =
24+
var x: String | Null = null
25+
var y: String | Null = null
26+
i match
27+
case 1 => x = "1"
28+
case _ => y = " "
29+
x.trim() // error
30+
31+
def test5(i: Int): String =
32+
var x: String | Null = null
33+
var y: String | Null = null
34+
i match
35+
case 1 => x = "1"
36+
case _ =>
37+
y = " "
38+
return y
2139
x.trim() // ok

0 commit comments

Comments
 (0)