Skip to content

Commit aa14cd8

Browse files
noti0na1tgodzik
authored andcommitted
Consider cases with Nothing type
1 parent cc6c783 commit aa14cd8

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,9 +1334,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
13341334
def thenPathInfo = cond1.notNullInfoIf(true).seq(result.thenp.notNullInfo)
13351335
def elsePathInfo = cond1.notNullInfoIf(false).seq(result.elsep.notNullInfo)
13361336
result.withNotNullInfo(
1337-
if result.thenp.tpe.isRef(defn.NothingClass) then
1337+
if result.thenp.tpe.isNothingType then
13381338
elsePathInfo.withRetracted(thenPathInfo)
1339-
else if result.elsep.tpe.isRef(defn.NothingClass) then
1339+
else if result.elsep.tpe.isNothingType then
13401340
thenPathInfo.withRetracted(elsePathInfo)
13411341
else thenPathInfo.alt(elsePathInfo)
13421342
)
@@ -1862,20 +1862,28 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
18621862
case1
18631863
}
18641864
.asInstanceOf[List[CaseDef]]
1865-
var nni = sel.notNullInfo
1866-
if cases1.nonEmpty then nni = nni.seq(cases1.map(_.notNullInfo).reduce(_.alt(_)))
1867-
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).cast(pt).withNotNullInfo(nni)
1865+
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).cast(pt)
1866+
.withNotNullInfo(notNullInfoFromCases(sel.notNullInfo, cases1))
18681867
}
18691868

18701869
// Overridden in InlineTyper for inline matches
18711870
def typedMatchFinish(tree: untpd.Match, sel: Tree, wideSelType: Type, cases: List[untpd.CaseDef], pt: Type)(using Context): Tree = {
18721871
val cases1 = harmonic(harmonize, pt)(typedCases(cases, sel, wideSelType, pt.dropIfProto))
18731872
.asInstanceOf[List[CaseDef]]
1874-
var nnInfo = sel.notNullInfo
1875-
if cases1.nonEmpty then nnInfo = nnInfo.seq(cases1.map(_.notNullInfo).reduce(_.alt(_)))
1876-
assignType(cpy.Match(tree)(sel, cases1), sel, cases1).withNotNullInfo(nnInfo)
1873+
assignType(cpy.Match(tree)(sel, cases1), sel, cases1)
1874+
.withNotNullInfo(notNullInfoFromCases(sel.notNullInfo, cases1))
18771875
}
18781876

1877+
private def notNullInfoFromCases(initInfo: NotNullInfo, cases: List[CaseDef])(using Context): NotNullInfo =
1878+
var nnInfo = initInfo
1879+
if cases.nonEmpty then
1880+
val (nothingCases, normalCases) = cases.partition(_.body.tpe.isNothingType)
1881+
nnInfo = nothingCases.foldLeft(nnInfo):
1882+
(nni, c) => nni.withRetracted(c.notNullInfo)
1883+
if normalCases.nonEmpty then
1884+
nnInfo = nnInfo.seq(normalCases.map(_.notNullInfo).reduce(_.alt(_)))
1885+
nnInfo
1886+
18791887
def typedCases(cases: List[untpd.CaseDef], sel: Tree, wideSelType: Type, pt: Type)(using Context): List[CaseDef] =
18801888
var caseCtx = ctx
18811889
cases.mapconserve { cas =>

tests/explicit-nulls/neg/i21380b.scala

Lines changed: 19 additions & 1 deletion
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() // error // LTS specific
21+
x.trim() // error // LTS specific
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 // error // LTS specific
39+
x.trim() // error // LTS specific

tests/explicit-nulls/neg/i21619.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test3: String =
4141
case e: Exception =>
4242
finally
4343
x = "f"
44-
x.replace("", "") // ok
44+
x.replace("", "") // error // LTS specific
4545

4646
def test4: String =
4747
var x: String | Null = null
@@ -76,4 +76,4 @@ def test5: Unit =
7676
catch
7777
case _ =>
7878
val z1: String = x.replace("", "") // error
79-
val z2: String = y.replace("", "")
79+
val z2: String = y.replace("", "") // error // LTS specific

0 commit comments

Comments
 (0)