@@ -3083,26 +3083,45 @@ getArgumentLabels(ConstraintSystem &cs, ConstraintLocatorBuilder locator) {
3083
3083
// / particularly fast in the face of deep class hierarchies or lots of protocol
3084
3084
// / conformances, but this is fine because it doesn't get invoked in the normal
3085
3085
// / name lookup path (only when lookup is about to fail).
3086
- static bool hasDynamicMemberLookupAttribute (CanType ty ,
3086
+ static bool hasDynamicMemberLookupAttribute (Type type ,
3087
3087
llvm::DenseMap<CanType, bool > &DynamicMemberLookupCache) {
3088
- auto it = DynamicMemberLookupCache.find (ty);
3088
+ auto canType = type->getCanonicalType ();
3089
+ auto it = DynamicMemberLookupCache.find (canType);
3089
3090
if (it != DynamicMemberLookupCache.end ()) return it->second ;
3090
-
3091
- auto calculate = [&]()-> bool {
3092
- // If this is a protocol composition, check to see if any of the protocols
3093
- // have the attribute on them.
3094
- if (auto protocolComp = ty->getAs <ProtocolCompositionType>()) {
3095
- for (auto p : protocolComp->getMembers ())
3096
- if (hasDynamicMemberLookupAttribute (p->getCanonicalType (),
3097
- DynamicMemberLookupCache))
3098
- return true ;
3099
- return false ;
3091
+
3092
+ // Calculate @dynamicMemberLookup attribute for composite types with multiple
3093
+ // components (protocol composition types and archetypes).
3094
+ auto calculateForComponentTypes =
3095
+ [&](ArrayRef<Type> componentTypes) -> bool {
3096
+ for (auto componentType : componentTypes)
3097
+ if (hasDynamicMemberLookupAttribute (componentType,
3098
+ DynamicMemberLookupCache))
3099
+ return true ;
3100
+ return false ;
3101
+ };
3102
+
3103
+ auto calculate = [&]() -> bool {
3104
+ // If this is an archetype type, check if any types it conforms to
3105
+ // (superclass or protocols) have the attribute.
3106
+ if (auto archetype = dyn_cast<ArchetypeType>(canType)) {
3107
+ SmallVector<Type, 2 > componentTypes;
3108
+ for (auto protocolDecl : archetype->getConformsTo ())
3109
+ componentTypes.push_back (protocolDecl->getDeclaredType ());
3110
+ if (auto superclass = archetype->getSuperclass ())
3111
+ componentTypes.push_back (superclass);
3112
+ return calculateForComponentTypes (componentTypes);
3100
3113
}
3101
-
3102
- // Otherwise this has to be a nominal type.
3103
- auto nominal = ty->getAnyNominal ();
3104
- if (!nominal) return false ; // Dynamic lookups don't exist on tuples, etc.
3105
-
3114
+
3115
+ // If this is a protocol composition, check if any of its members have the
3116
+ // attribute.
3117
+ if (auto protocolComp = dyn_cast<ProtocolCompositionType>(canType))
3118
+ return calculateForComponentTypes (protocolComp->getMembers ());
3119
+
3120
+ // Otherwise, this must be a nominal type.
3121
+ // Dynamic member lookup doesn't work for tuples, etc.
3122
+ auto nominal = canType->getAnyNominal ();
3123
+ if (!nominal) return false ;
3124
+
3106
3125
// If this type conforms to a protocol with the attribute, then return true.
3107
3126
for (auto p : nominal->getAllProtocols ())
3108
3127
if (p->getAttrs ().hasAttribute <DynamicMemberLookupAttr>())
@@ -3132,11 +3151,9 @@ static bool hasDynamicMemberLookupAttribute(CanType ty,
3132
3151
};
3133
3152
3134
3153
auto result = calculate ();
3135
-
3136
- // Cache this if we can.
3137
- if (!ty->hasTypeVariable ())
3138
- DynamicMemberLookupCache[ty] = result;
3139
-
3154
+ // Cache the result if the type does not contain type variables.
3155
+ if (!type->hasTypeVariable ())
3156
+ DynamicMemberLookupCache[canType] = result;
3140
3157
return result;
3141
3158
}
3142
3159
@@ -3552,8 +3569,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3552
3569
constraintKind == ConstraintKind::ValueMember &&
3553
3570
memberName.isSimpleName () && !memberName.isSpecial ()) {
3554
3571
auto name = memberName.getBaseIdentifier ();
3555
- if ( hasDynamicMemberLookupAttribute (instanceTy-> getCanonicalType (),
3556
- DynamicMemberLookupCache)) {
3572
+ // TC.extract
3573
+ if ( hasDynamicMemberLookupAttribute (instanceTy, DynamicMemberLookupCache)) {
3557
3574
auto &ctx = getASTContext ();
3558
3575
3559
3576
// Recursively look up `subscript(dynamicMember:)` methods in this type.
@@ -4680,7 +4697,11 @@ getDynamicCallableMethods(Type type, ConstraintSystem &CS,
4680
4697
}
4681
4698
};
4682
4699
4683
- return CS.DynamicCallableCache [canType] = calculate ();
4700
+ auto result = calculate ();
4701
+ // Cache the result if the type does not contain type variables.
4702
+ if (!type->hasTypeVariable ())
4703
+ CS.DynamicCallableCache [canType] = result;
4704
+ return result;
4684
4705
}
4685
4706
4686
4707
ConstraintSystem::SolutionKind
0 commit comments