@@ -352,7 +352,7 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
352352 // Check all of the types listed in the inheritance clause.
353353 Type superclassTy;
354354 SourceRange superclassRange;
355- llvm::SmallDenseMap<CanType, std::pair<unsigned , SourceRange>> inheritedTypes ;
355+ Optional< std::pair<unsigned , SourceRange>> inheritedAnyObject ;
356356 for (unsigned i = 0 , n = inheritedClause.size (); i != n; ++i) {
357357 auto &inherited = inheritedClause[i];
358358
@@ -368,36 +368,36 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
368368 if (inheritedTy->hasError ())
369369 continue ;
370370
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 ;
386382 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+ }
391396 continue ;
392397 }
393398
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 () };
401401 }
402402
403403 if (inheritedTy->isExistentialType ()) {
@@ -455,10 +455,16 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
455455 if (isa<EnumDecl>(decl)) {
456456 // Check if we already had a raw type.
457457 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+ }
462468 continue ;
463469 }
464470
@@ -487,12 +493,19 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
487493 if (superclassTy) {
488494 // FIXME: Check for shadowed protocol names, i.e., NSObject?
489495
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+ }
496509 continue ;
497510 }
498511
0 commit comments