Skip to content

Commit 400fdb8

Browse files
committed
[NFC] Sema: Tidy up tuple pattern handling in coercePatternToType
1 parent e8be44d commit 400fdb8

File tree

1 file changed

+52
-57
lines changed

1 file changed

+52
-57
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 52 additions & 57 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,50 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
12251233
} else {
12261234
P = sub;
12271235
}
1228-
return P;
1229-
};
1236+
} else {
1237+
if (!tupleTy) {
1238+
diags.diagnose(TP->getStartLoc(),
1239+
diag::tuple_pattern_in_non_tuple_context, type);
12301240

1231-
// The context type must be a tuple.
1232-
TupleType *tupleTy = type->getAs<TupleType>();
1233-
if (!tupleTy && !hadError) {
1234-
if (canDecayToParen)
1235-
return decayToParen();
1236-
diags.diagnose(TP->getStartLoc(),
1237-
diag::tuple_pattern_in_non_tuple_context, type);
1238-
hadError = true;
1239-
}
1241+
return nullptr;
1242+
}
12401243

1241-
// The number of elements must match exactly.
1242-
if (!hadError && tupleTy->getNumElements() != TP->getNumElements()) {
1243-
if (canDecayToParen)
1244-
return decayToParen();
1245-
1246-
diags.diagnose(TP->getStartLoc(), diag::tuple_pattern_length_mismatch,
1247-
type);
1248-
hadError = true;
1249-
}
1244+
// The number of elements must match exactly.
1245+
if (tupleTy->getNumElements() != TP->getNumElements()) {
1246+
diags.diagnose(TP->getStartLoc(), diag::tuple_pattern_length_mismatch,
1247+
type);
12501248

1251-
// Coerce each tuple element to the respective type.
1252-
P->setType(type);
1249+
return nullptr;
1250+
}
12531251

1254-
for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) {
1255-
TuplePatternElt &elt = TP->getElement(i);
1252+
// Coerce each tuple element to the respective type.
1253+
for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) {
1254+
TuplePatternElt &patternElt = TP->getElement(i);
1255+
const auto &typeElt = tupleTy->getElement(i);
1256+
1257+
// If the tuple pattern had a label for the tuple element, it must match
1258+
// the label for the tuple type being matched.
1259+
if (!patternElt.getLabel().empty() &&
1260+
patternElt.getLabel() != typeElt.getName()) {
1261+
diags.diagnose(patternElt.getLabelLoc(),
1262+
diag::tuple_pattern_label_mismatch,
1263+
patternElt.getLabel(), typeElt.getName());
1264+
return nullptr;
1265+
}
12561266

1257-
Type CoercionType;
1258-
if (hadError)
1259-
CoercionType = ErrorType::get(Context);
1260-
else
1261-
CoercionType = tupleTy->getElement(i).getType();
1262-
1263-
// If the tuple pattern had a label for the tuple element, it must match
1264-
// 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;
1270-
}
1267+
auto *sub =
1268+
coercePatternToType(pattern.forSubPattern(patternElt.getPattern(),
1269+
/*retainTopLevel=*/false),
1270+
typeElt.getType(), subOptions);
1271+
if (!sub)
1272+
return nullptr;
12711273

1272-
auto sub = coercePatternToType(
1273-
pattern.forSubPattern(elt.getPattern(), /*retainTopLevel=*/false),
1274-
CoercionType, subOptions);
1275-
if (!sub)
1276-
return nullptr;
1274+
patternElt.setPattern(sub);
1275+
}
12771276

1278-
if (!hadError)
1279-
elt.setPattern(sub);
1277+
P->setType(type);
12801278
}
12811279

1282-
if (hadError)
1283-
return nullptr;
1284-
12851280
return P;
12861281
}
12871282

0 commit comments

Comments
 (0)