Skip to content

Commit d2f3903

Browse files
authored
Merge pull request #39828 from DougGregor/unsafe-concurrency-in-function-types
Adjust the referenced function type for @_unsafeSendable and @_unsafeMainActor
2 parents 94f2394 + 3945ce0 commit d2f3903

File tree

14 files changed

+321
-195
lines changed

14 files changed

+321
-195
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6265,14 +6265,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
62656265
Optional<unsigned> findPotentialCompletionHandlerParam(
62666266
const AbstractFunctionDecl *asyncAlternative = nullptr) const;
62676267

6268-
/// Determine whether this function is implicitly known to have its
6269-
/// parameters of function type be @_unsafeSendable.
6270-
///
6271-
/// This hard-codes knowledge of a number of functions that will
6272-
/// eventually have @_unsafeSendable and, eventually, @Sendable,
6273-
/// on their parameters of function type.
6274-
bool hasKnownUnsafeSendableFunctionParams() const;
6275-
62766268
using DeclContext::operator new;
62776269
using DeclContext::operator delete;
62786270
using Decl::getASTContext;

include/swift/AST/Expr.h

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3683,12 +3683,6 @@ class ClosureExpr : public AbstractClosureExpr {
36833683
SeparatelyTypeChecked,
36843684
};
36853685

