Skip to content

Commit 91951c8

Browse files
committed
[Type checker] Delete unnecessary, bogus optimization for initializers.
An early optimization in constraint generation attempted to simplify type construction (e.g., X(...)) when the type in question has no failable initializers. However, the optimization didn't appropriately clear out the cached bit when new information became available (e.g., new conformances, new extensions), and didn't seem to help anything performance-wise (type-checking times didn't increase at all when I turned this off). Fixes rdar://problem/30588177.
1 parent 2986e81 commit 91951c8

File tree

3 files changed

+14
-92
lines changed

3 files changed

+14
-92
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -445,17 +445,10 @@ class alignas(1 << DeclAlignInBits) Decl {
445445
/// to this declaration.
446446
unsigned AddedImplicitInitializers : 1;
447447

448-
/// \brief Whether or not this declaration has a failable initializer member,
449-
/// and whether or not we've actually searched for one.
450-
unsigned HasFailableInits : 1;
451-
452-
/// Whether we have already searched for failable initializers.
453-
unsigned SearchedForFailableInits : 1;
454-
455448
/// Whether there is are lazily-loaded conformances for this nominal type.
456449
unsigned HasLazyConformances : 1;
457450
};
458-
enum { NumNominalTypeDeclBits = NumGenericTypeDeclBits + 5 };
451+
enum { NumNominalTypeDeclBits = NumGenericTypeDeclBits + 3 };
459452
static_assert(NumNominalTypeDeclBits <= 32, "fits in an unsigned");
460453

461454
class ProtocolDeclBitfields {
@@ -2744,8 +2737,6 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
27442737
NominalTypeDeclBits.HasDelayedMembers = false;
27452738
NominalTypeDeclBits.AddedImplicitInitializers = false;
27462739
ExtensionGeneration = 0;
2747-
NominalTypeDeclBits.SearchedForFailableInits = false;
2748-
NominalTypeDeclBits.HasFailableInits = false;
27492740
NominalTypeDeclBits.HasLazyConformances = false;
27502741
}
27512742

@@ -2795,19 +2786,6 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
27952786
NominalTypeDeclBits.AddedImplicitInitializers = true;
27962787
}
27972788

2798-
bool getHasFailableInits() const {
2799-
return NominalTypeDeclBits.HasFailableInits;
2800-
}
2801-
void setHasFailableInits(bool failable = true) {
2802-
NominalTypeDeclBits.HasFailableInits = failable;
2803-
}
2804-
void setSearchedForFailableInits(bool searched = true) {
2805-
NominalTypeDeclBits.SearchedForFailableInits = searched;
2806-
}
2807-
bool getSearchedForFailableInits() const {
2808-
return NominalTypeDeclBits.SearchedForFailableInits;
2809-
}
2810-
28112789
/// Compute the type of this nominal type.
28122790
void computeType();
28132791

lib/Sema/CSGen.cpp

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -678,56 +678,6 @@ namespace {
678678
}
679679
}
680680

681-
/// Determine whether or not a given NominalTypeDecl has a failable
682-
/// initializer member.
683-
bool hasFailableInits(NominalTypeDecl *NTD,
684-
ConstraintSystem *CS) {
685-
686-
// TODO: Note that we search manually, rather than invoking lookupMember
687-
// on the ConstraintSystem object. Because this is a hot path, this keeps
688-
// the overhead of the check low, and is twice as fast.
689-
if (!NTD->getSearchedForFailableInits()) {
690-
// Set flag before recursing to catch circularity.
691-
NTD->setSearchedForFailableInits();
692-
693-
for (auto member : NTD->getMembers()) {
694-
if (auto CD = dyn_cast<ConstructorDecl>(member)) {
695-
if (CD->getFailability()) {
696-
NTD->setHasFailableInits();
697-
break;
698-
}
699-
}
700-
}
701-
702-
if (!NTD->getHasFailableInits()) {
703-
for (auto extension : NTD->getExtensions()) {
704-
for (auto member : extension->getMembers()) {
705-
if (auto CD = dyn_cast<ConstructorDecl>(member)) {
706-
if (CD->getFailability()) {
707-
NTD->setHasFailableInits();
708-
break;
709-
}
710-
}
711-
}
712-
}
713-
714-
if (!NTD->getHasFailableInits()) {
715-
for (auto parentTyLoc : NTD->getInherited()) {
716-
if (auto nominalType =
717-
parentTyLoc.getType()->getAs<NominalType>()) {
718-
if (hasFailableInits(nominalType->getDecl(), CS)) {
719-
NTD->setHasFailableInits();
720-
break;
721-
}
722-
}
723-
}
724-
}
725-
}
726-
}
727-
728-
return NTD->getHasFailableInits();
729-
}
730-
731681
size_t getOperandCount(Type t) {
732682
size_t nOperands = 0;
733683

@@ -2385,25 +2335,6 @@ namespace {
23852335
if (auto fnType = CS.getType(fnExpr)->getAs<AnyFunctionType>()) {
23862336
outputTy = fnType->getResult();
23872337
}
2388-
} else if (auto TE = dyn_cast<TypeExpr>(fnExpr)) {
2389-
outputTy = CS.getInstanceType(TE);
2390-
NominalTypeDecl *NTD = nullptr;
2391-
2392-
if (auto nominalType = outputTy->getAs<NominalType>()) {
2393-
NTD = nominalType->getDecl();
2394-
} else if (auto bgT = outputTy->getAs<BoundGenericType>()) {
2395-
NTD = bgT->getDecl();
2396-
}
2397-
2398-
if (NTD) {
2399-
if (!(isa<ClassDecl>(NTD) || isa<StructDecl>(NTD)) ||
2400-
hasFailableInits(NTD, &CS)) {
2401-
outputTy = Type();
2402-
}
2403-
} else {
2404-
outputTy = Type();
2405-
}
2406-
24072338
} else if (auto OSR = dyn_cast<OverloadSetRefExpr>(fnExpr)) {
24082339
if (auto FD = dyn_cast<FuncDecl>(OSR->getDecls()[0])) {
24092340

test/Constraints/construction.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,16 @@ Int(i32 - 2 + 1) // expected-warning{{unused}}
139139
let xx: UInt64 = 100
140140
let yy = ((xx + 10) - 5) / 5
141141
let zy = (xx + (10 - 5)) / 5
142+
143+
// rdar://problem/30588177
144+
struct S3 {
145+
init() { }
146+
}
147+
148+
let s3a = S3()
149+
150+
extension S3 {
151+
init?(maybe: S3) { return nil }
152+
}
153+
154+
let s3b = S3(maybe: s3a)

0 commit comments

Comments
 (0)