Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import parsing.JavaParsers.JavaParser
import parsing.Parsers.Parser
import Annotations.*
import Inferencing.*
import Nullables.*
import transform.ValueClasses.*
import TypeErasure.erasure
import reporting.*
Expand Down Expand Up @@ -784,12 +785,18 @@ class Namer { typer: Typer =>

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

private var myNotNullInfos: List[NotNullInfo] | Null = null

/** The context with which this completer was created */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should mention that this is affected by setNotNullInfos

given creationContext: Context = ictx
given creationContext[Dummy_so_its_a_def]: Context =
if myNotNullInfos == null then ictx else ictx.withNotNullInfos(myNotNullInfos.nn)

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

def setNotNullInfos(infos: List[NotNullInfo]): Unit =
myNotNullInfos = infos

protected def typeSig(sym: Symbol): Type = original match
case original: ValDef =>
if (sym.is(Module)) moduleValSig(sym)
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3361,12 +3361,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
mdef.getAttachment(SymOfTree) match {
case Some(sym) => sym.infoOrCompleter match {
case completer: Namer#Completer =>
if (completer.creationContext.notNullInfos ne ctx.notNullInfos)
if completer.creationContext.notNullInfos ne ctx.notNullInfos then
// The RHS of a val def should know about not null facts established
// in preceding statements (unless the DefTree is completed ahead of time,
// then it is impossible).
sym.info = Completer(completer.original)(
completer.creationContext.withNotNullInfos(ctx.notNullInfos))
completer.setNotNullInfos(ctx.notNullInfos)
true
case _ =>
// If it has been completed, then it must be because there is a forward reference
Expand Down
27 changes: 27 additions & 0 deletions tests/explicit-nulls/pos/i19202.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Test {
def test1(s: String | Null): Unit = {
if s == null then return

case class XXX()
}

def test2(s: String | Null): Unit = {
if s == "" then return

case class XXX()
}

def test3(s: String | Null): Unit = {
if s == null then return

case class XXX()
()
}

def test4(s: String | Null): String | Null = {
if s == null then return ""

case class XXX()
"xxx"
}
}
27 changes: 27 additions & 0 deletions tests/pos/i19202.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Test {
def test1(s: String): Unit = {
if s == null then return

case class XXX()
}

def test2(s: String): Unit = {
if s == "" then return

case class XXX()
}

def test3(s: String): Unit = {
if s == null then return

case class XXX()
()
}

def test4(s: String): String = {
if s == null then return ""

case class XXX()
"xxx"
}
}