@@ -3924,15 +3924,22 @@ namespace {
3924
3924
}
3925
3925
3926
3926
Expr *visitCoerceExprImpl (CoerceExpr *expr) {
3927
- // Simplify and update the type we're coercing to.
3928
- assert (expr->getCastTypeRepr ());
3929
- const auto toType = simplifyType (cs.getType (expr->getCastTypeRepr ()));
3930
- expr->setCastType (toType);
3931
- cs.setType (expr->getCastTypeRepr (), toType);
3927
+ if (auto *castTypeRepr = expr->getCastTypeRepr ()) {
3928
+ // Simplify and update the type we're coercing to.
3929
+ auto toType = simplifyType (cs.getType (castTypeRepr));
3930
+ expr->setCastType (toType);
3931
+ cs.setType (castTypeRepr, toType);
3932
+ } else {
3933
+ assert (expr->isImplicit ());
3934
+ assert (expr->getCastType ());
3935
+ }
3936
+
3937
+ cs.setType (expr, expr->getCastType ());
3932
3938
3933
3939
// If this is a literal that got converted into constructor call
3934
3940
// lets put proper source information in place.
3935
3941
if (expr->isLiteralInit ()) {
3942
+ auto toType = expr->getCastType ();
3936
3943
auto *literalInit = expr->getSubExpr ();
3937
3944
if (auto *call = dyn_cast<CallExpr>(literalInit)) {
3938
3945
cs.forEachExpr (call->getFn (), [&](Expr *subExpr) -> Expr * {
@@ -3958,7 +3965,6 @@ namespace {
3958
3965
literalInit->setImplicit (false );
3959
3966
}
3960
3967
3961
- cs.setType (expr, toType);
3962
3968
// Keep the coercion around, because it contains the source range
3963
3969
// for the original constructor call.
3964
3970
return expr;
@@ -3980,28 +3986,30 @@ namespace {
3980
3986
// Convert the subexpression.
3981
3987
Expr *sub = expr->getSubExpr ();
3982
3988
3983
- sub = solution.coerceToType (sub, toType, cs.getConstraintLocator (sub));
3989
+ sub = solution.coerceToType (sub, expr->getCastType (),
3990
+ cs.getConstraintLocator (sub));
3984
3991
if (!sub)
3985
3992
return nullptr ;
3986
3993
3987
3994
expr->setSubExpr (sub);
3988
- cs.setType (expr, toType);
3989
3995
return expr;
3990
3996
}
3991
3997
3992
3998
// Bridging conversion.
3993
3999
assert (choice == 1 && " should be bridging" );
3994
4000
3995
4001
// Handle optional bindings.
3996
- Expr *sub = handleOptionalBindings (expr->getSubExpr (), toType,
3997
- OptionalBindingsCastKind::Bridged,
3998
- [&](Expr *sub, Type toInstanceType) {
3999
- return buildObjCBridgeExpr (sub, toInstanceType, locator);
4000
- });
4002
+ Expr *sub = handleOptionalBindings (
4003
+ expr->getSubExpr (), expr->getCastType (),
4004
+ OptionalBindingsCastKind::Bridged,
4005
+ [&](Expr *sub, Type toInstanceType) {
4006
+ return buildObjCBridgeExpr (sub, toInstanceType, locator);
4007
+ });
4008
+
4009
+ if (!sub)
4010
+ return nullptr ;
4001
4011
4002
- if (!sub) return nullptr ;
4003
4012
expr->setSubExpr (sub);
4004
- cs.setType (expr, toType);
4005
4013
return expr;
4006
4014
}
4007
4015
@@ -4011,24 +4019,35 @@ namespace {
4011
4019
auto sub = cs.coerceToRValue (expr->getSubExpr ());
4012
4020
expr->setSubExpr (sub);
4013
4021
4022
+ const auto fromType = cs.getType (sub);
4023
+
4024
+ Type toType;
4025
+ SourceRange castTypeRange;
4026
+
4014
4027
// Simplify and update the type we're casting to.
4015
- auto *const castTypeRepr = expr->getCastTypeRepr ();
4028
+ if (auto *const castTypeRepr = expr->getCastTypeRepr ()) {
4029
+ toType = simplifyType (cs.getType (castTypeRepr));
4030
+ castTypeRange = castTypeRepr->getSourceRange ();
4031
+
4032
+ cs.setType (castTypeRepr, toType);
4033
+ expr->setCastType (toType);
4034
+ } else {
4035
+ assert (expr->isImplicit ());
4036
+ assert (expr->getCastType ());
4037
+
4038
+ toType = expr->getCastType ();
4039
+ }
4016
4040
4017
- const auto fromType = cs.getType (sub);
4018
- auto toType = simplifyType (cs.getType (castTypeRepr));
4019
4041
if (hasForcedOptionalResult (expr))
4020
4042
toType = toType->getOptionalObjectType ();
4021
4043
4022
- expr->setCastType (toType);
4023
- cs.setType (castTypeRepr, toType);
4024
-
4025
- auto castContextKind =
4026
- SuppressDiagnostics ? CheckedCastContextKind::None
4027
- : CheckedCastContextKind::ForcedCast;
4044
+ auto castContextKind = SuppressDiagnostics || expr->isImplicit ()
4045
+ ? CheckedCastContextKind::None
4046
+ : CheckedCastContextKind::ForcedCast;
4028
4047
4029
4048
const auto castKind = TypeChecker::typeCheckCheckedCast (
4030
- fromType, toType, castContextKind, cs. DC , expr->getLoc (), sub,
4031
- castTypeRepr-> getSourceRange () );
4049
+ fromType, toType, castContextKind, dc , expr->getLoc (), sub,
4050
+ castTypeRange );
4032
4051
switch (castKind) {
4033
4052
// / Invalid cast.
4034
4053
case CheckedCastKind::Unresolved:
@@ -4048,16 +4067,30 @@ namespace {
4048
4067
expr->setCastKind (castKind);
4049
4068
break ;
4050
4069
}
4051
-
4070
+
4052
4071
return handleOptionalBindingsForCast (expr, simplifyType (cs.getType (expr)),
4053
4072
OptionalBindingsCastKind::Forced);
4054
4073
}
4055
4074
4056
4075
Expr *visitConditionalCheckedCastExpr (ConditionalCheckedCastExpr *expr) {
4057
- // Simplify and update the type we're casting to.
4058
4076
auto *const castTypeRepr = expr->getCastTypeRepr ();
4077
+
4078
+ // If there is no type repr, it means this is implicit cast which
4079
+ // should have a type set.
4080
+ if (!castTypeRepr) {
4081
+ assert (expr->isImplicit ());
4082
+ assert (expr->getCastType ());
4083
+
4084
+ auto sub = cs.coerceToRValue (expr->getSubExpr ());
4085
+ expr->setSubExpr (sub);
4086
+
4087
+ return expr;
4088
+ }
4089
+
4090
+ // Simplify and update the type we're casting to.
4059
4091
const auto toType = simplifyType (cs.getType (castTypeRepr));
4060
4092
expr->setCastType (toType);
4093
+
4061
4094
cs.setType (castTypeRepr, toType);
4062
4095
4063
4096
// If we need to insert a force-unwrap for coercions of the form
@@ -4094,7 +4127,7 @@ namespace {
4094
4127
: CheckedCastContextKind::ConditionalCast;
4095
4128
4096
4129
auto castKind = TypeChecker::typeCheckCheckedCast (
4097
- fromType, toType, castContextKind, cs. DC , expr->getLoc (), sub,
4130
+ fromType, toType, castContextKind, dc , expr->getLoc (), sub,
4098
4131
castTypeRepr->getSourceRange ());
4099
4132
switch (castKind) {
4100
4133
// Invalid cast.
@@ -4107,7 +4140,7 @@ namespace {
4107
4140
// Special handle for literals conditional checked cast when they can
4108
4141
// be statically coerced to the cast type.
4109
4142
if (protocol && TypeChecker::conformsToProtocol (
4110
- toType, protocol, cs. DC ->getParentModule ())) {
4143
+ toType, protocol, dc ->getParentModule ())) {
4111
4144
ctx.Diags
4112
4145
.diagnose (expr->getLoc (),
4113
4146
diag::literal_conditional_downcast_to_coercion,
0 commit comments