Skip to content

Commit 454afbd

Browse files
authored
Space Engine: check for empty spaces in Space::forConstructor (#17684)
This is the last optimization performed in Space::simplify, so now we can remove that as well. No intended functionality change.
1 parent bacca6f commit 454afbd

File tree

1 file changed

+15
-61
lines changed

1 file changed

+15
-61
lines changed

lib/Sema/TypeCheckSwitchStmt.cpp

Lines changed: 15 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,17 @@ namespace {
223223
}
224224
static Space forConstructor(Type T, Identifier H, bool downgrade,
225225
ArrayRef<Space> SP) {
226+
if (llvm::any_of(SP, std::mem_fn(&Space::isEmpty))) {
227+
// A constructor with an unconstructible parameter can never actually
228+
// be used.
229+
return Space();
230+
}
226231
return Space(T, H, downgrade, SP);
227232
}
228233
static Space forConstructor(Type T, Identifier H, bool downgrade,
229234
std::forward_list<Space> SP) {
235+
// No need to filter SP here; this is only used to copy other
236+
// Constructor spaces.
230237
return Space(T, H, downgrade, SP);
231238
}
232239
static Space forBool(bool C) {
@@ -495,9 +502,11 @@ namespace {
495502
}
496503
}
497504

505+
/// Convenience declaration to make the intersection operation look more
506+
/// symmetric.
498507
static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
499508
const DeclContext *DC) {
500-
return a.intersect(b, TC, DC).simplify(TC, DC);
509+
return a.intersect(b, TC, DC);
501510
}
502511

503512
// Returns the intersection of this space with another. The intersection
@@ -738,13 +747,12 @@ namespace {
738747
PAIRCASE (SpaceKind::Constructor, SpaceKind::UnknownCase): {
739748
SmallVector<Space, 4> newSubSpaces;
740749
for (auto subSpace : this->getSpaces()) {
741-
auto diff = subSpace.minus(other, TC, DC, minusCount);
742-
if (!diff)
750+
auto nextSpace = subSpace.minus(other, TC, DC, minusCount);
751+
if (!nextSpace)
743752
return None;
744-
auto nextSpace = diff->simplify(TC, DC);
745-
if (nextSpace.isEmpty())
753+
if (nextSpace.getValue().isEmpty())
746754
return Space();
747-
newSubSpaces.push_back(nextSpace);
755+
newSubSpaces.push_back(nextSpace.getValue());
748756
}
749757
return Space::forConstructor(this->getType(), this->getHead(),
750758
this->canDowngradeToWarning(),
@@ -949,59 +957,6 @@ namespace {
949957
}
950958
}
951959

952-
// For optimization, attempt to simplify a space by removing any empty
953-
// cases and unpacking empty or singular disjunctions where possible.
954-
Space simplify(TypeChecker &TC, const DeclContext *DC) const {
955-
switch (getKind()) {
956-
case SpaceKind::Constructor: {
957-
// If a constructor has no spaces it is an enum without a payload and
958-
// cannot be optimized further.
959-
if (getSpaces().empty()) {
960-
return *this;
961-
}
962-
963-
// Simplify each component subspace. If, after simplification, any
964-
// subspace contains an empty, then the whole space is empty.
965-
SmallVector<Space, 4> simplifiedSpaces;
966-
for (const auto &space : Spaces) {
967-
auto simplified = space.simplify(TC, DC);
968-
if (simplified.isEmpty())
969-
return Space();
970-
971-
simplifiedSpaces.push_back(simplified);
972-
}
973-
974-
return Space::forConstructor(getType(), Head, canDowngradeToWarning(),
975-
simplifiedSpaces);
976-
}
977-
case SpaceKind::Type: {
978-
// If the decomposition of a space is empty, the space is empty.
979-
if (canDecompose(this->getType(), DC)) {
980-
SmallVector<Space, 4> ss;
981-
decompose(TC, DC, this->getType(), ss);
982-
if (ss.empty()) {
983-
return Space();
984-
}
985-
return *this;
986-
} else {
987-
return *this;
988-
}
989-
}
990-
case SpaceKind::Disjunct: {
991-
// Simplify each disjunct.
992-
SmallVector<Space, 4> simplifiedSpaces;
993-
std::transform(Spaces.begin(), Spaces.end(),
994-
std::back_inserter(simplifiedSpaces),
995-
[&](const Space &el){
996-
return el.simplify(TC, DC);
997-
});
998-
return Space::forDisjunct(simplifiedSpaces);
999-
}
1000-
default:
1001-
return *this;
1002-
}
1003-
}
1004-
1005960
static bool isSwift3DowngradeExhaustivityCase(TypeChecker &TC,
1006961
const EnumElementDecl *eed){
1007962
if (TC.getLangOpts().isSwiftVersionAtLeast(4))
@@ -1270,7 +1225,7 @@ namespace {
12701225
return;
12711226
}
12721227

1273-
auto uncovered = diff->simplify(TC, DC);
1228+
auto uncovered = diff.getValue();
12741229
if (unknownCase && uncovered.isEmpty()) {
12751230
TC.diagnose(unknownCase->getLoc(), diag::redundant_particular_case)
12761231
.highlight(unknownCase->getSourceRange());
@@ -1281,7 +1236,6 @@ namespace {
12811236
// that are implicitly frozen.
12821237
uncovered = *uncovered.minus(Space::forUnknown(unknownCase == nullptr),
12831238
TC, DC, /*&minusCount*/ nullptr);
1284-
uncovered = uncovered.simplify(TC, DC);
12851239

12861240
if (uncovered.isEmpty())
12871241
return;

0 commit comments

Comments
 (0)