Skip to content

Commit 0cc72fb

Browse files
authored
Merge pull request swiftlang#68889 from Visckmart/throwing_super_init_diagnostics
Fixes throwing super.init() diagnostics
2 parents 0ea2eb1 + b932739 commit 0cc72fb

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4838,6 +4838,12 @@ ERROR(return_init_non_nil,none,
48384838
"'nil' is the only return value permitted in an initializer",
48394839
())
48404840

4841+
ERROR(implicit_throws_super_init,none,
4842+
"missing call to superclass's initializer; "
4843+
"'super.init' is a throwing initializer and requires either an explicit "
4844+
"call or that this initializer is also marked as 'throws'",
4845+
())
4846+
48414847
ERROR(implicit_async_super_init,none,
48424848
"missing call to superclass's initializer; "
48434849
"'super.init' is 'async' and requires an explicit call",

lib/Sema/TypeCheckStmt.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2230,7 +2230,17 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
22302230
fromCtor->diagnose(diag::availability_unavailable_implicit_init,
22312231
ctor, superclassDecl->getName());
22322232
}
2233-
2233+
2234+
// Only allowed to synthesize a throwing super.init() call if the init being
2235+
// checked is also throwing.
2236+
if (ctor->hasThrows()) {
2237+
// Diagnose on nonthrowing or rethrowing initializer.
2238+
if (!fromCtor->hasThrows() || fromCtor->hasPolymorphicEffect(EffectKind::Throws)) {
2239+
fromCtor->diagnose(diag::implicit_throws_super_init);
2240+
return true; // considered an error
2241+
}
2242+
}
2243+
22342244
// Not allowed to implicitly generate a super.init() call if the init
22352245
// is async; that would hide the 'await' from the programmer.
22362246
if (ctor->hasAsync()) {

test/Sema/throwing_super_init.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
class ThrowingInitSuperclass {
4+
init() throws { }
5+
}
6+
7+
// Implicitly calling the super.init IS possible here because the initializer
8+
// is a throwing initializer.
9+
class ThrowingInitClass: ThrowingInitSuperclass {
10+
init(simpleArgument: Int) throws { }
11+
}
12+
13+
// Implicitly calling the super.init IS NOT possible here because the
14+
// initializer is not a throwing initializer.
15+
class NonThrowingInitClass: ThrowingInitSuperclass {
16+
init(simpleArgument: Int) { } // expected-error {{missing call to superclass's initializer; 'super.init' is a throwing initializer and requires either an explicit call or that this initializer is also marked as 'throws'}}
17+
}
18+
19+
// Implicitly calling the super.init IS NOT possible here because the
20+
// initializer is a rethrowing initializer, which means it can only
21+
// rethrow errors from its parameters.
22+
class RethrowingInitClass: ThrowingInitSuperclass {
23+
init(throwingArgument: () throws -> Void) rethrows { } // expected-error {{missing call to superclass's initializer; 'super.init' is a throwing initializer and requires either an explicit call or that this initializer is also marked as 'throws'}}
24+
}

0 commit comments

Comments
 (0)