Skip to content

Commit 77df754

Browse files
committed
add usedOutOfOrder
1 parent 0230180 commit 77df754

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import StdNames.nme
99
import util.Property
1010
import Names.Name
1111
import util.Spans.Span
12-
import Flags.Mutable
12+
import Flags._
1313
import NullOpsDecorator._
1414
import collection.mutable
1515

@@ -151,11 +151,7 @@ object Nullables with
151151
|| { val sym = ref.symbol
152152
sym.is(Mutable)
153153
&& sym.owner.isTerm
154-
&& ( sym.owner == curCtx.owner
155-
|| !curCtx.owner.is(Flags.Lazy) // not at the rhs of lazy ValDef
156-
&& sym.owner.enclosingMethod == curCtx.owner.enclosingMethod // not in different methods
157-
// TODO: need to check by-name paramter
158-
)
154+
&& !ref.usedOutOfOrder // todo: remove
159155
&& sym.span.exists
160156
&& curCtx.compilationUnit != null // could be null under -Ytest-pickler
161157
&& curCtx.compilationUnit.assignmentSpans.contains(sym.span.start)
@@ -206,6 +202,24 @@ object Nullables with
206202
then infos
207203
else info :: infos
208204

205+
given refOps: extension (ref: TermRef) with
206+
207+
def usedOutOfOrder(given Context) =
208+
val refSym = ref.symbol
209+
val refOwner = refSym.owner
210+
211+
def enclosedInClosure(s: Symbol): Boolean =
212+
s != NoSymbol
213+
&& s != refOwner
214+
&& (s.isOneOf(Lazy | Method) // not at the rhs of lazy ValDef or in a method (or lambda)
215+
|| s.isClass // not in a class
216+
// TODO: need to check by-name paramter
217+
|| enclosedInClosure(s.owner))
218+
219+
refSym.is(Mutable)
220+
&& refSym.owner.isTerm
221+
&& enclosedInClosure(curCtx.owner)
222+
209223
given treeOps: extension (tree: Tree) with
210224

211225
/* The `tree` with added nullability attachment */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class Typer extends Namer
353353
def toNotNullTermRef(tree: Tree, pt: Type)(implicit ctx: Context): Tree = tree.tpe match
354354
case ref @ OrNull(tpnn) : TermRef
355355
if pt != AssignProto && // Ensure it is not the lhs of Assign
356+
!ref.usedOutOfOrder &&
356357
ctx.notNullInfos.impliesNotNull(ref) =>
357358
tree.select(defn.Any_typeCast).appliedToType(AndType(ref, tpnn))
358359
case _ =>

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ object VarRef {
1313
}
1414
}
1515

16+
locally {
17+
var x: String|Null = ???
18+
var y = {
19+
if (x != null) {
20+
val _: String = x // ok: y doesn't create closure
21+
}
22+
}
23+
if (x != null) {
24+
val a: String = x // ok
25+
}
26+
}
27+
1628
locally {
1729
var x: String|Null = ???
1830
lazy val y = {

0 commit comments

Comments
 (0)