mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Sema] Fix throwing super.init() diagnostics
The compiler now diagnoses appropriately the case where a super.init() is marked as throwing while a subclass' initializer isn't marked as throwing nor explicitly calls the super.init().
This commit is contained in:
@@ -4807,6 +4807,12 @@ ERROR(return_init_non_nil,none,
|
||||
"'nil' is the only return value permitted in an initializer",
|
||||
())
|
||||
|
||||
ERROR(implicit_throws_super_init,none,
|
||||
"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'",
|
||||
())
|
||||
|
||||
ERROR(implicit_async_super_init,none,
|
||||
"missing call to superclass's initializer; "
|
||||
"'super.init' is 'async' and requires an explicit call",
|
||||
|
||||
@@ -2236,7 +2236,17 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
|
||||
fromCtor->diagnose(diag::availability_unavailable_implicit_init,
|
||||
ctor, superclassDecl->getName());
|
||||
}
|
||||
|
||||
|
||||
// Only allowed to synthesize a throwing super.init() call if the init being
|
||||
// checked is also throwing.
|
||||
if (ctor->hasThrows()) {
|
||||
// Diagnose on nonthrowing or rethrowing initializer.
|
||||
if (!fromCtor->hasThrows() || fromCtor->hasPolymorphicEffect(EffectKind::Throws)) {
|
||||
fromCtor->diagnose(diag::implicit_throws_super_init);
|
||||
return true; // considered an error
|
||||
}
|
||||
}
|
||||
|
||||
// Not allowed to implicitly generate a super.init() call if the init
|
||||
// is async; that would hide the 'await' from the programmer.
|
||||
if (ctor->hasAsync()) {
|
||||
|
||||
24
test/Sema/throwing_super_init.swift
Normal file
24
test/Sema/throwing_super_init.swift
Normal file
@@ -0,0 +1,24 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
class ThrowingInitSuperclass {
|
||||
init() throws { }
|
||||
}
|
||||
|
||||
// Implicitly calling the super.init IS possible here because the initializer
|
||||
// is a throwing initializer.
|
||||
class ThrowingInitClass: ThrowingInitSuperclass {
|
||||
init(simpleArgument: Int) throws { }
|
||||
}
|
||||
|
||||
// Implicitly calling the super.init IS NOT possible here because the
|
||||
// initializer is not a throwing initializer.
|
||||
class NonThrowingInitClass: ThrowingInitSuperclass {
|
||||
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'}}
|
||||
}
|
||||
|
||||
// Implicitly calling the super.init IS NOT possible here because the
|
||||
// initializer is a rethrowing initializer, which means it can only
|
||||
// rethrow errors from its parameters.
|
||||
class RethrowingInitClass: ThrowingInitSuperclass {
|
||||
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'}}
|
||||
}
|
||||
Reference in New Issue
Block a user