@@ -3170,7 +3170,7 @@ namespace {
3170
3170
cast->setImplicit ();
3171
3171
3172
3172
// Type-check this conditional case.
3173
- Expr *result = visitConditionalCheckedCastExpr (cast, true );
3173
+ Expr *result = handleConditionalCheckedCastExpr (cast, true );
3174
3174
if (!result)
3175
3175
return nullptr ;
3176
3176
@@ -3409,7 +3409,28 @@ namespace {
3409
3409
return addFinalOptionalInjections (result);
3410
3410
}
3411
3411
3412
+ bool hasForcedOptionalResult (ExplicitCastExpr *expr) {
3413
+ auto *TR = expr->getCastTypeLoc ().getTypeRepr ();
3414
+ if (TR && TR->getKind () == TypeReprKind::ImplicitlyUnwrappedOptional) {
3415
+ auto *locator = cs.getConstraintLocator (
3416
+ expr, ConstraintLocator::ImplicitlyUnwrappedCoercionResult);
3417
+ return solution.getDisjunctionChoice (locator);
3418
+ }
3419
+ return false ;
3420
+ }
3421
+
3412
3422
Expr *visitCoerceExpr (CoerceExpr *expr) {
3423
+ // If we need to insert a force-unwrap for coercions of the form
3424
+ // 'as T!', do so now.
3425
+ if (hasForcedOptionalResult (expr)) {
3426
+ auto *coerced = visitCoerceExpr (expr, None);
3427
+ if (!coerced)
3428
+ return nullptr ;
3429
+
3430
+ return coerceImplicitlyUnwrappedOptionalToValue (
3431
+ coerced, cs.getType (coerced)->getOptionalObjectType ());
3432
+ }
3433
+
3413
3434
return visitCoerceExpr (expr, None);
3414
3435
}
3415
3436
@@ -3482,7 +3503,24 @@ namespace {
3482
3503
return expr;
3483
3504
}
3484
3505
3506
+ // Rewrite ForcedCheckedCastExpr based on what the solver computed.
3485
3507
Expr *visitForcedCheckedCastExpr (ForcedCheckedCastExpr *expr) {
3508
+ // If we need to insert a force-unwrap for coercions of the form
3509
+ // 'as! T!', do so now.
3510
+ if (hasForcedOptionalResult (expr)) {
3511
+ auto *coerced = handleForcedCheckedCastExpr (expr);
3512
+ if (!coerced)
3513
+ return nullptr ;
3514
+
3515
+ return coerceImplicitlyUnwrappedOptionalToValue (
3516
+ coerced, cs.getType (coerced)->getOptionalObjectType ());
3517
+ }
3518
+
3519
+ return handleForcedCheckedCastExpr (expr);
3520
+ }
3521
+
3522
+ // Most of the logic for dealing with ForcedCheckedCastExpr.
3523
+ Expr *handleForcedCheckedCastExpr (ForcedCheckedCastExpr *expr) {
3486
3524
// Simplify the type we're casting to.
3487
3525
auto toType = simplifyType (expr->getCastTypeLoc ().getType ());
3488
3526
expr->getCastTypeLoc ().setType (toType, /* validated=*/ true );
@@ -3546,8 +3584,23 @@ namespace {
3546
3584
OptionalBindingsCastKind::Forced);
3547
3585
}
3548
3586
3549
- Expr *visitConditionalCheckedCastExpr (ConditionalCheckedCastExpr *expr,
3550
- bool isInsideIsExpr = false ) {
3587
+ Expr *visitConditionalCheckedCastExpr (ConditionalCheckedCastExpr *expr) {
3588
+ // If we need to insert a force-unwrap for coercions of the form
3589
+ // 'as! T!', do so now.
3590
+ if (hasForcedOptionalResult (expr)) {
3591
+ auto *coerced = handleConditionalCheckedCastExpr (expr);
3592
+ if (!coerced)
3593
+ return nullptr ;
3594
+
3595
+ return coerceImplicitlyUnwrappedOptionalToValue (
3596
+ coerced, cs.getType (coerced)->getOptionalObjectType ());
3597
+ }
3598
+
3599
+ return handleConditionalCheckedCastExpr (expr);
3600
+ }
3601
+
3602
+ Expr *handleConditionalCheckedCastExpr (ConditionalCheckedCastExpr *expr,
3603
+ bool isInsideIsExpr = false ) {
3551
3604
// Simplify the type we're casting to.
3552
3605
auto toType = simplifyType (expr->getCastTypeLoc ().getType ());
3553
3606
checkForImportedUsedConformances (toType);
0 commit comments