Skip to content

Commit a6de931

Browse files
committed
Support @dynamicCallable archetypes.
Support @dynamicCallable method lookup for archetypes. Generalize code for protocol composition types.
1 parent 6075027 commit a6de931

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4302,33 +4302,51 @@ getDynamicCallableMethods(Type type, ConstraintSystem &CS,
43024302
auto it = CS.DynamicCallableCache.find(canType);
43034303
if (it != CS.DynamicCallableCache.end()) return it->second;
43044304

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;
43204318
}
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;
43284326
}
4327+
methods.keywordArgumentsMethod = tmp.keywordArgumentsMethod;
43294328
}
4330-
return methods;
43314329
}
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());
43324350

43334351
// Otherwise, this must be a nominal type.
43344352
// Dynamic calling doesn't work for tuples, etc.

0 commit comments

Comments
 (0)