@@ -1141,20 +1141,51 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
1141
1141
if (tuple1->getNumElements () != tuple2->getNumElements ())
1142
1142
return getTypeMatchFailure (locator);
1143
1143
1144
+ // Determine whether this conversion is performed as part
1145
+ // of a larger pattern matching operation.
1146
+ bool inPatternMatchingContext = false ;
1147
+ {
1148
+ SmallVector<LocatorPathElt, 4 > path;
1149
+ (void )locator.getLocatorParts (path);
1150
+
1151
+ if (!path.empty ()) {
1152
+ // Direct pattern matching between tuple pattern and tuple type.
1153
+ if (path.back ().is <LocatorPathElt::PatternMatch>()) {
1154
+ inPatternMatchingContext = true ;
1155
+ } else if (path.size () > 1 ) {
1156
+ // sub-pattern matching as part of the enum element matching
1157
+ // where sub-element is a tuple pattern e.g.
1158
+ // `case .foo((a: 42, _)) = question`
1159
+ auto lastIdx = path.size () - 1 ;
1160
+ if (path[lastIdx - 1 ].is <LocatorPathElt::PatternMatch>() &&
1161
+ path[lastIdx].is <LocatorPathElt::FunctionArgument>())
1162
+ inPatternMatchingContext = true ;
1163
+ }
1164
+ }
1165
+ }
1166
+
1144
1167
for (unsigned i = 0 , n = tuple1->getNumElements (); i != n; ++i) {
1145
1168
const auto &elt1 = tuple1->getElement (i);
1146
1169
const auto &elt2 = tuple2->getElement (i);
1147
1170
1148
- // If the names don't match, we may have a conflict.
1149
- if (elt1. getName () != elt2. getName ()) {
1150
- // Same-type requirements require exact name matches.
1151
- if (kind <= ConstraintKind::Equal)
1171
+ // If the tuple pattern had a label for the tuple element,
1172
+ // it must match the label for the tuple type being matched.
1173
+ if (inPatternMatchingContext) {
1174
+ if (elt1. hasName () && elt1. getName () != elt2. getName ()) {
1152
1175
return getTypeMatchFailure (locator);
1176
+ }
1177
+ } else {
1178
+ // If the names don't match, we may have a conflict.
1179
+ if (elt1.getName () != elt2.getName ()) {
1180
+ // Same-type requirements require exact name matches.
1181
+ if (kind <= ConstraintKind::Equal)
1182
+ return getTypeMatchFailure (locator);
1153
1183
1154
- // For subtyping constraints, just make sure that this name isn't
1155
- // used at some other position.
1156
- if (elt2.hasName () && tuple1->getNamedElementId (elt2.getName ()) != -1 )
1157
- return getTypeMatchFailure (locator);
1184
+ // For subtyping constraints, just make sure that this name isn't
1185
+ // used at some other position.
1186
+ if (elt2.hasName () && tuple1->getNamedElementId (elt2.getName ()) != -1 )
1187
+ return getTypeMatchFailure (locator);
1188
+ }
1158
1189
}
1159
1190
1160
1191
// Variadic bit must match.
@@ -1794,14 +1825,21 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
1794
1825
// FIXME: We should check value ownership too, but it's not completely
1795
1826
// trivial because of inout-to-pointer conversions.
1796
1827
1828
+ // For equality contravariance doesn't matter, but let's make sure
1829
+ // that types are matched in original order because that is important
1830
+ // when function types are equated as part of pattern matching.
1831
+ auto paramType1 = kind == ConstraintKind::Equal ? func1Param.getOldType ()
1832
+ : func2Param.getOldType ();
1833
+
1834
+ auto paramType2 = kind == ConstraintKind::Equal ? func2Param.getOldType ()
1835
+ : func1Param.getOldType ();
1836
+
1797
1837
// Compare the parameter types.
1798
- auto result = matchTypes (func2Param.getOldType (),
1799
- func1Param.getOldType (),
1800
- subKind, subflags,
1838
+ auto result = matchTypes (paramType1, paramType2, subKind, subflags,
1801
1839
(func1Params.size () == 1
1802
- ? argumentLocator
1803
- : argumentLocator.withPathElement (
1804
- LocatorPathElt::TupleElement (i))));
1840
+ ? argumentLocator
1841
+ : argumentLocator.withPathElement (
1842
+ LocatorPathElt::TupleElement (i))));
1805
1843
if (result.isFailure ())
1806
1844
return result;
1807
1845
}
0 commit comments