Skip to content

Commit 78f4b9d

Browse files
committed
Skip redecl errors for inits that conflict with an inherited init
This can only happen when the conflicting init is within an extension. It is the override checker's responsibility to emit a sensible diagnostic here.
1 parent a9fe0a6 commit 78f4b9d

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,8 @@ ERROR(reserved_member_name,none,
668668

669669
ERROR(invalid_redecl,none,"invalid redeclaration of %0", (DeclName))
670670
ERROR(invalid_redecl_init,none,
671-
"invalid redeclaration of %select{synthesized|"
672-
"synthesized memberwise|inherited}1 %0", (DeclName, unsigned))
671+
"invalid redeclaration of synthesized %select{|memberwise }1%0",
672+
(DeclName, bool))
673673
WARNING(invalid_redecl_swift5_warning,none,
674674
"redeclaration of %0 is deprecated and will be an error in Swift 5",
675675
(DeclName))

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -917,16 +917,14 @@ static void checkRedeclaration(TypeChecker &tc, ValueDecl *current) {
917917
const auto *otherInit = dyn_cast<ConstructorDecl>(other);
918918
// Provide a better description for implicit initializers.
919919
if (otherInit && otherInit->isImplicit()) {
920-
enum {
921-
Synthetic, SyntheticMemberwise, Inherited
922-
} kind = Synthetic;
923-
if (otherInit->isMemberwiseInitializer())
924-
kind = SyntheticMemberwise;
925-
else if (otherInit->getOverriddenDecl())
926-
kind = Inherited;
927-
928-
tc.diagnose(current, diag::invalid_redecl_init,
929-
current->getFullName(), kind);
920+
// Skip conflicts with inherited initializers, which only happen
921+
// when the current declaration is within an extension. The override
922+
// checker should have already taken care of emitting a more
923+
// productive diagnostic.
924+
if (!other->getOverriddenDecl())
925+
tc.diagnose(current, diag::invalid_redecl_init,
926+
current->getFullName(),
927+
otherInit->isMemberwiseInitializer());
930928
} else {
931929
tc.diagnose(current, diag::invalid_redecl, current->getFullName());
932930
tc.diagnose(other, diag::invalid_redecl_prev, other->getFullName());

test/decl/init/basic_init.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ extension Foo {
1919

2020
class InitClass {
2121
init(arg: Bool) {} // expected-note{{add '@objc' to make this declaration overridable}}
22+
@objc init(baz: Int) {} // expected-note{{overridden declaration is here}}
23+
@objc dynamic init(bar: Int) {}
2224
}
2325
class InitSubclass: InitClass {}
26+
// expected-note@-1 {{'init(bar:)' previously overridden here}}
27+
// expected-note@-2 {{'init(baz:)' previously overridden here}}
2428
extension InitSubclass {
25-
convenience init(arg: Bool) {}
26-
// expected-error@-1{{invalid redeclaration of inherited 'init(arg:)'}}
27-
// expected-error@-2{{overriding non-@objc declarations from extensions is not supported}}
29+
convenience init(arg: Bool) {} // expected-error{{overriding non-@objc declarations from extensions is not supported}}
30+
convenience override init(baz: Int) {}
31+
// expected-error@-1 {{cannot override a non-dynamic class declaration from an extension}}
32+
// expected-error@-2 {{'init(baz:)' has already been overridden}}
33+
convenience override init(bar: Int) {} // expected-error{{'init(bar:)' has already been overridden}}
2834
}
2935

3036
struct InitStruct {

0 commit comments

Comments
 (0)