Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2030,18 +2030,33 @@ pub(crate) enum OverflowingBinHexSub<'a> {
}

#[derive(Subdiagnostic)]
#[suggestion(
"to use as a negative number (decimal `{$negative_val}`), consider using the type `{$uint_ty}` for the literal and cast it to `{$int_ty}`",
code = "{lit_no_suffix}{uint_ty} as {int_ty}",
applicability = "maybe-incorrect"
)]
pub(crate) struct OverflowingBinHexSignBitSub<'a> {
#[primary_span]
pub span: Span,
pub lit_no_suffix: &'a str,
pub negative_val: String,
pub uint_ty: &'a str,
pub int_ty: &'a str,
pub(crate) enum OverflowingBinHexSignBitSub<'a> {
#[suggestion(
"to use as a negative number (decimal `{$negative_val}`), consider using the type `{$uint_ty}` for the literal and cast it to `{$int_ty}`",
code = "{lit_no_suffix}{uint_ty}.cast_signed()",
applicability = "maybe-incorrect"
)]
CastSigned {
#[primary_span]
span: Span,
lit_no_suffix: &'a str,
negative_val: String,
uint_ty: &'a str,
int_ty: &'a str,
},
#[suggestion(
"to use as a negative number (decimal `{$negative_val}`), consider using the type `{$uint_ty}` for the literal and cast it to `{$int_ty}`",
code = "{lit_no_suffix}{uint_ty} as {int_ty}",
applicability = "maybe-incorrect"
)]
AsCast {
#[primary_span]
span: Span,
lit_no_suffix: &'a str,
negative_val: String,
uint_ty: &'a str,
int_ty: &'a str,
},
}

#[derive(Diagnostic)]
Expand Down
26 changes: 19 additions & 7 deletions compiler/rustc_lint/src/types/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,25 @@ fn report_bin_hex_error(
&repr_str
};

Some(OverflowingBinHexSignBitSub {
span,
lit_no_suffix,
negative_val: actually,
int_ty: int_ty.name_str(),
uint_ty: Integer::fit_unsigned(val).uint_ty_str(),
})
let uint_ty = Integer::fit_unsigned(val);
// `cast_signed` only supports equal-width integer casts.
if uint_ty.size() == size {
Some(OverflowingBinHexSignBitSub::CastSigned {
span,
lit_no_suffix,
negative_val: actually,
uint_ty: uint_ty.uint_ty_str(),
int_ty: int_ty.name_str(),
})
} else {
Some(OverflowingBinHexSignBitSub::AsCast {
span,
lit_no_suffix,
negative_val: actually,
uint_ty: uint_ty.uint_ty_str(),
int_ty: int_ty.name_str(),
})
}
Comment thread
YingqiDuan marked this conversation as resolved.
})
.flatten();

Expand Down
9 changes: 5 additions & 4 deletions tests/ui/fmt/no-inline-literals-out-of-range.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ LL + format_args!("{}", 0x8f_u8); // issue #115423
|
help: to use as a negative number (decimal `-113`), consider using the type `u8` for the literal and cast it to `i8`
|
LL | format_args!("{}", 0x8f_u8 as i8); // issue #115423
| +++++
LL - format_args!("{}", 0x8f_i8); // issue #115423
LL + format_args!("{}", 0x8f_u8.cast_signed()); // issue #115423
|

error: literal out of range for `u8`
--> $DIR/no-inline-literals-out-of-range.rs:6:24
Expand Down Expand Up @@ -50,8 +51,8 @@ LL | format_args!("{}", 0xffff_ffff); // treat unsuffixed literals as i32
= help: consider using the type `u32` instead
help: to use as a negative number (decimal `-1`), consider using the type `u32` for the literal and cast it to `i32`
|
LL | format_args!("{}", 0xffff_ffffu32 as i32); // treat unsuffixed literals as i32
| ++++++++++
LL | format_args!("{}", 0xffff_ffffu32.cast_signed()); // treat unsuffixed literals as i32
| +++++++++++++++++

error: aborting due to 5 previous errors

14 changes: 8 additions & 6 deletions tests/ui/lint/type-overflow.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ LL + let fail = 0b1000_0001u8;
|
help: to use as a negative number (decimal `-127`), consider using the type `u8` for the literal and cast it to `i8`
|
LL | let fail = 0b1000_0001u8 as i8;
| +++++
LL - let fail = 0b1000_0001i8;
LL + let fail = 0b1000_0001u8.cast_signed();
|

warning: literal out of range for `i64`
--> $DIR/type-overflow.rs:15:16
Expand All @@ -43,8 +44,9 @@ LL + let fail = 0x8000_0000_0000_0000u64;
|
help: to use as a negative number (decimal `-9223372036854775808`), consider using the type `u64` for the literal and cast it to `i64`
|
LL | let fail = 0x8000_0000_0000_0000u64 as i64;
| ++++++
LL - let fail = 0x8000_0000_0000_0000i64;
LL + let fail = 0x8000_0000_0000_0000u64.cast_signed();
|

warning: literal out of range for `u32`
--> $DIR/type-overflow.rs:19:16
Expand All @@ -64,8 +66,8 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
= help: consider using the type `u128` instead
help: to use as a negative number (decimal `-170141183460469231731687303715884105728`), consider using the type `u128` for the literal and cast it to `i128`
|
LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128 as i128;
| ++++++++++++
LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.cast_signed();
| ++++++++++++++++++

warning: literal out of range for `i32`
--> $DIR/type-overflow.rs:27:16
Expand Down
Loading