Skip to content

Commit 7e3c13c

Browse files
committed
[Type checker] Infer @objc for witnesses of protocol conformances from superclasses.
Extend @objc inference for witnesses to also consider optional protocols whose conformances come from superclasses. Because we don't do real binding of witnesses for inherited conformances, this is a bit of an heuristic, looking at whether the witness is a potential match (vs. the known exact match), so it can infer @objc somewhat more liberally than a complete solution. Fixes rdar://problem/27348369.
1 parent 7e2efe5 commit 7e3c13c

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ matchWitness(TypeChecker &tc,
899899
static RequirementMatch
900900
matchWitness(TypeChecker &tc,
901901
ProtocolDecl *proto,
902-
NormalProtocolConformance *conformance,
902+
ProtocolConformance *conformance,
903903
DeclContext *dc, ValueDecl *req, ValueDecl *witness) {
904904
using namespace constraints;
905905

@@ -4915,6 +4915,26 @@ TypeChecker::findWitnessedObjCRequirements(const ValueDecl *witness,
49154915
if ((*conformance)->getWitness(req, this).getDecl() == witness) {
49164916
result.push_back(req);
49174917
if (anySingleRequirement) return result;
4918+
continue;
4919+
}
4920+
4921+
// If we have an inherited conformance, check whether the potential
4922+
// witness matches the requirement.
4923+
// FIXME: for now, don't even try this with generics involved. We
4924+
// should be tracking how subclasses implement optional requirements,
4925+
// in which case the getWitness() check above would suffice.
4926+
if (req->getAttrs().hasAttribute<OptionalAttr>() &&
4927+
isa<InheritedProtocolConformance>(*conformance)) {
4928+
auto normal = (*conformance)->getRootNormalConformance();
4929+
if (!(*conformance)->getDeclContext()->getGenericSignatureOfContext() &&
4930+
!normal->getDeclContext()->getGenericSignatureOfContext() &&
4931+
matchWitness(*this, proto, *conformance, witness->getDeclContext(),
4932+
req, const_cast<ValueDecl *>(witness)).Kind
4933+
== MatchKind::ExactMatch) {
4934+
result.push_back(req);
4935+
if (anySingleRequirement) return result;
4936+
continue;
4937+
}
49184938
}
49194939
}
49204940
}

test/attr/attr_objc.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,7 +2164,7 @@ class SuperclassImplementsProtocol : InferFromProtocol { }
21642164

21652165
// Note: no inference for subclasses
21662166
class SubclassInfersFromProtocol1 : SuperclassImplementsProtocol {
2167-
// CHECK: {{^}} func method1(value: Int)
2167+
// CHECK: {{^}} @objc func method1(value: Int)
21682168
func method1(value: Int) { }
21692169
}
21702170

@@ -2173,7 +2173,7 @@ class SubclassInfersFromProtocol2 : SuperclassImplementsProtocol {
21732173
}
21742174

21752175
extension SubclassInfersFromProtocol2 {
2176-
// CHECK: {{^}} func method1(value: Int)
2176+
// CHECK: {{^}} @objc dynamic func method1(value: Int)
21772177
func method1(value: Int) { }
21782178
}
21792179

0 commit comments

Comments
 (0)