3686-
/// Bits used to indicate contextual information that is concurrency-specific.
3687-
enum UnsafeConcurrencyBits {
3688-
Sendable = 1 << 0,
3689-
MainActor = 1 << 1
3690-
};
3691-
36923686
private:
36933687
/// The attributes attached to the closure.
36943688
DeclAttributes Attributes;
@@ -3703,10 +3697,7 @@ class ClosureExpr : public AbstractClosureExpr {
37033697
/// the CaptureListExpr which would normally maintain this sort of
37043698
/// information about captured variables), we need to have some way to access
37053699
/// this information directly on the ClosureExpr.
3706-
///
3707-
/// The integer indicates how the closure is contextually concurrent.
3708-
llvm::PointerIntPair<VarDecl *, 2, uint8_t>
3709-
CapturedSelfDeclAndUnsafeConcurrent;
3700+
VarDecl *CapturedSelfDecl;
37103701

37113702
/// The location of the "async", if present.
37123703
SourceLoc AsyncLoc;
@@ -3736,7 +3727,7 @@ class ClosureExpr : public AbstractClosureExpr {
37363727
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
37373728
discriminator, parent),
37383729
Attributes(attributes), BracketRange(bracketRange),
3739-
CapturedSelfDeclAndUnsafeConcurrent(capturedSelfDecl, 0),
3730+
CapturedSelfDecl(capturedSelfDecl),
37403731
AsyncLoc(asyncLoc), ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc),
37413732
InLoc(inLoc),
37423733
ExplicitResultTypeAndBodyState(explicitResultType, BodyState::Parsed),
@@ -3864,27 +3855,7 @@ class ClosureExpr : public AbstractClosureExpr {
38643855

38653856
/// VarDecl captured by this closure under the literal name \c self , if any.
38663857
VarDecl *getCapturedSelfDecl() const {
3867-
return CapturedSelfDeclAndUnsafeConcurrent.getPointer();
3868-
}
3869-
3870-
bool isUnsafeSendable() const {
3871-
return CapturedSelfDeclAndUnsafeConcurrent.getInt() &
3872-
UnsafeConcurrencyBits::Sendable;
3873-
}
3874-
3875-
bool isUnsafeMainActor() const {
3876-
return CapturedSelfDeclAndUnsafeConcurrent.getInt() &
3877-
UnsafeConcurrencyBits::MainActor;
3878-
}
3879-
3880-
void setUnsafeConcurrent(bool sendable, bool forMainActor) {
3881-
uint8_t bits = 0;
3882-
if (sendable)
3883-
bits |= UnsafeConcurrencyBits::Sendable;
3884-
if (forMainActor)
3885-
bits |= UnsafeConcurrencyBits::MainActor;
3886-
3887-
CapturedSelfDeclAndUnsafeConcurrent.setInt(bits);
3858+
return CapturedSelfDecl;
38883859
}
38893860

38903861
/// Get the type checking state of this closure's body.

include/swift/AST/Types.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,8 +3395,6 @@ struct ParameterListInfo {
33953395
SmallBitVector defaultArguments;
33963396
SmallBitVector acceptsUnlabeledTrailingClosures;
33973397
SmallBitVector propertyWrappers;
3398-
SmallBitVector unsafeSendable;
3399-
SmallBitVector unsafeMainActor;
34003398
SmallBitVector implicitSelfCapture;
34013399
SmallBitVector inheritActorContext;
34023400

@@ -3417,16 +3415,6 @@ struct ParameterListInfo {
34173415
/// property wrapper.
34183416
bool hasExternalPropertyWrapper(unsigned paramIdx) const;
34193417

3420-
/// Whether the given parameter is unsafe Sendable, meaning that
3421-
/// we will treat it as Sendable in a context that has adopted concurrency
3422-
/// features.
3423-
bool isUnsafeSendable(unsigned paramIdx) const;
3424-
3425-
/// Whether the given parameter is unsafe MainActor, meaning that
3426-
/// we will treat it as being part of the main actor but that it is not
3427-
/// part of the type system.
3428-
bool isUnsafeMainActor(unsigned paramIdx) const;
3429-
34303418
/// Whether the given parameter is a closure that should allow capture of
34313419
/// 'self' to be implicit, without requiring "self.".
34323420
bool isImplicitSelfCapture(unsigned paramIdx) const;

lib/AST/Decl.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7733,27 +7733,6 @@ void AbstractFunctionDecl::addDerivativeFunctionConfiguration(
77337733
DerivativeFunctionConfigs->insert(config);
77347734
}
77357735

7736-
bool AbstractFunctionDecl::hasKnownUnsafeSendableFunctionParams() const {
7737-
auto nominal = getDeclContext()->getSelfNominalTypeDecl();
7738-
if (!nominal)
7739-
return false;
7740-
7741-
// DispatchQueue operations.
7742-
auto nominalName = nominal->getName().str();
7743-
if (nominalName == "DispatchQueue") {
7744-
auto name = getBaseName().userFacingName();
7745-
return llvm::StringSwitch<bool>(name)
7746-
.Case("sync", true)
7747-
.Case("async", true)
7748-
.Case("asyncAndWait", true)
7749-
.Case("asyncAfter", true)
7750-
.Case("concurrentPerform", true)
7751-
.Default(false);
7752-
}
7753-
7754-
return false;
7755-
}
7756-
77577736
void FuncDecl::setResultInterfaceType(Type type) {
77587737
getASTContext().evaluator.cacheOutput(ResultTypeRequest{this},
77597738
std::move(type));

lib/AST/Type.cpp

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -928,36 +928,12 @@ static bool allowsUnlabeledTrailingClosureParameter(const ParamDecl *param) {
928928
return paramType->is<AnyFunctionType>();
929929
}
930930

931-
/// Determine whether the parameter is contextually Sendable.
932-
static bool isParamUnsafeSendable(const ParamDecl *param) {
933-
// Check for @_unsafeSendable.
934-
if (param->getAttrs().hasAttribute<UnsafeSendableAttr>())
935-
return true;
936-
937-
// Check that the parameter is of function type.
938-
Type paramType = param->isVariadic() ? param->getVarargBaseTy()
939-
: param->getInterfaceType();
940-
paramType = paramType->getRValueType()->lookThroughAllOptionalTypes();
941-
if (!paramType->is<FunctionType>())
942-
return false;
943-
944-
// Check whether this function is known to have @_unsafeSendable function
945-
// parameters.
946-
auto func = dyn_cast<AbstractFunctionDecl>(param->getDeclContext());
947-
if (!func)
948-
return false;
949-
950-
return func->hasKnownUnsafeSendableFunctionParams();
951-
}
952-
953931
ParameterListInfo::ParameterListInfo(
954932
ArrayRef<AnyFunctionType::Param> params,
955933
const ValueDecl *paramOwner,
956934
bool skipCurriedSelf) {
957935
defaultArguments.resize(params.size());
958936
propertyWrappers.resize(params.size());
959-
unsafeSendable.resize(params.size());
960-
unsafeMainActor.resize(params.size());
961937
implicitSelfCapture.resize(params.size());
962938
inheritActorContext.resize(params.size());
963939

@@ -1012,14 +988,6 @@ ParameterListInfo::ParameterListInfo(
1012988
propertyWrappers.set(i);
1013989
}
1014990

1015-
if (isParamUnsafeSendable(param)) {
1016-
unsafeSendable.set(i);
1017-
}
1018-
1019-
if (param->getAttrs().hasAttribute<UnsafeMainActorAttr>()) {
1020-
unsafeMainActor.set(i);
1021-
}
1022-
1023991
if (param->getAttrs().hasAttribute<ImplicitSelfCaptureAttr>()) {
1024992
implicitSelfCapture.set(i);
1025993
}
@@ -1045,18 +1013,6 @@ bool ParameterListInfo::hasExternalPropertyWrapper(unsigned paramIdx) const {
10451013
return paramIdx < propertyWrappers.size() ? propertyWrappers[paramIdx] : false;
10461014
}
10471015

1048-
bool ParameterListInfo::isUnsafeSendable(unsigned paramIdx) const {
1049-
return paramIdx < unsafeSendable.size()
1050-
? unsafeSendable[paramIdx]
1051-
: false;
1052-
}
1053-
1054-
bool ParameterListInfo::isUnsafeMainActor(unsigned paramIdx) const {
1055-
return paramIdx < unsafeMainActor.size()
1056-
? unsafeMainActor[paramIdx]
1057-
: false;
1058-
}
1059-
10601016
bool ParameterListInfo::isImplicitSelfCapture(unsigned paramIdx) const {
10611017
return paramIdx < implicitSelfCapture.size()
10621018
? implicitSelfCapture[paramIdx]
@@ -1070,8 +1026,7 @@ bool ParameterListInfo::inheritsActorContext(unsigned paramIdx) const {
10701026
}
10711027

10721028
bool ParameterListInfo::anyContextualInfo() const {
1073-
return unsafeSendable.any() || unsafeMainActor.any() ||
1074-
implicitSelfCapture.any() || inheritActorContext.any();
1029+
return implicitSelfCapture.any() || inheritActorContext.any();
10751030
}
10761031

10771032
/// Turn a param list into a symbolic and printable representation that does not

lib/SILGen/SILGenProlog.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
583583
break;
584584
}
585585
} else if (auto *closureExpr = dyn_cast<AbstractClosureExpr>(FunctionDC)) {
586-
bool wantExecutor = F.isAsync() ||
587-
(wantDataRaceChecks &&
588-
!(isa<ClosureExpr>(closureExpr) &&
589-
cast<ClosureExpr>(closureExpr)->isUnsafeMainActor()));
586+
bool wantExecutor = F.isAsync() || wantDataRaceChecks;
590587
auto actorIsolation = closureExpr->getActorIsolation();
591588
switch (actorIsolation.getKind()) {
592589
case ClosureActorIsolation::Independent:

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5631,59 +5631,25 @@ static bool hasCurriedSelf(ConstraintSystem &cs, ConcreteDeclRef callee,
56315631

56325632
/// Apply the contextually Sendable flag to the given expression,
56335633
static void applyContextualClosureFlags(
5634-
Expr *expr, bool sendable, bool forMainActor, bool implicitSelfCapture,
5635-
bool inheritActorContext) {
5634+
Expr *expr, bool implicitSelfCapture, bool inheritActorContext) {
56365635
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
5637-
closure->setUnsafeConcurrent(sendable, forMainActor);
56385636
closure->setAllowsImplicitSelfCapture(implicitSelfCapture);
56395637
closure->setInheritsActorContext(inheritActorContext);
56405638
return;
56415639
}
56425640

56435641
if (auto captureList = dyn_cast<CaptureListExpr>(expr)) {
56445642
applyContextualClosureFlags(
5645-
captureList->getClosureBody(), sendable, forMainActor,
5646-
implicitSelfCapture, inheritActorContext);
5643+
captureList->getClosureBody(), implicitSelfCapture,
5644+
inheritActorContext);
56475645
}
56485646

56495647
if (auto identity = dyn_cast<IdentityExpr>(expr)) {
56505648
applyContextualClosureFlags(
5651-
identity->getSubExpr(), sendable, forMainActor,
5652-
implicitSelfCapture, inheritActorContext);
5649+
identity->getSubExpr(), implicitSelfCapture, inheritActorContext);
56535650
}
56545651
}
56555652

5656-
/// Whether this is a reference to a method on the main dispatch queue.
5657-
static bool isMainDispatchQueue(Expr *arg) {
5658-
auto call = dyn_cast<DotSyntaxCallExpr>(arg);
5659-
if (!call)
5660-
return false;
5661-
5662-
auto memberRef = dyn_cast<MemberRefExpr>(
5663-
call->getBase()->getValueProvidingExpr());
5664-
if (!memberRef)
5665-
return false;
5666-
5667-
auto member = memberRef->getMember();
5668-
if (member.getDecl()->getName().getBaseName().userFacingName() != "main")
5669-
return false;
5670-
5671-
auto typeExpr = dyn_cast<TypeExpr>(
5672-
memberRef->getBase()->getValueProvidingExpr());
5673-
if (!typeExpr)
5674-
return false;
5675-
5676-
Type baseType = typeExpr->getInstanceType();
5677-
if (!baseType)
5678-
return false;
5679-
5680-
auto baseNominal = baseType->getAnyNominal();
5681-
if (!baseNominal)
5682-
return false;
5683-
5684-
return baseNominal->getName().str() == "DispatchQueue";
5685-
}
5686-
56875653
ArgumentList *ExprRewriter::coerceCallArguments(
56885654
ArgumentList *args, AnyFunctionType *funcType, ConcreteDeclRef callee,
56895655
ApplyExpr *apply, ConstraintLocatorBuilder locator,
@@ -5825,16 +5791,12 @@ ArgumentList *ExprRewriter::coerceCallArguments(
58255791
// for things like trailing closures and args to property wrapper params.
58265792
arg.setLabel(param.getLabel());
58275793

5828-
// Determine whether the parameter is unsafe Sendable or MainActor, and
5829-
// record it as such.
5830-
bool isUnsafeSendable = paramInfo.isUnsafeSendable(paramIdx);
5831-
bool isMainActor = paramInfo.isUnsafeMainActor(paramIdx) ||
5832-
(isUnsafeSendable && apply && isMainDispatchQueue(apply->getFn()));
5794+
// Determine whether the closure argument should be treated as having
5795+
// implicit self capture or inheriting actor context.
58335796
bool isImplicitSelfCapture = paramInfo.isImplicitSelfCapture(paramIdx);
58345797
bool inheritsActorContext = paramInfo.inheritsActorContext(paramIdx);
58355798
applyContextualClosureFlags(
5836-
argExpr, isUnsafeSendable && contextUsesConcurrencyFeatures(dc),
5837-
isMainActor, isImplicitSelfCapture, inheritsActorContext);
5799+
argExpr, isImplicitSelfCapture, inheritsActorContext);
58385800

58395801
// If the types exactly match, this is easy.
58405802
auto paramType = param.getOldType();

0 commit comments

Comments
 (0)