Skip to content

[SpaceEngine] intersect cleanups #16765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 49 additions & 75 deletions lib/Sema/TypeCheckSwitchStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,14 @@ namespace {

// (_ : Ty1) <= (_ : Ty2) iff D(Ty1) == D(Ty2)
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> disjuncts;
decompose(TC, DC, this->getType(), disjuncts);
Space or1Space = Space::forDisjunct(disjuncts);
Space or1Space = decompose(TC, DC, this->getType());
if (or1Space.isSubspace(other, TC, DC)) {
return true;
}
}

if (canDecompose(other.getType(), DC)) {
SmallVector<Space, 4> disjuncts;
decompose(TC, DC, other.getType(), disjuncts);
Space or2Space = Space::forDisjunct(disjuncts);
Space or2Space = decompose(TC, DC, other.getType());
return this->isSubspace(or2Space, TC, DC);
}

Expand All @@ -406,17 +402,13 @@ namespace {
if (!canDecompose(this->getType(), DC)) {
return false;
}
SmallVector<Space, 4> disjuncts;
decompose(TC, DC, this->getType(), disjuncts);
Space or1Space = Space::forDisjunct(disjuncts);
Space or1Space = decompose(TC, DC, this->getType());
return or1Space.isSubspace(other, TC, DC);
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
// (_ : Ty1) <= H(p1 | ... | pn) iff D(Ty1) <= H(p1 | ... | pn)
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> disjuncts;
decompose(TC, DC, this->getType(), disjuncts);
Space or1Space = Space::forDisjunct(disjuncts);
Space or1Space = decompose(TC, DC, this->getType());
return or1Space.isSubspace(other, TC, DC);
}
// An undecomposable type is always larger than its constructor space.
Expand Down Expand Up @@ -501,6 +493,11 @@ namespace {
}
}

static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
const DeclContext *DC) {
return a.intersect(b, TC, DC).simplify(TC, DC);
}

// Returns the intersection of this space with another. The intersection
// is the largest shared subspace occupied by both arguments.
Space intersect(const Space &other, TypeChecker &TC,
Expand All @@ -519,11 +516,10 @@ namespace {
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Disjunct): {
// S & (S1 || ... || Sn) iff (S & S1) && ... && (S & Sn)
SmallVector<Space, 4> intersectedCases;
std::transform(other.getSpaces().begin(), other.getSpaces().end(),
std::back_inserter(intersectedCases),
[&](const Space &s) {
return this->intersect(s, TC, DC);
});
std::transform(
other.getSpaces().begin(), other.getSpaces().end(),
std::back_inserter(intersectedCases),
[&](const Space &s) { return intersect(*this, s, TC, DC); });
return Space::forDisjunct(intersectedCases);
}

Expand All @@ -533,38 +529,26 @@ namespace {
PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
// (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
SmallVector<Space, 4> intersectedCases;
std::transform(this->getSpaces().begin(), this->getSpaces().end(),
std::back_inserter(intersectedCases),
[&](const Space &s) {
return s.intersect(other, TC, DC);
});
return Space::forDisjunct(intersectedCases);
return intersect(other, *this, TC, DC);
}
PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
// Optimization: The intersection of equal types is that type.
if (this->getType()->isEqual(other.getType())) {
return other;
} else if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, this->getType(), spaces);
auto decomposition = Space::forDisjunct(spaces);
return decomposition.intersect(other, TC, DC);
auto decomposition = decompose(TC, DC, this->getType());
return intersect(decomposition, other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, other.getType(), spaces);
auto disjunctSp = Space::forDisjunct(spaces);
return this->intersect(disjunctSp, TC, DC);
auto decomposition = decompose(TC, DC, other.getType());
return intersect(*this, decomposition, TC, DC);
} else {
return other;
}
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, this->getType(), spaces);
auto decomposition = Space::forDisjunct(spaces);
return decomposition.intersect(other, TC, DC);
auto decomposition = decompose(TC, DC, this->getType());
return intersect(decomposition, other, TC, DC);
} else {
return other;
}
Expand All @@ -582,10 +566,11 @@ namespace {

PAIRCASE (SpaceKind::Constructor, SpaceKind::UnknownCase): {
SmallVector<Space, 4> newSubSpaces;
for (auto subSpace : this->getSpaces()) {
Space nextSpace = subSpace.intersect(other, TC, DC);
newSubSpaces.push_back(nextSpace.simplify(TC, DC));
}
std::transform(this->getSpaces().begin(), this->getSpaces().end(),
std::back_inserter(newSubSpaces),
[&](const Space &subSpace) {
return intersect(subSpace, other, TC, DC);
});
return Space::forConstructor(this->getType(), this->getHead(),
this->canDowngradeToWarning(),
newSubSpaces);
Expand All @@ -609,21 +594,21 @@ namespace {
auto j = other.getSpaces().begin();
for (; i != this->getSpaces().end() && j != other.getSpaces().end();
++i, ++j) {
auto intersection = (*i).intersect(*j, TC, DC).simplify(TC, DC);
auto result = intersect(*i, *j, TC, DC);
// If at least one of the constructor sub-spaces is empty,
// it makes the whole space empty as well.
if (intersection.isEmpty()) {
if (result.isEmpty()) {
return Space();
}
paramSpace.push_back(intersection);
paramSpace.push_back(result);
}

return Space::forDisjunct(paramSpace);
}

PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
return other.intersect(*this, TC, DC);
return intersect(other, *this, TC, DC);
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
if (other.isAllowedButNotRequired())
return other;
Expand All @@ -638,10 +623,8 @@ namespace {
}

if (canDecompose(other.getType(), DC)) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, other.getType(), spaces);
auto disjunctSp = Space::forDisjunct(spaces);
return this->intersect(disjunctSp, TC, DC);
auto decomposition = decompose(TC, DC, other.getType());
return intersect(*this, decomposition, TC, DC);
}
return Space();
}
Expand All @@ -651,14 +634,7 @@ namespace {
return Space();

PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, this->getType(), spaces);
auto disjunctSp = Space::forDisjunct(spaces);
return disjunctSp.intersect(other, TC, DC);
} else {
return Space();
}
return intersect(other, *this, TC, DC);
}

PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
Expand Down Expand Up @@ -701,23 +677,18 @@ namespace {
if (this->getType()->isEqual(other.getType())) {
return Space();
} else if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
this->decompose(TC, DC, this->getType(), spaces);
return Space::forDisjunct(spaces).intersect(other, TC, DC);
auto decomposition = decompose(TC, DC, this->getType());
return intersect(decomposition, other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
SmallVector<Space, 4> spaces;
this->decompose(TC, DC, other.getType(), spaces);
auto decomp = Space::forDisjunct(spaces);
return this->intersect(decomp, TC, DC);
auto decomposition = decompose(TC, DC, other.getType());
return intersect(*this, decomposition, TC, DC);
}
return Space();
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
this->decompose(TC, DC, this->getType(), spaces);
auto decomp = Space::forDisjunct(spaces);
return decomp.minus(other, TC, DC, minusCount);
auto decomposition = decompose(TC, DC, this->getType());
return decomposition.minus(other, TC, DC, minusCount);
} else {
return *this;
}
Expand Down Expand Up @@ -802,7 +773,7 @@ namespace {
auto &s2 = *j;
// If the intersection of each subspace is ever empty then the
// two spaces are disjoint and their difference is the first space.
if (s1.intersect(s2, TC, DC).simplify(TC, DC).isEmpty()) {
if (intersect(s1, s2, TC, DC).isEmpty()) {
return *this;
}

Expand Down Expand Up @@ -862,10 +833,8 @@ namespace {
}

if (canDecompose(other.getType(), DC)) {
SmallVector<Space, 4> spaces;
this->decompose(TC, DC, other.getType(), spaces);
auto disjunctSp = Space::forDisjunct(spaces);
return this->minus(disjunctSp, TC, DC, minusCount);
auto decomposition = decompose(TC, DC, other.getType());
return this->minus(decomposition, TC, DC, minusCount);
}
return *this;
}
Expand All @@ -876,9 +845,7 @@ namespace {

PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
if (canDecompose(this->getType(), DC)) {
SmallVector<Space, 4> spaces;
this->decompose(TC, DC, this->getType(), spaces);
auto orSpace = Space::forDisjunct(spaces);
auto orSpace = decompose(TC, DC, this->getType());
return orSpace.minus(other, TC, DC, minusCount);
} else {
return *this;
Expand Down Expand Up @@ -1117,6 +1084,13 @@ namespace {
}
}

static Space decompose(TypeChecker &TC, const DeclContext *DC,
Type type) {
SmallVector<Space, 4> spaces;
decompose(TC, DC, type, spaces);
return Space::forDisjunct(spaces);
}

static bool canDecompose(Type tp, const DeclContext *DC) {
return tp->is<TupleType>() || tp->isBool() ||
tp->getEnumOrBoundGenericEnum();
Expand Down