From 5c21cdf4a66a64c4a8c6ab8cf9fa7628f9c996eb Mon Sep 17 00:00:00 2001 From: Minhyuk Kim Date: Thu, 21 Jan 2021 23:25:16 +0900 Subject: [PATCH] Modify override_decl_extension error to be more descriptive --- include/swift/AST/DiagnosticsSema.def | 6 ++++-- lib/Sema/TypeCheckDeclOverride.cpp | 10 +++++++--- test/ClangImporter/objc-cross-module-override.swift | 2 +- test/attr/attr_objc_override.swift | 6 +++--- test/decl/func/static_func.swift | 12 ++++++------ test/decl/inherit/override.swift | 4 ++-- test/decl/init/basic_init.swift | 2 +- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index e41504e017b4c..bcfa4c1804268 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2454,8 +2454,10 @@ NOTE(overridden_near_match_here,none, "potential overridden %0 %1 here", (DescriptiveDeclKind, DeclName)) ERROR(override_decl_extension,none, - "overriding %select{|non-@objc }0declarations " - "%select{in extensions|from extensions}0 is not supported", (bool, bool)) + "%select{|non-@objc}0 %2 %3 %select{" + "is declared in extension of %4 and cannot be overriden|" + "declared in %4 cannot be overriden from extension}1", + (bool, bool, DescriptiveDeclKind, DeclName, DeclName)) NOTE(overridden_here,none, "overridden declaration is here", ()) NOTE(overridden_here_can_be_objc,none, diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 99e54ee3f95e4..5658c979085c9 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1009,8 +1009,8 @@ static void checkOverrideAccessControl(ValueDecl *baseDecl, ValueDecl *decl, !baseHasOpenAccess && baseDecl->getModuleContext() != decl->getModuleContext() && !isa(decl)) { - // NSObject.hashValue and NSObject.hash(into:) was made non-overridable in - // Swift 5; one should override NSObject.hash instead. + // NSObject.hashValue and NSObject.hash(into:) is not overridable; + // one should override NSObject.hash instead. if (isNSObjectHashValue(baseDecl)) { diags.diagnose(decl, diag::override_nsobject_hashvalue_error) .fixItReplace(SourceRange(decl->getNameLoc()), "hash"); @@ -1814,9 +1814,13 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) { if ((isNSObjectHashValue(base) || isNSObjectHashMethod(base)) && !base->hasOpenAccess(override->getDeclContext())) return true; + bool baseCanBeObjC = canBeRepresentedInObjC(base); + auto nominal = base->getDeclContext()->getSelfNominalTypeDecl(); diags.diagnose(override, diag::override_decl_extension, baseCanBeObjC, - !isa(base->getDeclContext())); + !isa(base->getDeclContext()), + override->getDescriptiveKind(), override->getName(), + nominal->getName()); // If the base and the override come from the same module, try to fix // the base declaration. Otherwise we can wind up diagnosing into e.g. the // SDK overlay modules. diff --git a/test/ClangImporter/objc-cross-module-override.swift b/test/ClangImporter/objc-cross-module-override.swift index c046dbe5de58b..bbf6af86352fb 100644 --- a/test/ClangImporter/objc-cross-module-override.swift +++ b/test/ClangImporter/objc-cross-module-override.swift @@ -11,7 +11,7 @@ import ImageInitializers final class MyImage : Image { - // CHECK: overriding non-@objc declarations from extensions is not supported + // CHECK: non-@objc initializer 'init(imageLiteralResourceName:)' is declared in extension of 'Image' and cannot be overriden // Make sure we aren't emitting a fixit into the extant module... // CHECK-NOT: add '@objc' to make this declaration overridable // CHECK: ImageInitializers.Image:{{.*}}: note: overridden declaration is here diff --git a/test/attr/attr_objc_override.swift b/test/attr/attr_objc_override.swift index b3cd53b1b0a73..9d7772f780fa5 100644 --- a/test/attr/attr_objc_override.swift +++ b/test/attr/attr_objc_override.swift @@ -29,11 +29,11 @@ class B : A { get { return self } // expected-error{{subscript getter with Objective-C selector 'objectForKeyedSubscript:' conflicts with subscript getter from superclass 'A'}} } - override func foo() { } // expected-error{{overriding non-@objc declarations from extensions is not supported}} + override func foo() { } // expected-error{{non-@objc instance method 'foo()' is declared in extension of 'A' and cannot be overriden}} - override func wibble(_: SwiftStruct) { } // expected-error{{overriding declarations in extensions is not supported}} + override func wibble(_: SwiftStruct) { } // expected-error{{instance method 'wibble' is declared in extension of 'A' and cannot be overriden}} } extension B { - override func bar() { } // expected-error{{overriding non-@objc declarations from extensions is not supported}} + override func bar() { } // expected-error{{non-@objc instance method 'bar()' declared in 'A' cannot be overriden from extension}} } diff --git a/test/decl/func/static_func.swift b/test/decl/func/static_func.swift index 2959cf0493b03..8886a0190efd0 100644 --- a/test/decl/func/static_func.swift +++ b/test/decl/func/static_func.swift @@ -83,8 +83,8 @@ class C_Derived : C { override class func f2() {} class override func f3() {} - override class func ef2() {} // expected-error {{not supported}} - class override func ef3() {} // expected-error {{not supported}} + override class func ef2() {} // expected-error {{cannot be overriden}} + class override func ef3() {} // expected-error {{cannot be overriden}} override static func f7() {} // expected-error {{static method overrides a 'final' class method}} } @@ -98,11 +98,11 @@ class C_Derived3 : C { } extension C_Derived { - override class func f4() {} // expected-error {{not supported}} - class override func f5() {} // expected-error {{not supported}} + override class func f4() {} // expected-error {{cannot be overriden}} + class override func f5() {} // expected-error {{cannot be overriden}} - override class func ef4() {} // expected-error {{not supported}} - class override func ef5() {} // expected-error {{not supported}} + override class func ef4() {} // expected-error {{cannot be overriden}} + class override func ef5() {} // expected-error {{cannot be overriden}} } protocol P { // expected-note{{extended type declared here}} diff --git a/test/decl/inherit/override.swift b/test/decl/inherit/override.swift index 141a60ca864c2..c93240a27dbd5 100644 --- a/test/decl/inherit/override.swift +++ b/test/decl/inherit/override.swift @@ -46,8 +46,8 @@ extension B { override func f3D() { } override func f4D() -> ObjCClassB { } - func f5() { } // expected-error{{overridi}} - func f6() -> A { } // expected-error{{overriding declarations in extensions is not supported}} + func f5() { } // expected-error{{overri}} + func f6() -> A { } // expected-error{{instance method 'f6()' is declared in extension of 'A' and cannot be overriden}} @objc override func f7() { } @objc override func f8() -> ObjCClassA { } diff --git a/test/decl/init/basic_init.swift b/test/decl/init/basic_init.swift index 0385214a39377..f954d1e432363 100644 --- a/test/decl/init/basic_init.swift +++ b/test/decl/init/basic_init.swift @@ -25,7 +25,7 @@ class InitSubclass: InitClass {} // expected-note@-1{{'init(baz:)' previously overridden here}} // expected-note@-2{{'init(bar:)' previously overridden here}} extension InitSubclass { - convenience init(arg: Bool) {} // expected-error{{overriding non-@objc declarations from extensions is not supported}} + convenience init(arg: Bool) {} // expected-error{{non-@objc initializer 'init(arg:)' declared in 'InitClass' cannot be overriden from extension}} convenience override init(baz: Int) {} // expected-error@-1 {{'init(baz:)' has already been overridden}} // expected-error@-2 {{cannot override a non-dynamic class declaration from an extension}}