@@ -215,7 +215,6 @@ static void validateAttributes(TypeChecker &TC, Decl *D);
215
215
// / file.
216
216
static void checkInheritanceClause (
217
217
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> declUnion) {
218
- TypeResolutionOptions options = None;
219
218
DeclContext *DC;
220
219
MutableArrayRef<TypeLoc> inheritedClause;
221
220
ExtensionDecl *ext = nullptr ;
@@ -224,7 +223,6 @@ static void checkInheritanceClause(
224
223
if ((ext = declUnion.dyn_cast <ExtensionDecl *>())) {
225
224
decl = ext;
226
225
DC = ext;
227
- options |= TypeResolutionFlags::AllowUnavailableProtocol;
228
226
229
227
inheritedClause = ext->getInherited ();
230
228
@@ -243,14 +241,17 @@ static void checkInheritanceClause(
243
241
decl = typeDecl;
244
242
if (auto nominal = dyn_cast<NominalTypeDecl>(typeDecl)) {
245
243
DC = nominal;
246
- options |= TypeResolutionFlags::AllowUnavailableProtocol;
247
244
} else {
248
245
DC = typeDecl->getDeclContext ();
249
246
}
250
247
251
248
inheritedClause = typeDecl->getInherited ();
252
249
}
253
250
251
+ bool canHaveSuperclass = (isa<ClassDecl>(decl) ||
252
+ (isa<ProtocolDecl>(decl) &&
253
+ !cast<ProtocolDecl>(decl)->isObjC ()));
254
+
254
255
ASTContext &ctx = decl->getASTContext ();
255
256
auto &diags = ctx.Diags ;
256
257
@@ -259,13 +260,6 @@ static void checkInheritanceClause(
259
260
if (ext)
260
261
return ext->getSourceRange ().End ;
261
262
262
- if (auto genericTypeDecl = dyn_cast<GenericTypeDecl>(typeDecl)) {
263
- if (auto genericParams = genericTypeDecl->getGenericParams ())
264
- return genericParams->getSourceRange ().End ;
265
-
266
- return genericTypeDecl->getNameLoc ();
267
- }
268
-
269
263
return typeDecl->getNameLoc ();
270
264
};
271
265
@@ -316,6 +310,12 @@ static void checkInheritanceClause(
316
310
if (!inheritedTy || inheritedTy->hasError ())
317
311
continue ;
318
312
313
+ // For generic parameters and associated types, the GSB checks constraints;
314
+ // however, we still want to fire off the requests to produce diagnostics
315
+ // in some circular validation cases.
316
+ if (isa<AbstractTypeParamDecl>(decl))
317
+ continue ;
318
+
319
319
// Check whether we inherited from 'AnyObject' twice.
320
320
// Other redundant-inheritance scenarios are checked below, the
321
321
// GenericSignatureBuilder (for protocol inheritance) or the
@@ -351,41 +351,36 @@ static void checkInheritanceClause(
351
351
if (inheritedTy->isExistentialType ()) {
352
352
auto layout = inheritedTy->getExistentialLayout ();
353
353
354
- // @objc protocols cannot have superclass constraints.
355
- if (layout.explicitSuperclass ) {
356
- if (auto *protoDecl = dyn_cast<ProtocolDecl>(decl)) {
357
- if (protoDecl->isObjC ()) {
358
- protoDecl->diagnose (diag::objc_protocol_with_superclass,
359
- protoDecl->getName ());
360
- continue ;
361
- }
362
- }
363
- }
354
+ // Inheritance from protocol compositions that do not contain classes
355
+ // or AnyObject is always OK.
356
+ if (!layout.hasExplicitAnyObject &&
357
+ !layout.explicitSuperclass )
358
+ continue ;
364
359
365
- // Protocols, generic parameters and associated types can inherit
366
- // from subclass existentials, which are "exploded" into their
367
- // corresponding requirements.
368
- //
369
- // Extensions, structs and enums can only inherit from protocol
370
- // compositions that do not contain AnyObject or class members.
371
- if (isa<ProtocolDecl>(decl) ||
372
- isa<AbstractTypeParamDecl>(decl) ||
373
- (!layout.hasExplicitAnyObject &&
374
- !layout.explicitSuperclass )) {
360
+ // Protocols can inherit from AnyObject.
361
+ if (layout.hasExplicitAnyObject &&
362
+ isa<ProtocolDecl>(decl))
375
363
continue ;
376
- }
377
364
378
- // Classes can inherit from subclass existentials as long as they
379
- // do not contain an explicit AnyObject member.
380
- if (isa<ClassDecl>(decl) &&
381
- !layout.hasExplicitAnyObject ) {
382
- // Superclass inheritance is handled below.
383
- inheritedTy = layout.explicitSuperclass ;
384
- if (!inheritedTy)
365
+ // Class-constrained protocol compositions are not allowed except in
366
+ // special cases.
367
+ if (layout.explicitSuperclass ) {
368
+ if (!canHaveSuperclass) {
369
+ decl->diagnose (diag::inheritance_from_protocol_with_superclass,
370
+ inheritedTy);
385
371
continue ;
372
+ }
373
+
374
+ // Classes can inherit from protocol compositions that contain a
375
+ // superclass, but not AnyObject.
376
+ if (isa<ClassDecl>(decl) &&
377
+ !layout.hasExplicitAnyObject ) {
378
+ // Superclass inheritance is handled below.
379
+ inheritedTy = layout.explicitSuperclass ;
380
+ }
386
381
}
387
382
}
388
-
383
+
389
384
// If this is an enum inheritance clause, check for a raw type.
390
385
if (isa<EnumDecl>(decl)) {
391
386
// Check if we already had a raw type.
@@ -445,29 +440,6 @@ static void checkInheritanceClause(
445
440
continue ;
446
441
}
447
442
448
- // @objc protocols cannot have superclass constraints.
449
- if (auto *protoDecl = dyn_cast<ProtocolDecl>(decl)) {
450
- if (protoDecl->isObjC ()) {
451
- protoDecl->diagnose (diag::objc_protocol_with_superclass,
452
- protoDecl->getName ());
453
- continue ;
454
- }
455
- }
456
-
457
- // If the declaration we're looking at doesn't allow a superclass,
458
- // complain.
459
- if (isa<StructDecl>(decl) || isa<ExtensionDecl>(decl)) {
460
- decl->diagnose (isa<ExtensionDecl>(decl)
461
- ? diag::extension_class_inheritance
462
- : diag::non_class_inheritance,
463
- isa<ExtensionDecl>(decl)
464
- ? cast<ExtensionDecl>(decl)->getDeclaredInterfaceType ()
465
- : cast<TypeDecl>(decl)->getDeclaredInterfaceType (),
466
- inheritedTy)
467
- .highlight (inherited.getSourceRange ());
468
- continue ;
469
- }
470
-
471
443
// If this is not the first entry in the inheritance clause, complain.
472
444
if (isa<ClassDecl>(decl) && i > 0 ) {
473
445
auto removeRange = getRemovalRange (i);
@@ -480,21 +452,18 @@ static void checkInheritanceClause(
480
452
// Fall through to record the superclass.
481
453
}
482
454
483
- // Record the superclass.
484
- superclassTy = inheritedTy;
485
- superclassRange = inherited.getSourceRange ();
486
- continue ;
455
+ if (canHaveSuperclass) {
456
+ // Record the superclass.
457
+ superclassTy = inheritedTy;
458
+ superclassRange = inherited.getSourceRange ();
459
+ continue ;
460
+ }
487
461
}
488
462
489
- // The GenericSignatureBuilder diagnoses problems with generic type
490
- // parameters.
491
- if (isa<GenericTypeParamDecl>(decl))
492
- continue ;
493
-
494
463
// We can't inherit from a non-class, non-protocol type.
495
- decl->diagnose ((isa<StructDecl>(decl) || isa<ExtensionDecl>(decl))
496
- ? diag::inheritance_from_non_protocol
497
- : diag::inheritance_from_non_protocol_or_class ,
464
+ decl->diagnose (canHaveSuperclass
465
+ ? diag::inheritance_from_non_protocol_or_class
466
+ : diag::inheritance_from_non_protocol ,
498
467
inheritedTy);
499
468
// FIXME: Note pointing to the declaration 'inheritedTy' references?
500
469
}
0 commit comments