@@ -4032,33 +4032,32 @@ static Type applyUnsafeConcurrencyToParameterType(
40324032 .withGlobalActor (globalActor));
40334033}
40344034
4035- // / Strip concurrency from the type of the given parameter.
4036- static Type stripConcurrencyFromParameterType (
4037- Type paramType, bool dropGlobalActor) {
4035+ // / Strip concurrency from the given type.
4036+ static Type stripConcurrencyFromType (Type type, bool dropGlobalActor) {
40384037 // Look through optionals.
4039- if (Type optionalObject = paramType ->getOptionalObjectType ()) {
4038+ if (Type optionalObject = type ->getOptionalObjectType ()) {
40404039 Type newOptionalObject =
4041- stripConcurrencyFromParameterType (optionalObject, dropGlobalActor);
4040+ stripConcurrencyFromType (optionalObject, dropGlobalActor);
40424041 if (optionalObject->isEqual (newOptionalObject))
4043- return paramType ;
4042+ return type ;
40444043
40454044 return OptionalType::get (newOptionalObject);
40464045 }
40474046
40484047 // For function types, strip off Sendable and possibly the global actor.
4049- if (auto fnType = paramType ->getAs <FunctionType>()) {
4048+ if (auto fnType = type ->getAs <FunctionType>()) {
40504049 auto extInfo = fnType->getExtInfo ().withConcurrent (false );
40514050 if (dropGlobalActor)
40524051 extInfo = extInfo.withGlobalActor (Type ());
40534052 auto newFnType = FunctionType::get (
40544053 fnType->getParams (), fnType->getResult (), extInfo);
4055- if (newFnType->isEqual (paramType ))
4056- return paramType ;
4054+ if (newFnType->isEqual (type ))
4055+ return type ;
40574056
40584057 return newFnType;
40594058 }
40604059
4061- return paramType ;
4060+ return type ;
40624061}
40634062
40644063// / Determine whether the given name is that of a DispatchQueue operation that
@@ -4094,18 +4093,42 @@ static bool hasKnownUnsafeSendableFunctionParams(AbstractFunctionDecl *func) {
40944093 return false ;
40954094}
40964095
4096+ Type swift::adjustVarTypeForConcurrency (
4097+ Type type, VarDecl *var, DeclContext *dc) {
4098+ if (!var->predatesConcurrency ())
4099+ return type;
4100+
4101+ if (contextUsesConcurrencyFeatures (dc))
4102+ return type;
4103+
4104+ bool isLValue = false ;
4105+ if (auto *lvalueType = type->getAs <LValueType>()) {
4106+ type = lvalueType->getObjectType ();
4107+ isLValue = true ;
4108+ }
4109+
4110+ type = stripConcurrencyFromType (type, /* dropGlobalActor=*/ true );
4111+
4112+ if (isLValue)
4113+ type = LValueType::get (type);
4114+
4115+ return type;
4116+ }
4117+
40974118// / Adjust a function type for @_unsafeSendable, @_unsafeMainActor, and
40984119// / @_predatesConcurrency.
40994120static AnyFunctionType *applyUnsafeConcurrencyToFunctionType (
4100- AnyFunctionType *fnType, ValueDecl *funcOrEnum ,
4121+ AnyFunctionType *fnType, ValueDecl *decl ,
41014122 bool inConcurrencyContext, unsigned numApplies, bool isMainDispatchQueue) {
4102- // Only functions can have @_unsafeSendable/@_unsafeMainActor parameters.
4103- auto func = dyn_cast<AbstractFunctionDecl>(funcOrEnum);
4104- if (!func)
4123+ // Functions/subscripts/enum elements have function types to adjust.
4124+ auto func = dyn_cast_or_null<AbstractFunctionDecl>(decl);
4125+ auto subscript = dyn_cast_or_null<SubscriptDecl>(decl);
4126+
4127+ if (!func && !subscript)
41054128 return fnType;
41064129
41074130 AnyFunctionType *outerFnType = nullptr ;
4108- if (func->hasImplicitSelfDecl ()) {
4131+ if (func && func ->hasImplicitSelfDecl ()) {
41094132 outerFnType = fnType;
41104133 fnType = outerFnType->getResult ()->castTo <AnyFunctionType>();
41114134
@@ -4115,15 +4138,13 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41154138
41164139 SmallVector<AnyFunctionType::Param, 4 > newTypeParams;
41174140 auto typeParams = fnType->getParams ();
4118- auto paramDecls = func->getParameters ();
4141+ auto paramDecls = func ? func ->getParameters () : subscript-> getIndices ();
41194142 assert (typeParams.size () == paramDecls->size ());
4120- bool knownUnsafeParams = hasKnownUnsafeSendableFunctionParams (func);
4143+ bool knownUnsafeParams = func && hasKnownUnsafeSendableFunctionParams (func);
41214144 bool stripConcurrency =
4122- funcOrEnum->predatesConcurrency () &&
4123- !inConcurrencyContext;
4145+ decl->predatesConcurrency () && !inConcurrencyContext;
41244146 for (unsigned index : indices (typeParams)) {
41254147 auto param = typeParams[index];
4126- auto paramDecl = (*paramDecls)[index];
41274148
41284149 // Determine whether the resulting parameter should be @Sendable or
41294150 // @MainActor. @Sendable occurs only in concurrency contents, while
@@ -4138,7 +4159,7 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41384159 newParamType = applyUnsafeConcurrencyToParameterType (
41394160 param.getPlainType (), addSendable, addMainActor);
41404161 } else if (stripConcurrency) {
4141- newParamType = stripConcurrencyFromParameterType (
4162+ newParamType = stripConcurrencyFromType (
41424163 param.getPlainType (), numApplies == 0 );
41434164 }
41444165
@@ -4160,14 +4181,25 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41604181 newTypeParams.push_back (param.withType (newParamType));
41614182 }
41624183
4184+ // Compute the new result type.
4185+ Type newResultType = fnType->getResult ();
4186+ if (stripConcurrency) {
4187+ newResultType = stripConcurrencyFromType (
4188+ newResultType, /* dropGlobalActor=*/ true );
4189+
4190+ if (!newResultType->isEqual (fnType->getResult ()) && newTypeParams.empty ()) {
4191+ newTypeParams.append (typeParams.begin (), typeParams.end ());
4192+ }
4193+ }
4194+
41634195 // If we didn't change any parameters, we're done.
4164- if (newTypeParams.empty ()) {
4196+ if (newTypeParams.empty () && newResultType-> isEqual (fnType-> getResult ()) ) {
41654197 return outerFnType ? outerFnType : fnType;
41664198 }
41674199
41684200 // Rebuild the (inner) function type.
41694201 fnType = FunctionType::get (
4170- newTypeParams, fnType-> getResult () , fnType->getExtInfo ());
4202+ newTypeParams, newResultType , fnType->getExtInfo ());
41714203
41724204 if (!outerFnType)
41734205 return fnType;
@@ -4184,39 +4216,41 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41844216}
41854217
41864218AnyFunctionType *swift::adjustFunctionTypeForConcurrency (
4187- AnyFunctionType *fnType, ValueDecl *funcOrEnum , DeclContext *dc,
4219+ AnyFunctionType *fnType, ValueDecl *decl , DeclContext *dc,
41884220 unsigned numApplies, bool isMainDispatchQueue) {
41894221 // Apply unsafe concurrency features to the given function type.
41904222 fnType = applyUnsafeConcurrencyToFunctionType (
4191- fnType, funcOrEnum , contextUsesConcurrencyFeatures (dc), numApplies,
4223+ fnType, decl , contextUsesConcurrencyFeatures (dc), numApplies,
41924224 isMainDispatchQueue);
41934225
41944226 Type globalActorType;
4195- switch (auto isolation = getActorIsolation (funcOrEnum)) {
4196- case ActorIsolation::ActorInstance:
4197- case ActorIsolation::DistributedActorInstance:
4198- case ActorIsolation::Independent:
4199- case ActorIsolation::Unspecified:
4200- return fnType;
4201-
4202- case ActorIsolation::GlobalActorUnsafe:
4203- // Only treat as global-actor-qualified within code that has adopted
4204- // Swift Concurrency features.
4205- if (!contextUsesConcurrencyFeatures (dc))
4227+ if (decl) {
4228+ switch (auto isolation = getActorIsolation (decl)) {
4229+ case ActorIsolation::ActorInstance:
4230+ case ActorIsolation::DistributedActorInstance:
4231+ case ActorIsolation::Independent:
4232+ case ActorIsolation::Unspecified:
42064233 return fnType;
42074234
4208- LLVM_FALLTHROUGH;
4235+ case ActorIsolation::GlobalActorUnsafe:
4236+ // Only treat as global-actor-qualified within code that has adopted
4237+ // Swift Concurrency features.
4238+ if (!contextUsesConcurrencyFeatures (dc))
4239+ return fnType;
42094240
4210- case ActorIsolation::GlobalActor:
4211- globalActorType = isolation.getGlobalActor ();
4212- break ;
4241+ LLVM_FALLTHROUGH;
4242+
4243+ case ActorIsolation::GlobalActor:
4244+ globalActorType = isolation.getGlobalActor ();
4245+ break ;
4246+ }
42134247 }
42144248
42154249 // If there's no implicit "self" declaration, apply the global actor to
42164250 // the outermost function type.
4217- bool hasImplicitSelfDecl = isa<EnumElementDecl>(funcOrEnum ) ||
4218- (isa<AbstractFunctionDecl>(funcOrEnum ) &&
4219- cast<AbstractFunctionDecl>(funcOrEnum )->hasImplicitSelfDecl ());
4251+ bool hasImplicitSelfDecl = decl && ( isa<EnumElementDecl>(decl ) ||
4252+ (isa<AbstractFunctionDecl>(decl ) &&
4253+ cast<AbstractFunctionDecl>(decl )->hasImplicitSelfDecl () ));
42204254 if (!hasImplicitSelfDecl) {
42214255 return fnType->withExtInfo (
42224256 fnType->getExtInfo ().withGlobalActor (globalActorType));
0 commit comments