From 8122fb643fe306da88cb6c98c2409a7b89402c9e Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 16 Oct 2022 19:50:50 +0100 Subject: [PATCH 1/2] Add cfg(no_128_bit) to core: removes most u128/i128 operations --- library/core/Cargo.toml | 2 +- library/core/src/fmt/num.rs | 38 +++++++++++++++++-- library/core/src/lib.rs | 1 + library/core/src/num/int_macros.rs | 3 +- library/core/src/num/mod.rs | 4 +- library/core/src/num/nonzero.rs | 20 +++++++--- library/core/src/num/uint_macros.rs | 3 +- src/bootstrap/lib.rs | 1 + .../core-no-128-bit/Makefile | 8 ++++ .../run-make-fulldeps/core-no-128-bit/lib.rs | 31 +++++++++++++++ 10 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 tests/run-make-fulldeps/core-no-128-bit/Makefile create mode 100644 tests/run-make-fulldeps/core-no-128-bit/lib.rs diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 3dc8c84e0bfde..d356171938bdf 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -7,7 +7,7 @@ description = "The Rust Core Library" autotests = false autobenches = false # If you update this, be sure to update it in a bunch of other places too! -# As of 2022, it was the ci/pgo.sh script and the core-no-fp-fmt-parse test. +# As of 2023, it was the ci/pgo.sh script and the core-no-fp-fmt-parse/core-no-128-bit tests. edition = "2021" [lib] diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index d8365ae9bf920..061f41d452687 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -176,9 +176,12 @@ integer! { i8, u8 } integer! { i16, u16 } integer! { i32, u32 } integer! { i64, u64 } +#[cfg(not(no_128_bit))] integer! { i128, u128 } + macro_rules! debug { - ($($T:ident)*) => {$( + ($($( #[$cfg:meta] )? $T:ident)*) => {$( + $( #[$cfg] )? #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for $T { #[inline] @@ -195,8 +198,30 @@ macro_rules! debug { )*}; } debug! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize + i8 i16 i32 i64 #[cfg(not(no_128_bit))] i128 isize + u8 u16 u32 u64 #[cfg(not(no_128_bit))] u128 usize +} + +macro_rules! fake_debug { + ($($( #[$cfg:meta] )? $T:ident)*) => {$( + $( #[$cfg] )? + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Debug for $T { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Debug formats are not stable so this is a legitimate implementation. + // It would be possible to hexdump the contents instead, or to + // fail or panic, but for an application which has specifically + // recompiled core to avoid i128, the former seems unnecessary + // and the latter needlessly harmful. + f.write_str(stringify!($T)) + } + } + )*} +} +fake_debug! { + #[cfg(no_128_bit)] i128 + #[cfg(no_128_bit)] u128 } // 2 digit decimal look up table @@ -476,9 +501,11 @@ mod imp { impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32); impl_Exp!(i64, u64 as u64 via to_u64 named exp_u64); } +#[cfg(not(no_128_bit))] impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128); /// Helper function for writing a u64 into `buf` going from last to first, with `curr`. +#[cfg(not(no_128_bit))] // unused for `no_128_bit` fn parse_u64_into(mut n: u64, buf: &mut [MaybeUninit; N], curr: &mut usize) { let buf_ptr = MaybeUninit::slice_as_mut_ptr(buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); @@ -566,6 +593,7 @@ fn parse_u64_into(mut n: u64, buf: &mut [MaybeUninit; N], cu } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(no_128_bit))] impl fmt::Display for u128 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt_u128(*self, true, f) @@ -573,6 +601,7 @@ impl fmt::Display for u128 { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(no_128_bit))] impl fmt::Display for i128 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let is_nonnegative = *self >= 0; @@ -590,6 +619,7 @@ impl fmt::Display for i128 { /// into at most 2 u64s, and then chunks by 10e16, 10e8, 10e4, 10e2, and then 10e1. /// It also has to handle 1 last item, as 10^40 > 2^128 > 10^39, whereas /// 10^20 > 2^64 > 10^19. +#[cfg(not(no_128_bit))] fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { // 2^128 is about 3*10^38, so 39 gives an extra byte of space let mut buf = [MaybeUninit::::uninit(); 39]; @@ -649,6 +679,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R /// in Proc. of the SIGPLAN94 Conference on Programming Language Design and /// Implementation, 1994, pp. 61–72 /// +#[cfg(not(no_128_bit))] fn udiv_1e19(n: u128) -> (u128, u64) { const DIV: u64 = 1e19 as u64; const FACTOR: u128 = 156927543384667019095894735580191660403; @@ -665,6 +696,7 @@ fn udiv_1e19(n: u128) -> (u128, u64) { /// Multiply unsigned 128 bit integers, return upper 128 bits of the result #[inline] +#[cfg(not(no_128_bit))] fn u128_mulhi(x: u128, y: u128) -> u128 { let x_lo = x as u64; let x_hi = (x >> 64) as u64; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8790649abe6f1..f9c38bec30967 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -64,6 +64,7 @@ not(test), any(not(feature = "miri-test-libstd"), test, doctest), no_fp_fmt_parse, + no_128_bit, target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64", diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 2cae98b8e4943..5258faa16a7ed 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3,7 +3,7 @@ macro_rules! int_impl { $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, $reversed:expr, $le_bytes:expr, $be_bytes:expr, $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr, - $bound_condition:expr) => { + $bound_condition:expr $(, #[$intrinsics_cfg:meta])?) => { /// The smallest value that can be represented by this integer type #[doc = concat!("(−2", $BITS_MINUS_ONE, "", $bound_condition, ")")] /// @@ -62,6 +62,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")] /// ``` #[stable(feature = "rust1", since = "1.0.0")] + $( #[$intrinsics_cfg] )? pub fn from_str_radix(src: &str, radix: u32) -> Result { from_str_radix(src, radix) } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ac7f579ebb5aa..4075da2b6dbc2 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -268,7 +268,7 @@ impl i128 { "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \ 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \ - 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "" } + 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "", "", #[cfg(not(no_128_bit))] } } #[cfg(target_pointer_width = "16")] @@ -940,7 +940,7 @@ impl u128 { 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \ 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", - "", "", ""} + "", "", "", #[cfg(not(no_128_bit))]} } #[cfg(target_pointer_width = "16")] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fbda8f82b1bd9..f2179858d3b2a 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -23,7 +23,7 @@ macro_rules! impl_nonzero_fmt { } macro_rules! nonzero_integers { - ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => { + ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $(#[$cfg: meta])? $Ty: ident($Int: ty); )+ ) => { $( /// An integer that is known not to equal zero. /// @@ -154,9 +154,12 @@ macro_rules! nonzero_integers { } } + $(#[$cfg])? impl_nonzero_fmt! { - #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty + #[$stability] (Display, Binary, Octal, LowerHex, UpperHex) for $Ty } + + impl_nonzero_fmt!(#[$stability] (Debug) for $Ty); )+ } } @@ -166,13 +169,15 @@ nonzero_integers! { #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16); #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32); #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64); - #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128); + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] + #[cfg(not(no_128_bit))] NonZeroU128(u128); #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize); #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8); #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16); #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32); #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64); - #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128); + #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] + #[cfg(not(no_128_bit))] NonZeroI128(i128); #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize); } @@ -191,8 +196,11 @@ macro_rules! from_str_radix_nzint_impl { )*} } -from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize -NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize } +from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroUsize +NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroIsize } + +#[cfg(not(no_128_bit))] +from_str_radix_nzint_impl! { NonZeroU128 NonZeroI128 } macro_rules! nonzero_leading_trailing_zeros { ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 1c97c46862833..9ea8ca0638a79 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -4,7 +4,7 @@ macro_rules! uint_impl { $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, $reversed:expr, $le_bytes:expr, $be_bytes:expr, $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr, - $bound_condition:expr) => { + $bound_condition:expr $(, #[$intrinsics_cfg:meta])?) => { /// The smallest value that can be represented by this integer type. /// /// # Examples @@ -63,6 +63,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")] /// ``` #[stable(feature = "rust1", since = "1.0.0")] + $( #[$intrinsics_cfg] )? pub fn from_str_radix(src: &str, radix: u32) -> Result { from_str_radix(src, radix) } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d44b96cfb991e..ac38b54192be0 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -207,6 +207,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] (Some(Mode::Codegen), "parallel_compiler", None), (Some(Mode::Std), "stdarch_intel_sde", None), (Some(Mode::Std), "no_fp_fmt_parse", None), + (Some(Mode::Std), "no_128_bit", None), (Some(Mode::Std), "no_global_oom_handling", None), (Some(Mode::Std), "no_rc", None), (Some(Mode::Std), "no_sync", None), diff --git a/tests/run-make-fulldeps/core-no-128-bit/Makefile b/tests/run-make-fulldeps/core-no-128-bit/Makefile new file mode 100644 index 0000000000000..4d9784e65abbf --- /dev/null +++ b/tests/run-make-fulldeps/core-no-128-bit/Makefile @@ -0,0 +1,8 @@ +include ../tools.mk + +all: + $(RUSTC) --edition=2021 --crate-type=rlib --crate-name=core ../../../library/core/src/lib.rs --cfg no_128_bit + $(RUSTC) --edition=2021 --crate-type=staticlib --crate-name=demo --sysroot=. -C panic=abort lib.rs + # Expect that objdump succeeds and grep fails. The grep pattern is for names like __multi3. + # There is no pipefail on dash so echo a string that will fail the test if objump fails. + (objdump -t $(TMPDIR)/libdemo.a || echo __objdumpfailedti) | (! grep -w '__[a-z]\+ti[0-9]\?') diff --git a/tests/run-make-fulldeps/core-no-128-bit/lib.rs b/tests/run-make-fulldeps/core-no-128-bit/lib.rs new file mode 100644 index 0000000000000..f52dc453bf97c --- /dev/null +++ b/tests/run-make-fulldeps/core-no-128-bit/lib.rs @@ -0,0 +1,31 @@ +#![feature(no_core)] + +#![no_std] +#![no_core] // supress compiler-builtins +extern crate core; +use core::prelude::rust_2021::*; +use core::fmt::Write; + +// An empty file might be sufficient here, but since formatting is one of the +// features affected by no_128_bit it seems worth including some. + +struct X(pub usize); +impl core::fmt::Write for X { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + self.0 += s.len(); + Ok(()) + } +} + +#[no_mangle] +extern "C" fn demo() -> usize { + let mut x = X(0); + // Writes "i128 u128 foo" due to the removal of u/i128 formatting. + core::write!(x, "{:?} {:?} {}", i128::MAX, u128::MIN, "foo").unwrap(); + x.0 +} + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} From c5c5be05605c360aaa62566ed7ca456d9a25b1e8 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 22 Jan 2023 23:08:40 +0000 Subject: [PATCH 2/2] Remove from_str_radix on i/u128 on no_128_bit --- library/core/src/num/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 4075da2b6dbc2..c79ee0417aed7 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1078,7 +1078,9 @@ macro_rules! from_str_radix_int_impl { } )*} } -from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } +from_str_radix_int_impl! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 } +#[cfg(not(no_128_bit))] +from_str_radix_int_impl! { i128 u128 } macro_rules! impl_helper_for { ($($t:ty)*) => ($(impl FromStrRadixHelper for $t { @@ -1099,7 +1101,9 @@ macro_rules! impl_helper_for { } })*) } -impl_helper_for! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } +impl_helper_for! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } +#[cfg(not(no_128_bit))] +impl_helper_for! { i128 u128 } /// Determines if a string of text of that length of that radix could be guaranteed to be /// stored in the given type T.