@@ -785,28 +785,11 @@ namespace {
785785 }
786786 }
787787
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,
796790 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 ()));
810793 };
811794
812795 // Decompose a type into its component spaces, ignoring any enum
@@ -843,19 +826,29 @@ namespace {
843826 return Space ();
844827 }
845828
846- // .e(a: X, b: X) -> (a: X, b: X)
847- // .f((a: X, b: X)) -> ((a: X, b: X)
848829 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 ;
858849 }
850+ constElemSpaces.push_back (
851+ Space::forType (payloadTy, param.getLabel ()));
859852 }
860853 return Space::forConstructor (tp, eed->getName (),
861854 constElemSpaces);
@@ -870,11 +863,8 @@ namespace {
870863 } else if (auto *TTy = tp->castTo <TupleType>()) {
871864 // Decompose each of the elements into its component type space.
872865 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+
878868 // Create an empty constructor head for the tuple space.
879869 arr.push_back (Space::forConstructor (tp, Identifier (),
880870 constElemSpaces));
@@ -1519,12 +1509,12 @@ namespace {
15191509 // matched by a single var pattern. Project it like the tuple it
15201510 // really is.
15211511 //
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.
15231514 if (SP->getKind () == PatternKind::Named
15241515 || 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);
15281518 else
15291519 conArgSpace.push_back (projectPattern (SP));
15301520 } else if (SP->getKind () == PatternKind::Tuple) {
0 commit comments