@@ -85,7 +85,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
85
85
/** Drops `private` from the flags of `symd` provided it is
86
86
* a parameter accessor that's not `constructorOnly` or `uncheckedCaptured`
87
87
* 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`.
89
89
*/
90
90
private def newFlagsFor (symd : SymDenotation )(using Context ): FlagSet =
91
91
@@ -303,6 +303,10 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
303
303
* 6. Perform normalizeCaptures
304
304
*/
305
305
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
+
306
310
val toCapturing = new DeepTypeMap with FollowAliasesMap :
307
311
override def toString = " expand aliases"
308
312
@@ -332,7 +336,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
332
336
else fntpe
333
337
334
338
/** 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
336
340
* universal capture sets from the parent of a CapturingType.
337
341
*/
338
342
def stripImpliedCaptureSet (tp : Type ): Type = tp match
@@ -341,18 +345,28 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
341
345
parent
342
346
case _ => tp
343
347
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
+
344
356
def apply (t : Type ) =
345
357
t match
346
358
case t @ CapturingType (parent, refs) =>
347
- t.derivedCapturingType(stripImpliedCaptureSet(this (parent)), refs)
359
+ checkSharedOK :
360
+ t.derivedCapturingType(stripImpliedCaptureSet(this (parent)), refs)
348
361
case t @ AnnotatedType (parent, ann) =>
349
362
val parent1 = this (parent)
350
363
if ann.symbol.isRetains then
351
364
val parent2 = stripImpliedCaptureSet(parent1)
352
365
if ! tptToCheck.isEmpty then
353
366
checkWellformedLater(parent2, ann.tree, tptToCheck)
354
367
try
355
- CapturingType (parent2, ann.tree.toCaptureSet)
368
+ checkSharedOK :
369
+ CapturingType (parent2, ann.tree.toCaptureSet)
356
370
catch case ex : IllegalCaptureRef =>
357
371
report.error(em " Illegal capture reference: ${ex.getMessage.nn}" , tptToCheck.srcPos)
358
372
parent2
@@ -369,9 +383,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
369
383
else normalizeCaptures(mapFollowingAliases(t))
370
384
end toCapturing
371
385
372
- def fail (msg : Message ) =
373
- if ! tptToCheck.isEmpty then report.error(msg, tptToCheck.srcPos)
374
-
375
386
val tp1 = toCapturing(tp)
376
387
val tp2 = Existential .mapCapInResults(fail)(tp1)
377
388
if tp2 ne tp then capt.println(i " expanded explicit in ${ctx.owner}: $tp --> $tp1 --> $tp2" )
0 commit comments