Skip to content

Commit 810fbce

Browse files
Merge pull request #81573 from AnthonyLatsis/pinus-sibirica-6.2
[6.2] AST, Sema: Cherry-pick 4 `NonisolatedNonsendingByDefault` bug fixes
2 parents 4b2d879 + e5a10a3 commit 810fbce

File tree

7 files changed

+195
-98
lines changed

7 files changed

+195
-98
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8634,23 +8634,23 @@ GROUPED_WARNING(
86348634
attr_execution_nonisolated_behavior_will_change_decl, NonisolatedNonsendingByDefault,
86358635
none,
86368636
"feature '%0' will cause nonisolated async %kindbase1 to run on the "
8637-
"caller's actor; use %2 to preserve behavior",
8638-
(StringRef, const AbstractFunctionDecl *, DeclAttribute))
8637+
"caller's actor; use '@concurrent' to preserve behavior",
8638+
(StringRef, const AbstractFunctionDecl *))
86398639
86408640
GROUPED_WARNING(
86418641
attr_execution_nonisolated_behavior_will_change_closure,
86428642
NonisolatedNonsendingByDefault, none,
86438643
"feature '%0' will cause nonisolated async closure to run on the caller's "
8644-
"actor; use %1 to preserve behavior",
8645-
(StringRef, DeclAttribute))
8644+
"actor; use '@concurrent' to preserve behavior",
8645+
(StringRef))
86468646
86478647
GROUPED_WARNING(
86488648
attr_execution_nonisolated_behavior_will_change_typerepr,
86498649
NonisolatedNonsendingByDefault, none,
86508650
"feature '%0' will cause nonisolated async function type to be treated as "
8651-
"specified to run on the caller's actor; use %1 to preserve "
8651+
"specified to run on the caller's actor; use '@concurrent' to preserve "
86528652
"behavior",
8653-
(StringRef, DeclAttribute))
8653+
(StringRef))
86548654
86558655
#define UNDEFINE_DIAGNOSTIC_MACROS
86568656
#include "DefineDiagnosticMacros.h"

