-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Warn if a non dynamic class declaration is overridden in an extension #6346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
f7a7ee9
7dcab12
7d8d275
2e1264f
4495fde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1703,6 +1703,12 @@ ERROR(override_ownership_mismatch,none, | |
| "cannot override %select{strong|weak|unowned|unowned(unsafe)}0 property " | ||
| "with %select{strong|weak|unowned|unowned(unsafe)}1 property", | ||
| (/*Ownership*/unsigned, /*Ownership*/unsigned)) | ||
| ERROR(override_class_declaration_in_extension,none, | ||
| "cannot override a non-dynamic class declaration from an extension.", | ||
| ()) | ||
| WARNING(override_class_declaration_in_extension_warning,none, | ||
| "cannot override a non-dynamic class declaration from an extension.", | ||
|
||
| ()) | ||
| ERROR(override_throws,none, | ||
| "cannot override non-throwing %select{method|initializer}0 with " | ||
| "throwing %select{method|initializer}0", (bool)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6072,6 +6072,23 @@ class DeclChecker : public DeclVisitor<DeclChecker> { | |
| new (TC.Context) OverrideAttr(SourceLoc())); | ||
| } | ||
|
|
||
| // If the overridden method is declared in a Swift Class Declaration, | ||
| // dispatch will use table dispatch. If the override is in an extension | ||
| // warn, since it is not added to the class vtable. | ||
| // | ||
| // FIXME: Only warn if the extension is in another module, and if | ||
| // it is in the same module, update the vtable. | ||
| if (auto *baseDecl = dyn_cast<ClassDecl>(base->getDeclContext())) { | ||
| if (baseDecl->hasKnownSwiftImplementation() && | ||
| !base->isDynamic() && | ||
| override->getDeclContext()->isExtensionContext()) { | ||
|
||
| // For compatibility, only generate a warning in Swift 3 | ||
| TC.diagnose(override, (TC.Context.isSwiftVersion3() | ||
| ? diag::override_class_declaration_in_extension_warning | ||
| : diag::override_class_declaration_in_extension)); | ||
| TC.diagnose(base, diag::overridden_here); | ||
| } | ||
| } | ||
| // If the overriding declaration is 'throws' but the base is not, | ||
| // complain. | ||
| if (auto overrideFn = dyn_cast<AbstractFunctionDecl>(override)) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 3 | ||
|
|
||
| class A { | ||
| @objc func objcVirtualFunction() { } // expected-note{{overridden declaration is here}} | ||
| } | ||
|
|
||
| class B : A { } | ||
|
|
||
| extension B { | ||
| override func objcVirtualFunction() { } // expected-warning{{cannot override a non-dynamic class declaration from an extension}} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: remove the .