Skip to content

Commit 236e88d

Browse files
committed
[NFC] Sema: Tidy up tuple pattern handling in coercePatternToType
1 parent 2888edc commit 236e88d

File tree

1 file changed

+39
-43
lines changed

1 file changed

+39
-43
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,17 +1204,25 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
12041204
// TODO: permit implicit conversions?
12051205
case PatternKind::Tuple: {
12061206
TuplePattern *TP = cast<TuplePattern>(P);
1207-
bool hadError = type->hasError();
1208-
1207+
1208+
TupleType *tupleTy = type->getAs<TupleType>();
1209+
12091210
// Sometimes a paren is just a paren. If the tuple pattern has a single
12101211
// element, we can reduce it to a paren pattern.
1211-
bool canDecayToParen = TP->getNumElements() == 1;
1212-
auto decayToParen = [&]() -> Pattern * {
1213-
assert(canDecayToParen);
1214-
Pattern *sub = TP->getElement(0).getPattern();
1215-
sub = TypeChecker::coercePatternToType(
1216-
pattern.forSubPattern(sub, /*retainTopLevel=*/false), type,
1217-
subOptions);
1212+
//
1213+
// FIXME: This condition is rather loose, e.g. it makes the following compile:
1214+
// switch 0 {
1215+
// case (int: 0): break
1216+
// default: break
1217+
// }
1218+
// Do we really want/need to support this?
1219+
//
1220+
if (TP->getNumElements() == 1 &&
1221+
(!tupleTy || tupleTy->getNumElements() != 1)) {
1222+
auto *sub = TypeChecker::coercePatternToType(
1223+
pattern.forSubPattern(TP->getElement(0).getPattern(),
1224+
/*retainTopLevel=*/false),
1225+
type, subOptions);
12181226
if (!sub)
12191227
return nullptr;
12201228

@@ -1225,63 +1233,51 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
12251233
} else {
12261234
P = sub;
12271235
}
1236+
12281237
return P;
1229-
};
1238+
}
12301239

1231-
// The context type must be a tuple.
1232-
TupleType *tupleTy = type->getAs<TupleType>();
1233-
if (!tupleTy && !hadError) {
1234-
if (canDecayToParen)
1235-
return decayToParen();
1240+
if (!tupleTy) {
12361241
diags.diagnose(TP->getStartLoc(),
12371242
diag::tuple_pattern_in_non_tuple_context, type);
1238-
hadError = true;
1243+
1244+
return nullptr;
12391245
}
12401246

12411247
// The number of elements must match exactly.
1242-
if (!hadError && tupleTy->getNumElements() != TP->getNumElements()) {
1243-
if (canDecayToParen)
1244-
return decayToParen();
1245-
1248+
if (tupleTy->getNumElements() != TP->getNumElements()) {
12461249
diags.diagnose(TP->getStartLoc(), diag::tuple_pattern_length_mismatch,
12471250
type);
1248-
hadError = true;
1251+
1252+
return nullptr;
12491253
}
12501254

12511255
// Coerce each tuple element to the respective type.
1252-
P->setType(type);
1253-
12541256
for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) {
1255-
TuplePatternElt &elt = TP->getElement(i);
1257+
TuplePatternElt &patternElt = TP->getElement(i);
1258+
const auto &typeElt = tupleTy->getElement(i);
12561259

1257-
Type CoercionType;
1258-
if (hadError)
1259-
CoercionType = ErrorType::get(Context);
1260-
else
1261-
CoercionType = tupleTy->getElement(i).getType();
1262-
12631260
// If the tuple pattern had a label for the tuple element, it must match
12641261
// the label for the tuple type being matched.
1265-
if (!hadError && !elt.getLabel().empty() &&
1266-
elt.getLabel() != tupleTy->getElement(i).getName()) {
1267-
diags.diagnose(elt.getLabelLoc(), diag::tuple_pattern_label_mismatch,
1268-
elt.getLabel(), tupleTy->getElement(i).getName());
1269-
hadError = true;
1262+
if (!patternElt.getLabel().empty() &&
1263+
patternElt.getLabel() != typeElt.getName()) {
1264+
diags.diagnose(patternElt.getLabelLoc(),
1265+
diag::tuple_pattern_label_mismatch,
1266+
patternElt.getLabel(), typeElt.getName());
1267+
return nullptr;
12701268
}
12711269

1272-
auto sub = coercePatternToType(
1273-
pattern.forSubPattern(elt.getPattern(), /*retainTopLevel=*/false),
1274-
CoercionType, subOptions);
1270+
auto *sub =
1271+
coercePatternToType(pattern.forSubPattern(patternElt.getPattern(),
1272+
/*retainTopLevel=*/false),
1273+
typeElt.getType(), subOptions);
12751274
if (!sub)
12761275
return nullptr;
12771276

1278-
if (!hadError)
1279-
elt.setPattern(sub);
1277+
patternElt.setPattern(sub);
12801278
}
12811279

1282-
if (hadError)
1283-
return nullptr;
1284-
1280+
P->setType(type);
12851281
return P;
12861282
}
12871283

0 commit comments

Comments
 (0)