Skip to content

Commit 4c593d5

Browse files
committed
Avoid using AsyncIteratorProtocol.next(isolation:) with @_unsafeInheritExecutor
`#isolation` in unsafe within a function that uses `@_unsafeInheritExecutor`, so avoid the implicit use of the new `AsyncIteratorProtocol.next(isolation:)` in such functions.
1 parent 40128f3 commit 4c593d5

File tree

4 files changed

+11
-5
lines changed

4 files changed

+11
-5
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,8 +2003,7 @@ bool swift::isAsyncDecl(ConcreteDeclRef declRef) {
20032003
return false;
20042004
}
20052005

2006-
/// Find an enclosing function that has @
2007-
static AbstractFunctionDecl *enclosingUnsafeInheritsExecutor(
2006+
AbstractFunctionDecl *swift::enclosingUnsafeInheritsExecutor(
20082007
const DeclContext *dc) {
20092008
for (; dc; dc = dc->getParent()) {
20102009
if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {

lib/Sema/TypeCheckConcurrency.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,9 @@ bool isPotentiallyIsolatedActor(
648648
bool diagnoseApplyArgSendability(
649649
swift::ApplyExpr *apply, const DeclContext *declContext);
650650

651+
/// If the enclosing function has @_unsafeInheritExecutorAttr, return it.
652+
AbstractFunctionDecl *enclosingUnsafeInheritsExecutor(const DeclContext *dc);
653+
651654
} // end namespace swift
652655

653656
namespace llvm {

lib/Sema/TypeCheckStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3283,6 +3283,11 @@ FuncDecl *TypeChecker::getForEachIteratorNextFunction(
32833283
if (!nextElement)
32843284
return ctx.getAsyncIteratorNext();
32853285

3286+
// If the enclosing function has @_unsafeInheritsExecutor, then #isolation
3287+
// does not work and we need to avoid relying on it.
3288+
if (enclosingUnsafeInheritsExecutor(dc))
3289+
return ctx.getAsyncIteratorNext();
3290+
32863291
// If availability checking is disabled, use next(_:).
32873292
if (ctx.LangOpts.DisableAvailabilityChecking || loc.isInvalid())
32883293
return nextElement;

test/Concurrency/unsafe_inherit_executor.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ func unsafeCallerC(x: Int, fn: () -> Void, fn2: () -> Void) async {
6363
}
6464

6565
@_unsafeInheritExecutor
66-
func unsafeCallerB(x: some AsyncSequence<Int, Never>) async {
67-
for await _ in x { }
68-
// expected-error@-1 2{{#isolation cannot be used within an `@_unsafeInheritExecutor` function}}
66+
func unsafeCallerAvoidsNewLoop(x: some AsyncSequence<Int, Never>) async throws {
67+
for try await _ in x { }
6968
}

0 commit comments

Comments
 (0)