Skip to content

Commit 905c0a1

Browse files
committed
---
yaml --- r: 317439 b: refs/heads/master-rebranch c: 63f23c3 h: refs/heads/master i: 317437: 4a985cf 317435: 7c2156a 317431: f8cb3cc 317423: cfbe951 317407: 026acef 317375: 11cbbc1 317311: 5e6b5b9 317183: 49eb58c 316927: b8f4d48 316415: 262328f 315391: 9d2bbec
1 parent ca55235 commit 905c0a1

File tree

5 files changed

+159
-138
lines changed

5 files changed

+159
-138
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,4 +1457,4 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14571457
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14581458
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14591459
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1460-
refs/heads/master-rebranch: 3320ada5e8a6c2e01a4a96f4febf620e63775638
1460+
refs/heads/master-rebranch: 63f23c32da11bb6f7a07874202d37a8bcd3aaff1

branches/master-rebranch/lib/Sema/CSSimplify.cpp

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3083,26 +3083,45 @@ getArgumentLabels(ConstraintSystem &cs, ConstraintLocatorBuilder locator) {
30833083
/// particularly fast in the face of deep class hierarchies or lots of protocol
30843084
/// conformances, but this is fine because it doesn't get invoked in the normal
30853085
/// name lookup path (only when lookup is about to fail).
3086-
static bool hasDynamicMemberLookupAttribute(CanType ty,
3086+
static bool hasDynamicMemberLookupAttribute(Type type,
30873087
llvm::DenseMap<CanType, bool> &DynamicMemberLookupCache) {
3088-
auto it = DynamicMemberLookupCache.find(ty);
3088+
auto canType = type->getCanonicalType();
3089+
auto it = DynamicMemberLookupCache.find(canType);
30893090
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);
31003113
}
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+
31063125
// If this type conforms to a protocol with the attribute, then return true.
31073126
for (auto p : nominal->getAllProtocols())
31083127
if (p->getAttrs().hasAttribute<DynamicMemberLookupAttr>())
@@ -3132,11 +3151,9 @@ static bool hasDynamicMemberLookupAttribute(CanType ty,
31323151
};
31333152

31343153
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;
31403157
return result;
31413158
}
31423159

@@ -3552,8 +3569,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
35523569
constraintKind == ConstraintKind::ValueMember &&
35533570
memberName.isSimpleName() && !memberName.isSpecial()) {
35543571
auto name = memberName.getBaseIdentifier();
3555-
if (hasDynamicMemberLookupAttribute(instanceTy->getCanonicalType(),
3556-
DynamicMemberLookupCache)) {
3572+
// TC.extract
3573+
if (hasDynamicMemberLookupAttribute(instanceTy, DynamicMemberLookupCache)) {
35573574
auto &ctx = getASTContext();
35583575

35593576
// Recursively look up `subscript(dynamicMember:)` methods in this type.
@@ -4680,7 +4697,11 @@ getDynamicCallableMethods(Type type, ConstraintSystem &CS,
46804697
}
46814698
};
46824699

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;
46844705
}
46854706

46864707
ConstraintSystem::SolutionKind

branches/master-rebranch/lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,26 +1074,20 @@ visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr) {
10741074
auto decl = cast<NominalTypeDecl>(D);
10751075
auto type = decl->getDeclaredType();
10761076

1077-
// Lookup our subscript.
1078-
auto subscriptName =
1079-
DeclName(TC.Context, DeclBaseName::createSubscript(),
1080-
TC.Context.Id_dynamicMember);
1077+
// Look up `subscript(dynamicMember:)` candidates.
1078+
auto subscriptName = DeclName(TC.Context, DeclBaseName::createSubscript(),
1079+
TC.Context.Id_dynamicMember);
1080+
auto candidates = TC.lookupMember(decl, type, subscriptName);
10811081

1082-
auto lookupOptions = defaultMemberTypeLookupOptions;
1083-
lookupOptions -= NameLookupFlags::PerformConformanceCheck;
1084-
1085-
// Lookup the implementations of our subscript.
1086-
auto candidates = TC.lookupMember(decl, type, subscriptName, lookupOptions);
1087-
1088-
// If we have none, then the attribute is invalid.
1082+
// If there are no candidates, then the attribute is invalid.
10891083
if (candidates.empty()) {
10901084
TC.diagnose(attr->getLocation(), diag::invalid_dynamic_member_lookup_type,
10911085
type);
10921086
attr->setInvalid();
10931087
return;
10941088
}
10951089

1096-
// If none of the ones we find are acceptable, then reject one.
1090+
// If no candidates are valid, then reject one.
10971091
auto oneCandidate = candidates.front();
10981092
candidates.filter([&](LookupResultEntry entry, bool isOuter) -> bool {
10991093
auto cand = cast<SubscriptDecl>(entry.getValueDecl());

branches/master-rebranch/test/attr/attr_dynamic_callable.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -typecheck -verify %s
1+
// RUN: %target-typecheck-verify-swift
22

33
@dynamicCallable
44
struct Callable {
@@ -64,8 +64,8 @@ func testIUO(
6464

6565
@dynamicCallable
6666
struct CallableReturningFunction {
67-
func dynamicallyCall(withArguments arguments: [Int]) -> (_ a: Int) -> Void {
68-
return { a in () }
67+
func dynamicallyCall(withArguments arguments: [Int]) -> (Int) -> Void {
68+
return { x in () }
6969
}
7070
}
7171

@@ -138,7 +138,7 @@ class InvalidDerived : InvalidBase {
138138
}
139139

140140
//===----------------------------------------------------------------------===//
141-
// Multiple `dynamicallyCall` method tests
141+
// Multiple `dynamicallyCall` methods
142142
//===----------------------------------------------------------------------===//
143143

144144
@dynamicCallable
@@ -160,7 +160,7 @@ func testOverloaded(x: OverloadedCallable) {
160160
}
161161

162162
//===----------------------------------------------------------------------===//
163-
// Existential tests
163+
// Existentials
164164
//===----------------------------------------------------------------------===//
165165

166166
@dynamicCallable
@@ -318,7 +318,7 @@ func testEnum() {
318318
}
319319

320320
//===----------------------------------------------------------------------===//
321-
// Generics tests
321+
// Generics
322322
//===----------------------------------------------------------------------===//
323323

324324
@dynamicCallable

0 commit comments

Comments
 (0)