@@ -85,7 +85,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
8585 /** Drops `private` from the flags of `symd` provided it is
8686 * a parameter accessor that's not `constructorOnly` or `uncheckedCaptured`
8787 * and that contains at least one @retains in co- or in-variant position.
88- * The @retains mught be implicit for a type deriving from `Capability`.
88+ * The @retains might be implicit for a type deriving from `Capability`.
8989 */
9090 private def newFlagsFor (symd : SymDenotation )(using Context ): FlagSet =
9191
@@ -303,6 +303,10 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
303303 * 6. Perform normalizeCaptures
304304 */
305305 private def transformExplicitType (tp : Type , tptToCheck : Tree = EmptyTree )(using Context ): Type =
306+
307+ def fail (msg : Message ) =
308+ if ! tptToCheck.isEmpty then report.error(msg, tptToCheck.srcPos)
309+
306310 val toCapturing = new DeepTypeMap with FollowAliasesMap :
307311 override def toString = " expand aliases"
308312
@@ -332,7 +336,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
332336 else fntpe
333337
334338 /** If C derives from Capability and we have a C^cs in source, we leave it as is
335- * instead of expanding it to C^{cap}^cs. We do this by stripping capability-generated
339+ * instead of expanding it to C^{cap.rd }^cs. We do this by stripping capability-generated
336340 * universal capture sets from the parent of a CapturingType.
337341 */
338342 def stripImpliedCaptureSet (tp : Type ): Type = tp match
@@ -341,18 +345,28 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
341345 parent
342346 case _ => tp
343347
348+ def checkSharedOK (tp : Type ): tp.type =
349+ tp match
350+ case CapturingType (parent, refs)
351+ if refs.isUniversal && parent.derivesFrom(defn.Caps_SharedCapability ) =>
352+ fail(em " $tp extends SharedCapability, so it cannot capture `cap` " )
353+ case _ =>
354+ tp
355+
344356 def apply (t : Type ) =
345357 t match
346358 case t @ CapturingType (parent, refs) =>
347- t.derivedCapturingType(stripImpliedCaptureSet(this (parent)), refs)
359+ checkSharedOK :
360+ t.derivedCapturingType(stripImpliedCaptureSet(this (parent)), refs)
348361 case t @ AnnotatedType (parent, ann) =>
349362 val parent1 = this (parent)
350363 if ann.symbol.isRetains then
351364 val parent2 = stripImpliedCaptureSet(parent1)
352365 if ! tptToCheck.isEmpty then
353366 checkWellformedLater(parent2, ann.tree, tptToCheck)
354367 try
355- CapturingType (parent2, ann.tree.toCaptureSet)
368+ checkSharedOK :
369+ CapturingType (parent2, ann.tree.toCaptureSet)
356370 catch case ex : IllegalCaptureRef =>
357371 report.error(em " Illegal capture reference: ${ex.getMessage.nn}" , tptToCheck.srcPos)
358372 parent2
@@ -369,9 +383,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
369383 else normalizeCaptures(mapFollowingAliases(t))
370384 end toCapturing
371385
372- def fail (msg : Message ) =
373- if ! tptToCheck.isEmpty then report.error(msg, tptToCheck.srcPos)
374-
375386 val tp1 = toCapturing(tp)
376387 val tp2 = Existential .mapCapInResults(fail)(tp1)
377388 if tp2 ne tp then capt.println(i " expanded explicit in ${ctx.owner}: $tp --> $tp1 --> $tp2" )
0 commit comments