@@ -171,20 +171,14 @@ static bool checkInvertibleConformanceCommon(ProtocolConformance *conformance,
171171 auto &ctx = nom->getASTContext ();
172172 bool conforms = true ;
173173
174- // An explicit `~IP` prevents conformance if any of these are true:
174+ // An explicit `~IP` prevents conformance if it appears on the same
175+ // declaration that also declares the conformance.
175176 //
176- // 1. It appears on a class.
177- // 2. Appears on the same declaration that also declares the conformance.
178- // So, if the nominal has `~Copyable` but this conformance is
179- // written in an extension, then we do not raise an error.
177+ // So, if the nominal has `~Copyable` but this conformance is
178+ // written in an extension, then we do not raise an error.
180179 auto marking = nom->getMarking (ip);
181- if (marking.getInverse ().getKind () == InverseMarking::Kind::Explicit) {
182- if (isa<ClassDecl>(nom)) {
183- ctx.Diags .diagnose (marking.getInverse ().getLoc (),
184- diag::inverse_on_class,
185- getProtocolName (kp));
186- conforms &= false ;
187- } else if (conformance->getDeclContext () == nom) {
180+ if (marking.getInverse ().isAnyExplicit ()) {
181+ if (conformance->getDeclContext () == nom) {
188182 ctx.Diags .diagnose (marking.getInverse ().getLoc (),
189183 diag::inverse_but_also_conforms,
190184 nom, getProtocolName (kp));
@@ -198,7 +192,7 @@ static bool checkInvertibleConformanceCommon(ProtocolConformance *conformance,
198192
199193 // Protocols do not directly define any storage.
200194 if (isa<ProtocolDecl, BuiltinTupleDecl>(nom))
201- llvm_unreachable (" unexpected nominal to check Copyable conformance" );
195+ llvm_unreachable (" unexpected nominal to check invertible's conformance" );
202196
203197 // A deinit prevents a struct or enum from conforming to Copyable.
204198 if (ip == InvertibleProtocolKind::Copyable) {
@@ -343,6 +337,7 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
343337 if (!ip)
344338 llvm_unreachable (" not an invertible protocol" );
345339
340+ assert (!isa<ClassDecl>(nominal) && " classes aren't handled here" );
346341 auto file = cast<FileUnit>(nominal->getModuleScopeContext ());
347342
348343 // Generates a conformance for the nominal to the protocol.
@@ -403,20 +398,6 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
403398 return generateConformance (ext);
404399 };
405400
406- switch (*ip) {
407- case InvertibleProtocolKind::Copyable:
408- // If move-only classes is enabled, we'll check the markings.
409- if (ctx.LangOpts .hasFeature (Feature::MoveOnlyClasses))
410- break ;
411-
412- LLVM_FALLTHROUGH;
413- case InvertibleProtocolKind::Escapable:
414- // Always derive unconditional IP conformance for classes
415- if (isa<ClassDecl>(nominal))
416- return generateConformance (nominal);
417- break ;
418- }
419-
420401 auto marking = nominal->getMarking (*ip);
421402
422403 // Unexpected to have any positive marking for IP if we're deriving it.
@@ -430,10 +411,8 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
430411 return nullptr ; // No positive IP conformance will be inferred.
431412
432413 case InverseMarking::Kind::Inferred:
433- if (!isa<ClassDecl>(nominal))
434- return generateConditionalConformance ();
414+ return generateConditionalConformance ();
435415
436- LLVM_FALLTHROUGH;
437416 case InverseMarking::Kind::None:
438417 // All types already start with conformances to the invertible protocols in
439418 // this case, within `NominalTypeDecl::prepareConformanceTable`.
0 commit comments