From 1cf9a8ae83e29d2ac8f1d11a08cebd85a6a321fe Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 18 Apr 2022 14:37:05 +0200 Subject: [PATCH 1/3] Honor language imports mode when unpickling --- .../dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 11 ++++++++++- tests/pos/i14947.scala | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i14947.scala diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index dd9f234e0365..cfdc62567ebf 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1060,7 +1060,16 @@ class TreeUnpickler(reader: TastyReader, Nil def readIndexedStats(exprOwner: Symbol, end: Addr)(using Context): List[Tree] = - until(end)(readIndexedStat(exprOwner)) + 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) + buf.toList def readStats(exprOwner: Symbol, end: Addr)(using Context): List[Tree] = { fork.indexStats(end) diff --git a/tests/pos/i14947.scala b/tests/pos/i14947.scala new file mode 100644 index 000000000000..eead3657d4bc --- /dev/null +++ b/tests/pos/i14947.scala @@ -0,0 +1,7 @@ +import scala.language.unsafeNulls +class C { + def g: String | Null = ??? + + def f = + if ??? then "" else g +} \ No newline at end of file From 92b1c5ae0fb80d0a65174ef6def041047ca9d015 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 18 Apr 2022 18:45:33 +0200 Subject: [PATCH 2/3] Fix test --- compiler/test/dotty/tools/dotc/CompilationTests.scala | 1 + tests/{pos => explicit-nulls/pos-special}/i14947.scala | 0 2 files changed, 1 insertion(+) rename tests/{pos => explicit-nulls/pos-special}/i14947.scala (100%) 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/pos/i14947.scala b/tests/explicit-nulls/pos-special/i14947.scala similarity index 100% rename from tests/pos/i14947.scala rename to tests/explicit-nulls/pos-special/i14947.scala From b34964bba316f9b16f5b19e34d6d3ca0692bc752 Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 19 Apr 2022 09:30:11 +0200 Subject: [PATCH 3/3] Also propagate language imports into block expressions --- .../tools/dotc/core/tasty/TreeUnpickler.scala | 15 ++++++++------- tests/explicit-nulls/pos-special/i14947.scala | 9 ++++++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index cfdc62567ebf..8ba0d8a8a60b 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1059,7 +1059,7 @@ class TreeUnpickler(reader: TastyReader, else Nil - def readIndexedStats(exprOwner: Symbol, end: Addr)(using Context): List[Tree] = + 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 @@ -1069,13 +1069,15 @@ class TreeUnpickler(reader: TastyReader, case stat: Import => curCtx = ctx.importContext(stat, stat.symbol) case _ => assert(currentAddr.index == end.index) - buf.toList + 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] } @@ -1183,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/tests/explicit-nulls/pos-special/i14947.scala b/tests/explicit-nulls/pos-special/i14947.scala index eead3657d4bc..b8f013f325b1 100644 --- a/tests/explicit-nulls/pos-special/i14947.scala +++ b/tests/explicit-nulls/pos-special/i14947.scala @@ -1,7 +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 -} \ No newline at end of file +}