Skip to content

Commit 1479c00

Browse files
[Sema] Detach did you mean from error missing force downcast diagnostic moving to note
1 parent 887464b commit 1479c00

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,9 +1108,13 @@ ERROR(missing_unwrap_optional_try,none,
11081108
"value of optional type %0 not unwrapped; did you mean to use 'try!' "
11091109
"or chain with '?'?",
11101110
(Type))
1111-
ERROR(missing_forced_downcast,none,
1112-
"%0 is not convertible to %1; "
1113-
"did you mean to use 'as!' to force downcast?", (Type, Type))
1111+
ERROR(cannot_coerce_to_type, none,
1112+
"%0 is not convertible to %1", (Type, Type))
1113+
NOTE(missing_forced_downcast, none,
1114+
"did you mean to use 'as!' to force downcast?", ())
1115+
NOTE(missing_optional_downcast, none,
1116+
"did you mean to use 'as?' to conditionally downcast?", ())
1117+
11141118
WARNING(coercion_may_fail_warning,none,
11151119
"coercion from %0 to %1 may fail; use 'as?' or 'as!' instead",
11161120
(Type, Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,26 @@ bool MissingForcedDowncastFailure::diagnoseAsError() {
975975
auto fromType = getFromType();
976976
auto toType = getToType();
977977

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+
981998
return true;
982999
}
9831000

@@ -1051,10 +1068,19 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
10511068
if (needsParensOutside)
10521069
insertAfter += ")";
10531070

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+
};
10571082

1083+
auto diag = diagnose();
10581084
if (!insertBefore.empty()) {
10591085
diag.fixItInsert(getSourceRange().Start, insertBefore);
10601086
}

0 commit comments

Comments
 (0)