Skip to content

Commit c335b18

Browse files
committed
Wrap unsafeNull members in flexible types during unpickling
1 parent 312c89a commit c335b18

File tree

5 files changed

+32
-3
lines changed

5 files changed

+32
-3
lines changed

compiler/src/dotty/tools/dotc/core/JavaNullInterop.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ object JavaNullInterop {
5353
*/
5454
def nullifyMember(sym: Symbol, tp: Type, isEnumValueDef: Boolean)(using Context): Type = {
5555
assert(ctx.explicitNulls)
56-
assert(sym.is(JavaDefined), "can only nullify java-defined members")
56+
// assert(sym.is(JavaDefined), "can only nullify java-defined members")
5757

5858
// Some special cases when nullifying the type
5959
if isEnumValueDef || sym.name == nme.TYPE_ then

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,12 @@ class TreeUnpickler(reader: TastyReader,
981981
sym.info = tpt.tpe
982982
ValDef(tpt)
983983
}
984+
985+
// If explicit nulls is enabled, and the source file did not have explicit
986+
// nulls enabled, nullify the member to allow for compatibility.
987+
if (ctx.explicitNulls && !explicitNulls) then
988+
sym.info = JavaNullInterop.nullifyMember(sym, sym.info, sym.is(Enum))
989+
984990
goto(end)
985991
setSpan(start, tree)
986992

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,18 @@ class CompilationTests {
213213
compileFilesInDir("tests/explicit-nulls/pos", explicitNullsOptions),
214214
compileFilesInDir("tests/explicit-nulls/flexible-types-common", explicitNullsOptions),
215215
compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions and "-language:unsafeNulls" and "-Yno-flexible-types"),
216-
)
217-
}.checkCompile()
216+
).checkCompile()
217+
218+
locally {
219+
val tests = List(
220+
compileFile("tests/explicit-nulls/flexible-unpickle/Unsafe_1.scala", explicitNullsOptions without "-Yexplicit-nulls"),
221+
compileFile("tests/explicit-nulls/flexible-unpickle/Flexible_2.scala", explicitNullsOptions.withClasspath(
222+
defaultOutputDir + testGroup + "/Unsafe_1/flexible-unpickle/Unsafe_1")),
223+
).map(_.keepOutput.checkCompile())
224+
225+
tests.foreach(_.delete())
226+
}
227+
}
218228

219229
@Test def explicitNullsWarn: Unit = {
220230
implicit val testGroup: TestGroup = TestGroup("explicitNullsWarn")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@main
2+
def Flexible_2() =
3+
val s2: String | Null = "foo"
4+
val unsafe = new Unsafe_1()
5+
val s: String = unsafe.foo(s2)
6+
unsafe.foo("")
7+
unsafe.foo(null)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Unsafe_1 {
2+
def foo(s: String): String = {
3+
if (s == null) then "nullString"
4+
else s
5+
}
6+
}

0 commit comments

Comments
 (0)