@@ -1204,17 +1204,25 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1204
1204
// TODO: permit implicit conversions?
1205
1205
case PatternKind::Tuple: {
1206
1206
TuplePattern *TP = cast<TuplePattern>(P);
1207
- bool hadError = type->hasError ();
1208
-
1207
+
1208
+ TupleType *tupleTy = type->getAs <TupleType>();
1209
+
1209
1210
// Sometimes a paren is just a paren. If the tuple pattern has a single
1210
1211
// 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);
1218
1226
if (!sub)
1219
1227
return nullptr ;
1220
1228
@@ -1225,63 +1233,51 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1225
1233
} else {
1226
1234
P = sub;
1227
1235
}
1236
+
1228
1237
return P;
1229
- };
1238
+ }
1230
1239
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) {
1236
1241
diags.diagnose (TP->getStartLoc (),
1237
1242
diag::tuple_pattern_in_non_tuple_context, type);
1238
- hadError = true ;
1243
+
1244
+ return nullptr ;
1239
1245
}
1240
1246
1241
1247
// 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 ()) {
1246
1249
diags.diagnose (TP->getStartLoc (), diag::tuple_pattern_length_mismatch,
1247
1250
type);
1248
- hadError = true ;
1251
+
1252
+ return nullptr ;
1249
1253
}
1250
1254
1251
1255
// Coerce each tuple element to the respective type.
1252
- P->setType (type);
1253
-
1254
1256
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);
1256
1259
1257
- Type CoercionType;
1258
- if (hadError)
1259
- CoercionType = ErrorType::get (Context);
1260
- else
1261
- CoercionType = tupleTy->getElement (i).getType ();
1262
-
1263
1260
// If the tuple pattern had a label for the tuple element, it must match
1264
1261
// 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 ;
1270
1268
}
1271
1269
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);
1275
1274
if (!sub)
1276
1275
return nullptr ;
1277
1276
1278
- if (!hadError)
1279
- elt.setPattern (sub);
1277
+ patternElt.setPattern (sub);
1280
1278
}
1281
1279
1282
- if (hadError)
1283
- return nullptr ;
1284
-
1280
+ P->setType (type);
1285
1281
return P;
1286
1282
}
1287
1283
0 commit comments