Skip to content

Commit 4f70eb2

Browse files
committed
[Concurrency] Suppress Sendable argument diagnostics for values that come
from `nonisolated(unsafe)` declarations. (cherry picked from commit 76ae065)
1 parent a4789dd commit 4f70eb2

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

include/swift/AST/Expr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
448448
return const_cast<Expr *>(this)->getValueProvidingExpr();
449449
}
450450

451+
/// Find the original expression value, looking through various
452+
/// implicit conversions.
453+
const Expr *findOriginalValue() const;
454+
451455
/// Find the original type of a value, looking through various implicit
452456
/// conversions.
453457
Type findOriginalType() const;

lib/AST/Expr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2803,7 +2803,7 @@ FrontendStatsTracer::getTraceFormatter<const Expr *>() {
28032803
return &TF;
28042804
}
28052805

2806-
Type Expr::findOriginalType() const {
2806+
const Expr *Expr::findOriginalValue() const {
28072807
auto *expr = this;
28082808
do {
28092809
expr = expr->getSemanticsProvidingExpr();
@@ -2826,5 +2826,10 @@ Type Expr::findOriginalType() const {
28262826
break;
28272827
} while (true);
28282828

2829+
return expr;
2830+
}
2831+
2832+
Type Expr::findOriginalType() const {
2833+
auto *expr = findOriginalValue();
28292834
return expr->getType()->getRValueType();
28302835
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,15 @@ static void noteGlobalActorOnContext(DeclContext *dc, Type globalActor) {
19471947
}
19481948
}
19491949

1950+
static bool shouldCheckSendable(Expr *expr) {
1951+
if (auto *declRef = dyn_cast<DeclRefExpr>(expr->findOriginalValue())) {
1952+
auto isolation = getActorIsolation(declRef->getDecl());
1953+
return isolation != ActorIsolation::NonisolatedUnsafe;
1954+
}
1955+
1956+
return true;
1957+
}
1958+
19501959
bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *declContext) {
19511960
auto isolationCrossing = apply->getIsolationCrossing();
19521961
if (!isolationCrossing.has_value())
@@ -1959,7 +1968,9 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
19591968
// Check the 'self' argument.
19601969
if (auto *selfApply = dyn_cast<SelfApplyExpr>(apply->getFn())) {
19611970
auto *base = selfApply->getBase();
1962-
if (diagnoseNonSendableTypes(
1971+
1972+
if (shouldCheckSendable(base) &&
1973+
diagnoseNonSendableTypes(
19631974
base->getType(),
19641975
declContext, base->getStartLoc(),
19651976
diag::non_sendable_call_argument,
@@ -1979,6 +1990,7 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
19791990
// Dig out the location of the argument.
19801991
SourceLoc argLoc = apply->getLoc();
19811992
Type argType;
1993+
bool checkSendable = true;
19821994
if (auto argList = apply->getArgs()) {
19831995
auto arg = argList->get(paramIdx);
19841996
if (arg.getStartLoc().isValid())
@@ -1987,11 +1999,13 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
19871999
// Determine the type of the argument, ignoring any implicit
19882000
// conversions that could have stripped sendability.
19892001
if (Expr *argExpr = arg.getExpr()) {
1990-
argType = argExpr->findOriginalType();
2002+
checkSendable = shouldCheckSendable(argExpr);
2003+
argType = argExpr->findOriginalType();
19912004
}
19922005
}
19932006

1994-
if (diagnoseNonSendableTypes(
2007+
if (checkSendable &&
2008+
diagnoseNonSendableTypes(
19952009
argType ? argType : param.getParameterType(),
19962010
declContext, argLoc, diag::non_sendable_call_argument,
19972011
isolationCrossing.value().exitsIsolation(),

test/Concurrency/experimental_feature_strictconcurrency.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,11 @@ func testLocalNonisolatedUnsafe() async {
8484
}
8585
print(await task.value)
8686
}
87+
88+
@MainActor
89+
func iterate(stream: AsyncStream<Int>) async {
90+
nonisolated(unsafe) var it = stream.makeAsyncIterator()
91+
while let element = await it.next() {
92+
print(element)
93+
}
94+
}

0 commit comments

Comments
 (0)