@@ -140,10 +140,51 @@ static void checkInvertibleConformanceCommon(DeclContext *dc,
140140 if (conformance.isConcrete ()) {
141141 auto concrete = conformance.getConcrete ();
142142 if (auto *normalConf = dyn_cast<NormalProtocolConformance>(concrete)) {
143- hasUnconditionalConformance =
144- normalConf->getConditionalRequirements ().empty ();
145143 conformanceLoc = normalConf->getLoc ();
146144 assert (conformanceLoc);
145+
146+ auto condReqs = normalConf->getConditionalRequirements ();
147+ hasUnconditionalConformance = condReqs.empty ();
148+ auto *thisProto = normalConf->getProtocol ();
149+
150+ // Ensure that conditional conformance to an invertible protocol IP only
151+ // depends conformance requirements involving IP, and its subject is not
152+ // a dependent member type.
153+ //
154+ // In theory, it could depend on any invertible protocol, but it may be
155+ // confusing if we permitted that and this simplifies the model a bit.
156+ for (auto req : condReqs) {
157+ Type illegalSecondType;
158+
159+ // If we are diagnosing, fill-in the second-type string of this req.
160+ switch (req.getKind ()) {
161+ case RequirementKind::Layout:
162+ assert (req.getLayoutConstraint ()->isClass ());
163+ illegalSecondType = ctx.getAnyObjectType ();
164+ break ;
165+ case RequirementKind::Conformance:
166+ if (req.getProtocolDecl () == thisProto
167+ && !req.getFirstType ()->is <DependentMemberType>())
168+ break ; // permitted, don't fill-in.
169+ LLVM_FALLTHROUGH;
170+ case RequirementKind::Superclass:
171+ case RequirementKind::SameType:
172+ case RequirementKind::SameShape:
173+ illegalSecondType = req.getSecondType ();
174+ break ;
175+ }
176+
177+ static_assert ((unsigned )RequirementKind::LAST_KIND == 4 ,
178+ " update %select in diagnostic!" );
179+ if (illegalSecondType) {
180+ auto t = ctx.Diags .diagnose (conformanceLoc,
181+ diag::inverse_cannot_be_conditional_on_requirement,
182+ thisProto,
183+ req.getFirstType (),
184+ static_cast <unsigned >(req.getKind ()),
185+ illegalSecondType);
186+ }
187+ }
147188 }
148189 }
149190 assert (!conformance.isPack () && " not handled" );
0 commit comments