@@ -140,10 +140,50 @@ 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+ std::optional<StringRef> illegalSecondTypeStr;
158+
159+ // If we are diagnosing, fill-in the second-type string of this req.
160+ switch (req.getKind ()) {
161+ case RequirementKind::Layout:
162+ illegalSecondTypeStr = req.getLayoutConstraint ().getString ();
163+ break ;
164+ case RequirementKind::Conformance:
165+ if (req.getProtocolDecl () == thisProto
166+ && !req.getFirstType ()->is <DependentMemberType>())
167+ break ; // permitted, don't fill-in.
168+ LLVM_FALLTHROUGH;
169+ case RequirementKind::Superclass:
170+ case RequirementKind::SameType:
171+ case RequirementKind::SameShape:
172+ illegalSecondTypeStr = req.getSecondType ().getString ();
173+ break ;
174+ }
175+
176+ static_assert ((unsigned )RequirementKind::LAST_KIND == 4 ,
177+ " update %select in diagnostic!" );
178+ if (illegalSecondTypeStr) {
179+ ctx.Diags .diagnose (conformanceLoc,
180+ diag::inverse_cannot_be_conditional_on_requirement,
181+ thisProto,
182+ req.getFirstType ().getString (),
183+ static_cast <unsigned >(req.getKind ()),
184+ *illegalSecondTypeStr);
185+ }
186+ }
147187 }
148188 }
149189 assert (!conformance.isPack () && " not handled" );
0 commit comments