Skip to content

Commit 626babd

Browse files
committed
Sema: Consolidate logic for allowing a requirement to have a default witness.
1 parent 43ce0df commit 626babd

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4388,10 +4388,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
43884388
//
43894389
// Treat 'unavailable' implicitly as if it were 'optional'.
43904390
// The compiler will reject actual uses.
4391-
auto Attrs = requirement->getAttrs();
4392-
if (Attrs.hasAttribute<OptionalAttr>() ||
4393-
Attrs.isUnavailable(getASTContext()) ||
4394-
!shouldRecordMissingWitness(Proto, Conformance, requirement)) {
4391+
if (allowOptionalWitness(requirement)) {
43954392
return ResolveWitnessResult::Missing;
43964393
}
43974394

@@ -4564,11 +4561,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
45644561
ValueDecl *requirement) {
45654562
assert(!isa<AssociatedTypeDecl>(requirement) && "Use resolveTypeWitnessVia*");
45664563

4567-
// An optional requirement is trivially satisfied with an empty requirement.
4568-
// An 'unavailable' requirement is treated like an optional requirement.
4569-
auto Attrs = requirement->getAttrs();
4570-
if (Attrs.hasAttribute<OptionalAttr>() ||
4571-
Attrs.isUnavailable(getASTContext())) {
4564+
if (allowOptionalWitness(requirement)) {
45724565
recordOptionalWitness(requirement);
45734566
return ResolveWitnessResult::Success;
45744567
}
@@ -4639,6 +4632,25 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
46394632
}
46404633
}
46414634

4635+
bool ConformanceChecker::allowOptionalWitness(ValueDecl *requirement) {
4636+
auto Attrs = requirement->getAttrs();
4637+
4638+
// An optional requirement is trivially satisfied with an empty requirement.
4639+
if (Attrs.hasAttribute<OptionalAttr>())
4640+
return true;
4641+
4642+
// An 'unavailable' requirement is treated like an optional requirement.
4643+
if (Attrs.isUnavailable(getASTContext()))
4644+
return true;
4645+
4646+
// A requirement with a satisfied Obj-C alternative requirement is effectively
4647+
// optional.
4648+
if (!shouldRecordMissingWitness(Proto, Conformance, requirement))
4649+
return true;
4650+
4651+
return false;
4652+
}
4653+
46424654
/// FIXME: It feels like this could be part of findExistentialSelfReferences().
46434655
static std::optional<Requirement>
46444656
hasInvariantSelfRequirement(const ProtocolDecl *proto,

lib/Sema/TypeCheckProtocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ class ConformanceChecker : public WitnessChecker {
168168
/// particular requirement and adoptee is required, before the
169169
/// conformance has been completed checked.
170170
void resolveSingleWitness(ValueDecl *requirement);
171+
172+
private:
173+
bool allowOptionalWitness(ValueDecl *requirement);
171174
};
172175

173176
/// Match the given witness to the given requirement.

0 commit comments

Comments
 (0)