Skip to content

Commit ce2c2ca

Browse files
committed
Return early from addImplicitInheritedConstructorsToClass
Now that it's only dealing with adding inherited constructors, bail out early if we don't have a superclass. The diff for this is best viewed without whitespace changes.
1 parent 821065f commit ce2c2ca

File tree

1 file changed

+94
-89
lines changed

1 file changed

+94
-89
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 94 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,8 @@ static bool hasUserDefinedDesignatedInit(Evaluator &eval,
864864
false);
865865
}
866866

867+
/// For a class with a superclass, automatically define overrides
868+
/// for all of the superclass's designated initializers.
867869
static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
868870
// Bail out if we're validating one of our constructors already;
869871
// we'll revisit the issue later.
@@ -911,123 +913,126 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
911913
}
912914
}
913915

916+
// We can only inherit initializers if we have a superclass.
917+
// FIXME: We should be bailing out earlier in the function, but unfortunately
918+
// that currently regresses associated type inference for cases like
919+
// compiler_crashers_2_fixed/0124-sr5825.swift due to the fact that we no
920+
// longer eagerly compute the interface types of the other constructors.
921+
auto superclassTy = decl->getSuperclass();
922+
if (!superclassTy)
923+
return;
924+
914925
// Check whether the user has defined a designated initializer for this class,
915926
// and whether all of its stored properties have initial values.
916927
bool foundDesignatedInit = hasUserDefinedDesignatedInit(ctx.evaluator, decl);
917928
bool defaultInitable =
918929
areAllStoredPropertiesDefaultInitializable(ctx.evaluator, decl);
919930

