Skip to content

Commit 10d965f

Browse files
committed
Add comments
1 parent 300bf40 commit 10d965f

File tree

4 files changed

+17
-1
lines changed

4 files changed

+17
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,8 @@ trait Applications extends Compatibility {
911911
case funRef: TermRef =>
912912
var app = ApplyTo(tree, fun1, funRef, proto, pt)
913913
if ctx.mode.is(Mode.UnsafeJavaReturn) then
914+
// When UnsafeJavaReturn is enabled and the applied function is Java defined,
915+
// we replece `| Null` with `@CanEqualNull` in the return type.
914916
val funSym = fun1.symbol
915917
if funSym.is(JavaDefined)
916918
&& funSym.isTerm

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,17 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
159159
cmpWithBoxed(cls2, cls1)
160160
else if ctx.mode.is(Mode.SafeNulls) then
161161
// If explicit nulls is enabled, and unsafeNulls is not enabled,
162+
// and the types don't have `@CanEqualNull` annotation,
162163
// we want to disallow comparison between Object and Null.
163164
// If we have to check whether a variable with a non-nullable type has null value
164165
// (for example, a NotNull java method returns null for some reasons),
165-
// we can still cast it to a nullable type then compare its value.
166+
// we can still use `eq/ne null` or cast it to a nullable type then compare its value.
166167
//
167168
// Example:
168169
// val x: String = null.asInstanceOf[String]
169170
// if (x == null) {} // error: x is non-nullable
170171
// if (x.asInstanceOf[String|Null] == null) {} // ok
172+
// if (x eq null) {} // ok
171173
cls1 == defn.NullClass && cls1 == cls2
172174
else if cls1 == defn.NullClass then
173175
cls1 == cls2 || cls2.derivesFrom(defn.ObjectClass)
@@ -182,6 +184,14 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
182184
* interpret.
183185
*/
184186
def canComparePredefined(tp1: Type, tp2: Type) =
187+
// In explicit nulls, when one of type has `@CanEqualNull` annotation,
188+
// we use unsafe nulls semantic to check, which allows reference types
189+
// to be compared with `Null`.
190+
// Example:
191+
// val s1: String = ???
192+
// s1 == null // error
193+
// val s2: String @CanEqualNull = ???
194+
// s2 == null // ok
185195
val checkCtx = if ctx.explicitNulls
186196
&& (tp1.hasAnnotation(defn.CanEqualNullAnnot) || tp2.hasAnnotation(defn.CanEqualNullAnnot))
187197
then ctx.retractMode(Mode.SafeNulls) else ctx

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
657657
else qual
658658
var sel = typedSelect(tree, pt, qual1).withSpan(tree.span).computeNullable()
659659
if ctx.mode.is(Mode.UnsafeJavaReturn) && pt != AssignProto then
660+
// When UnsafeJavaReturn is enabled and the selected member is Java defined,
661+
// we replece `| Null` with `@CanEqualNull` in its type
662+
// if it is not at left hand side of assignments.
660663
val sym = sel.symbol
661664
if sym.is(JavaDefined) && sym.isTerm && !sym.is(Method) then
662665
val stp1 = sel.tpe.widen

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class CompilationTests {
250250
compileFilesInDir("tests/explicit-nulls/pos-separate", explicitNullsOptions),
251251
compileFilesInDir("tests/explicit-nulls/pos-patmat", explicitNullsOptions and "-Xfatal-warnings"),
252252
compileFilesInDir("tests/explicit-nulls/unsafe-common", explicitNullsOptions and "-language:unsafeNulls"),
253+
compileFilesInDir("tests/explicit-nulls/unsafe-java", explicitNullsOptions),
253254
compileFile("tests/explicit-nulls/pos-special/i14682.scala", explicitNullsOptions and "-Ysafe-init"),
254255
compileFile("tests/explicit-nulls/pos-special/i14947.scala", explicitNullsOptions and "-Ytest-pickler" and "-Xprint-types"),
255256
)

0 commit comments

Comments
 (0)