Skip to content

Commit d2c9b3f

Browse files
noti0na1WojciechMazur
authored andcommitted
Fix typing cases
[Cherry-picked 7f92b53]
1 parent 6ff6b10 commit d2c9b3f

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19291929
}
19301930
val pat1 = indexPattern(tree).transform(pat)
19311931
val guard1 = typedExpr(tree.guard, defn.BooleanType)
1932-
var body1 = ensureNoLocalRefs(typedExpr(tree.body, pt1), pt1, ctx.scope.toList)
1932+
var body1 = ensureNoLocalRefs(
1933+
typedExpr(tree.body, pt1)(using ctx.addNotNullInfo(guard1.notNullInfoIf(true))),
1934+
pt1, ctx.scope.toList)
19331935
if ctx.gadt.isNarrowing then
19341936
// Store GADT constraint to later retrieve it (in PostTyper, for now).
19351937
// GADT constraints are necessary to correctly check bounds of type app,
@@ -1940,7 +1942,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19401942
if pt1.isValueType then // insert a cast if body does not conform to expected type if we disregard gadt bounds
19411943
body1 = body1.ensureConforms(pt1)(using originalCtx)
19421944
val nni = pat1.notNullInfo
1943-
.seq(guard1.notNullInfoIf(false).alt(guard1.notNullInfoIf(true)))
1945+
.seq(guard1.notNullInfoIf(true))
19441946
.seq(body1.notNullInfo)
19451947
assignType(cpy.CaseDef(tree)(pat1, guard1, body1), pat1, body1).withNotNullInfo(nni)
19461948
}
@@ -2062,7 +2064,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20622064
val cases2 = cases2x.asInstanceOf[List[CaseDef]]
20632065

20642066
var nni = expr2.notNullInfo.retractedInfo
2065-
if cases2.nonEmpty then nni = nni.seq(cases2.map(_.notNullInfo).reduce(_.alt(_)))
2067+
if cases2.nonEmpty then nni = nni.seq(cases2.map(_.notNullInfo.retractedInfo).reduce(_.alt(_)))
20662068
val finalizer1 = typed(tree.finalizer, defn.UnitType)(using ctx.addNotNullInfo(nni))
20672069
nni = nni.seq(finalizer1.notNullInfo)
20682070
assignType(cpy.Try(tree)(expr2, cases2, finalizer1), expr2, cases2).withNotNullInfo(nni)

tests/explicit-nulls/neg/i21380b.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ def test2(i: Int) =
1111
i match
1212
case 1 => x = "1"
1313
case _ => x = " "
14-
x.replace("", "") // ok
14+
x.replace("", "") // ok
15+
16+
def test3(i: Int) =
17+
var x: String | Null = null
18+
i match
19+
case 1 if x != null => ()
20+
case _ => x = " "
21+
x.trim() // ok

tests/explicit-nulls/neg/i21380c.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,15 @@ def test4: Int =
3131
catch
3232
case npe: NullPointerException => x = ""
3333
case _ => x = ""
34-
x.length // ok
34+
x.length // error
35+
// Although the catch block here is exhaustive,
36+
// it is possible that the exception is thrown and not caught.
37+
// Therefore, the code after the try block can only rely on the retracted info.
38+
39+
def test5: Int =
40+
var x: String | Null = null
41+
try
42+
x = ""
43+
throw new Exception()
44+
catch
45+
case npe: NullPointerException => val i: Int = x.length // error

0 commit comments

Comments
 (0)