Skip to content

Commit 50b70ca

Browse files
committed
Add while, match tests
1 parent ce606b6 commit 50b70ca

File tree

9 files changed

+99
-27
lines changed

9 files changed

+99
-27
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ object Nullables with
111111
sym.is(Mutable)
112112
&& sym.owner.isTerm
113113
&& (if sym.owner != curCtx.owner then
114+
// TODO: need to check by-name parameters
114115
!curCtx.owner.is(Flags.Lazy) // not at the rhs of lazy ValDef
115116
&& sym.owner.enclosingMethod == curCtx.owner.enclosingMethod // not in different DefDef
116117
else true)

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,6 @@ class Typer extends Namer
352352
case ref @ OrNull(tpnn) : TermRef
353353
if pt != AssignProto && // Ensure it is not the lhs of Assign
354354
ctx.notNullInfos.impliesNotNull(ref) =>
355-
// val tpeA = TypeTree(tpnn)
356-
// val tpeB = TypeTree(AndType(ref, tpnn))
357-
// Apply(
358-
// TypeApply(Ident(defn.Compiletime_notNull.namedType), tpeA :: tpeB :: Nil),
359-
// tree :: Nil)
360355
tree.select(defn.Any_typeCast).appliedToType(AndType(ref, tpnn))
361356
case _ =>
362357
tree

tests/explicit-nulls/neg/var-ref-in-closure.scala

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ object VarRef {
4141

4242

4343
locally {
44-
var x: String|Null = "???"
44+
var x: String|Null = ???
4545
lazy val y = {
4646
if (x != null) {
4747
val a: String = x // error: x exists in closure, no longer tackable
@@ -51,7 +51,7 @@ object VarRef {
5151
}
5252

5353
locally {
54-
var x: String|Null = "???"
54+
var x: String|Null = ???
5555
def y = {
5656
if (x != null) {
5757
val a: String = x // error: x exists in closure, no longer tackable
@@ -61,7 +61,7 @@ object VarRef {
6161
}
6262

6363
lazy val lazyblock = {
64-
var x: String|Null = "???"
64+
var x: String|Null = ???
6565
lazy val y = {
6666
if (x != null) {
6767
// The enclosingMethods of x definition and x reference hare are same
@@ -70,5 +70,71 @@ object VarRef {
7070
x
7171
}
7272
}
73-
}
7473

74+
abstract class F {
75+
def get(): String | Null
76+
}
77+
78+
locally {
79+
var x: String|Null = ???
80+
val y: F = new F {
81+
def get() = {
82+
if (x != null) x = null
83+
x
84+
}
85+
}
86+
if (x != null) {
87+
val a: String = x // error: x exists in closure, no longer tackable
88+
}
89+
}
90+
91+
locally {
92+
var x: String|Null = ???
93+
val y: F = new F {
94+
def get() = {
95+
if (x != null) {
96+
val a: String = x // error: x exists in closure, no longer tackable
97+
}
98+
x
99+
}
100+
}
101+
}
102+
103+
def f(x: => String | Null): F = new F {
104+
def get() = x
105+
}
106+
107+
locally {
108+
var x: String|Null = ???
109+
val y: F = f {
110+
if (x != null) {
111+
x = null
112+
}
113+
x
114+
}
115+
if (x != null) {
116+
val a: String = x // error: x exists in closure, no longer tackable
117+
}
118+
}
119+
120+
// TODO: not working now
121+
// locally {
122+
// var x: String|Null = ???
123+
// val y: F = f {
124+
// if (x != null) {
125+
// val a: String = x // err: x exists in closure, no longer tackable
126+
// }
127+
// x
128+
// }
129+
// }
130+
131+
locally {
132+
var x: String|Null = ???
133+
val y: String => String|Null = s => {
134+
if (x != null) {
135+
val a: String = x // error: x exists in closure, no longer tackable
136+
}
137+
x
138+
}
139+
}
140+
}

tests/explicit-nulls/pos/flow3.scala

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/explicit-nulls/pos/flow4.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ class TreeOps {
77
abstract class Tree[A, B](val key: A, val value: B)
88
class RedTree[A, B](override val key: A, override val value: B) extends Tree[A, B](key, value)
99

10-
private[this] inline def isRedTree(tree: Tree[_, _]) = (tree == null) && tree.isInstanceOf[RedTree[_, _]]
10+
private[this] inline def isRedTree(tree: Tree[_, _] | Null) = (tree != null) && tree.isInstanceOf[RedTree[_, _]]
1111

12-
def foo[A, B](tree: Tree[A, B]): Unit = {
12+
def foo[A, B](tree: Tree[A, B] | Null): Unit = {
1313
if (isRedTree(tree)) {
1414
val key = tree.key
1515
val value = tree.value

tests/explicit-nulls/pos/match.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Test NotNullInfo from non-null cases
2+
3+
object MatchTest {
4+
locally {
5+
val s: String|Null = ???
6+
s match {
7+
case _: String => println(s.length)
8+
case _ => println(0)
9+
}
10+
}
11+
}

tests/explicit-nulls/pos/while-loop.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ def f = {
66
val xsx: Int = xs.x
77
// Currently, we can't track a path with a mutable variable prefix,
88
// even though the variable is trackable, like (xs.next != null).
9-
// TODO: support this in the future?
109
val xscpy: C = xs
1110
if (xscpy.next != null) {
1211
val _: Int = xscpy.next.x
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
1
2+
2
3+
3
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
object Test {
3+
class C(val x: Int, val next: C|Null)
4+
5+
def main(args: Array[String]): Unit = {
6+
var xs: C|Null = C(1, C(2, C(3, null)))
7+
while (xs != null) {
8+
println(xs.x)
9+
xs = xs.next
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)