@@ -1089,7 +1089,7 @@ class CheckCaptures extends Recheck, SymTransformer:
10891089
10901090      if  actualBoxed eq actual then 
10911091        //  Only `addOuterRefs` when there is no box adaptation
1092-         expected1 =  addOuterRefs(expected1, actual)
1092+         expected1 =  addOuterRefs(expected1, actual, tree.srcPos )
10931093      if  isCompatible(actualBoxed, expected1) then 
10941094        if  debugSuccesses then  tree match 
10951095            case  Ident (_) => 
@@ -1130,8 +1130,12 @@ class CheckCaptures extends Recheck, SymTransformer:
11301130     *     that are outside `Cls`. These are all accessed through `Cls.this`, 
11311131     *     so we can assume they are already accounted for by `Ce` and adding 
11321132     *     them explicitly to `Ce` changes nothing. 
1133+      *   - To make up for this, we also add these variables to the capture set of `Cls`, 
1134+      *     so that all instances of `Cls` will capture these outer references. 
1135+      *  So in a sense we use `{Cls.this}` as a placeholder for certain outer captures. 
1136+      *  that we needed to be subsumed by `Cls.this`. 
11331137     */  
1134-     private  def  addOuterRefs (expected : Type , actual : Type )(using  Context ):  Type  = 
1138+     private  def  addOuterRefs (expected : Type , actual : Type ,  pos :  SrcPos )(using  Context ):  Type  = 
11351139
11361140      def  isPure (info : Type ):  Boolean  =  info match 
11371141        case  info : PolyType  =>  isPure(info.resType)
@@ -1144,19 +1148,40 @@ class CheckCaptures extends Recheck, SymTransformer:
11441148        else  isPure(owner.info) &&  isPureContext(owner.owner, limit)
11451149
11461150      //  Augment expeced capture set `erefs` by all references in actual capture
1147-       //  set `arefs` that are outside some `this.type` reference in `erefs`
1151+       //  set `arefs` that are outside some `C.this.type` reference in `erefs` for an enclosing
1152+       //  class `C`. If an added reference is not a ThisType itself, add it to the capture set
1153+       //  (i.e. use set) of the `C`. This makes sure that any outer reference implicitly subsumed
1154+       //  by `C.this` becomes a capture reference of every instance of `C`.
11481155      def  augment (erefs : CaptureSet , arefs : CaptureSet ):  CaptureSet  = 
11491156        (erefs /:  erefs.elems):  (erefs, eref) => 
11501157          eref match 
11511158            case  eref : ThisType  if  isPureContext(ctx.owner, eref.cls) => 
1152-               def  isOuterRef (aref : Type ):  Boolean  =  aref match 
1153-                 case  aref : TermRef  => 
1154-                   val  owner  =  aref.symbol.owner
1155-                   if  owner.isClass then  isOuterRef(aref.prefix)
1156-                   else  eref.cls.isProperlyContainedIn(owner)
1159+ 
1160+               def  pathRoot (aref : Type ):  Type  =  aref match 
1161+                 case  aref : NamedType  if  aref.symbol.owner.isClass =>  pathRoot(aref.prefix)
1162+                 case  _ =>  aref
1163+ 
1164+               def  isOuterRef (aref : Type ):  Boolean  =  pathRoot(aref) match 
1165+                 case  aref : NamedType  =>  eref.cls.isProperlyContainedIn(aref.symbol.owner)
11571166                case  aref : ThisType  =>  eref.cls.isProperlyContainedIn(aref.cls)
11581167                case  _ =>  false 
1159-               erefs ++  arefs.filter(isOuterRef)
1168+ 
1169+               val  outerRefs  =  arefs.filter(isOuterRef)
1170+ 
1171+               //  Include implicitly added outer references in the capture set of the class of `eref`.
1172+               for  outerRef <-  outerRefs.elems do 
1173+                 if  ! erefs.elems.contains(outerRef)
1174+                     &&  ! pathRoot(outerRef).isInstanceOf [ThisType ]
1175+                     //  we don't need to add outer ThisTypes as these are anyway added as path
1176+                     //  prefixes at the use site. And this exemption is required since capture sets
1177+                     //  of non-local classes are always empty, so we can't add an outer this to them.
1178+                 then 
1179+                   def  provenance  = 
1180+                     i """  of the enclosing class  ${eref.cls}. 
1181+                        |The reference was included since we tried to establish that  $arefs <:  $erefs""" 
1182+                   checkElem(outerRef, capturedVars(eref.cls), pos, provenance)
1183+ 
1184+               erefs ++  outerRefs
11601185            case  _ => 
11611186              erefs
11621187
@@ -1341,7 +1366,7 @@ class CheckCaptures extends Recheck, SymTransformer:
13411366        *  @param  sym   symbol of the field definition that is being checked 
13421367        */  
13431368        override  def  checkSubType (actual : Type , expected : Type )(using  Context ):  Boolean  = 
1344-           val  expected1  =  alignDependentFunction(addOuterRefs(expected, actual), actual.stripCapturing)
1369+           val  expected1  =  alignDependentFunction(addOuterRefs(expected, actual, srcPos ), actual.stripCapturing)
13451370          val  actual1  = 
13461371            val  saved  =  curEnv
13471372            try 
0 commit comments