Skip to content

Commit 2152d15

Browse files
Backport "Fix #19202: Passing NotNullInfos to a mutable field of a Completer" to LTS (#20841)
Backports #19463 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 0fd4aae + da600b6 commit 2152d15

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import parsing.JavaParsers.JavaParser
2222
import parsing.Parsers.Parser
2323
import Annotations.*
2424
import Inferencing.*
25+
import Nullables.*
2526
import transform.ValueClasses.*
2627
import TypeErasure.erasure
2728
import reporting.*
@@ -781,12 +782,19 @@ class Namer { typer: Typer =>
781782

782783
protected def localContext(owner: Symbol): FreshContext = ctx.fresh.setOwner(owner).setTree(original)
783784

785+
/** Stores the latest NotNullInfos (updated by `setNotNullInfos`) */
786+
private var myNotNullInfos: List[NotNullInfo] | Null = null
787+
784788
/** The context with which this completer was created */
785-
given creationContext: Context = ictx
789+
given creationContext[Dummy_so_its_a_def]: Context =
790+
if myNotNullInfos == null then ictx else ictx.withNotNullInfos(myNotNullInfos.nn)
786791

787792
// make sure testing contexts are not captured by completers
788793
assert(!ictx.reporter.isInstanceOf[ExploringReporter])
789794

795+
def setNotNullInfos(infos: List[NotNullInfo]): Unit =
796+
myNotNullInfos = infos
797+
790798
protected def typeSig(sym: Symbol): Type = original match
791799
case original: ValDef =>
792800
if (sym.is(Module)) moduleValSig(sym)

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -3297,12 +3297,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
32973297
mdef.getAttachment(SymOfTree) match {
32983298
case Some(sym) => sym.infoOrCompleter match {
32993299
case completer: Namer#Completer =>
3300-
if (completer.creationContext.notNullInfos ne ctx.notNullInfos)
3300+
if completer.creationContext.notNullInfos ne ctx.notNullInfos then
33013301
// The RHS of a val def should know about not null facts established
33023302
// in preceding statements (unless the DefTree is completed ahead of time,
33033303
// then it is impossible).
3304-
sym.info = Completer(completer.original)(
3305-
completer.creationContext.withNotNullInfos(ctx.notNullInfos))
3304+
completer.setNotNullInfos(ctx.notNullInfos)
33063305
true
33073306
case _ =>
33083307
// If it has been completed, then it must be because there is a forward reference

tests/explicit-nulls/pos/i19202.scala

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Test {
2+
def test1(s: String | Null): Unit = {
3+
if s == null then return
4+
5+
case class XXX()
6+
}
7+
8+
def test2(s: String | Null): Unit = {
9+
if s == "" then return
10+
11+
case class XXX()
12+
}
13+
14+
def test3(s: String | Null): Unit = {
15+
if s == null then return
16+
17+
case class XXX()
18+
()
19+
}
20+
21+
def test4(s: String | Null): String | Null = {
22+
if s == null then return ""
23+
24+
case class XXX()
25+
"xxx"
26+
}
27+
}

tests/pos/i19202.scala

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Test {
2+
def test1(s: String): Unit = {
3+
if s == null then return
4+
5+
case class XXX()
6+
}
7+
8+
def test2(s: String): Unit = {
9+
if s == "" then return
10+
11+
case class XXX()
12+
}
13+
14+
def test3(s: String): Unit = {
15+
if s == null then return
16+
17+
case class XXX()
18+
()
19+
}
20+
21+
def test4(s: String): String = {
22+
if s == null then return ""
23+
24+
case class XXX()
25+
"xxx"
26+
}
27+
}

0 commit comments

Comments
 (0)