@@ -248,6 +248,8 @@ static void checkInheritanceClause(
248
248
inheritedClause = typeDecl->getInherited ();
249
249
}
250
250
251
+ // Can this declaration's inheritance clause contain a class or
252
+ // subclass existential?
251
253
bool canHaveSuperclass = (isa<ClassDecl>(decl) ||
252
254
(isa<ProtocolDecl>(decl) &&
253
255
!cast<ProtocolDecl>(decl)->isObjC ()));
@@ -351,34 +353,38 @@ static void checkInheritanceClause(
351
353
if (inheritedTy->isExistentialType ()) {
352
354
auto layout = inheritedTy->getExistentialLayout ();
353
355
354
- // Inheritance from protocol compositions that do not contain classes
355
- // or AnyObject is always OK.
356
- if (!layout.hasExplicitAnyObject &&
357
- !layout.explicitSuperclass )
356
+ // Subclass existentials are not allowed except on classes and
357
+ // non-@objc protocols.
358
+ if (layout.explicitSuperclass &&
359
+ !canHaveSuperclass) {
360
+ decl->diagnose (diag::inheritance_from_protocol_with_superclass,
361
+ inheritedTy);
358
362
continue ;
363
+ }
359
364
360
- // Protocols can inherit from AnyObject .
365
+ // AnyObject is not allowed except on protocols .
361
366
if (layout.hasExplicitAnyObject &&
362
- isa<ProtocolDecl>(decl))
367
+ !isa<ProtocolDecl>(decl)) {
368
+ decl->diagnose (canHaveSuperclass
369
+ ? diag::inheritance_from_non_protocol_or_class
370
+ : diag::inheritance_from_non_protocol,
371
+ inheritedTy);
363
372
continue ;
373
+ }
364
374
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);
371
- continue ;
372
- }
375
+ // If the existential did not have a class constraint, we're done.
376
+ if (!layout.explicitSuperclass )
377
+ continue ;
373
378
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
- }
381
- }
379
+ // Classes and protocols can inherit from subclass existentials.
380
+ // For classes, we check for a duplicate superclass below.
381
+ // For protocols, the GSB emits its own warning instead.
382
+ if (isa<ProtocolDecl>(decl))
383
+ continue ;
384
+
385
+ assert (isa<ClassDecl>(decl));
386
+ assert (canHaveSuperclass);
387
+ inheritedTy = layout.explicitSuperclass ;
382
388
}
383
389
384
390
// If this is an enum inheritance clause, check for a raw type.
@@ -418,7 +424,9 @@ static void checkInheritanceClause(
418
424
continue ;
419
425
}
420
426
421
- // If this is a class type, it may be the superclass.
427
+ // If this is a class type, it may be the superclass. We end up here when
428
+ // the inherited type is either itself a class, or when it is a subclass
429
+ // existential via the existential type path above.
422
430
if (inheritedTy->getClassOrBoundGenericClass ()) {
423
431
// First, check if we already had a superclass.
424
432
if (superclassTy) {
0 commit comments