@@ -1695,6 +1695,39 @@ static void diagnoseWrittenPlaceholderTypes(ASTContext &Ctx,
1695
1695
}
1696
1696
}
1697
1697
1698
+ // / Make sure that every protocol conformance requirement on 'Self' is
1699
+ // / directly stated in the protocol's inheritance clause.
1700
+ // /
1701
+ // / This disallows protocol declarations where a conformance requirement on
1702
+ // / 'Self' is implied by some other requirement, such as this:
1703
+ // /
1704
+ // / protocol Other { ... }
1705
+ // / protocol Foo { associatedtype A : Other }
1706
+ // / protocol Bar {
1707
+ // / associatedtype A : Foo where Self == A.A
1708
+ // / }
1709
+ // /
1710
+ // / Since name lookup is upstream of generic signature computation, we
1711
+ // / want 'Other' to appear in the inheritance clause of 'Bar', so that
1712
+ // / name lookup on Bar can find members of Other.
1713
+ static void checkProtocolRefinementRequirements (ProtocolDecl *proto) {
1714
+ auto requiredProtos = proto->getGenericSignature ()->getRequiredProtocols (
1715
+ proto->getSelfInterfaceType ());
1716
+
1717
+ for (auto *otherProto : requiredProtos) {
1718
+ // Every protocol 'P' has an implied requirement 'Self : P'; skip it.
1719
+ if (otherProto == proto)
1720
+ continue ;
1721
+
1722
+ // GenericSignature::getRequiredProtocols() canonicalizes the protocol
1723
+ // list by dropping protocols that are inherited by other protocols in
1724
+ // the list. Any protocols that remain in the list other than 'proto'
1725
+ // itself are implied by a conformance requirement on 'Self', but are
1726
+ // not (transitively) inherited by 'proto'.
1727
+ proto->diagnose (diag::missing_protocol_refinement, proto, otherProto);
1728
+ }
1729
+ }
1730
+
1698
1731
namespace {
1699
1732
class DeclChecker : public DeclVisitor <DeclChecker> {
1700
1733
public:
@@ -2670,6 +2703,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2670
2703
2671
2704
checkInheritanceClause (PD);
2672
2705
2706
+ if (PD->getASTContext ().LangOpts .RequirementMachineProtocolSignatures
2707
+ == RequirementMachineMode::Enabled) {
2708
+ checkProtocolRefinementRequirements (PD);
2709
+ }
2710
+
2673
2711
TypeChecker::checkDeclCircularity (PD);
2674
2712
if (PD->isResilient ())
2675
2713
if (!SF || SF->Kind != SourceFileKind::Interface)
0 commit comments