@@ -785,28 +785,11 @@ namespace {
785
785
}
786
786
}
787
787
788
- // / Use this if you're doing getAs<TupleType> on a Type (and it succeeds)
789
- // / to compute the spaces for it. Handy for disambiguating fields
790
- // / that are tuples from associated values.
791
- // /
792
- // / .e((a: X, b: X)) -> ((a: X, b: X))
793
- // / vs .f(a: X, b: X) -> (a: X, b: X)
794
- static void getTupleTypeSpaces (Type &outerType,
795
- TupleType *tty,
788
+ // / Splat a tuple type into a set of element type spaces.
789
+ static void getTupleTypeSpaces (TupleType *tty,
796
790
SmallVectorImpl<Space> &spaces) {
797
- ArrayRef<TupleTypeElt> ttyElts = tty->getElements ();
798
- if (isa<ParenType>(outerType.getPointer ())) {
799
- // We had an actual tuple!
800
- SmallVector<Space, 4 > innerSpaces;
801
- for (auto &elt: ttyElts)
802
- innerSpaces.push_back (Space::forType (elt.getType (), elt.getName ()));
803
- spaces.push_back (
804
- Space::forConstructor (tty, Identifier (), innerSpaces));
805
- } else {
806
- // We're looking at the fields of a constructor here.
807
- for (auto &elt: ttyElts)
808
- spaces.push_back (Space::forType (elt.getType (), elt.getName ()));
809
- }
791
+ for (auto &elt : tty->getElements ())
792
+ spaces.push_back (Space::forType (elt.getType (), elt.getName ()));
810
793
};
811
794
812
795
// Decompose a type into its component spaces, ignoring any enum
@@ -843,19 +826,29 @@ namespace {
843
826
return Space ();
844
827
}
845
828
846
- // .e(a: X, b: X) -> (a: X, b: X)
847
- // .f((a: X, b: X)) -> ((a: X, b: X)
848
829
SmallVector<Space, 4 > constElemSpaces;
849
- if (auto payloadTy = eed->getPayloadInterfaceType ()) {
850
- auto eedTy = tp->getCanonicalType ()->getTypeOfMember (
851
- eed, payloadTy);
852
- if (auto *TTy = eedTy->getAs <TupleType>()) {
853
- Space::getTupleTypeSpaces (eedTy, TTy, constElemSpaces);
854
- } else if (auto *TTy =
855
- dyn_cast<ParenType>(eedTy.getPointer ())) {
856
- constElemSpaces.push_back (
857
- Space::forType (TTy->getUnderlyingType (), Identifier ()));
830
+ auto params = eed->getCaseConstructorParams ();
831
+ auto isParenLike = params.size () == 1 && !params[0 ].hasLabel ();
832
+
833
+ // .e(a: X, b: X) -> (a: X, b: X)
834
+ // .f((a: X, b: X)) -> ((a: X, b: X))
835
+ for (auto ¶m : params) {
836
+ auto payloadTy = tp->getCanonicalType ()->getTypeOfMember (
837
+ eed, param.getParameterType ());
838
+ // A single tuple payload gets splatted into a constructor
839
+ // space of its constituent elements. This allows the
840
+ // deprecated ability to match using a .x(a, b, c) pattern
841
+ // instead of a .x((a, b, c)) pattern.
842
+ auto *tupleTy = payloadTy->getAs <TupleType>();
843
+ if (tupleTy && isParenLike) {
844
+ SmallVector<Space, 4 > innerSpaces;
845
+ Space::getTupleTypeSpaces (tupleTy, innerSpaces);
846
+ constElemSpaces.push_back (Space::forConstructor (
847
+ tupleTy, Identifier (), innerSpaces));
848
+ continue ;
858
849
}
850
+ constElemSpaces.push_back (
851
+ Space::forType (payloadTy, param.getLabel ()));
859
852
}
860
853
return Space::forConstructor (tp, eed->getName (),
861
854
constElemSpaces);
@@ -870,11 +863,8 @@ namespace {
870
863
} else if (auto *TTy = tp->castTo <TupleType>()) {
871
864
// Decompose each of the elements into its component type space.
872
865
SmallVector<Space, 4 > constElemSpaces;
873
- llvm::transform (TTy->getElements (),
874
- std::back_inserter (constElemSpaces),
875
- [&](TupleTypeElt elt) {
876
- return Space::forType (elt.getType (), elt.getName ());
877
- });
866
+ Space::getTupleTypeSpaces (TTy, constElemSpaces);
867
+
878
868
// Create an empty constructor head for the tuple space.
879
869
arr.push_back (Space::forConstructor (tp, Identifier (),
880
870
constElemSpaces));
@@ -1519,12 +1509,12 @@ namespace {
1519
1509
// matched by a single var pattern. Project it like the tuple it
1520
1510
// really is.
1521
1511
//
1522
- // FIXME: SE-0155 makes this case unreachable.
1512
+ // FIXME: SE-0155 will eventually this case unreachable. For now it's
1513
+ // permitted as a deprecated behavior.
1523
1514
if (SP->getKind () == PatternKind::Named
1524
1515
|| SP->getKind () == PatternKind::Any) {
1525
- Type outerType = SP->getType ();
1526
- if (auto *TTy = outerType->getAs <TupleType>())
1527
- Space::getTupleTypeSpaces (outerType, TTy, conArgSpace);
1516
+ if (auto *TTy = SP->getType ()->getAs <TupleType>())
1517
+ Space::getTupleTypeSpaces (TTy, conArgSpace);
1528
1518
else
1529
1519
conArgSpace.push_back (projectPattern (SP));
1530
1520
} else if (SP->getKind () == PatternKind::Tuple) {
0 commit comments