Skip to content

Commit 0181ee7

Browse files
committed
Add comment
1 parent 1d96b26 commit 0181ee7

File tree

5 files changed

+101
-1
lines changed

5 files changed

+101
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,24 @@ object NullOpsDecorator:
4444
if ctx.explicitNulls then strip(self) else self
4545
}
4646

47+
/** Strips `|Null` from the return type of a Java method,
48+
* replacing it with a `@CanEqualNull` annotation
49+
*/
4750
def replaceOrNull(using Context): Type =
51+
// Since this method should only be called on types from Java,
52+
// handling these cases is enough.
4853
def recur(tp: Type): Type = tp match
4954
case tp @ OrType(lhs, rhs) if rhs.isNullType =>
5055
AnnotatedType(recur(lhs), Annotation(defn.CanEqualNullAnnot))
5156
case tp: AndOrType =>
5257
tp.derivedAndOrType(recur(tp.tp1), recur(tp.tp2))
5358
case tp @ AppliedType(tycon, targs) =>
5459
tp.derivedAppliedType(tycon, targs.map(recur))
60+
case mptp: MethodOrPoly =>
61+
mptp.derivedLambdaType(resType = recur(mptp.resType))
5562
case _ => tp
5663
if ctx.explicitNulls then recur(self) else self
5764

58-
5965
/** Is self (after widening and dealiasing) a type of the form `T | Null`? */
6066
def isNullableUnion(using Context): Boolean = {
6167
val stripped = self.stripNull
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class J1 {
2+
J2 getJ2() { return new J2(); }
3+
}
4+
5+
class J2 {
6+
J1 getJ1() { return new J1(); }
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class S {
2+
val j: J2 = new J2()
3+
j.getJ1().getJ2().getJ1().getJ2().getJ1().getJ2() // error
4+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import java.util.List;
2+
3+
public class JC {
4+
5+
public int a;
6+
7+
public String b;
8+
9+
public String[] c;
10+
11+
public int f1() {
12+
return 0;
13+
}
14+
15+
public int[] f2() {
16+
return null;
17+
}
18+
19+
public String g1() {
20+
return null;
21+
}
22+
23+
public List<String> g2() {
24+
return null;
25+
}
26+
27+
public String[] g3() {
28+
return null;
29+
}
30+
31+
public <T> T h1() {
32+
return null;
33+
}
34+
35+
public <T> List<T> h2() {
36+
return null;
37+
}
38+
39+
public <T> T[] h3() {
40+
return null;
41+
}
42+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import scala.language.unsafeJavaReturn
2+
import java.{util => ju}
3+
4+
class S {
5+
6+
def test[T <: AnyRef](jc: JC) = {
7+
// val a: Int = jc.a
8+
9+
// val b = jc.b // it returns String @CanEqualNull
10+
// val b2: String = b
11+
// val b3: String = jc.b
12+
// val bb = jc.b == null // it's ok to compare String @CanEqualNull with Null
13+
// val btl = jc.b.trim().length() // String @CanEqualNull is just String, unsafe selecting
14+
15+
// val c = jc.c
16+
// val cl = c.length
17+
// val c2: Array[String] = c
18+
val c3: Array[String] = jc.c
19+
// val c4: Array[Int] = c.map(_.length())
20+
21+
// val f1: Int = jc.f1()
22+
// val f2: Array[Int] = jc.f2()
23+
// val f2n = jc.f2() == null
24+
25+
// val g1: String = jc.g1()
26+
// val g1n = jc.g1() == null
27+
// val g1tl = jc.g1().trim().length()
28+
29+
// val g2h: ju.List[String] = jc.g2()
30+
31+
// val g3: Array[String] = jc.g3()
32+
// val g3n = jc.g3() == null
33+
// val g3m: Array[Boolean] = jc.g3().map(_ == null)
34+
35+
// val h1: T = jc.h1[T]()
36+
37+
// val h2: ju.List[T] = jc.h2()
38+
39+
// val h3: Array[T] = jc.h3()
40+
}
41+
}

0 commit comments

Comments
 (0)