Skip to content

Commit a339e04

Browse files
committed
Also increase level for classes
1 parent fa30d7f commit a339e04

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed

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

+5
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ class CCState:
7070
myLevel += 1
7171
try op finally myLevel -=1
7272

73+
inline def inNestedLevelUnless[T](inline p: Boolean)(inline op: T): T =
74+
val saved = myLevel
75+
if !p then myLevel += 1
76+
try op finally myLevel = saved
77+
7378
/** The level of the current environment. Levels start at 0 and increase for
7479
* each nested function or class. -1 means the level is undefined.
7580
*/

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,8 @@ class CheckCaptures extends Recheck, SymTransformer:
775775
checkSubset(thisSet,
776776
CaptureSet.empty.withDescription(i"of pure base class $pureBase"),
777777
selfType.srcPos, cs1description = " captured by this self type")
778-
super.recheckClassDef(tree, impl, cls)
778+
ccState.inNestedLevelUnless(cls.is(Module)):
779+
super.recheckClassDef(tree, impl, cls)
779780
finally
780781
curEnv = saved
781782

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

+36-33
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,11 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
437437
transformTT(arg, boxed = true, exact = false) // type arguments in type applications are boxed
438438

439439
case tree: TypeDef if tree.symbol.isClass =>
440-
ccState.recordLevel(tree.symbol)
441-
inContext(ctx.withOwner(tree.symbol)):
442-
traverseChildren(tree)
440+
val sym = tree.symbol
441+
ccState.recordLevel(sym)
442+
ccState.inNestedLevelUnless(sym.is(Module)):
443+
inContext(ctx.withOwner(sym))
444+
traverseChildren(tree)
443445

444446
case tree @ SeqLiteral(elems, tpt: TypeTree) =>
445447
traverse(elems)
@@ -546,36 +548,37 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
546548
case tree: TypeDef =>
547549
tree.symbol match
548550
case cls: ClassSymbol =>
549-
val cinfo @ ClassInfo(prefix, _, ps, decls, selfInfo) = cls.classInfo
550-
def innerModule = cls.is(ModuleClass) && !cls.isStatic
551-
val selfInfo1 =
552-
if (selfInfo ne NoType) && !innerModule then
553-
// if selfInfo is explicitly given then use that one, except if
554-
// self info applies to non-static modules, these still need to be inferred
555-
selfInfo
556-
else if cls.isPureClass then
557-
// is cls is known to be pure, nothing needs to be added to self type
558-
selfInfo
559-
else if !cls.isEffectivelySealed && !cls.baseClassHasExplicitSelfType then
560-
// assume {cap} for completely unconstrained self types of publicly extensible classes
561-
CapturingType(cinfo.selfType, CaptureSet.universal)
562-
else
563-
// Infer the self type for the rest, which is all classes without explicit
564-
// self types (to which we also add nested module classes), provided they are
565-
// neither pure, nor are publicily extensible with an unconstrained self type.
566-
CapturingType(cinfo.selfType, CaptureSet.Var(cls, level = ccState.currentLevel))
567-
val ps1 = inContext(ctx.withOwner(cls)):
568-
ps.mapConserve(transformExplicitType(_))
569-
if (selfInfo1 ne selfInfo) || (ps1 ne ps) then
570-
val newInfo = ClassInfo(prefix, cls, ps1, decls, selfInfo1)
571-
updateInfo(cls, newInfo)
572-
capt.println(i"update class info of $cls with parents $ps selfinfo $selfInfo to $newInfo")
573-
cls.thisType.asInstanceOf[ThisType].invalidateCaches()
574-
if cls.is(ModuleClass) then
575-
// if it's a module, the capture set of the module reference is the capture set of the self type
576-
val modul = cls.sourceModule
577-
updateInfo(modul, CapturingType(modul.info, selfInfo1.asInstanceOf[Type].captureSet))
578-
modul.termRef.invalidateCaches()
551+
ccState.inNestedLevelUnless(cls.is(Module)):
552+
val cinfo @ ClassInfo(prefix, _, ps, decls, selfInfo) = cls.classInfo
553+
def innerModule = cls.is(ModuleClass) && !cls.isStatic
554+
val selfInfo1 =
555+
if (selfInfo ne NoType) && !innerModule then
556+
// if selfInfo is explicitly given then use that one, except if
557+
// self info applies to non-static modules, these still need to be inferred
558+
selfInfo
559+
else if cls.isPureClass then
560+
// is cls is known to be pure, nothing needs to be added to self type
561+
selfInfo
562+
else if !cls.isEffectivelySealed && !cls.baseClassHasExplicitSelfType then
563+
// assume {cap} for completely unconstrained self types of publicly extensible classes
564+
CapturingType(cinfo.selfType, CaptureSet.universal)
565+
else
566+
// Infer the self type for the rest, which is all classes without explicit
567+
// self types (to which we also add nested module classes), provided they are
568+
// neither pure, nor are publicily extensible with an unconstrained self type.
569+
CapturingType(cinfo.selfType, CaptureSet.Var(cls, level = ccState.currentLevel))
570+
val ps1 = inContext(ctx.withOwner(cls)):
571+
ps.mapConserve(transformExplicitType(_))
572+
if (selfInfo1 ne selfInfo) || (ps1 ne ps) then
573+
val newInfo = ClassInfo(prefix, cls, ps1, decls, selfInfo1)
574+
updateInfo(cls, newInfo)
575+
capt.println(i"update class info of $cls with parents $ps selfinfo $selfInfo to $newInfo")
576+
cls.thisType.asInstanceOf[ThisType].invalidateCaches()
577+
if cls.is(ModuleClass) then
578+
// if it's a module, the capture set of the module reference is the capture set of the self type
579+
val modul = cls.sourceModule
580+
updateInfo(modul, CapturingType(modul.info, selfInfo1.asInstanceOf[Type].captureSet))
581+
modul.termRef.invalidateCaches()
579582
case _ =>
580583
case _ =>
581584
end postProcess

0 commit comments

Comments
 (0)