diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index dd9f234e0365..8ba0d8a8a60b 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1059,14 +1059,25 @@ class TreeUnpickler(reader: TastyReader, else Nil - def readIndexedStats(exprOwner: Symbol, end: Addr)(using Context): List[Tree] = - until(end)(readIndexedStat(exprOwner)) + def readIndexedStats[T](exprOwner: Symbol, end: Addr, k: (List[Tree], Context) => T = sameTrees)(using Context): T = + val buf = new mutable.ListBuffer[Tree] + var curCtx = ctx + while currentAddr.index < end.index do + val stat = readIndexedStat(exprOwner)(using curCtx) + buf += stat + stat match + case stat: Import => curCtx = ctx.importContext(stat, stat.symbol) + case _ => + assert(currentAddr.index == end.index) + k(buf.toList, curCtx) - def readStats(exprOwner: Symbol, end: Addr)(using Context): List[Tree] = { + def readStats[T](exprOwner: Symbol, end: Addr, k: (List[Tree], Context) => T = sameTrees)(using Context): T = { fork.indexStats(end) - readIndexedStats(exprOwner, end) + readIndexedStats(exprOwner, end, k) } + private def sameTrees(xs: List[Tree], ctx: Context) = xs + def readIndexedParams[T <: MemberDef](tag: Int)(using Context): List[T] = collectWhile(nextByte == tag) { readIndexedDef().asInstanceOf[T] } @@ -1174,9 +1185,8 @@ class TreeUnpickler(reader: TastyReader, case BLOCK => val exprReader = fork skipTree() - val stats = readStats(ctx.owner, end) - val expr = exprReader.readTerm() - Block(stats, expr) + readStats(ctx.owner, end, + (stats, ctx) => Block(stats, exprReader.readTerm()(using ctx))) case INLINED => val exprReader = fork skipTree() diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 6b2af4c1ff85..5ff62a0d97d1 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -249,6 +249,7 @@ class CompilationTests { compileFilesInDir("tests/explicit-nulls/pos-patmat", explicitNullsOptions and "-Xfatal-warnings"), compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions and "-language:unsafeNulls"), compileFile("tests/explicit-nulls/pos-special/i14682.scala", explicitNullsOptions and "-Ysafe-init"), + compileFile("tests/explicit-nulls/pos-special/i14947.scala", explicitNullsOptions and "-Ytest-pickler" and "-Xprint-types"), ) }.checkCompile() diff --git a/tests/explicit-nulls/pos-special/i14947.scala b/tests/explicit-nulls/pos-special/i14947.scala new file mode 100644 index 000000000000..b8f013f325b1 --- /dev/null +++ b/tests/explicit-nulls/pos-special/i14947.scala @@ -0,0 +1,14 @@ +class B: + def g: String | Null = ??? + + def f = + import scala.language.unsafeNulls + if ??? then "" else g + +import scala.language.unsafeNulls +class C { + def g: String | Null = ??? + + def f = + if ??? then "" else g +}