Skip to content

Commit 780baec

Browse files
committed
[NFC] Sema: Tidy up tuple pattern handling in coercePatternToType
1 parent 08207ee commit 780baec

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
@@ -1192,17 +1192,25 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
11921192
// TODO: permit implicit conversions?
11931193
case PatternKind::Tuple: {
11941194
TuplePattern *TP = cast<TuplePattern>(P);
1195-
bool hadError = type->hasError();
1196-
1195+
1196+
TupleType *tupleTy = type->getAs<TupleType>();
1197+
11971198
// Sometimes a paren is just a paren. If the tuple pattern has a single
11981199
// element, we can reduce it to a paren pattern.
1199-
bool canDecayToParen = TP->getNumElements() == 1;
1200-
auto decayToParen = [&]() -> Pattern * {
1201-
assert(canDecayToParen);
1202-
Pattern *sub = TP->getElement(0).getPattern();
1203-
sub = TypeChecker::coercePatternToType(
1204-
pattern.forSubPattern(sub, /*retainTopLevel=*/false), type,
1205-
subOptions);
1200+
//
1201+
// FIXME: This condition is rather loose, e.g. it makes the following compile:
1202+
// switch 0 {
1203+
// case (int: 0): break
1204+
// default: break
1205+
// }
1206+
// Do we really want/need to support this?
1207+
//
1208+
if (TP->getNumElements() == 1 &&
1209+
(!tupleTy || tupleTy->getNumElements() != 1)) {
1210+
auto *sub = TypeChecker::coercePatternToType(
1211+
pattern.forSubPattern(TP->getElement(0).getPattern(),
1212+
/*retainTopLevel=*/false),
1213+
type, subOptions);
12061214
if (!sub)
12071215
return nullptr;
12081216

@@ -1213,63 +1221,50 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
12131221
} else {
12141222
P = sub;
12151223
}
1216-
return P;
1217-
};
1224+
} else {
1225+
if (!tupleTy) {
1226+
diags.diagnose(TP->getStartLoc(),
1227+
diag::tuple_pattern_in_non_tuple_context, type);
12181228

1219-
// The context type must be a tuple.
1220-
TupleType *tupleTy = type->getAs<TupleType>();
1221-
if (!tupleTy && !hadError) {
1222-
if (canDecayToParen)
1223-
return decayToParen();
1224-
diags.diagnose(TP->getStartLoc(),
1225-
diag::tuple_pattern_in_non_tuple_context, type);
1226-
hadError = true;
1227-
}
1229+
return nullptr;
1230+
}
12281231

1229-
// The number of elements must match exactly.
1230-
if (!hadError && tupleTy->getNumElements() != TP->getNumElements()) {
1231-
if (canDecayToParen)
1232-
return decayToParen();
1233-
1234-
diags.diagnose(TP->getStartLoc(), diag::tuple_pattern_length_mismatch,
1235-
type);
1236-
hadError = true;
1237-
}
1232+
// The number of elements must match exactly.
1233+
if (tupleTy->getNumElements() != TP->getNumElements()) {
1234+
diags.diagnose(TP->getStartLoc(), diag::tuple_pattern_length_mismatch,
1235+
type);
12381236

1239-
// Coerce each tuple element to the respective type.
1240-
P->setType(type);
1237+
return nullptr;
1238+
}
12411239

1242-
for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) {
1243-
TuplePatternElt &elt = TP->getElement(i);
1240+
// Coerce each tuple element to the respective type.
1241+
for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) {
1242+
TuplePatternElt &patternElt = TP->getElement(i);
1243+
const auto &typeElt = tupleTy->getElement(i);
1244+
1245+
// If the tuple pattern had a label for the tuple element, it must match
1246+
// the label for the tuple type being matched.
1247+
if (!patternElt.getLabel().empty() &&
1248+
patternElt.getLabel() != typeElt.getName()) {
1249+
diags.diagnose(patternElt.getLabelLoc(),
1250+
diag::tuple_pattern_label_mismatch,
1251+
patternElt.getLabel(), typeElt.getName());
1252+
return nullptr;
1253+
}
12441254

1245-
Type CoercionType;
1246-
if (hadError)
1247-
CoercionType = ErrorType::get(Context);
1248-
else
1249-
CoercionType = tupleTy->getElement(i).getType();
1250-
1251-
// If the tuple pattern had a label for the tuple element, it must match
1252-
// the label for the tuple type being matched.
1253-
if (!hadError && !elt.getLabel().empty() &&
1254-
elt.getLabel() != tupleTy->getElement(i).getName()) {
1255-
diags.diagnose(elt.getLabelLoc(), diag::tuple_pattern_label_mismatch,
1256-
elt.getLabel(), tupleTy->getElement(i).getName());
1257-
hadError = true;
1258-
}
1255+
auto *sub =
1256+
coercePatternToType(pattern.forSubPattern(patternElt.getPattern(),
1257+
/*retainTopLevel=*/false),
1258+
typeElt.getType(), subOptions);
1259+
if (!sub)
1260+
return nullptr;
12591261

1260-
auto sub = coercePatternToType(
1261-
pattern.forSubPattern(elt.getPattern(), /*retainTopLevel=*/false),
1262-
CoercionType, subOptions);
1263-
if (!sub)
1264-
return nullptr;
1262+
patternElt.setPattern(sub);
1263+
}
12651264

1266-
if (!hadError)
1267-
elt.setPattern(sub);
1265+
P->setType(type);
12681266
}
12691267

1270-
if (hadError)
1271-
return nullptr;
1272-
12731268
return P;
12741269
}
12751270

0 commit comments

Comments
 (0)