@@ -4032,33 +4032,32 @@ static Type applyUnsafeConcurrencyToParameterType(
4032
4032
.withGlobalActor (globalActor));
4033
4033
}
4034
4034
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) {
4038
4037
// Look through optionals.
4039
- if (Type optionalObject = paramType ->getOptionalObjectType ()) {
4038
+ if (Type optionalObject = type ->getOptionalObjectType ()) {
4040
4039
Type newOptionalObject =
4041
- stripConcurrencyFromParameterType (optionalObject, dropGlobalActor);
4040
+ stripConcurrencyFromType (optionalObject, dropGlobalActor);
4042
4041
if (optionalObject->isEqual (newOptionalObject))
4043
- return paramType ;
4042
+ return type ;
4044
4043
4045
4044
return OptionalType::get (newOptionalObject);
4046
4045
}
4047
4046
4048
4047
// 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>()) {
4050
4049
auto extInfo = fnType->getExtInfo ().withConcurrent (false );
4051
4050
if (dropGlobalActor)
4052
4051
extInfo = extInfo.withGlobalActor (Type ());
4053
4052
auto newFnType = FunctionType::get (
4054
4053
fnType->getParams (), fnType->getResult (), extInfo);
4055
- if (newFnType->isEqual (paramType ))
4056
- return paramType ;
4054
+ if (newFnType->isEqual (type ))
4055
+ return type ;
4057
4056
4058
4057
return newFnType;
4059
4058
}
4060
4059
4061
- return paramType ;
4060
+ return type ;
4062
4061
}
4063
4062
4064
4063
// / Determine whether the given name is that of a DispatchQueue operation that
@@ -4094,18 +4093,42 @@ static bool hasKnownUnsafeSendableFunctionParams(AbstractFunctionDecl *func) {
4094
4093
return false ;
4095
4094
}
4096
4095
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
+
4097
4118
// / Adjust a function type for @_unsafeSendable, @_unsafeMainActor, and
4098
4119
// / @_predatesConcurrency.
4099
4120
static AnyFunctionType *applyUnsafeConcurrencyToFunctionType (
4100
- AnyFunctionType *fnType, ValueDecl *funcOrEnum ,
4121
+ AnyFunctionType *fnType, ValueDecl *decl ,
4101
4122
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)
4105
4128
return fnType;
4106
4129
4107
4130
AnyFunctionType *outerFnType = nullptr ;
4108
- if (func->hasImplicitSelfDecl ()) {
4131
+ if (func && func ->hasImplicitSelfDecl ()) {
4109
4132
outerFnType = fnType;
4110
4133
fnType = outerFnType->getResult ()->castTo <AnyFunctionType>();
4111
4134
@@ -4115,15 +4138,13 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
4115
4138
4116
4139
SmallVector<AnyFunctionType::Param, 4 > newTypeParams;
4117
4140
auto typeParams = fnType->getParams ();
4118
- auto paramDecls = func->getParameters ();
4141
+ auto paramDecls = func ? func ->getParameters () : subscript-> getIndices ();
4119
4142
assert (typeParams.size () == paramDecls->size ());
4120
- bool knownUnsafeParams = hasKnownUnsafeSendableFunctionParams (func);
4143
+ bool knownUnsafeParams = func && hasKnownUnsafeSendableFunctionParams (func);
4121
4144
bool stripConcurrency =
4122
- funcOrEnum->predatesConcurrency () &&
4123
- !inConcurrencyContext;
4145
+ decl->predatesConcurrency () && !inConcurrencyContext;
4124
4146
for (unsigned index : indices (typeParams)) {
4125
4147
auto param = typeParams[index];
4126
- auto paramDecl = (*paramDecls)[index];
4127
4148
4128
4149
// Determine whether the resulting parameter should be @Sendable or
4129
4150
// @MainActor. @Sendable occurs only in concurrency contents, while
@@ -4138,7 +4159,7 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
4138
4159
newParamType = applyUnsafeConcurrencyToParameterType (
4139
4160
param.getPlainType (), addSendable, addMainActor);
4140
4161
} else if (stripConcurrency) {
4141
- newParamType = stripConcurrencyFromParameterType (
4162
+ newParamType = stripConcurrencyFromType (
4142
4163
param.getPlainType (), numApplies == 0 );
4143
4164
}
4144
4165
@@ -4160,14 +4181,25 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
4160
4181
newTypeParams.push_back (param.withType (newParamType));
4161
4182
}
4162
4183
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
+
4163
4195
// If we didn't change any parameters, we're done.
4164
- if (newTypeParams.empty ()) {
4196
+ if (newTypeParams.empty () && newResultType-> isEqual (fnType-> getResult ()) ) {
4165
4197
return outerFnType ? outerFnType : fnType;
4166
4198
}
4167
4199
4168
4200
// Rebuild the (inner) function type.
4169
4201
fnType = FunctionType::get (
4170
- newTypeParams, fnType-> getResult () , fnType->getExtInfo ());
4202
+ newTypeParams, newResultType , fnType->getExtInfo ());
4171
4203
4172
4204
if (!outerFnType)
4173
4205
return fnType;
@@ -4184,39 +4216,41 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
4184
4216
}
4185
4217
4186
4218
AnyFunctionType *swift::adjustFunctionTypeForConcurrency (
4187
- AnyFunctionType *fnType, ValueDecl *funcOrEnum , DeclContext *dc,
4219
+ AnyFunctionType *fnType, ValueDecl *decl , DeclContext *dc,
4188
4220
unsigned numApplies, bool isMainDispatchQueue) {
4189
4221
// Apply unsafe concurrency features to the given function type.
4190
4222
fnType = applyUnsafeConcurrencyToFunctionType (
4191
- fnType, funcOrEnum , contextUsesConcurrencyFeatures (dc), numApplies,
4223
+ fnType, decl , contextUsesConcurrencyFeatures (dc), numApplies,
4192
4224
isMainDispatchQueue);
4193
4225
4194
4226
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:
4206
4233
return fnType;
4207
4234
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;
4209
4240
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
+ }
4213
4247
}
4214
4248
4215
4249
// If there's no implicit "self" declaration, apply the global actor to
4216
4250
// 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 () ));
4220
4254
if (!hasImplicitSelfDecl) {
4221
4255
return fnType->withExtInfo (
4222
4256
fnType->getExtInfo ().withGlobalActor (globalActorType));
0 commit comments