@@ -6414,14 +6414,12 @@ bool ProtocolDecl::isMarkerProtocol() const {
64146414 return getAttrs().hasAttribute<MarkerAttr>();
64156415}
64166416
6417- bool ProtocolDecl::isInvertibleProtocol() const {
6418- if (auto kp = getKnownProtocolKind()) {
6419- if (getInvertibleProtocolKind(*kp)) {
6420- assert(isMarkerProtocol());
6421- return true;
6422- }
6423- }
6424- return false;
6417+ llvm::Optional<InvertibleProtocolKind>
6418+ ProtocolDecl::getInvertibleProtocolKind() const {
6419+ if (auto kp = getKnownProtocolKind())
6420+ return ::getInvertibleProtocolKind(*kp);
6421+
6422+ return llvm::None;
64256423}
64266424
64276425ArrayRef<ProtocolDecl *> ProtocolDecl::getInheritedProtocols() const {
@@ -6560,9 +6558,14 @@ bool ProtocolDecl::walkInheritedProtocols(
65606558}
65616559
65626560bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
6561+ assert(super);
6562+
65636563 if (this == super)
65646564 return false;
65656565
6566+ if (auto ip = super->getInvertibleProtocolKind())
6567+ return requiresInvertible(*ip);
6568+
65666569 return walkInheritedProtocols([super](ProtocolDecl *inherited) {
65676570 if (inherited == super)
65686571 return TypeWalker::Action::Stop;
@@ -6571,6 +6574,30 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
65716574 });
65726575}
65736576
6577+ bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
6578+ // HACK: until we enable Feature::NoncopyableGenerics in the stdlib,
6579+ // hardcode the fact that an invertible protocol does not require any other!
6580+ if (getInvertibleProtocolKind())
6581+ return false;
6582+
6583+ auto kp = ::getKnownProtocolKind(ip);
6584+ return walkInheritedProtocols([kp, ip](ProtocolDecl *proto) {
6585+ if (proto->isSpecificProtocol(kp))
6586+ return TypeWalker::Action::Stop; // it is required.
6587+
6588+ switch (proto->getMarking(ip).getInverse().getKind()) {
6589+ case InverseMarking::Kind::None:
6590+ return TypeWalker::Action::Stop; // it is required.
6591+
6592+ case InverseMarking::Kind::LegacyExplicit:
6593+ case InverseMarking::Kind::Explicit:
6594+ case InverseMarking::Kind::Inferred:
6595+ // the implicit requirement was suppressed on this protocol, keep looking.
6596+ return TypeWalker::Action::Continue;
6597+ }
6598+ });
6599+ }
6600+
65746601bool ProtocolDecl::requiresClass() const {
65756602 return evaluateOrDefault(getASTContext().evaluator,
65766603 ProtocolRequiresClassRequest{const_cast<ProtocolDecl *>(this)}, false);
0 commit comments