Skip to content

Commit c9b3164

Browse files
committed
Correct the DeclContext Used For 'super.init()' Synthesis
When a subclass inherits from a superclass that declares a no-args desginated initializer and no other visible inits, the subclass may elide calls to 'super.init()'. The way this was enforced was by looking into the superclass *from the subclass' init*, not from the subclass. This ensured that not only would we get results for initializers, we'd get results for initializers that were actually _callable_ from the subclass. The changes in swiftlang#33515 accidentally swapped the decl context here, which caused this lookup to start returning additional results. In that case, we consider it ambiguous as to which designated initializer we should synthesize, and so we bail. The net result is DI errors where there previously were none. Let's put this back in order. rdar://67560590, rdar://67686660, rdar://67690116, SR-13427
1 parent 5c4c4dc commit c9b3164

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,9 +1764,9 @@ static bool checkSuperInit(ConstructorDecl *fromCtor,
17641764
NLOptions subOptions = NL_QualifiedDefault | NL_KnownNonCascadingDependency;
17651765

17661766
SmallVector<ValueDecl *, 4> lookupResults;
1767-
dc->lookupQualified(superclassDecl,
1768-
DeclNameRef::createConstructor(),
1769-
subOptions, lookupResults);
1767+
fromCtor->lookupQualified(superclassDecl,
1768+
DeclNameRef::createConstructor(),
1769+
subOptions, lookupResults);
17701770

17711771
for (auto decl : lookupResults) {
17721772
auto superclassCtor = dyn_cast<ConstructorDecl>(decl);

test/SILOptimizer/Inputs/definite_init_cross_module/OtherModule.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,14 @@ public struct Empty {
4141
public struct GenericEmpty<T> {
4242
public init() {}
4343
}
44+
45+
open class VisibleNoArgsDesignatedInit {
46+
var x: Float
47+
public init() { x = 0.0 }
48+
49+
// Add some designated inits the subclass cannot see.
50+
private init(x: Float) { self.x = x }
51+
fileprivate init(y: Float) { self.x = y }
52+
internal init(z: Float) { self.x = z }
53+
}
54+

test/SILOptimizer/definite_init_cross_module.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,27 @@ extension GenericEmpty {
254254
init(xx: Double) {
255255
} // expected-error {{'self.init' isn't called on all paths before returning from initializer}}
256256
}
257+
258+
class AcceptsVisibleNoArgsDesignatedInit: VisibleNoArgsDesignatedInit {
259+
var y: Float
260+
init(y: Float) {
261+
self.y = y
262+
// no error
263+
}
264+
}
265+
266+
open class InModuleVisibleNoArgsDesignatedInit {
267+
var x: Float
268+
public init() { x = 0.0 }
269+
270+
// Add a designated init the subclass cannot see.
271+
private init(x: Float) { self.x = x }
272+
}
273+
274+
class AcceptsInModuleVisibleNoArgsDesignatedInit: InModuleVisibleNoArgsDesignatedInit {
275+
var y: Float
276+
init(y: Float) {
277+
self.y = y
278+
// no error
279+
}
280+
}

0 commit comments

Comments
 (0)