@@ -47,10 +47,13 @@ namespace {
47
47
48
48
namespace {
49
49
50
- // / The SpaceEngine encapsulates an algorithm for computing the exhaustiveness
51
- // / of a switch statement using an algebra of spaces described by Fengyun Liu
52
- // / and an algorithm for computing warnings for pattern matching by
53
- // / Luc Maranget.
50
+ // / The SpaceEngine encapsulates
51
+ // /
52
+ // / 1. An algorithm for computing the exhaustiveness of a switch statement
53
+ // / using an algebra of spaces based on Fengyun Liu's
54
+ // / "A Generic Algorithm for Checking Exhaustivity of Pattern Matching".
55
+ // / 2. An algorithm for computing warnings for pattern matching based on
56
+ // / Luc Maranget's "Warnings for pattern matching".
54
57
// /
55
58
// / The main algorithm centers around the computation of the difference and
56
59
// / the containment of the "Spaces" given in each case, which reduces the
@@ -298,7 +301,6 @@ namespace {
298
301
}
299
302
300
303
switch (PairSwitch (getKind (), other.getKind ())) {
301
- PAIRCASE (SpaceKind::Disjunct, SpaceKind::Empty):
302
304
PAIRCASE (SpaceKind::Disjunct, SpaceKind::Type):
303
305
PAIRCASE (SpaceKind::Disjunct, SpaceKind::Constructor):
304
306
PAIRCASE (SpaceKind::Disjunct, SpaceKind::Disjunct):
@@ -748,8 +750,6 @@ namespace {
748
750
auto children = E->getAllElements ();
749
751
std::transform (children.begin (), children.end (),
750
752
std::back_inserter (arr), [&](EnumElementDecl *eed) {
751
- SmallVector<Space, 4 > constElemSpaces;
752
-
753
753
// We need the interface type of this enum case but it may
754
754
// not have been computed.
755
755
if (!eed->hasInterfaceType ()) {
@@ -768,17 +768,28 @@ namespace {
768
768
return Space ();
769
769
}
770
770
771
+ // .e(a: X, b: X) -> (a: X, b: X)
772
+ // .f((a: X, b: X)) -> ((a: X, b: X)
771
773
auto eedTy = tp->getCanonicalType ()
772
774
->getTypeOfMember (E->getModuleContext (), eed,
773
775
eed->getArgumentInterfaceType ());
776
+ SmallVector<Space, 4 > constElemSpaces;
774
777
if (eedTy) {
775
778
if (auto *TTy = eedTy->getAs <TupleType>()) {
776
- // Decompose the payload tuple into its component type spaces.
777
- llvm::transform (TTy->getElements (),
778
- std::back_inserter (constElemSpaces),
779
- [&](TupleTypeElt elt) {
780
- return Space::forType (elt.getType (), elt.getName ());
781
- });
779
+ if (isa<ParenType>(eedTy.getPointer ())) {
780
+ // We had an actual tuple!
781
+ SmallVector<Space, 4 > innerElemSpaces;
782
+ for (auto &elt: TTy->getElements ())
783
+ innerElemSpaces.push_back (
784
+ Space::forType (elt.getType (), elt.getName ()));
785
+ constElemSpaces.push_back (
786
+ Space::forConstructor (TTy, Identifier (), innerElemSpaces));
787
+ } else {
788
+ // We're just looking at fields of a constructor here.
789
+ for (auto &elt: TTy->getElements ())
790
+ constElemSpaces.push_back (
791
+ Space::forType (elt.getType (), elt.getName ()));
792
+ }
782
793
} else if (auto *TTy = dyn_cast<ParenType>(eedTy.getPointer ())) {
783
794
constElemSpaces.push_back (
784
795
Space::forType (TTy->getUnderlyingType (), Identifier ()));
@@ -1458,9 +1469,7 @@ namespace {
1458
1469
if (argTupleSpace.isEmpty ())
1459
1470
return Space ();
1460
1471
assert (argTupleSpace.getKind () == SpaceKind::Constructor);
1461
- conArgSpace.insert (conArgSpace.end (),
1462
- argTupleSpace.getSpaces ().begin (),
1463
- argTupleSpace.getSpaces ().end ());
1472
+ conArgSpace.push_back (argTupleSpace);
1464
1473
} else {
1465
1474
conArgSpace.push_back (projectPattern (TC, SP));
1466
1475
}
0 commit comments