Skip to content

Commit f950d04

Browse files
committed
[SpaceEngine] Change space intersection to always return simplified result
Based on the `intersect` usage it would be beneficial for it to always return a result in simplified form instead of relying on callers to request simplification. Also as part of this change remove boilerplate code from commutative space intersections e.g. Type ∩ Bool, Unknown ∩ Disjuct.
1 parent b823db8 commit f950d04

File tree

1 file changed

+29
-37
lines changed

1 file changed

+29
-37
lines changed

lib/Sema/TypeCheckSwitchStmt.cpp

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,11 @@ namespace {
501501
}
502502
}
503503

504+
static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
505+
const DeclContext *DC) {
506+
return a.intersect(b, TC, DC).simplify(TC, DC);
507+
}
508+
504509
// Returns the intersection of this space with another. The intersection
505510
// is the largest shared subspace occupied by both arguments.
506511
Space intersect(const Space &other, TypeChecker &TC,
@@ -519,11 +524,10 @@ namespace {
519524
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Disjunct): {
520525
// S & (S1 || ... || Sn) iff (S & S1) && ... && (S & Sn)
521526
SmallVector<Space, 4> intersectedCases;
522-
std::transform(other.getSpaces().begin(), other.getSpaces().end(),
523-
std::back_inserter(intersectedCases),
524-
[&](const Space &s) {
525-
return this->intersect(s, TC, DC);
526-
});
527+
std::transform(
528+
other.getSpaces().begin(), other.getSpaces().end(),
529+
std::back_inserter(intersectedCases),
530+
[&](const Space &s) { return intersect(*this, s, TC, DC); });
527531
return Space::forDisjunct(intersectedCases);
528532
}
529533

@@ -533,13 +537,7 @@ namespace {
533537
PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
534538
PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
535539
// (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
536-
SmallVector<Space, 4> intersectedCases;
537-
std::transform(this->getSpaces().begin(), this->getSpaces().end(),
538-
std::back_inserter(intersectedCases),
539-
[&](const Space &s) {
540-
return s.intersect(other, TC, DC);
541-
});
542-
return Space::forDisjunct(intersectedCases);
540+
return intersect(other, *this, TC, DC);
543541
}
544542
PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
545543
// Optimization: The intersection of equal types is that type.
@@ -549,12 +547,12 @@ namespace {
549547
SmallVector<Space, 4> spaces;
550548
decompose(TC, DC, this->getType(), spaces);
551549
auto decomposition = Space::forDisjunct(spaces);
552-
return decomposition.intersect(other, TC, DC);
550+
return intersect(decomposition, other, TC, DC);
553551
} else if (canDecompose(other.getType(), DC)) {
554552
SmallVector<Space, 4> spaces;
555553
decompose(TC, DC, other.getType(), spaces);
556554
auto disjunctSp = Space::forDisjunct(spaces);
557-
return this->intersect(disjunctSp, TC, DC);
555+
return intersect(*this, disjunctSp, TC, DC);
558556
} else {
559557
return other;
560558
}
@@ -564,7 +562,7 @@ namespace {
564562
SmallVector<Space, 4> spaces;
565563
decompose(TC, DC, this->getType(), spaces);
566564
auto decomposition = Space::forDisjunct(spaces);
567-
return decomposition.intersect(other, TC, DC);
565+
return intersect(decomposition, other, TC, DC);
568566
} else {
569567
return other;
570568
}
@@ -582,10 +580,11 @@ namespace {
582580

583581
PAIRCASE (SpaceKind::Constructor, SpaceKind::UnknownCase): {
584582
SmallVector<Space, 4> newSubSpaces;
585-
for (auto subSpace : this->getSpaces()) {
586-
Space nextSpace = subSpace.intersect(other, TC, DC);
587-
newSubSpaces.push_back(nextSpace.simplify(TC, DC));
588-
}
583+
std::transform(this->getSpaces().begin(), this->getSpaces().end(),
584+
std::back_inserter(newSubSpaces),
585+
[&](const Space &subSpace) {
586+
return intersect(subSpace, other, TC, DC);
587+
});
589588
return Space::forConstructor(this->getType(), this->getHead(),
590589
this->canDowngradeToWarning(),
591590
newSubSpaces);
@@ -609,21 +608,21 @@ namespace {
609608
auto j = other.getSpaces().begin();
610609
for (; i != this->getSpaces().end() && j != other.getSpaces().end();
611610
++i, ++j) {
612-
auto intersection = (*i).intersect(*j, TC, DC).simplify(TC, DC);
611+
auto result = intersect(*i, *j, TC, DC);
613612
// If at least one of the constructor sub-spaces is empty,
614613
// it makes the whole space empty as well.
615-
if (intersection.isEmpty()) {
614+
if (result.isEmpty()) {
616615
return Space();
617616
}
618-
paramSpace.push_back(intersection);
617+
paramSpace.push_back(result);
619618
}
620619

621620
return Space::forDisjunct(paramSpace);
622621
}
623622

624-
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
625-
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
626-
return other.intersect(*this, TC, DC);
623+
PAIRCASE(SpaceKind::UnknownCase, SpaceKind::Type):
624+
PAIRCASE(SpaceKind::UnknownCase, SpaceKind::Constructor):
625+
return intersect(other, *this, TC, DC);
627626
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
628627
if (other.isAllowedButNotRequired())
629628
return other;
@@ -641,7 +640,7 @@ namespace {
641640
SmallVector<Space, 4> spaces;
642641
decompose(TC, DC, other.getType(), spaces);
643642
auto disjunctSp = Space::forDisjunct(spaces);
644-
return this->intersect(disjunctSp, TC, DC);
643+
return intersect(*this, disjunctSp, TC, DC);
645644
}
646645
return Space();
647646
}
@@ -651,14 +650,7 @@ namespace {
651650
return Space();
652651

653652
PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
654-
if (canDecompose(this->getType(), DC)) {
655-
SmallVector<Space, 4> spaces;
656-
decompose(TC, DC, this->getType(), spaces);
657-
auto disjunctSp = Space::forDisjunct(spaces);
658-
return disjunctSp.intersect(other, TC, DC);
659-
} else {
660-
return Space();
661-
}
653+
return intersect(other, *this, TC, DC);
662654
}
663655

664656
PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
@@ -703,12 +695,12 @@ namespace {
703695
} else if (canDecompose(this->getType(), DC)) {
704696
SmallVector<Space, 4> spaces;
705697
this->decompose(TC, DC, this->getType(), spaces);
706-
return Space::forDisjunct(spaces).intersect(other, TC, DC);
698+
return intersect(Space::forDisjunct(spaces), other, TC, DC);
707699
} else if (canDecompose(other.getType(), DC)) {
708700
SmallVector<Space, 4> spaces;
709701
this->decompose(TC, DC, other.getType(), spaces);
710702
auto decomp = Space::forDisjunct(spaces);
711-
return this->intersect(decomp, TC, DC);
703+
return intersect(*this, decomp, TC, DC);
712704
}
713705
return Space();
714706
}
@@ -802,7 +794,7 @@ namespace {
802794
auto &s2 = *j;
803795
// If the intersection of each subspace is ever empty then the
804796
// two spaces are disjoint and their difference is the first space.
805-
if (s1.intersect(s2, TC, DC).simplify(TC, DC).isEmpty()) {
797+
if (intersect(s1, s2, TC, DC).isEmpty()) {
806798
return *this;
807799
}
808800

0 commit comments

Comments
 (0)