Skip to content

Commit f96a003

Browse files
committed
Use a single warning, but dynamically specify 'nil' or 'Optional.none'
1 parent c2bf0f9 commit f96a003

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4007,11 +4007,8 @@ WARNING(use_of_qq_on_non_optional_value,none,
40074007
"left side of nil coalescing operator '?""?' has non-optional type %0, "
40084008
"so the right side is never used", (Type))
40094009
WARNING(nonoptional_compare_to_nil,none,
4010-
"comparing non-optional value of type %0 to 'nil' always returns"
4011-
" %select{false|true}1", (Type, bool))
4012-
WARNING(nonoptional_compare_to_optional_none_case,none,
4013-
"comparing non-optional value of type %0 to 'Optional.none' always returns"
4014-
" %select{false|true}1", (Type, bool))
4010+
"comparing non-optional value of type %0 to '%select{Optional.none|nil}1' always returns"
4011+
" %select{false|true}2", (Type, bool, bool))
40154012
WARNING(optional_check_nonoptional,none,
40164013
"non-optional expression of type %0 used in a check for optionals",
40174014
(Type))

lib/Sema/MiscDiagnostics.cpp

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,19 +1282,28 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
12821282

12831283
}
12841284

1285-
/// Returns true if this is a 'nil' literal
1286-
bool isNilLiteral(Expr *E) {
1285+
/// Return true if this is a 'nil' literal. This looks
1286+
/// like this if the type is Optional<T>:
1287+
///
1288+
/// (dot_syntax_call_expr type='String?'
1289+
/// (declref_expr type='(Optional<String>.Type) -> Optional<String>'
1290+
/// decl=Swift.(file).Optional.none function_ref=unapplied)
1291+
/// (argument_list implicit
1292+
/// (argument
1293+
/// (type_expr implicit type='String?.Type' typerepr='String?'))))
1294+
///
1295+
/// Or like this if it is any other ExpressibleByNilLiteral type:
1296+
///
1297+
/// (nil_literal_expr)
1298+
///
1299+
bool isTypeCheckedOptionalNil(Expr *E) {
12871300
if (dyn_cast<NilLiteralExpr>(E)) return true;
1288-
return false;
1289-
}
1290-
1291-
/// Returns true if this is a expression is a reference to
1292-
/// the `Optional.none` case specifically (e.g. not `nil`).
1293-
bool isOptionalNoneCase(Expr *E) {
1301+
12941302
auto CE = dyn_cast<ApplyExpr>(E->getSemanticsProvidingExpr());
12951303
if (!CE)
12961304
return false;
12971305

1306+
// First case -- Optional.none
12981307
if (auto DRE = dyn_cast<DeclRefExpr>(CE->getSemanticFn()))
12991308
return DRE->getDecl() == Ctx.getOptionalNoneDecl();
13001309

@@ -1339,30 +1348,15 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
13391348

13401349
if (calleeName == "==" || calleeName == "!=" ||
13411350
calleeName == "===" || calleeName == "!==") {
1342-
bool isTrue = calleeName == "!=" || calleeName == "!==";
1343-
1344-
// Diagnose a redundant comparison of a non-optional to a `nil` literal
13451351
if (((subExpr = isImplicitPromotionToOptional(lhs)) &&
1346-
isNilLiteral(rhs)) ||
1347-
(isNilLiteral(lhs) &&
1352+
isTypeCheckedOptionalNil(rhs)) ||
1353+
(isTypeCheckedOptionalNil(lhs) &&
13481354
(subExpr = isImplicitPromotionToOptional(rhs)))) {
13491355
bool isTrue = calleeName == "!=" || calleeName == "!==";
1356+
bool isNilLiteral = dyn_cast<NilLiteralExpr>(lhs) || dyn_cast<NilLiteralExpr>(rhs);
13501357

13511358
Ctx.Diags.diagnose(DRE->getLoc(), diag::nonoptional_compare_to_nil,
1352-
subExpr->getType(), isTrue)
1353-
.highlight(lhs->getSourceRange())
1354-
.highlight(rhs->getSourceRange());
1355-
return;
1356-
}
1357-
1358-
// Diagnose a redundant comparison of a non-optional to the `Optional.none` case
1359-
if (((subExpr = isImplicitPromotionToOptional(lhs)) &&
1360-
isOptionalNoneCase(rhs)) ||
1361-
(isOptionalNoneCase(lhs) &&
1362-
(subExpr = isImplicitPromotionToOptional(rhs)))) {
1363-
1364-
Ctx.Diags.diagnose(DRE->getLoc(), diag::nonoptional_compare_to_optional_none_case,
1365-
subExpr->getType(), isTrue)
1359+
subExpr->getType(), isNilLiteral, isTrue)
13661360
.highlight(lhs->getSourceRange())
13671361
.highlight(rhs->getSourceRange());
13681362
return;

0 commit comments

Comments
 (0)