920-
// For a class with a superclass, automatically define overrides
921-
// for all of the superclass's designated initializers.
922-
if (Type superclassTy = decl->getSuperclass()) {
923-
bool canInheritInitializers = defaultInitable && !foundDesignatedInit;
931+
// We can't define these overrides if we have any uninitialized
932+
// stored properties.
933+
if (!defaultInitable && !foundDesignatedInit && !decl->hasClangNode())
934+
return;
924935

925-
// We can't define these overrides if we have any uninitialized
926-
// stored properties.
927-
if (!defaultInitable && !foundDesignatedInit && !decl->hasClangNode())
928-
return;
936+
auto *superclassDecl = superclassTy->getClassOrBoundGenericClass();
937+
assert(superclassDecl && "Superclass of class is not a class?");
938+
if (!superclassDecl->addedImplicitInitializers())
939+
ctx.getLazyResolver()->resolveImplicitConstructors(superclassDecl);
929940

930-
auto *superclassDecl = superclassTy->getClassOrBoundGenericClass();
931-
assert(superclassDecl && "Superclass of class is not a class?");
932-
if (!superclassDecl->addedImplicitInitializers())
933-
ctx.getLazyResolver()->resolveImplicitConstructors(superclassDecl);
941+
auto ctors = TypeChecker::lookupConstructors(
942+
decl, superclassTy,
943+
NameLookupFlags::IgnoreAccessControl);
934944

935-
auto ctors = TypeChecker::lookupConstructors(
936-
decl, superclassTy,
937-
NameLookupFlags::IgnoreAccessControl);
945+
bool canInheritInitializers = defaultInitable && !foundDesignatedInit;
938946

939-
bool canInheritConvenienceInitalizers =
940-
!superclassDecl->hasMissingDesignatedInitializers();
941-
SmallVector<ConstructorDecl *, 4> requiredConvenienceInitializers;
942-
for (auto memberResult : ctors) {
943-
auto member = memberResult.getValueDecl();
947+
bool canInheritConvenienceInitalizers =
948+
!superclassDecl->hasMissingDesignatedInitializers();
949+
SmallVector<ConstructorDecl *, 4> requiredConvenienceInitializers;
950+
for (auto memberResult : ctors) {
951+
auto member = memberResult.getValueDecl();
944952

945-
// Skip unavailable superclass initializers.
946-
if (AvailableAttr::isUnavailable(member))
947-
continue;
953+
// Skip unavailable superclass initializers.
954+
if (AvailableAttr::isUnavailable(member))
955+
continue;
948956

949-
// Skip invalid superclass initializers.
950-
auto superclassCtor = dyn_cast<ConstructorDecl>(member);
951-
if (superclassCtor->isInvalid())
952-
continue;
957+
// Skip invalid superclass initializers.
958+
auto superclassCtor = dyn_cast<ConstructorDecl>(member);
959+
if (superclassCtor->isInvalid())
960+
continue;
953961

954-
// If we have an override for this constructor, it's okay.
955-
if (overriddenInits.count(superclassCtor) > 0)
956-
continue;
962+
// If we have an override for this constructor, it's okay.
963+
if (overriddenInits.count(superclassCtor) > 0)
964+
continue;
957965

958-
// We only care about required or designated initializers.
959-
if (!superclassCtor->isDesignatedInit()) {
960-
if (superclassCtor->isRequired()) {
961-
assert(superclassCtor->isInheritable() &&
962-
"factory initializers cannot be 'required'");
963-
requiredConvenienceInitializers.push_back(superclassCtor);
964-
}
965-
continue;
966+
// We only care about required or designated initializers.
967+
if (!superclassCtor->isDesignatedInit()) {
968+
if (superclassCtor->isRequired()) {
969+
assert(superclassCtor->isInheritable() &&
970+
"factory initializers cannot be 'required'");
971+
requiredConvenienceInitializers.push_back(superclassCtor);
966972
}
973+
continue;
974+
}
967975

968-
// Otherwise, it may no longer be safe to inherit convenience
969-
// initializers.
970-
canInheritConvenienceInitalizers &= canInheritInitializers;
976+
// Otherwise, it may no longer be safe to inherit convenience
977+
// initializers.
978+
canInheritConvenienceInitalizers &= canInheritInitializers;
971979

972-
// Everything after this is only relevant for Swift classes being defined.
973-
if (decl->hasClangNode())
974-
continue;
980+
// Everything after this is only relevant for Swift classes being defined.
981+
if (decl->hasClangNode())
982+
continue;
975983

976-
// If the superclass initializer is not accessible from the derived
977-
// class, don't synthesize an override, since we cannot reference the
978-
// superclass initializer's method descriptor at all.
979-
//
980-
// FIXME: This should be checked earlier as part of calculating
981-
// canInheritInitializers.
982-
if (!superclassCtor->isAccessibleFrom(decl))
983-
continue;
984+
// If the superclass initializer is not accessible from the derived
985+
// class, don't synthesize an override, since we cannot reference the
986+
// superclass initializer's method descriptor at all.
987+
//
988+
// FIXME: This should be checked earlier as part of calculating
989+
// canInheritInitializers.
990+
if (!superclassCtor->isAccessibleFrom(decl))
991+
continue;
984992

985-
// Diagnose a missing override of a required initializer.
986-
if (superclassCtor->isRequired() && !canInheritInitializers) {
987-
diagnoseMissingRequiredInitializer(decl, superclassCtor, ctx);
988-
continue;
989-
}
993+
// Diagnose a missing override of a required initializer.
994+
if (superclassCtor->isRequired() && !canInheritInitializers) {
995+
diagnoseMissingRequiredInitializer(decl, superclassCtor, ctx);
996+
continue;
997+
}
990998

991-
// A designated or required initializer has not been overridden.
999+
// A designated or required initializer has not been overridden.
9921000

993-
bool alreadyDeclared = false;
994-
for (const auto &ctorAndType : declaredInitializers) {
995-
auto *ctor = ctorAndType.first;
996-
auto type = ctorAndType.second;
997-
auto parentType = getMemberTypeForComparison(
998-
ctx, superclassCtor, ctor);
1001+
bool alreadyDeclared = false;
1002+
for (const auto &ctorAndType : declaredInitializers) {
1003+
auto *ctor = ctorAndType.first;
1004+
auto type = ctorAndType.second;
1005+
auto parentType = getMemberTypeForComparison(
1006+
ctx, superclassCtor, ctor);
9991007

1000-
if (isOverrideBasedOnType(ctor, type, superclassCtor, parentType)) {
1001-
alreadyDeclared = true;
1002-
break;
1003-
}
1008+
if (isOverrideBasedOnType(ctor, type, superclassCtor, parentType)) {
1009+
alreadyDeclared = true;
1010+
break;
10041011
}
1012+
}
10051013

1006-
// If we have already introduced an initializer with this parameter type,
1007-
// don't add one now.
1008-
if (alreadyDeclared)
1009-
continue;
1010-
1011-
// If we're inheriting initializers, create an override delegating
1012-
// to 'super.init'. Otherwise, create a stub which traps at runtime.
1013-
auto kind = canInheritInitializers
1014-
? DesignatedInitKind::Chaining
1015-
: DesignatedInitKind::Stub;
1014+
// If we have already introduced an initializer with this parameter type,
1015+
// don't add one now.
1016+
if (alreadyDeclared)
1017+
continue;
10161018

1017-
if (auto ctor = createDesignatedInitOverride(
1018-
decl, superclassCtor, kind, ctx)) {
1019-
decl->addMember(ctor);
1020-
}
1021-
}
1019+
// If we're inheriting initializers, create an override delegating
1020+
// to 'super.init'. Otherwise, create a stub which traps at runtime.
1021+
auto kind = canInheritInitializers
1022+
? DesignatedInitKind::Chaining
1023+
: DesignatedInitKind::Stub;
10221024

1023-
if (canInheritConvenienceInitalizers) {
1024-
decl->setInheritsSuperclassInitializers();
1025-
} else {
1026-
for (ConstructorDecl *requiredCtor : requiredConvenienceInitializers)
1027-
diagnoseMissingRequiredInitializer(decl, requiredCtor, ctx);
1025+
if (auto ctor = createDesignatedInitOverride(
1026+
decl, superclassCtor, kind, ctx)) {
1027+
decl->addMember(ctor);
10281028
}
1029+
}
10291030

1030-
return;
1031+
if (canInheritConvenienceInitalizers) {
1032+
decl->setInheritsSuperclassInitializers();
1033+
} else {
1034+
for (ConstructorDecl *requiredCtor : requiredConvenienceInitializers)
1035+
diagnoseMissingRequiredInitializer(decl, requiredCtor, ctx);
10311036
}
10321037
}
10331038

0 commit comments

Comments
 (0)