diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-06-11 14:16:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-11 14:16:47 +0100 |
| commit | cfd48bdd7e124565de8022f8b87ef5a3aa7f78cd (patch) | |
| tree | 569c4ba9fde857fd201ec0729b3f7048ddb0051a /compiler/rustc_middle/src | |
| parent | 2a94a5bc218c6af1667a856f9fee1fdfe892fdc7 (diff) | |
| parent | de4ac0c465facfdfd56ce08dc6bb5cfee901561c (diff) | |
Rollup merge of #126265 - RalfJung:interpret-cast-validity, r=oli-obk
interpret: ensure we check bool/char for validity when they are used in a cast In general, `Scalar::to_bits` is a bit dangerous as it bypasses all type information. We should usually prefer matching on the type and acting according to that. So I also refactored `unary_op` handling of integers to do that. The remaining `to_bits` uses are operations that just fundamentally don't care about the sign (and only work on integers). invalid_char_cast.rs is the key new test, the others already passed before this PR. r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/int.rs | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 52320dd141b..13691b61941 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -209,8 +209,8 @@ impl ScalarInt { #[inline] pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> { - let data = i.into(); - if size.truncate(data) == data { Some(Self::raw(data, size)) } else { None } + let (r, overflow) = Self::truncate_from_uint(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. @@ -223,20 +223,15 @@ impl ScalarInt { #[inline] pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> { - let i = i.into(); - // `into` performed sign extension, we have to truncate - let truncated = size.truncate(i as u128); - if size.sign_extend(truncated) as i128 == i { - Some(Self::raw(truncated, size)) - } else { - None - } + let (r, overflow) = Self::truncate_from_int(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. #[inline] pub fn truncate_from_int(i: impl Into<i128>, size: Size) -> (Self, bool) { let data = i.into(); + // `into` performed sign extension, we have to truncate let r = Self::raw(size.truncate(data as u128), size); (r, size.sign_extend(r.data) as i128 != data) } |
