@@ -171,20 +171,14 @@ static bool checkInvertibleConformanceCommon(ProtocolConformance *conformance,
171
171
auto &ctx = nom->getASTContext ();
172
172
bool conforms = true ;
173
173
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.
175
176
//
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.
180
179
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) {
188
182
ctx.Diags .diagnose (marking.getInverse ().getLoc (),
189
183
diag::inverse_but_also_conforms,
190
184
nom, getProtocolName (kp));
@@ -198,7 +192,7 @@ static bool checkInvertibleConformanceCommon(ProtocolConformance *conformance,
198
192
199
193
// Protocols do not directly define any storage.
200
194
if (isa<ProtocolDecl, BuiltinTupleDecl>(nom))
201
- llvm_unreachable (" unexpected nominal to check Copyable conformance" );
195
+ llvm_unreachable (" unexpected nominal to check invertible's conformance" );
202
196
203
197
// A deinit prevents a struct or enum from conforming to Copyable.
204
198
if (ip == InvertibleProtocolKind::Copyable) {
@@ -343,6 +337,7 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
343
337
if (!ip)
344
338
llvm_unreachable (" not an invertible protocol" );
345
339
340
+ assert (!isa<ClassDecl>(nominal) && " classes aren't handled here" );
346
341
auto file = cast<FileUnit>(nominal->getModuleScopeContext ());
347
342
348
343
// Generates a conformance for the nominal to the protocol.
@@ -403,20 +398,6 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
403
398
return generateConformance (ext);
404
399
};
405
400
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
-
420
401
auto marking = nominal->getMarking (*ip);
421
402
422
403
// Unexpected to have any positive marking for IP if we're deriving it.
@@ -430,10 +411,8 @@ ProtocolConformance *deriveConformanceForInvertible(Evaluator &evaluator,
430
411
return nullptr ; // No positive IP conformance will be inferred.
431
412
432
413
case InverseMarking::Kind::Inferred:
433
- if (!isa<ClassDecl>(nominal))
434
- return generateConditionalConformance ();
414
+ return generateConditionalConformance ();
435
415
436
- LLVM_FALLTHROUGH;
437
416
case InverseMarking::Kind::None:
438
417
// All types already start with conformances to the invertible protocols in
439
418
// this case, within `NominalTypeDecl::prepareConformanceTable`.
0 commit comments