Skip to content

Commit 1c8e4ba

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. (cherry picked from commit 7e3c13c)
1 parent 05ad3da commit 1c8e4ba

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

@@ -4878,6 +4878,26 @@ TypeChecker::findWitnessedObjCRequirements(const ValueDecl *witness,
48784878
if ((*conformance)->getWitness(req, this).getDecl() == witness) {
48794879
result.push_back(req);
48804880
if (anySingleRequirement) return result;
4881+
continue;
4882+
}
4883+
4884+
// If we have an inherited conformance, check whether the potential
4885+
// witness matches the requirement.
4886+
// FIXME: for now, don't even try this with generics involved. We
4887+
// should be tracking how subclasses implement optional requirements,
4888+
// in which case the getWitness() check above would suffice.
4889+
if (req->getAttrs().hasAttribute<OptionalAttr>() &&
4890+
isa<InheritedProtocolConformance>(*conformance)) {
4891+
auto normal = (*conformance)->getRootNormalConformance();
4892+
if (!(*conformance)->getDeclContext()->getGenericSignatureOfContext() &&
4893+
!normal->getDeclContext()->getGenericSignatureOfContext() &&
4894+
matchWitness(*this, proto, *conformance, witness->getDeclContext(),
4895+
req, const_cast<ValueDecl *>(witness)).Kind
4896+
== MatchKind::ExactMatch) {
4897+
result.push_back(req);
4898+
if (anySingleRequirement) return result;
4899+
continue;
4900+
}
48814901
}
48824902
}
48834903
}

test/attr/attr_objc.swift

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

21322132
// Note: no inference for subclasses
21332133
class SubclassInfersFromProtocol1 : SuperclassImplementsProtocol {
2134-
// CHECK: {{^}} func method1(value: Int)
2134+
// CHECK: {{^}} @objc func method1(value: Int)
21352135
func method1(value: Int) { }
21362136
}
21372137

@@ -2140,7 +2140,7 @@ class SubclassInfersFromProtocol2 : SuperclassImplementsProtocol {
21402140
}
21412141

21422142
extension SubclassInfersFromProtocol2 {
2143-
// CHECK: {{^}} func method1(value: Int)
2143+
// CHECK: {{^}} @objc dynamic func method1(value: Int)
21442144
func method1(value: Int) { }
21452145
}
21462146

0 commit comments

Comments
 (0)