From 6e4dcea0d92e83bbcd983b525abf2a87971a9fe8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 6 Mar 2021 17:32:47 +0900 Subject: [PATCH] Handle negative literals in cast overflow warning --- compiler/rustc_lint/src/types.rs | 27 +++++++++++++++++++++------ src/test/ui/lint/type-overflow.stderr | 3 ++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 792655ff35a..2d311cc32f8 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -217,7 +217,11 @@ fn report_bin_hex_error( cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| { let (t, actually) = match ty { attr::IntType::SignedInt(t) => { - let actually = size.sign_extend(val) as i128; + let actually = if negative { + -(size.sign_extend(val) as i128) + } else { + size.sign_extend(val) as i128 + }; (t.name_str(), actually.to_string()) } attr::IntType::UnsignedInt(t) => { @@ -226,11 +230,22 @@ fn report_bin_hex_error( } }; let mut err = lint.build(&format!("literal out of range for `{}`", t)); - err.note(&format!( - "the literal `{}` (decimal `{}`) does not fit into \ - the type `{}` and will become `{}{}`", - repr_str, val, t, actually, t - )); + if negative { + // If the value is negative, + // emits a note about the value itself, apart from the literal. + err.note(&format!( + "the literal `{}` (decimal `{}`) does not fit into \ + the type `{}`", + repr_str, val, t + )); + err.note(&format!("and the value `-{}` will become `{}{}`", repr_str, actually, t)); + } else { + err.note(&format!( + "the literal `{}` (decimal `{}`) does not fit into \ + the type `{}` and will become `{}{}`", + repr_str, val, t, actually, t + )); + } if let Some(sugg_ty) = get_type_suggestion(&cx.typeck_results().node_type(expr.hir_id), val, negative) { diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 521223e3256..8a31fd44746 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -60,7 +60,8 @@ warning: literal out of range for `i8` LL | let fail = -0b1111_1111i8; | ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16` | - = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` and will become `-1i8` + = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` + = note: and the value `-0b1111_1111i8` will become `1i8` warning: 7 warnings emitted