@@ -352,7 +352,7 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
352
352
// Check all of the types listed in the inheritance clause.
353
353
Type superclassTy;
354
354
SourceRange superclassRange;
355
- llvm::SmallDenseMap<CanType, std::pair<unsigned , SourceRange>> inheritedTypes ;
355
+ Optional< std::pair<unsigned , SourceRange>> inheritedAnyObject ;
356
356
for (unsigned i = 0 , n = inheritedClause.size (); i != n; ++i) {
357
357
auto &inherited = inheritedClause[i];
358
358
@@ -368,36 +368,36 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
368
368
if (inheritedTy->hasError ())
369
369
continue ;
370
370
371
- // Check whether we inherited from the same type twice.
372
- auto knownPair = inheritedTypes.insert ({ inheritedTy->getCanonicalType (),
373
- {i, inherited.getSourceRange () }});
374
- if (knownPair.second == /* insertion failed*/ false ) {
375
- auto knownIndex = knownPair.first ->second .first ;
376
- auto knownRange = knownPair.first ->second .second ;
377
- // If the duplicated type is 'AnyObject', check whether the first was
378
- // written as 'class'. Downgrade the error to a warning in such cases
379
- // for backward compatibility with Swift <= 4.
380
- if (!Context.LangOpts .isSwiftVersionAtLeast (5 ) &&
381
- inheritedTy->isAnyObject () &&
382
- (isa<ProtocolDecl>(decl) || isa<AbstractTypeParamDecl>(decl)) &&
383
- Lexer::getTokenAtLocation (Context.SourceMgr , knownRange.Start )
384
- .is (tok::kw_class)) {
385
- SourceLoc classLoc = knownRange.Start ;
371
+ // Check whether we inherited from 'AnyObject' twice.
372
+ // Other redundant-inheritance scenarios are checked below, the
373
+ // GenericSignatureBuilder (for protocol inheritance) or the
374
+ // ConformanceLookupTable (for protocol conformance).
375
+ if (inheritedTy->isAnyObject ()) {
376
+ if (inheritedAnyObject) {
377
+ // If the first occurrence was written as 'class', downgrade the error
378
+ // to a warning in such cases
379
+ // for backward compatibility with Swift <= 4.
380
+ auto knownIndex = inheritedAnyObject->first ;
381
+ auto knownRange = inheritedAnyObject->second ;
386
382
SourceRange removeRange = getRemovalRange (knownIndex);
387
-
388
- diagnose (classLoc, diag::duplicate_anyobject_class_inheritance)
389
- .fixItRemoveChars (removeRange.Start , removeRange.End );
390
- inherited.setInvalidType (Context);
383
+ if (!Context.LangOpts .isSwiftVersionAtLeast (5 ) &&
384
+ (isa<ProtocolDecl>(decl) || isa<AbstractTypeParamDecl>(decl)) &&
385
+ Lexer::getTokenAtLocation (Context.SourceMgr , knownRange.Start )
386
+ .is (tok::kw_class)) {
387
+ SourceLoc classLoc = knownRange.Start ;
388
+
389
+ diagnose (classLoc, diag::duplicate_anyobject_class_inheritance)
390
+ .fixItRemoveChars (removeRange.Start , removeRange.End );
391
+ } else {
392
+ diagnose (inherited.getSourceRange ().Start ,
393
+ diag::duplicate_inheritance, inheritedTy)
394
+ .fixItRemoveChars (removeRange.Start , removeRange.End );
395
+ }
391
396
continue ;
392
397
}
393
398
394
- auto removeRange = getRemovalRange (i);
395
- diagnose (inherited.getSourceRange ().Start ,
396
- diag::duplicate_inheritance, inheritedTy)
397
- .fixItRemoveChars (removeRange.Start , removeRange.End )
398
- .highlight (knownRange);
399
- inherited.setInvalidType (Context);
400
- continue ;
399
+ // Note that we saw inheritance from 'AnyObject'.
400
+ inheritedAnyObject = { i, inherited.getSourceRange () };
401
401
}
402
402
403
403
if (inheritedTy->isExistentialType ()) {
@@ -455,10 +455,16 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
455
455
if (isa<EnumDecl>(decl)) {
456
456
// Check if we already had a raw type.
457
457
if (superclassTy) {
458
- diagnose (inherited.getSourceRange ().Start ,
459
- diag::multiple_enum_raw_types, superclassTy, inheritedTy)
460
- .highlight (superclassRange);
461
- inherited.setInvalidType (Context);
458
+ if (superclassTy->isEqual (inheritedTy)) {
459
+ auto removeRange = getRemovalRange (i);
460
+ diagnose (inherited.getSourceRange ().Start ,
461
+ diag::duplicate_inheritance, inheritedTy)
462
+ .fixItRemoveChars (removeRange.Start , removeRange.End );
463
+ } else {
464
+ diagnose (inherited.getSourceRange ().Start ,
465
+ diag::multiple_enum_raw_types, superclassTy, inheritedTy)
466
+ .highlight (superclassRange);
467
+ }
462
468
continue ;
463
469
}
464
470
@@ -487,12 +493,19 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
487
493
if (superclassTy) {
488
494
// FIXME: Check for shadowed protocol names, i.e., NSObject?
489
495
490
- // Complain about multiple inheritance.
491
- // Don't emit a Fix-It here. The user has to think harder about this.
492
- diagnose (inherited.getSourceRange ().Start ,
493
- diag::multiple_inheritance, superclassTy, inheritedTy)
494
- .highlight (superclassRange);
495
- inherited.setInvalidType (Context);
496
+ if (superclassTy->isEqual (inheritedTy)) {
497
+ // Duplicate superclass.
498
+ auto removeRange = getRemovalRange (i);
499
+ diagnose (inherited.getSourceRange ().Start ,
500
+ diag::duplicate_inheritance, inheritedTy)
501
+ .fixItRemoveChars (removeRange.Start , removeRange.End );
502
+ } else {
503
+ // Complain about multiple inheritance.
504
+ // Don't emit a Fix-It here. The user has to think harder about this.
505
+ diagnose (inherited.getSourceRange ().Start ,
506
+ diag::multiple_inheritance, superclassTy, inheritedTy)
507
+ .highlight (superclassRange);
508
+ }
496
509
continue ;
497
510
}
498
511
0 commit comments