-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #73513 - oli-obk:const_binop_overflow, r=estebank
Show the values and computation that would overflow a const evaluation or propagation Fixes #71134 In contrast to the example in the issue it doesn't use individual spans for each operand. The effort required to implement that is quite high compared to the little (if at all) benefit it would bring to diagnostics. cc @shepmaster The way this is implemented it is also fairly easy to do the same for overflow panics at runtime, but that should be done in a separate PR since it may have runtime performance implications.
- Loading branch information
Showing
202 changed files
with
1,273 additions
and
986 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use crate::mir::interpret::truncate; | ||
use rustc_target::abi::Size; | ||
|
||
#[derive(Copy, Clone)] | ||
/// A type for representing any integer. Only used for printing. | ||
// FIXME: Use this for the integer-tree representation needed for type level ints and | ||
// const generics? | ||
pub struct ConstInt { | ||
/// Number of bytes of the integer. Only 1, 2, 4, 8, 16 are legal values. | ||
size: u8, | ||
/// Whether the value is of a signed integer type. | ||
signed: bool, | ||
/// Whether the value is a `usize` or `isize` type. | ||
is_ptr_sized_integral: bool, | ||
/// Raw memory of the integer. All bytes beyond the `size` are unused and must be zero. | ||
raw: u128, | ||
} | ||
|
||
impl ConstInt { | ||
pub fn new(raw: u128, size: Size, signed: bool, is_ptr_sized_integral: bool) -> Self { | ||
assert!(raw <= truncate(u128::MAX, size)); | ||
Self { raw, size: size.bytes() as u8, signed, is_ptr_sized_integral } | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for ConstInt { | ||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let Self { size, signed, raw, is_ptr_sized_integral } = *self; | ||
if signed { | ||
let bit_size = size * 8; | ||
let min = 1u128 << (bit_size - 1); | ||
let max = min - 1; | ||
if raw == min { | ||
match (size, is_ptr_sized_integral) { | ||
(_, true) => write!(fmt, "isize::MIN"), | ||
(1, _) => write!(fmt, "i8::MIN"), | ||
(2, _) => write!(fmt, "i16::MIN"), | ||
(4, _) => write!(fmt, "i32::MIN"), | ||
(8, _) => write!(fmt, "i64::MIN"), | ||
(16, _) => write!(fmt, "i128::MIN"), | ||
_ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed), | ||
} | ||
} else if raw == max { | ||
match (size, is_ptr_sized_integral) { | ||
(_, true) => write!(fmt, "isize::MAX"), | ||
(1, _) => write!(fmt, "i8::MAX"), | ||
(2, _) => write!(fmt, "i16::MAX"), | ||
(4, _) => write!(fmt, "i32::MAX"), | ||
(8, _) => write!(fmt, "i64::MAX"), | ||
(16, _) => write!(fmt, "i128::MAX"), | ||
_ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed), | ||
} | ||
} else { | ||
match size { | ||
1 => write!(fmt, "{}", raw as i8)?, | ||
2 => write!(fmt, "{}", raw as i16)?, | ||
4 => write!(fmt, "{}", raw as i32)?, | ||
8 => write!(fmt, "{}", raw as i64)?, | ||
16 => write!(fmt, "{}", raw as i128)?, | ||
_ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed), | ||
} | ||
if fmt.alternate() { | ||
match (size, is_ptr_sized_integral) { | ||
(_, true) => write!(fmt, "_isize")?, | ||
(1, _) => write!(fmt, "_i8")?, | ||
(2, _) => write!(fmt, "_i16")?, | ||
(4, _) => write!(fmt, "_i32")?, | ||
(8, _) => write!(fmt, "_i64")?, | ||
(16, _) => write!(fmt, "_i128")?, | ||
_ => bug!(), | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} else { | ||
let max = truncate(u128::MAX, Size::from_bytes(size)); | ||
if raw == max { | ||
match (size, is_ptr_sized_integral) { | ||
(_, true) => write!(fmt, "usize::MAX"), | ||
(1, _) => write!(fmt, "u8::MAX"), | ||
(2, _) => write!(fmt, "u16::MAX"), | ||
(4, _) => write!(fmt, "u32::MAX"), | ||
(8, _) => write!(fmt, "u64::MAX"), | ||
(16, _) => write!(fmt, "u128::MAX"), | ||
_ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed), | ||
} | ||
} else { | ||
match size { | ||
1 => write!(fmt, "{}", raw as u8)?, | ||
2 => write!(fmt, "{}", raw as u16)?, | ||
4 => write!(fmt, "{}", raw as u32)?, | ||
8 => write!(fmt, "{}", raw as u64)?, | ||
16 => write!(fmt, "{}", raw as u128)?, | ||
_ => bug!("ConstInt 0x{:x} with size = {} and signed = {}", raw, size, signed), | ||
} | ||
if fmt.alternate() { | ||
match (size, is_ptr_sized_integral) { | ||
(_, true) => write!(fmt, "_usize")?, | ||
(1, _) => write!(fmt, "_u8")?, | ||
(2, _) => write!(fmt, "_u16")?, | ||
(4, _) => write!(fmt, "_u32")?, | ||
(8, _) => write!(fmt, "_u64")?, | ||
(16, _) => write!(fmt, "_u128")?, | ||
_ => bug!(), | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.