[Concurrency] Apply nonisolated(unsafe) to iterator variables for

async for-in loops.

Async iterators are not `Sendable`; they're only meant to be used from
the isolation domain that creates them. But the `next()` method runs on
the generic executor, so calling it from an actor-isolated context passes
non-`Sendable` state across the isolation boundary. `next()` should
inherit the isolation of the caller, but for now, use the opt out.
This commit is contained in:
Holly Borla
2024-01-03 13:39:07 -08:00
parent 76ae065c29
commit 0c6c369e0c
2 changed files with 19 additions and 0 deletions

View File

@@ -4516,6 +4516,19 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
sequenceExpr->getStartLoc(), ctx.getIdentifier(name), dc);
makeIteratorVar->setImplicit();
// FIXME: Apply `nonisolated(unsafe)` to async iterators.
//
// Async iterators are not `Sendable`; they're only meant to be used from
// the isolation domain that creates them. But the `next()` method runs on
// the generic executor, so calling it from an actor-isolated context passes
// non-`Sendable` state across the isolation boundary. `next()` should
// inherit the isolation of the caller, but for now, use the opt out.
if (isAsync) {
auto *nonisolated = new (ctx)
NonisolatedAttr(/*unsafe=*/true, /*implicit=*/true);
makeIteratorVar->getAttrs().add(nonisolated);
}
// First, let's form a call from sequence to `.makeIterator()` and save
// that in a special variable which is going to be used by SILGen.
{