@@ -975,9 +975,26 @@ bool MissingForcedDowncastFailure::diagnoseAsError() {
975
975
auto fromType = getFromType ();
976
976
auto toType = getToType ();
977
977
978
- emitDiagnostic (diag::missing_forced_downcast, fromType, toType)
979
- .highlight (getSourceRange ())
980
- .fixItReplace (getLoc (), " as!" );
978
+ emitDiagnostic (diag::cannot_coerce_to_type, fromType, toType);
979
+
980
+ auto &solution = getSolution ();
981
+ auto restriction = solution.ConstraintRestrictions .find (
982
+ {toType->getCanonicalType (),
983
+ OptionalType::get (toType)->getCanonicalType ()});
984
+ // If the type has an value to optional conversion we can instead suggest
985
+ // the conditional downcast as it is safer in situations like conditional
986
+ // binding.
987
+ if (restriction != solution.ConstraintRestrictions .end () &&
988
+ restriction->getSecond () == ConversionRestrictionKind::ValueToOptional) {
989
+ emitDiagnostic (diag::missing_optional_downcast)
990
+ .highlight (getSourceRange ())
991
+ .fixItReplace (getLoc (), " as?" );
992
+ } else {
993
+ emitDiagnostic (diag::missing_forced_downcast)
994
+ .highlight (getSourceRange ())
995
+ .fixItReplace (getLoc (), " as!" );
996
+ }
997
+
981
998
return true ;
982
999
}
983
1000
@@ -1051,10 +1068,19 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
1051
1068
if (needsParensOutside)
1052
1069
insertAfter += " )" ;
1053
1070
1054
- auto diagID =
1055
- useAs ? diag::missing_explicit_conversion : diag::missing_forced_downcast;
1056
- auto diag = emitDiagnostic (diagID, fromType, toType);
1071
+ auto diagnose = [&]() {
1072
+ if (useAs) {
1073
+ return emitDiagnostic (diag::missing_explicit_conversion, fromType,
1074
+ toType);
1075
+ } else {
1076
+ // Emit error diagnostic.
1077
+ emitDiagnostic (diag::cannot_coerce_to_type, fromType, toType);
1078
+ // Emit and return note suggesting as! where the fixit will be placed.
1079
+ return emitDiagnostic (diag::missing_forced_downcast);
1080
+ }
1081
+ };
1057
1082
1083
+ auto diag = diagnose ();
1058
1084
if (!insertBefore.empty ()) {
1059
1085
diag.fixItInsert (getSourceRange ().Start , insertBefore);
1060
1086
}
0 commit comments