lib/AST/DiagnosticEngine.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -393,15 +393,17 @@ InFlightDiagnostic::fixItAddAttribute(const DeclAttribute *Attr,
393393
const ClosureExpr *E) {
394394
ASSERT(!E->isImplicit());
395395

396-
SourceLoc insertionLoc;
397-
398-
if (auto *paramList = E->getParameters()) {
399-
// HACK: Don't set insertion loc to param list start loc if it's equal to
400-
// closure start loc (meaning it's implicit).
401-
// FIXME: Don't set the start loc of an implicit param list, or put an
402-
// isImplicit bit on ParameterList.
403-
if (paramList->getStartLoc() != E->getStartLoc()) {
404-
insertionLoc = paramList->getStartLoc();
396+
SourceLoc insertionLoc = E->getBracketRange().Start;
397+
398+
if (insertionLoc.isInvalid()) {
399+
if (auto *paramList = E->getParameters()) {
400+
// HACK: Don't set insertion loc to param list start loc if it's equal to
401+
// closure start loc (meaning it's implicit).
402+
// FIXME: Don't set the start loc of an implicit param list, or put an
403+
// isImplicit bit on ParameterList.
404+
if (paramList->getStartLoc() != E->getStartLoc()) {
405+
insertionLoc = paramList->getStartLoc();
406+
}
405407
}
406408
}
407409

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,11 +1414,6 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14141414
bool async = expr->getAsyncLoc().isValid();
14151415
bool sendable = expr->getAttrs().hasAttribute<SendableAttr>();
14161416

1417-
// `@concurrent` attribute is only valid on asynchronous function types.
1418-
if (expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
1419-
async = true;
1420-
}
1421-
14221417
if (throws || async) {
14231418
return ASTExtInfoBuilder()
14241419
.withThrows(throws, /*FIXME:*/Type())
@@ -1432,11 +1427,17 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14321427
if (!body)
14331428
return ASTExtInfoBuilder().withSendable(sendable).build();
14341429

1430+
// `@concurrent` attribute is only valid on asynchronous function types.
1431+
bool asyncFromAttr = false;
1432+
if (expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
1433+
asyncFromAttr = true;
1434+
}
1435+
14351436
auto throwFinder = FindInnerThrows(expr);
14361437
body->walk(throwFinder);
14371438
return ASTExtInfoBuilder()
14381439
.withThrows(throwFinder.foundThrow(), /*FIXME:*/Type())
1439-
.withAsync(bool(findAsyncNode(expr)))
1440+
.withAsync(asyncFromAttr || bool(findAsyncNode(expr)))
14401441
.withSendable(sendable)
14411442
.build();
14421443
}

lib/Sema/NonisolatedNonsendingByDefaultMigration.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,21 @@ void NonisolatedNonsendingByDefaultMigrationTarget::diagnose() const {
168168
ctx.Diags
169169
.diagnose(functionDecl->getLoc(),
170170
diag::attr_execution_nonisolated_behavior_will_change_decl,
171-
featureName, functionDecl, &attr)
171+
featureName, functionDecl)
172172
.fixItInsertAttribute(
173173
decl->getAttributeInsertionLoc(/*forModifier=*/false), &attr);
174174
} else if (closure) {
175175
ctx.Diags
176176
.diagnose(closure->getLoc(),
177177
diag::attr_execution_nonisolated_behavior_will_change_closure,
178-
featureName, &attr)
178+
featureName)
179179
.fixItAddAttribute(&attr, closure);
180180
} else {
181181
ctx.Diags
182182
.diagnose(
183183
functionRepr->getStartLoc(),
184184
diag::attr_execution_nonisolated_behavior_will_change_typerepr,
185-
featureName, &attr)
185+
featureName)
186186
.fixItInsertAttribute(functionRepr->getStartLoc(), &attr);
187187
}
188188
}

