Skip to content

Commit c9b8140

Browse files
xedinrjmccall
authored andcommitted
[CSSimplify] NFC: Refactor TupleMatcher to consolidate pack expansion matching
1 parent 6badca6 commit c9b8140

File tree

1 file changed

+43
-82
lines changed

1 file changed

+43
-82
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 43 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,13 +2069,19 @@ class TupleMatcher {
20692069
TupleType *tuple2;
20702070

20712071
public:
2072+
enum class MatchKind : uint8_t {
2073+
Equality,
2074+
Subtype,
2075+
Conversion,
2076+
};
2077+
20722078
SmallVector<MatchedPair, 4> pairs;
20732079
bool hasLabelMismatch = false;
20742080

20752081
TupleMatcher(TupleType *tuple1, TupleType *tuple2)
2076-
: tuple1(tuple1), tuple2(tuple2) {}
2082+
: tuple1(tuple1), tuple2(tuple2) {}
20772083

2078-
bool matchBind() {
2084+
bool match(MatchKind kind, ConstraintLocatorBuilder locator) {
20792085
// FIXME: TuplePackMatcher should completely replace the non-variadic
20802086
// case too eventually.
20812087
if (tuple1->containsPackExpansionType() ||
@@ -2091,42 +2097,32 @@ class TupleMatcher {
20912097
if (tuple1->getNumElements() != tuple2->getNumElements())
20922098
return true;
20932099

2094-
for (unsigned i = 0, n = tuple1->getNumElements(); i != n; ++i) {
2095-
const auto &elt1 = tuple1->getElement(i);
2096-
const auto &elt2 = tuple2->getElement(i);
2100+
switch (kind) {
2101+
case MatchKind::Equality:
2102+
return matchEquality(isInPatternMatchingContext(locator));
20972103

2098-
// If the names don't match, we have a conflict.
2099-
if (elt1.getName() != elt2.getName())
2100-
return true;
2104+
case MatchKind::Subtype:
2105+
return matchSubtype();
21012106

2102-
pairs.emplace_back(elt1.getType(), elt2.getType(), i, i);
2107+
case MatchKind::Conversion:
2108+
return matchConversion();
21032109
}
2104-
2105-
return false;
21062110
}
21072111

2108-
bool matchInPatternMatchingContext() {
2109-
// FIXME: TuplePackMatcher should completely replace the non-variadic
2110-
// case too eventually.
2111-
if (tuple1->containsPackExpansionType() ||
2112-
tuple2->containsPackExpansionType()) {
2113-
TuplePackMatcher matcher(tuple1, tuple2);
2114-
if (matcher.match())
2115-
return true;
2116-
2117-
pairs = matcher.pairs;
2118-
return false;
2119-
}
2120-
2121-
if (tuple1->getNumElements() != tuple2->getNumElements())
2122-
return true;
2123-
2112+
private:
2113+
bool matchEquality(bool inPatternMatchingContext) {
21242114
for (unsigned i = 0, n = tuple1->getNumElements(); i != n; ++i) {
21252115
const auto &elt1 = tuple1->getElement(i);
21262116
const auto &elt2 = tuple2->getElement(i);
21272117

2128-
if (elt1.hasName() && elt1.getName() != elt2.getName())
2129-
return true;
2118+
if (inPatternMatchingContext) {
2119+
if (elt1.hasName() && elt1.getName() != elt2.getName())
2120+
return true;
2121+
} else {
2122+
// If the names don't match, we have a conflict.
2123+
if (elt1.getName() != elt2.getName())
2124+
return true;
2125+
}
21302126

21312127
pairs.emplace_back(elt1.getType(), elt2.getType(), i, i);
21322128
}
@@ -2135,21 +2131,6 @@ class TupleMatcher {
21352131
}
21362132

21372133
bool matchSubtype() {
2138-
// FIXME: TuplePackMatcher should completely replace the non-variadic
2139-
// case too eventually.
2140-
if (tuple1->containsPackExpansionType() ||
2141-
tuple2->containsPackExpansionType()) {
2142-
TuplePackMatcher matcher(tuple1, tuple2);
2143-
if (matcher.match())
2144-
return true;
2145-
2146-
pairs = matcher.pairs;
2147-
return false;
2148-
}
2149-
2150-
if (tuple1->getNumElements() != tuple2->getNumElements())
2151-
return true;
2152-
21532134
for (unsigned i = 0, n = tuple1->getNumElements(); i != n; ++i) {
21542135
const auto &elt1 = tuple1->getElement(i);
21552136
const auto &elt2 = tuple2->getElement(i);
@@ -2173,18 +2154,6 @@ class TupleMatcher {
21732154
}
21742155

21752156
bool matchConversion() {
2176-
// FIXME: TuplePackMatcher should completely replace the non-variadic
2177-
// case too eventually.
2178-
if (tuple1->containsPackExpansionType() ||
2179-
tuple2->containsPackExpansionType()) {
2180-
TuplePackMatcher matcher(tuple1, tuple2);
2181-
if (matcher.match())
2182-
return true;
2183-
2184-
pairs = matcher.pairs;
2185-
return false;
2186-
}
2187-
21882157
SmallVector<unsigned, 4> sources;
21892158
if (computeTupleShuffle(tuple1, tuple2, sources))
21902159
return true;
@@ -2208,23 +2177,16 @@ ConstraintSystem::TypeMatchResult
22082177
ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
22092178
ConstraintKind kind, TypeMatchOptions flags,
22102179
ConstraintLocatorBuilder locator) {
2211-
TupleMatcher matcher(tuple1, tuple2);
2180+
using TupleMatchKind = TupleMatcher::MatchKind;
22122181

22132182
ConstraintKind subkind;
2183+
TupleMatchKind matchKind;
22142184

22152185
switch (kind) {
22162186
case ConstraintKind::Bind:
22172187
case ConstraintKind::Equal: {
22182188
subkind = kind;
2219-
2220-
if (isInPatternMatchingContext(locator)) {
2221-
if (matcher.matchInPatternMatchingContext())
2222-
return getTypeMatchFailure(locator);
2223-
} else {
2224-
if (matcher.matchBind())
2225-
return getTypeMatchFailure(locator);
2226-
}
2227-
2189+
matchKind = TupleMatchKind::Equality;
22282190
break;
22292191
}
22302192

@@ -2234,29 +2196,15 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
22342196
case ConstraintKind::Subtype:
22352197
case ConstraintKind::BindToPointerType: {
22362198
subkind = kind;
2237-
2238-
if (matcher.matchSubtype())
2239-
return getTypeMatchFailure(locator);
2240-
2241-
if (matcher.hasLabelMismatch) {
2242-
// If we had a label mismatch, emit a warning. This is something we
2243-
// shouldn't permit, as it's more permissive than what a conversion would
2244-
// allow. Ideally we'd turn this into an error in Swift 6 mode.
2245-
recordFix(AllowTupleLabelMismatch::create(
2246-
*this, tuple1, tuple2, getConstraintLocator(locator)));
2247-
}
2199+
matchKind = TupleMatchKind::Subtype;
22482200
break;
22492201
}
22502202

22512203
case ConstraintKind::Conversion:
22522204
case ConstraintKind::ArgumentConversion:
22532205
case ConstraintKind::OperatorArgumentConversion: {
22542206
subkind = ConstraintKind::Conversion;
2255-
2256-
// Compute the element shuffles for conversions.
2257-
if (matcher.matchConversion())
2258-
return getTypeMatchFailure(locator);
2259-
2207+
matchKind = TupleMatchKind::Conversion;
22602208
break;
22612209
}
22622210

@@ -2296,6 +2244,19 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
22962244
llvm_unreachable("Bad constraint kind in matchTupleTypes()");
22972245
}
22982246

2247+
TupleMatcher matcher(tuple1, tuple2);
2248+
2249+
if (matcher.match(matchKind, locator))
2250+
return getTypeMatchFailure(locator);
2251+
2252+
if (matcher.hasLabelMismatch) {
2253+
// If we had a label mismatch, emit a warning. This is something we
2254+
// shouldn't permit, as it's more permissive than what a conversion would
2255+
// allow. Ideally we'd turn this into an error in Swift 6 mode.
2256+
recordFix(AllowTupleLabelMismatch::create(*this, tuple1, tuple2,
2257+
getConstraintLocator(locator)));
2258+
}
2259+
22992260
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
23002261

23012262
for (auto pair : matcher.pairs) {

0 commit comments

Comments
 (0)