Skip to content

Commit 6a79065

Browse files
committed
Avoid null-checks against environments
We already have a sentinel value in rootEnv; use that instead.
1 parent 66d11de commit 6a79065

File tree

1 file changed

+19
-20
lines changed

1 file changed

+19
-20
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ object CheckCaptures:
5656
* @param nestedClosure under deferredReaches: If this is an env of a method with an anonymous function or
5757
* anonymous class as RHS, the symbol of that function or class. NoSymbol in all other cases.
5858
*/
59-
case class Env(
60-
owner: Symbol,
61-
kind: EnvKind,
62-
captured: CaptureSet,
63-
outer0: Env | Null,
64-
nestedClosure: Symbol = NoSymbol)(using @constructorOnly ictx: Context):
59+
class Env(
60+
val owner: Symbol,
61+
val kind: EnvKind,
62+
val captured: CaptureSet,
63+
outer0: Env | Null,
64+
val nestedClosure: Symbol = NoSymbol)(using @constructorOnly ictx: Context) {
6565

6666
assert(definesEnv(owner))
6767
captured match
@@ -71,16 +71,16 @@ object CheckCaptures:
7171

7272
def outer = outer0.nn
7373

74-
def isOutermost = outer0 == null
74+
def isRoot(using Context) = owner.is(Package)
7575

76-
def outersIterator: Iterator[Env] = new:
76+
def outersIterator(using Context): Iterator[Env] = new:
7777
private var cur = Env.this
78-
def hasNext = !cur.isOutermost
78+
def hasNext = !cur.isRoot
7979
def next(): Env =
8080
val res = cur
8181
cur = cur.outer
8282
res
83-
end Env
83+
}
8484

8585
def definesEnv(sym: Symbol)(using Context): Boolean =
8686
sym.isOneOf(MethodOrLazy) || sym.isClass
@@ -477,9 +477,9 @@ class CheckCaptures extends Recheck, SymTransformer:
477477
/** The next environment enclosing `env` that needs to be charged
478478
* with free references.
479479
*/
480-
def nextEnvToCharge(env: Env)(using Context): Env | Null =
481-
if env.owner.isConstructor then env.outer.outer0
482-
else env.outer0
480+
def nextEnvToCharge(env: Env)(using Context): Env =
481+
if env.owner.isConstructor then env.outer.outer
482+
else env.outer
483483

484484
/** A description where this environment comes from */
485485
private def provenance(env: Env)(using Context): String =
@@ -497,9 +497,8 @@ class CheckCaptures extends Recheck, SymTransformer:
497497
* Does the given environment belong to a method that is (a) nested in a term
498498
* and (b) not the method of an anonymous function?
499499
*/
500-
def isOfNestedMethod(env: Env | Null)(using Context) =
500+
def isOfNestedMethod(env: Env)(using Context) =
501501
ccConfig.deferredReaches
502-
&& env != null
503502
&& env.owner.is(Method)
504503
&& env.owner.owner.isTerm
505504
&& !env.owner.isAnonymousFunction
@@ -604,7 +603,7 @@ class CheckCaptures extends Recheck, SymTransformer:
604603
capt.println(i"Include call or box capture $included from $cs in ${env.owner} --> ${env.captured}")
605604
if !isOfNestedMethod(env) then
606605
val nextEnv = nextEnvToCharge(env)
607-
if nextEnv != null then
606+
if !nextEnv.isRoot then
608607
if nextEnv.owner != env.owner
609608
&& env.owner.isReadOnlyMember
610609
&& env.owner.owner.derivesFrom(defn.Caps_Stateful)
@@ -1842,11 +1841,11 @@ class CheckCaptures extends Recheck, SymTransformer:
18421841
private def debugShowEnvs()(using Context): Unit =
18431842
def showEnv(env: Env): String = i"Env(${env.owner}, ${env.kind}, ${env.captured})"
18441843
val sb = StringBuilder()
1845-
@annotation.tailrec def walk(env: Env | Null): Unit =
1846-
if env != null then
1844+
@annotation.tailrec def walk(env: Env): Unit =
1845+
if !env.isRoot then
18471846
sb ++= showEnv(env)
18481847
sb ++= "\n"
1849-
walk(env.outer0)
1848+
walk(env.outer)
18501849
sb ++= "===== Current Envs ======\n"
18511850
walk(curEnv)
18521851
sb ++= "===== End ======\n"
@@ -2247,7 +2246,7 @@ class CheckCaptures extends Recheck, SymTransformer:
22472246
else if env.owner.isStaticOwner then NoSymbol
22482247
else
22492248
val nextEnv = nextEnvToCharge(env)
2250-
if nextEnv == null then NoSymbol else boxedOwner(nextEnv)
2249+
if nextEnv.isRoot then NoSymbol else boxedOwner(nextEnv)
22512250

22522251
def checkUseUnlessBoxed(c: Capability, croot: NamedType) =
22532252
if !boxedOwner(env).isContainedIn(croot.symbol.owner) then

0 commit comments

Comments
 (0)