Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cfg(no_128_bit) to core: removes u128/i128 formatting #103126

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion library/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
38 changes: 35 additions & 3 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is an i128/u128 impl necessary in the first place?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question; I haven’t tried removing it. I think it’s conventional to provide Debug for everything public in the standard library; not sure if that could be waived in this case?

}
}
)*}
}
fake_debug! {
#[cfg(no_128_bit)] i128
#[cfg(no_128_bit)] u128
}

// 2 digit decimal look up table
Expand Down Expand Up @@ -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<const N: usize>(mut n: u64, buf: &mut [MaybeUninit<u8>; N], curr: &mut usize) {
let buf_ptr = MaybeUninit::slice_as_mut_ptr(buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
Expand Down Expand Up @@ -566,13 +593,15 @@ fn parse_u64_into<const N: usize>(mut n: u64, buf: &mut [MaybeUninit<u8>; 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)
}
}

#[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;
Expand All @@ -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::<u8>::uninit(); 39];
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ")")]
///
Expand Down Expand Up @@ -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] )?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is doing more than just controlling the removal of formatting: this function is about parsing. If not called, the function should not be included by the linker, different to what's happening to stuff called by the fmt machinery that is always included the moment anything that uses the fmt machinery is included.

pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
from_str_radix(src, radix)
}
Expand Down
12 changes: 8 additions & 4 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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")]
Expand Down Expand Up @@ -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 {
Expand All @@ -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.
Expand Down
20 changes: 14 additions & 6 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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);
)+
}
}
Expand All @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I don't think it should be cfg'd out in this PR.

#[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);
}

Expand All @@ -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 ;)+ ) => {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<Self, ParseIntError> {
from_str_radix(src, radix)
}
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'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),
Expand Down
8 changes: 8 additions & 0 deletions tests/run-make-fulldeps/core-no-128-bit/Makefile
Original file line number Diff line number Diff line change
@@ -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]\?')
31 changes: 31 additions & 0 deletions tests/run-make-fulldeps/core-no-128-bit/lib.rs
Original file line number Diff line number Diff line change
@@ -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 {}
}