@@ -4302,33 +4302,51 @@ getDynamicCallableMethods(Type type, ConstraintSystem &CS,
4302
4302
auto it = CS.DynamicCallableCache .find (canType);
4303
4303
if (it != CS.DynamicCallableCache .end ()) return it->second ;
4304
4304
4305
- auto calculate = [&]() -> DynamicCallableMethods {
4306
- // If this is a protocol composition, check if any of the protocols have the
4307
- // attribute.
4308
- if (auto protocolComp = dyn_cast<ProtocolCompositionType>(canType)) {
4309
- DynamicCallableMethods methods;
4310
- for (auto protocolType : protocolComp->getMembers ()) {
4311
- auto tmp = getDynamicCallableMethods (protocolType, CS, locator, error);
4312
- if (error) return methods;
4313
- if (tmp.argumentsMethod ) {
4314
- if (methods.argumentsMethod &&
4315
- methods.argumentsMethod != tmp.argumentsMethod ) {
4316
- error = true ;
4317
- return methods;
4318
- }
4319
- methods.argumentsMethod = tmp.argumentsMethod ;
4305
+ // Calculate @dynamicCallable methods for composite types with multiple
4306
+ // components (protocol composition types and archetypes).
4307
+ auto calculateForComponentTypes =
4308
+ [&](ArrayRef<Type> componentTypes) -> DynamicCallableMethods {
4309
+ DynamicCallableMethods methods;
4310
+ for (auto componentType : componentTypes) {
4311
+ auto tmp = getDynamicCallableMethods (componentType, CS, locator, error);
4312
+ if (error) return methods;
4313
+ if (tmp.argumentsMethod ) {
4314
+ if (methods.argumentsMethod &&
4315
+ methods.argumentsMethod != tmp.argumentsMethod ) {
4316
+ error = true ;
4317
+ return methods;
4320
4318
}
4321
- if ( tmp.keywordArgumentsMethod ) {
4322
- if (methods. keywordArgumentsMethod &&
4323
- methods. keywordArgumentsMethod != tmp.keywordArgumentsMethod ) {
4324
- error = true ;
4325
- return methods;
4326
- }
4327
- methods. keywordArgumentsMethod = tmp. keywordArgumentsMethod ;
4319
+ methods. argumentsMethod = tmp.argumentsMethod ;
4320
+ }
4321
+ if ( tmp.keywordArgumentsMethod ) {
4322
+ if (methods. keywordArgumentsMethod &&
4323
+ methods. keywordArgumentsMethod != tmp. keywordArgumentsMethod ) {
4324
+ error = true ;
4325
+ return methods ;
4328
4326
}
4327
+ methods.keywordArgumentsMethod = tmp.keywordArgumentsMethod ;
4329
4328
}
4330
- return methods;
4331
4329
}
4330
+ return methods;
4331
+ };
4332
+
4333
+ // Calculate @dynamicCallable methods.
4334
+ auto calculate = [&]() -> DynamicCallableMethods {
4335
+ // If this is an archetype type, check if any types it conforms to
4336
+ // (superclass or protocols) have the attribute.
4337
+ if (auto archetype = dyn_cast<ArchetypeType>(canType)) {
4338
+ SmallVector<Type, 2 > componentTypes;
4339
+ for (auto protocolDecl : archetype->getConformsTo ())
4340
+ componentTypes.push_back (protocolDecl->getDeclaredType ());
4341
+ if (auto superclass = archetype->getSuperclass ())
4342
+ componentTypes.push_back (superclass);
4343
+ return calculateForComponentTypes (componentTypes);
4344
+ }
4345
+
4346
+ // If this is a protocol composition, check if any of its members have the
4347
+ // attribute.
4348
+ if (auto protocolComp = dyn_cast<ProtocolCompositionType>(canType))
4349
+ return calculateForComponentTypes (protocolComp->getMembers ());
4332
4350
4333
4351
// Otherwise, this must be a nominal type.
4334
4352
// Dynamic calling doesn't work for tuples, etc.
0 commit comments