Skip to content

Commit 035db92

Browse files
authored
Merge pull request #35987 from slavapestov/designated-init-rethrows
Sema: Inherited designated initializers should inherit the 'rethrows' attribute
2 parents 3d4091c + 20d4a3e commit 035db92

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ configureInheritedDesignatedInitAttributes(ClassDecl *classDecl,
557557
ctor->getAttrs().add(clonedAttr);
558558
}
559559

560+
// Inherit the rethrows attribute.
561+
if (superclassCtor->getAttrs().hasAttribute<RethrowsAttr>()) {
562+
auto *clonedAttr = new (ctx) RethrowsAttr(/*implicit=*/true);
563+
ctor->getAttrs().add(clonedAttr);
564+
}
565+
560566
// If the superclass has its own availability, make sure the synthesized
561567
// constructor is only as available as its superclass's constructor.
562568
if (superclassCtor->getAttrs().hasAttribute<AvailableAttr>()) {

test/Sema/rethrows_init.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
enum MyError : Error {
4+
case bad
5+
}
6+
7+
class Base {
8+
init(_ fn: () throws -> ()) rethrows {} // expected-note {{overridden declaration is here}}
9+
10+
convenience init(rethrows: (), fn: () throws -> ()) rethrows {
11+
try self.init(fn)
12+
}
13+
14+
convenience init(throws1: (), fn: () throws -> ()) rethrows {
15+
throw MyError.bad // expected-error {{a function declared 'rethrows' may only throw if its parameter does}}
16+
}
17+
18+
convenience init(throws2: (), fn: () throws -> ()) rethrows {
19+
try self.init { throw MyError.bad } // FIXME
20+
}
21+
22+
convenience init() {
23+
self.init {}
24+
}
25+
}
26+
27+
class DerivedInheritInit : Base {}
28+
29+
_ = DerivedInheritInit {}
30+
_ = try DerivedInheritInit { throw MyError.bad }
31+
32+
_ = DerivedInheritInit(rethrows: ()) {}
33+
_ = try DerivedInheritInit(rethrows: ()) { throw MyError.bad }
34+
35+
class DerivedOverrideInitBad : Base {
36+
override init(_ fn: () throws -> ()) throws {} // expected-error {{override of 'rethrows' initializer should also be 'rethrows'}}
37+
}
38+
39+
class DerivedOverrideInitGood : Base {
40+
override init(_ fn: () throws -> ()) rethrows {}
41+
}
42+
43+
_ = DerivedOverrideInitGood {}
44+
_ = try DerivedOverrideInitGood { throw MyError.bad }
45+
46+
_ = DerivedOverrideInitGood(rethrows: ()) {}
47+
_ = try DerivedOverrideInitGood(rethrows: ()) { throw MyError.bad }
48+
49+
class DerivedWithSuperInitCall : Base {
50+
override init(_ fn: () throws -> ()) rethrows {
51+
try super.init(fn)
52+
}
53+
54+
init(throws1: (), _ fn: () throws -> ()) rethrows {
55+
throw MyError.bad // expected-error {{a function declared 'rethrows' may only throw if its parameter does}}
56+
}
57+
58+
init(throws2: (), _ fn: () throws -> ()) rethrows {
59+
try super.init { throw MyError.bad } // FIXME
60+
}
61+
}

0 commit comments

Comments
 (0)