@@ -954,7 +954,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
954
954
// / "repair" the pattern if needed. This ensures that the pattern engine
955
955
// / receives well-formed input, avoiding the need to implement an additional
956
956
// / compatibility hack there, as doing that is lot more tricky due to the
957
- // / different cases that need to handled.
957
+ // / different cases that need to be handled.
958
958
// /
959
959
// / We also emit diagnostics and potentially a fix-it to help the user.
960
960
// /
@@ -1011,12 +1011,16 @@ void repairTupleOrAssociatedValuePatternIfApplicable(
1011
1011
addDeclNote = true ;
1012
1012
}
1013
1013
}
1014
- } else if (auto *tupleType = enumPayloadType->getAs <TupleType>()) {
1014
+ } else if (auto *tupleType = enumPayloadType
1015
+ // Account for implicit optional promotion.
1016
+ ->lookThroughAllOptionalTypes ()
1017
+ ->getAs <TupleType>()) {
1015
1018
if (tupleType->getNumElements () >= 2 ) {
1016
1019
if (auto *tuplePattern = dyn_cast<TuplePattern>(enumElementInnerPat)) {
1017
1020
DE.diagnose (enumElementInnerPat->getLoc (),
1018
1021
diag::converting_several_associated_values_into_tuple,
1019
1022
enumCase->getNameStr (),
1023
+ enumPayloadType->isOptional (),
1020
1024
tupleType->getNumElements ())
1021
1025
.fixItInsert (enumElementInnerPat->getStartLoc (), " (" )
1022
1026
.fixItInsertAfter (enumElementInnerPat->getEndLoc (), " )" );
@@ -1237,6 +1241,21 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1237
1241
return P;
1238
1242
}
1239
1243
1244
+ // Allow optional promotion only when pattern matching is allowed to
1245
+ // fail (in statement conditions, 'switch' case items, but not pattern
1246
+ // binding declarations).
1247
+ const bool allowOptionalPromotion = !pattern.getPatternBindingDecl ();
1248
+
1249
+ const auto origTy = type;
1250
+ if (allowOptionalPromotion) {
1251
+ // Peel away any optionality. If the coercion succeeds, we will promote
1252
+ // the resulting pattern to the original type by wrapping it in
1253
+ // 'OptionalSome' patterns.
1254
+ type = type->lookThroughAllOptionalTypes ();
1255
+ }
1256
+
1257
+ tupleTy = type->getAs <TupleType>();
1258
+
1240
1259
if (!tupleTy) {
1241
1260
diags.diagnose (TP->getStartLoc (),
1242
1261
diag::tuple_pattern_in_non_tuple_context, type);
@@ -1278,6 +1297,21 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1278
1297
}
1279
1298
1280
1299
P->setType (type);
1300
+
1301
+ if (allowOptionalPromotion) {
1302
+ // If the original coercion type is optional, promote the resulting
1303
+ // pattern to a matching optionality.
1304
+ if (auto wrappedTy = origTy->getOptionalObjectType ()) {
1305
+ do {
1306
+ auto *OSP =
1307
+ OptionalSomePattern::createImplicit (Context, P, P->getEndLoc ());
1308
+ OSP->setType (OptionalType::get (P->getType ()));
1309
+ P = OSP;
1310
+ wrappedTy = wrappedTy->getOptionalObjectType ();
1311
+ } while (wrappedTy);
1312
+ }
1313
+ }
1314
+
1281
1315
return P;
1282
1316
}
1283
1317
0 commit comments