Skip to content

Commit b11b67c

Browse files
committed
[DiagnosticsQoI] Inform the User When Unavailable Inits Are Called
When a no-args init is the only designated init in the superclass, Swift will automatically call it from the subclass. Unfortunately, if this initializer is unavailable, an error is issued that points at the subclass' init but makes no mention of the implicit call. Fix that by providing a note that explains what's going on here.
1 parent eeb0ea2 commit b11b67c

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5291,6 +5291,10 @@ ERROR(availabilty_string_subscript_migration, none,
52915291
"subscripts returning String were obsoleted in Swift 4; explicitly "
52925292
"construct a String from subscripted result", ())
52935293

5294+
NOTE(availability_unavailable_implicit_init, none,
5295+
"call to unavailable %0 %1 from superclass %2 occurs implicitly at the "
5296+
"end of this initializer", (DescriptiveDeclKind, DeclName, DeclName))
5297+
52945298
// Conformance availability checking diagnostics
52955299

52965300
ERROR(conformance_availability_unavailable, none,

lib/Sema/TypeCheckStmt.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
16621662

16631663
for (auto decl : lookupResults) {
16641664
auto superclassCtor = dyn_cast<ConstructorDecl>(decl);
1665-
if (!superclassCtor || !superclassCtor->isDesignatedInit() ||
1665+
if (!superclassCtor || !superclassCtor->isDesignatedInit() ||
16661666
superclassCtor == ctor)
16671667
continue;
16681668

@@ -1673,9 +1673,14 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
16731673

16741674
// Make sure we can reference the designated initializer correctly.
16751675
auto loc = fromCtor->getLoc();
1676-
diagnoseDeclAvailability(
1676+
const bool didDiagnose = diagnoseDeclAvailability(
16771677
ctor, loc, nullptr,
16781678
ExportContext::forFunctionBody(fromCtor, loc));
1679+
if (didDiagnose) {
1680+
fromCtor->diagnose(diag::availability_unavailable_implicit_init,
1681+
ctor->getDescriptiveKind(), ctor->getName(),
1682+
superclassDecl->getName());
1683+
}
16791684
}
16801685

16811686

test/attr/attr_availability.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,3 +1117,14 @@ func testBadRename() {
11171117

11181118
struct AvailableGenericParam<@available(*, deprecated) T> {}
11191119
// expected-error@-1 {{'@available' attribute cannot be applied to this declaration}}
1120+
1121+
class UnavailableNoArgsSuperclassInit {
1122+
@available(*, unavailable)
1123+
init() {} // expected-note {{'init()' has been explicitly marked unavailable here}}
1124+
}
1125+
1126+
class UnavailableNoArgsSubclassInit: UnavailableNoArgsSuperclassInit {
1127+
init(marker: ()) {}
1128+
// expected-error@-1 {{'init()' is unavailable}}
1129+
// expected-note@-2 {{call to unavailable initializer 'init()' from superclass 'UnavailableNoArgsSuperclassInit' occurs implicitly at the end of this initializer}}
1130+
}

test/attr/attr_inlinable.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ public class Derived3 : Base3 {
229229
@inlinable
230230
public init(_: Int) {}
231231
// expected-error@-1 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
232+
// expected-note@-2 {{call to unavailable initializer 'init()' from superclass 'Base3' occurs implicitly at the end of this initializer}}
232233
}
233234

234235
@_fixed_layout
@@ -245,6 +246,7 @@ class Derived4 : Middle4 {
245246
@inlinable
246247
public init(_: Int) {}
247248
// expected-error@-1 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
249+
// expected-note@-2 {{call to unavailable initializer 'init()' from superclass 'Middle4' occurs implicitly at the end of this initializer}}
248250
}
249251

250252

0 commit comments

Comments
 (0)