lib/Sema/TypeCheckType.cpp

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,6 +2418,11 @@ namespace {
24182418
class TypeAttrSet {
24192419
const ASTContext &ctx;
24202420

2421+
/// FIXME:
2422+
/// `nonisolated(nonsending)` is modeled as a separate `TypeRepr`, but
2423+
/// needs to be considered together with subsequent attributes.
2424+
CallerIsolatedTypeRepr *nonisolatedNonsendingAttr;
2425+
24212426
llvm::TinyPtrVector<CustomAttr*> customAttrs;
24222427
EnumMap<TypeAttrKind, TypeAttribute *> typeAttrs;
24232428

@@ -2429,7 +2434,9 @@ namespace {
24292434
#endif
24302435

24312436
public:
2432-
TypeAttrSet(const ASTContext &ctx) : ctx(ctx) {}
2437+
TypeAttrSet(const ASTContext &ctx,
2438+
CallerIsolatedTypeRepr *nonisolatedNonsendingAttr = nullptr)
2439+
: ctx(ctx), nonisolatedNonsendingAttr(nonisolatedNonsendingAttr) {}
24332440

24342441
TypeAttrSet(const TypeAttrSet &) = delete;
24352442
TypeAttrSet &operator=(const TypeAttrSet &) = delete;
@@ -2448,6 +2455,10 @@ namespace {
24482455
/// will be diagnosed.
24492456
void accumulate(ArrayRef<TypeOrCustomAttr> attrs);
24502457

2458+
CallerIsolatedTypeRepr *getNonisolatedNonsendingAttr() const {
2459+
return nonisolatedNonsendingAttr;
2460+
}
2461+
24512462
/// Return all of the custom attributes.
24522463
ArrayRef<CustomAttr*> getCustomAttrs() const {
24532464
return customAttrs;
@@ -2547,9 +2558,17 @@ namespace {
25472558
}
25482559

25492560
template <class AttrClass>
2550-
AttrClass *getWithoutClaiming(TypeAttrSet *attrs) {
2561+
std::enable_if_t<std::is_base_of_v<TypeAttribute, AttrClass>, AttrClass *>
2562+
getWithoutClaiming(TypeAttrSet *attrs) {
25512563
return (attrs ? getWithoutClaiming<AttrClass>(*attrs) : nullptr);
25522564
}
2565+
2566+
template <class AttrClass>
2567+
std::enable_if_t<std::is_same_v<AttrClass, CallerIsolatedTypeRepr>,
2568+
CallerIsolatedTypeRepr *>
2569+
getWithoutClaiming(TypeAttrSet *attrs) {
2570+
return attrs ? attrs->getNonisolatedNonsendingAttr() : nullptr;
2571+
}
25532572
} // end anonymous namespace
25542573

25552574
Type TypeResolution::resolveContextualType(
@@ -4247,10 +4266,19 @@ NeverNullType TypeResolver::resolveASTFunctionType(
42474266
};
42484267

42494268
if (auto concurrentAttr = claim<ConcurrentTypeAttr>(attrs)) {
4269+
if (auto *nonisolatedNonsendingAttr =
4270+
getWithoutClaiming<CallerIsolatedTypeRepr>(attrs)) {
4271+
diagnoseInvalid(
4272+
nonisolatedNonsendingAttr, nonisolatedNonsendingAttr->getStartLoc(),
4273+
diag::cannot_use_nonisolated_nonsending_together_with_concurrent,
4274+
nonisolatedNonsendingAttr);
4275+
}
4276+
42504277
checkExecutionBehaviorAttribute(concurrentAttr);
4278+
42514279
if (!repr->isInvalid())
42524280
isolation = FunctionTypeIsolation::forNonIsolated();
4253-
} else {
4281+
} else if (!getWithoutClaiming<CallerIsolatedTypeRepr>(attrs)) {
42544282
if (ctx.LangOpts.getFeatureState(Feature::NonisolatedNonsendingByDefault)
42554283
.isEnabledForMigration()) {
42564284
// Diagnose only in the interface stage, which is run once.
@@ -5281,7 +5309,20 @@ TypeResolver::resolveSendingTypeRepr(SendingTypeRepr *repr,
52815309
NeverNullType
52825310
TypeResolver::resolveCallerIsolatedTypeRepr(CallerIsolatedTypeRepr *repr,
52835311
TypeResolutionOptions options) {
5284-
Type type = resolveType(repr->getBase(), options);
5312+
Type type;
5313+
{
5314+
TypeAttrSet attrs(getASTContext(), repr);
5315+
5316+
auto *baseRepr = repr->getBase();
5317+
if (auto *attrRepr = dyn_cast<AttributedTypeRepr>(baseRepr)) {
5318+
baseRepr = attrs.accumulate(attrRepr);
5319+
}
5320+
5321+
type = resolveAttributedType(baseRepr, options, attrs);
5322+
5323+
attrs.diagnoseUnclaimed(resolution, options, type);
5324+
}
5325+
52855326
if (type->hasError())
52865327
return ErrorType::get(getASTContext());
52875328

@@ -5297,15 +5338,6 @@ TypeResolver::resolveCallerIsolatedTypeRepr(CallerIsolatedTypeRepr *repr,
52975338
diag::nonisolated_nonsending_only_on_async, repr);
52985339
}
52995340

5300-
if (auto *ATR = dyn_cast<AttributedTypeRepr>(repr->getBase())) {
5301-
if (ATR->get(TypeAttrKind::Concurrent)) {
5302-
diagnoseInvalid(
5303-
repr, repr->getStartLoc(),
5304-
diag::cannot_use_nonisolated_nonsending_together_with_concurrent,
5305-
repr);
5306-
}
5307-
}
5308-
53095341
switch (fnType->getIsolation().getKind()) {
53105342
case FunctionTypeIsolation::Kind::NonIsolated:
53115343
break;

0 commit comments

Comments
 (0)