Pre-Request Cleanup For Implicit Constructors

Push through an easy refactoring to the way we validate and install
implicit constructors.  This patch would be NFC but for a regression
test that now must diagnose.  #26159 changed validation order in such
a way that the code in validation-test-macosx-x86_64/compiler_crashers_2_fixed/0124-sr5825.swift
used to be accepted.  This patch once again changes validation order, so
we now reject this code, restoring the behavior seen on all prior
versions of Swift.

On its face, this test should work.  In order for it to do so, witness
matching has to be smarter about the declarations it asks for their
interface type, or it will risk these circular constructions
accidentally being accepted or rejected on a whim.
This commit is contained in:
Robert Widmann
2019-10-30 16:32:25 -07:00
parent 64401ac92c
commit 0af343469b
4 changed files with 32 additions and 37 deletions

View File

@@ -920,17 +920,6 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
decl->setAddedImplicitInitializers();
auto &ctx = decl->getASTContext();
SmallVector<std::pair<ValueDecl *, Type>, 4> declaredInitializers;
for (auto member : decl->getMembers()) {
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
if (!ctor->isInvalid()) {
auto type = getMemberTypeForComparison(ctx, ctor, nullptr);
declaredInitializers.push_back({ctor, type});
}
}
}
// We can only inherit initializers if we have a superclass.
// FIXME: We should be bailing out earlier in the function, but unfortunately
// that currently regresses associated type inference for cases like
@@ -942,6 +931,7 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
// Check whether the user has defined a designated initializer for this class,
// and whether all of its stored properties have initial values.
auto &ctx = decl->getASTContext();
bool foundDesignatedInit = hasUserDefinedDesignatedInit(ctx.evaluator, decl);
bool defaultInitable =
areAllStoredPropertiesDefaultInitializable(ctx.evaluator, decl);
@@ -985,14 +975,19 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
// A designated or required initializer has not been overridden.
bool alreadyDeclared = false;
for (const auto &ctorAndType : declaredInitializers) {
auto *ctor = ctorAndType.first;
auto type = ctorAndType.second;
auto parentType = getMemberTypeForComparison(ctx, superclassCtor, ctor);
for (auto *member : decl->getMembers()) {
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
// Skip any invalid constructors.
if (ctor->isInvalid())
continue;
if (isOverrideBasedOnType(ctor, type, superclassCtor, parentType)) {
alreadyDeclared = true;
break;
auto type = swift::getMemberTypeForComparison(ctor, nullptr);
auto parentType = swift::getMemberTypeForComparison(superclassCtor, ctor);
if (isOverrideBasedOnType(ctor, type, superclassCtor, parentType)) {
alreadyDeclared = true;
break;
}
}
}