Skip to content

Commit da00515

Browse files
committed
Expand level owner of unscoped fresh caps only where necessary
1 parent 54de369 commit da00515

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -512,35 +512,42 @@ object Capabilities:
512512

513513
final def isParamPath(using Context): Boolean = paramPathRoot.exists
514514

515-
final def ccOwner(using Context): Symbol = this match
515+
/** Compute ccOwner or (part of level owner).
516+
* @param mapUnscoped if true, return the nclosing toplevel class for FreshCaps
517+
* classified as Unscoped that don't have a prefix
518+
*/
519+
private def computeOwner(mapUnscoped: Boolean)(using Context): Symbol = this match
516520
case self: ThisType => self.cls
517-
case TermRef(prefix: Capability, _) => prefix.ccOwner
521+
case TermRef(prefix: Capability, _) => prefix.computeOwner(mapUnscoped)
518522
case self: NamedType => self.symbol
519-
case self: DerivedCapability => self.underlying.ccOwner
523+
case self: DerivedCapability => self.underlying.computeOwner(mapUnscoped)
520524
case self: FreshCap =>
521525
val setOwner = self.hiddenSet.owner
522526
self.prefix match
523527
case prefix: ThisType if setOwner.isTerm && setOwner.owner == prefix.cls =>
524528
setOwner
525-
case prefix: Capability => prefix.ccOwner
526-
case NoPrefix if classifier.derivesFrom(defn.Caps_Unscoped) =>
529+
case prefix: Capability => prefix.computeOwner(mapUnscoped)
530+
case NoPrefix if mapUnscoped && classifier.derivesFrom(defn.Caps_Unscoped) =>
527531
ctx.owner.topLevelClass
528532
case _ => setOwner
529533
case _ /* : GlobalCap | ResultCap | ParamRef */ => NoSymbol
530534

535+
final def ccOwner(using Context): Symbol = computeOwner(mapUnscoped = false)
536+
531537
final def visibility(using Context): Symbol = this match
532-
case self: FreshCap => adjustOwner(ccOwner)
538+
case self: FreshCap => adjustOwner(computeOwner(mapUnscoped = true))
533539
case _ =>
534-
val vis = ccOwner
540+
val vis = computeOwner(mapUnscoped = true)
535541
if vis.is(Param) then vis.owner else vis
536542

537543
/** The symbol that represents the level closest-enclosing ccOwner.
538544
* Symbols representing levels are
539545
* - class symbols, but not inner (non-static) module classes
540546
* - method symbols, but not accessors or constructors
547+
* For Unscoped FreshCaps the level owner is the top-level class.
541548
*/
542549
final def levelOwner(using Context): Symbol =
543-
adjustOwner(ccOwner)
550+
adjustOwner(computeOwner(mapUnscoped = true))
544551

545552
private def adjustOwner(owner: Symbol)(using Context): Symbol =
546553
if !owner.exists

0 commit comments

Comments
 (0)