Skip to content

Commit 4645d00

Browse files
committed
Don't inherit a designated initializer if there is already a convenience initializer with the same signature <rdar://problem/17785840>.
Swift SVN r21075
1 parent 8e093f1 commit 4645d00

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6686,18 +6686,38 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl,
66866686
if (decl->addedImplicitInitializers())
66876687
return;
66886688

6689+
// Local function that produces the canonical parameter type of the given
6690+
// initializer.
6691+
// FIXME: Doesn't work properly for generics.
6692+
auto getInitializerParamType = [](ConstructorDecl *ctor) -> CanType {
6693+
auto interfaceTy = ctor->getInterfaceType();
6694+
6695+
// Skip the 'self' parameter.
6696+
auto uncurriedInitTy = interfaceTy->castTo<AnyFunctionType>()->getResult();
6697+
6698+
// Grab the parameter type;
6699+
auto paramTy = uncurriedInitTy->castTo<AnyFunctionType>()->getInput();
6700+
6701+
return paramTy->getCanonicalType();
6702+
};
6703+
66896704
// Check whether there is a user-declared constructor or an instance
66906705
// variable.
66916706
bool FoundInstanceVar = false;
66926707
bool FoundUninitializedVars = false;
66936708
bool FoundDesignatedInit = false;
66946709
decl->setAddedImplicitInitializers();
6710+
SmallPtrSet<CanType, 4> initializerParamTypes;
66956711
for (auto member : decl->getMembers()) {
66966712
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
6713+
validateDecl(ctor);
6714+
66976715
if (ctor->isDesignatedInit()) {
66986716
FoundDesignatedInit = true;
6699-
break;
67006717
}
6718+
6719+
if (!ctor->isInvalid())
6720+
initializerParamTypes.insert(getInitializerParamType(ctor));
67016721
continue;
67026722
}
67036723

@@ -6761,6 +6781,12 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl,
67616781
|| superclassCtor->isInvalid())
67626782
continue;
67636783

6784+
// If we have already introduced an initializer with this parameter type,
6785+
// don't add one now.
6786+
if (!initializerParamTypes.insert(
6787+
getInitializerParamType(superclassCtor)))
6788+
continue;
6789+
67646790
// We have a designated initializer. Create an override of it.
67656791
if (auto ctor = createDesignatedInitOverride(
67666792
*this, classDecl, superclassCtor,

test/decl/func/complete_object_init.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,18 @@ extension Extensible {
141141
self.init()
142142
}
143143
}
144+
145+
// <rdar://problem/17785840>
146+
protocol Protocol {
147+
init(string: String)
148+
}
149+
150+
class Parent: Protocol {
151+
required init(string: String) {}
152+
}
153+
154+
class Child: Parent {
155+
convenience required init(string: String) {
156+
self.init(string: "")
157+
}
158+
}

0 commit comments

Comments
 (0)