From be2369708a0fd53fc1ed80cbcca25f24e12a781d Mon Sep 17 00:00:00 2001 From: spore Date: Wed, 8 Jan 2025 18:31:29 +0800 Subject: [PATCH 01/13] Detect overflow when the literal is larger than i128::MAX --- compiler/rustc_lint/src/types/literal.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index 83942918e3b58..c3e558a3e20a9 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -206,12 +206,15 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), ty::Int(_) if negative => Some(Integer::fit_signed(-(val as i128)).int_ty_str()), ty::Int(int) => { - let signed = Integer::fit_signed(val as i128); let unsigned = Integer::fit_unsigned(val); - Some(if Some(unsigned.size().bits()) == int.bit_width() { - unsigned.uint_ty_str() + Some(if let Ok(signed) = i128::try_from(val).map(Integer::fit_signed) { + if Some(unsigned.size().bits()) == int.bit_width() { + unsigned.uint_ty_str() + } else { + signed.int_ty_str() + } } else { - signed.int_ty_str() + unsigned.uint_ty_str() }) } _ => None, From 330be171440eb4efe479c5b1fcfd079153c5159d Mon Sep 17 00:00:00 2001 From: spore Date: Wed, 8 Jan 2025 19:00:10 +0800 Subject: [PATCH 02/13] Detect overflow when the literal is negative --- compiler/rustc_lint/src/types/literal.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index c3e558a3e20a9..13eca89fba67b 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -204,7 +204,13 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static match t.kind() { ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None, ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), - ty::Int(_) if negative => Some(Integer::fit_signed(-(val as i128)).int_ty_str()), + ty::Int(_) if negative => { + if val > i128::MAX as u128 + 1 { + None + } else { + Some(Integer::fit_signed(val.wrapping_neg() as i128).int_ty_str()) + } + } ty::Int(int) => { let unsigned = Integer::fit_unsigned(val); Some(if let Ok(signed) = i128::try_from(val).map(Integer::fit_signed) { From 1517a41c57b328b2e89641d79b1272e7004f7514 Mon Sep 17 00:00:00 2001 From: spore Date: Wed, 8 Jan 2025 19:00:35 +0800 Subject: [PATCH 03/13] Add test cases and test for `HELP` --- tests/ui/lint/type-overflow.rs | 26 +++++++++++++++ tests/ui/lint/type-overflow.stderr | 51 ++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs index 7239e1c983764..0848d676e237c 100644 --- a/tests/ui/lint/type-overflow.rs +++ b/tests/ui/lint/type-overflow.rs @@ -3,20 +3,46 @@ fn main() { let error = 255i8; //~WARNING literal out of range for `i8` + //~^ HELP consider using the type `u8` instead let ok = 0b1000_0001; // should be ok -> i32 let ok = 0b0111_1111i8; // should be ok -> 127i8 let fail = 0b1000_0001i8; //~WARNING literal out of range for `i8` + //~^ HELP consider using the type `u8` instead + //~| HELP consider using the type `u8` for the literal and cast it to `i8` let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for `i64` + //~^ HELP consider using the type `u64` instead + //~| HELP consider using the type `u64` for the literal and cast it to `i64` let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for `u32` + //~^ HELP consider using the type `u64` instead let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; //~^ WARNING literal out of range for `i128` + //~| HELP consider using the type `u128` instead + //~| HELP consider using the type `u128` for the literal and cast it to `i128` + + let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000; + //~^ WARNING literal out of range for `i32` + //~| HELP consider using the type `u128` instead + + let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; + //~^ WARNING literal out of range for `i32` + //~| HELP consider using the type `i128` instead + + let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128; + //~^ WARNING literal out of range for `i128` + + let fail = 340282366920938463463374607431768211455i8; + //~^ WARNING literal out of range for `i8` + //~| HELP consider using the type `u128` instead let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32` + //~| HELP consider using the type `i128` instead + //~| HELP let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8` + //~| HELP consider using the type `i16` instead } diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index e7c90dcc81bb2..dbbe81e5c182d 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -13,7 +13,7 @@ LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ warning: literal out of range for `i8` - --> $DIR/type-overflow.rs:10:16 + --> $DIR/type-overflow.rs:11:16 | LL | let fail = 0b1000_0001i8; | ^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | let fail = 0b1000_0001u8 as i8; | ~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i64` - --> $DIR/type-overflow.rs:12:16 + --> $DIR/type-overflow.rs:15:16 | LL | let fail = 0x8000_0000_0000_0000i64; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let fail = 0x8000_0000_0000_0000u64 as i64; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `u32` - --> $DIR/type-overflow.rs:14:16 + --> $DIR/type-overflow.rs:19:16 | LL | let fail = 0x1_FFFF_FFFFu32; | ^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x1_FFFF_FFFFu64` @@ -53,7 +53,7 @@ LL | let fail = 0x1_FFFF_FFFFu32; = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into the type `u32` and will become `4294967295u32` warning: literal out of range for `i128` - --> $DIR/type-overflow.rs:16:22 + --> $DIR/type-overflow.rs:22:22 | LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,44 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128 as i128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i32` - --> $DIR/type-overflow.rs:19:16 + --> $DIR/type-overflow.rs:27:16 + | +LL | let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` and will become `0i32` + = help: consider using the type `u128` instead + +warning: literal out of range for `i32` + --> $DIR/type-overflow.rs:31:17 + | +LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` + = note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0000` will become `0i32` + = help: consider using the type `i128` instead + +warning: literal out of range for `i128` + --> $DIR/type-overflow.rs:35:17 + | +LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0001i128` (decimal `170141183460469231731687303715884105729`) does not fit into the type `i128` + = note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0001i128` will become `170141183460469231731687303715884105727i128` + +warning: literal out of range for `i8` + --> $DIR/type-overflow.rs:38:16 + | +LL | let fail = 340282366920938463463374607431768211455i8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `340282366920938463463374607431768211455i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u128` instead + +warning: literal out of range for `i32` + --> $DIR/type-overflow.rs:42:16 | LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; | ^^^^^^^^^^^^^^^^^^^^^ @@ -79,7 +116,7 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu32 as i32; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i8` - --> $DIR/type-overflow.rs:21:17 + --> $DIR/type-overflow.rs:46:17 | LL | let fail = -0b1111_1111i8; | ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16` @@ -87,5 +124,5 @@ LL | let fail = -0b1111_1111i8; = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` = note: and the value `-0b1111_1111i8` will become `1i8` -warning: 7 warnings emitted +warning: 11 warnings emitted From c04e65dbc5f936fdd4dc53ba7b7a058165aad157 Mon Sep 17 00:00:00 2001 From: spore Date: Thu, 9 Jan 2025 02:02:40 +0800 Subject: [PATCH 04/13] Extract integer conversion into a function --- compiler/rustc_lint/src/types/literal.rs | 38 ++++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index 13eca89fba67b..4faf345bcd58f 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -204,29 +204,35 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static match t.kind() { ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None, ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), - ty::Int(_) if negative => { - if val > i128::MAX as u128 + 1 { - None - } else { - Some(Integer::fit_signed(val.wrapping_neg() as i128).int_ty_str()) - } - } ty::Int(int) => { - let unsigned = Integer::fit_unsigned(val); - Some(if let Ok(signed) = i128::try_from(val).map(Integer::fit_signed) { - if Some(unsigned.size().bits()) == int.bit_width() { - unsigned.uint_ty_str() - } else { - signed.int_ty_str() - } + let signed = literal_to_i128(val, negative).map(|v| Integer::fit_signed(v)); + if negative { + signed.map(Integer::int_ty_str) } else { - unsigned.uint_ty_str() - }) + let unsigned = Integer::fit_unsigned(val); + Some(if let Some(signed) = signed { + if Some(unsigned.size().bits()) == int.bit_width() { + unsigned.uint_ty_str() + } else { + signed.int_ty_str() + } + } else { + unsigned.uint_ty_str() + }) + } } _ => None, } } +fn literal_to_i128(val: u128, negative: bool) -> Option { + if negative { + (val <= i128::MAX as u128 + 1).then(|| val.wrapping_neg() as i128) + } else { + val.try_into().ok() + } +} + fn lint_int_literal<'tcx>( cx: &LateContext<'tcx>, type_limits: &TypeLimits, From d9d17bc90f1117435b6f0c9b5d713d02a635c035 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 13 Dec 2024 18:58:15 +0100 Subject: [PATCH 05/13] panic_unwind: add `#![warn(unreachable_pub)]` --- library/panic_unwind/src/dummy.rs | 4 ++-- library/panic_unwind/src/emcc.rs | 4 ++-- library/panic_unwind/src/gcc.rs | 4 ++-- library/panic_unwind/src/hermit.rs | 4 ++-- library/panic_unwind/src/lib.rs | 1 + library/panic_unwind/src/miri.rs | 4 ++-- library/panic_unwind/src/seh.rs | 32 +++++++++++++++--------------- 7 files changed, 27 insertions(+), 26 deletions(-) diff --git a/library/panic_unwind/src/dummy.rs b/library/panic_unwind/src/dummy.rs index a4bcd216c60f0..a0d6876691833 100644 --- a/library/panic_unwind/src/dummy.rs +++ b/library/panic_unwind/src/dummy.rs @@ -6,10 +6,10 @@ use alloc::boxed::Box; use core::any::Any; use core::intrinsics; -pub unsafe fn cleanup(_ptr: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box { intrinsics::abort() } -pub unsafe fn panic(_data: Box) -> u32 { +pub(crate) unsafe fn panic(_data: Box) -> u32 { intrinsics::abort() } diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs index b986fc1c2a829..9127449edb1a7 100644 --- a/library/panic_unwind/src/emcc.rs +++ b/library/panic_unwind/src/emcc.rs @@ -64,7 +64,7 @@ struct Exception { data: Option>, } -pub unsafe fn cleanup(ptr: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box { // intrinsics::try actually gives us a pointer to this structure. #[repr(C)] struct CatchData { @@ -93,7 +93,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box { out } -pub unsafe fn panic(data: Box) -> u32 { +pub(crate) unsafe fn panic(data: Box) -> u32 { let exception = __cxa_allocate_exception(mem::size_of::()) as *mut Exception; if exception.is_null() { return uw::_URC_FATAL_PHASE1_ERROR as u32; diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs index b2389078afd0f..e478f6c5fc86c 100644 --- a/library/panic_unwind/src/gcc.rs +++ b/library/panic_unwind/src/gcc.rs @@ -58,7 +58,7 @@ struct Exception { cause: Box, } -pub unsafe fn panic(data: Box) -> u32 { +pub(crate) unsafe fn panic(data: Box) -> u32 { let exception = Box::new(Exception { _uwe: uw::_Unwind_Exception { exception_class: RUST_EXCEPTION_CLASS, @@ -82,7 +82,7 @@ pub unsafe fn panic(data: Box) -> u32 { } } -pub unsafe fn cleanup(ptr: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box { let exception = ptr as *mut uw::_Unwind_Exception; if (*exception).exception_class != RUST_EXCEPTION_CLASS { uw::_Unwind_DeleteException(exception); diff --git a/library/panic_unwind/src/hermit.rs b/library/panic_unwind/src/hermit.rs index 69b9edb77c564..8ac827dd9ccbe 100644 --- a/library/panic_unwind/src/hermit.rs +++ b/library/panic_unwind/src/hermit.rs @@ -5,14 +5,14 @@ use alloc::boxed::Box; use core::any::Any; -pub unsafe fn cleanup(_ptr: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box { extern "C" { pub fn __rust_abort() -> !; } __rust_abort(); } -pub unsafe fn panic(_data: Box) -> u32 { +pub(crate) unsafe fn panic(_data: Box) -> u32 { extern "C" { pub fn __rust_abort() -> !; } diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index dc78be76cb4d5..d682816419565 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -26,6 +26,7 @@ #![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] #![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))] +#![warn(unreachable_pub)] use alloc::boxed::Box; use core::any::Any; diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs index 695adadd59b55..a86f0e91eefcc 100644 --- a/library/panic_unwind/src/miri.rs +++ b/library/panic_unwind/src/miri.rs @@ -12,14 +12,14 @@ extern "Rust" { fn miri_start_unwind(payload: *mut u8) -> !; } -pub unsafe fn panic(payload: Box) -> u32 { +pub(crate) unsafe fn panic(payload: Box) -> u32 { // The payload we pass to `miri_start_unwind` will be exactly the argument we get // in `cleanup` below. So we just box it up once, to get something pointer-sized. let payload_box: Payload = Box::new(payload); miri_start_unwind(Box::into_raw(payload_box) as *mut u8) } -pub unsafe fn cleanup(payload_box: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(payload_box: *mut u8) -> Box { // Recover the underlying `Box`. let payload_box: Payload = Box::from_raw(payload_box as *mut _); *payload_box diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 5afa0a1975612..21bfe74e1a259 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -111,18 +111,18 @@ struct Exception { mod imp { #[repr(transparent)] #[derive(Copy, Clone)] - pub struct ptr_t(*mut u8); + pub(super) struct ptr_t(*mut u8); impl ptr_t { - pub const fn null() -> Self { + pub(super) const fn null() -> Self { Self(core::ptr::null_mut()) } - pub const fn new(ptr: *mut u8) -> Self { + pub(super) const fn new(ptr: *mut u8) -> Self { Self(ptr) } - pub const fn raw(self) -> *mut u8 { + pub(super) const fn raw(self) -> *mut u8 { self.0 } } @@ -133,18 +133,18 @@ mod imp { // On 64-bit systems, SEH represents pointers as 32-bit offsets from `__ImageBase`. #[repr(transparent)] #[derive(Copy, Clone)] - pub struct ptr_t(u32); + pub(super) struct ptr_t(u32); extern "C" { - pub static __ImageBase: u8; + static __ImageBase: u8; } impl ptr_t { - pub const fn null() -> Self { + pub(super) const fn null() -> Self { Self(0) } - pub fn new(ptr: *mut u8) -> Self { + pub(super) fn new(ptr: *mut u8) -> Self { // We need to expose the provenance of the pointer because it is not carried by // the `u32`, while the FFI needs to have this provenance to excess our statics. // @@ -159,7 +159,7 @@ mod imp { Self(offset as u32) } - pub const fn raw(self) -> u32 { + pub(super) const fn raw(self) -> u32 { self.0 } } @@ -168,7 +168,7 @@ mod imp { use imp::ptr_t; #[repr(C)] -pub struct _ThrowInfo { +struct _ThrowInfo { pub attributes: c_uint, pub pmfnUnwind: ptr_t, pub pForwardCompat: ptr_t, @@ -176,13 +176,13 @@ pub struct _ThrowInfo { } #[repr(C)] -pub struct _CatchableTypeArray { +struct _CatchableTypeArray { pub nCatchableTypes: c_int, pub arrayOfCatchableTypes: [ptr_t; 1], } #[repr(C)] -pub struct _CatchableType { +struct _CatchableType { pub properties: c_uint, pub pType: ptr_t, pub thisDisplacement: _PMD, @@ -191,14 +191,14 @@ pub struct _CatchableType { } #[repr(C)] -pub struct _PMD { +struct _PMD { pub mdisp: c_int, pub pdisp: c_int, pub vdisp: c_int, } #[repr(C)] -pub struct _TypeDescriptor { +struct _TypeDescriptor { pub pVFTable: *const u8, pub spare: *mut u8, pub name: [u8; 11], @@ -288,7 +288,7 @@ cfg_if::cfg_if! { } } -pub unsafe fn panic(data: Box) -> u32 { +pub(crate) unsafe fn panic(data: Box) -> u32 { use core::intrinsics::atomic_store_seqcst; // _CxxThrowException executes entirely on this stack frame, so there's no @@ -350,7 +350,7 @@ pub unsafe fn panic(data: Box) -> u32 { _CxxThrowException(throw_ptr, (&raw mut THROW_INFO) as *mut _); } -pub unsafe fn cleanup(payload: *mut u8) -> Box { +pub(crate) unsafe fn cleanup(payload: *mut u8) -> Box { // A null payload here means that we got here from the catch (...) of // __rust_try. This happens when a non-Rust foreign exception is caught. if payload.is_null() { From 1953ddd8a21070dacbc3fdec8b8c10ae07c00230 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 13 Dec 2024 19:25:26 +0100 Subject: [PATCH 06/13] rtstartup: add `#![warn(unreachable_pub)]` --- library/rtstartup/rsbegin.rs | 1 + library/rtstartup/rsend.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs index 9a3d95bd8ddfb..d3ff5c14aa4a8 100644 --- a/library/rtstartup/rsbegin.rs +++ b/library/rtstartup/rsbegin.rs @@ -19,6 +19,7 @@ #![no_core] #![allow(non_camel_case_types)] #![allow(internal_features)] +#![warn(unreachable_pub)] #[lang = "sized"] trait Sized {} diff --git a/library/rtstartup/rsend.rs b/library/rtstartup/rsend.rs index 2514eb0034402..81acfbed4477d 100644 --- a/library/rtstartup/rsend.rs +++ b/library/rtstartup/rsend.rs @@ -6,6 +6,7 @@ #![crate_type = "rlib"] #![no_core] #![allow(internal_features)] +#![warn(unreachable_pub)] #[lang = "sized"] trait Sized {} From 2fa6dbc23b19cdc15430608cc26706d56243feca Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 13 Dec 2024 19:53:04 +0100 Subject: [PATCH 07/13] core: add `#![warn(unreachable_pub)]` --- library/core/src/array/mod.rs | 2 +- library/core/src/escape.rs | 22 +++++++------- library/core/src/ffi/mod.rs | 20 ++++++------- library/core/src/lib.rs | 4 ++- library/core/src/net/display_buffer.rs | 6 ++-- library/core/src/num/dec2flt/decimal.rs | 20 ++++++------- library/core/src/num/dec2flt/fpu.rs | 6 ++-- library/core/src/num/dec2flt/table.rs | 9 +++--- library/core/src/num/int_log10.rs | 28 +++++++++--------- library/core/src/num/int_sqrt.rs | 8 +++--- library/core/src/num/overflow_panic.rs | 16 +++++------ library/core/src/num/wrapping.rs | 38 ++++++++++++------------- library/core/src/ops/index_range.rs | 14 ++++----- library/core/src/ops/try_trait.rs | 7 +++-- library/core/src/slice/rotate.rs | 2 +- library/core/src/unicode/mod.rs | 2 ++ src/etc/dec2flt_table.py | 10 +++---- 17 files changed, 111 insertions(+), 103 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 95c1eb460cd94..5868c14b606b9 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -893,7 +893,7 @@ impl Guard<'_, T> { /// /// No more than N elements must be initialized. #[inline] - pub unsafe fn push_unchecked(&mut self, item: T) { + pub(crate) unsafe fn push_unchecked(&mut self, item: T) { // SAFETY: If `initialized` was correct before and the caller does not // invoke this method more than N times then writes will be in-bounds // and slots will not be initialized more than once. diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs index 0685f525dca83..0c3329f676eeb 100644 --- a/library/core/src/escape.rs +++ b/library/core/src/escape.rs @@ -163,28 +163,28 @@ pub(crate) struct EscapeIterInner { } impl EscapeIterInner { - pub const fn backslash(c: ascii::Char) -> Self { + pub(crate) const fn backslash(c: ascii::Char) -> Self { let (data, range) = backslash(c); Self { data, alive: range } } - pub const fn ascii(c: u8) -> Self { + pub(crate) const fn ascii(c: u8) -> Self { let (data, range) = escape_ascii(c); Self { data, alive: range } } - pub const fn unicode(c: char) -> Self { + pub(crate) const fn unicode(c: char) -> Self { let (data, range) = escape_unicode(c); Self { data, alive: range } } #[inline] - pub const fn empty() -> Self { + pub(crate) const fn empty() -> Self { Self { data: [ascii::Char::Null; N], alive: 0..0 } } #[inline] - pub fn as_ascii(&self) -> &[ascii::Char] { + pub(crate) fn as_ascii(&self) -> &[ascii::Char] { // SAFETY: `self.alive` is guaranteed to be a valid range for indexing `self.data`. unsafe { self.data.get_unchecked(usize::from(self.alive.start)..usize::from(self.alive.end)) @@ -192,34 +192,34 @@ impl EscapeIterInner { } #[inline] - pub fn as_str(&self) -> &str { + pub(crate) fn as_str(&self) -> &str { self.as_ascii().as_str() } #[inline] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { usize::from(self.alive.end - self.alive.start) } - pub fn next(&mut self) -> Option { + pub(crate) fn next(&mut self) -> Option { let i = self.alive.next()?; // SAFETY: `i` is guaranteed to be a valid index for `self.data`. unsafe { Some(self.data.get_unchecked(usize::from(i)).to_u8()) } } - pub fn next_back(&mut self) -> Option { + pub(crate) fn next_back(&mut self) -> Option { let i = self.alive.next_back()?; // SAFETY: `i` is guaranteed to be a valid index for `self.data`. unsafe { Some(self.data.get_unchecked(usize::from(i)).to_u8()) } } - pub fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + pub(crate) fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { self.alive.advance_by(n) } - pub fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + pub(crate) fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { self.alive.advance_back_by(n) } } diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 5f32775822be6..79d094556c45c 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -172,10 +172,10 @@ mod c_char_definition { target_arch = "xtensa", ) ))] { - pub type c_char = u8; + pub(super) type c_char = u8; } else { // On every other target, c_char is signed. - pub type c_char = i8; + pub(super) type c_char = i8; } } } @@ -183,11 +183,11 @@ mod c_char_definition { mod c_int_definition { cfg_if! { if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] { - pub type c_int = i16; - pub type c_uint = u16; + pub(super) type c_int = i16; + pub(super) type c_uint = u16; } else { - pub type c_int = i32; - pub type c_uint = u32; + pub(super) type c_int = i32; + pub(super) type c_uint = u32; } } } @@ -195,12 +195,12 @@ mod c_int_definition { mod c_long_definition { cfg_if! { if #[cfg(all(target_pointer_width = "64", not(windows)))] { - pub type c_long = i64; - pub type c_ulong = u64; + pub(super) type c_long = i64; + pub(super) type c_ulong = u64; } else { // The minimal size of `long` in the C standard is 32 bits - pub type c_long = i32; - pub type c_ulong = u32; + pub(super) type c_long = i32; + pub(super) type c_ulong = u32; } } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index e845bb34426c4..f58eab3b1b1a2 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -101,6 +101,7 @@ #![warn(multiple_supertrait_upcastable)] #![allow(internal_features)] #![deny(ffi_unwind_calls)] +#![warn(unreachable_pub)] // Do not check link redundancy on bootstraping phase #![allow(rustdoc::redundant_explicit_links)] #![warn(rustdoc::unescaped_backticks)] @@ -396,7 +397,8 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn, ambiguous_glob_reexports, - deprecated_in_future + deprecated_in_future, + unreachable_pub )] #[allow(rustdoc::bare_urls)] mod core_arch; diff --git a/library/core/src/net/display_buffer.rs b/library/core/src/net/display_buffer.rs index bab84a97308b3..2bc31fcd2d58c 100644 --- a/library/core/src/net/display_buffer.rs +++ b/library/core/src/net/display_buffer.rs @@ -2,19 +2,19 @@ use crate::mem::MaybeUninit; use crate::{fmt, str}; /// Used for slow path in `Display` implementations when alignment is required. -pub struct DisplayBuffer { +pub(super) struct DisplayBuffer { buf: [MaybeUninit; SIZE], len: usize, } impl DisplayBuffer { #[inline] - pub const fn new() -> Self { + pub(super) const fn new() -> Self { Self { buf: [MaybeUninit::uninit(); SIZE], len: 0 } } #[inline] - pub fn as_str(&self) -> &str { + pub(super) fn as_str(&self) -> &str { // SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation // which writes a valid UTF-8 string to `buf` and correctly sets `len`. unsafe { diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs index be9c0eccd5eb8..b37724ba62d5e 100644 --- a/library/core/src/num/dec2flt/decimal.rs +++ b/library/core/src/num/dec2flt/decimal.rs @@ -12,7 +12,7 @@ use crate::num::dec2flt::common::{ByteSlice, is_8digits}; #[derive(Clone)] -pub struct Decimal { +pub(super) struct Decimal { /// The number of significant digits in the decimal. pub num_digits: usize, /// The offset of the decimal point in the significant digits. @@ -55,13 +55,13 @@ impl Decimal { /// /// In Python: /// `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))` - pub const MAX_DIGITS: usize = 768; + pub(super) const MAX_DIGITS: usize = 768; /// The max digits that can be exactly represented in a 64-bit integer. - pub const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19; - pub const DECIMAL_POINT_RANGE: i32 = 2047; + pub(super) const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19; + pub(super) const DECIMAL_POINT_RANGE: i32 = 2047; /// Append a digit to the buffer. - pub fn try_add_digit(&mut self, digit: u8) { + pub(super) fn try_add_digit(&mut self, digit: u8) { if self.num_digits < Self::MAX_DIGITS { self.digits[self.num_digits] = digit; } @@ -69,7 +69,7 @@ impl Decimal { } /// Trim trailing zeros from the buffer. - pub fn trim(&mut self) { + pub(super) fn trim(&mut self) { // All of the following calls to `Decimal::trim` can't panic because: // // 1. `parse_decimal` sets `num_digits` to a max of `Decimal::MAX_DIGITS`. @@ -83,7 +83,7 @@ impl Decimal { } } - pub fn round(&self) -> u64 { + pub(super) fn round(&self) -> u64 { if self.num_digits == 0 || self.decimal_point < 0 { return 0; } else if self.decimal_point > 18 { @@ -111,7 +111,7 @@ impl Decimal { } /// Computes decimal * 2^shift. - pub fn left_shift(&mut self, shift: usize) { + pub(super) fn left_shift(&mut self, shift: usize) { if self.num_digits == 0 { return; } @@ -152,7 +152,7 @@ impl Decimal { } /// Computes decimal * 2^-shift. - pub fn right_shift(&mut self, shift: usize) { + pub(super) fn right_shift(&mut self, shift: usize) { let mut read_index = 0; let mut write_index = 0; let mut n = 0_u64; @@ -202,7 +202,7 @@ impl Decimal { } /// Parse a big integer representation of the float as a decimal. -pub fn parse_decimal(mut s: &[u8]) -> Decimal { +pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal { let mut d = Decimal::default(); let start = s; diff --git a/library/core/src/num/dec2flt/fpu.rs b/library/core/src/num/dec2flt/fpu.rs index 8d62684f8d383..4cd4838d97c73 100644 --- a/library/core/src/num/dec2flt/fpu.rs +++ b/library/core/src/num/dec2flt/fpu.rs @@ -1,7 +1,7 @@ //! Platform-specific, assembly instructions to avoid //! intermediate rounding on architectures with FPUs. -pub use fpu_precision::set_precision; +pub(super) use fpu_precision::set_precision; // On x86, the x87 FPU is used for float operations if the SSE/SSE2 extensions are not available. // The x87 FPU operates with 80 bits of precision by default, which means that operations will @@ -57,7 +57,7 @@ mod fpu_precision { } /// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`. - pub fn set_precision() -> FPUControlWord { + pub(crate) fn set_precision() -> FPUControlWord { let mut cw = 0_u16; // Compute the value for the Precision Control field that is appropriate for `T`. @@ -97,5 +97,5 @@ mod fpu_precision { // precision of the computation is determined on a per-operation basis. #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] mod fpu_precision { - pub fn set_precision() {} + pub(crate) fn set_precision() {} } diff --git a/library/core/src/num/dec2flt/table.rs b/library/core/src/num/dec2flt/table.rs index 4856074a62bd0..942c2eacfd276 100644 --- a/library/core/src/num/dec2flt/table.rs +++ b/library/core/src/num/dec2flt/table.rs @@ -6,16 +6,17 @@ //! //! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py` -pub const SMALLEST_POWER_OF_FIVE: i32 = -342; -pub const LARGEST_POWER_OF_FIVE: i32 = 308; -pub const N_POWERS_OF_FIVE: usize = (LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1) as usize; +pub(super) const SMALLEST_POWER_OF_FIVE: i32 = -342; +pub(super) const LARGEST_POWER_OF_FIVE: i32 = 308; +pub(super) const N_POWERS_OF_FIVE: usize = + (LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1) as usize; // Use static to avoid long compile times: Rust compiler errors // can have the entire table compiled multiple times, and then // emit code multiple times, even if it's stripped out in // the final binary. #[rustfmt::skip] -pub static POWER_OF_FIVE_128: [(u64, u64); N_POWERS_OF_FIVE] = [ +pub(super) static POWER_OF_FIVE_128: [(u64, u64); N_POWERS_OF_FIVE] = [ (0xeef453d6923bd65a, 0x113faa2906a13b3f), // 5^-342 (0x9558b4661b6565f8, 0x4ac7ca59a424c507), // 5^-341 (0xbaaee17fa23ebf76, 0x5d79bcf00d2df649), // 5^-340 diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs index 0ce31b40a3845..28a3f5d880ad7 100644 --- a/library/core/src/num/int_log10.rs +++ b/library/core/src/num/int_log10.rs @@ -3,7 +3,7 @@ // 0 < val <= u8::MAX #[inline] -pub const fn u8(val: u8) -> u32 { +pub(super) const fn u8(val: u8) -> u32 { let val = val as u32; // For better performance, avoid branches by assembling the solution @@ -45,13 +45,13 @@ const fn less_than_5(val: u32) -> u32 { // 0 < val <= u16::MAX #[inline] -pub const fn u16(val: u16) -> u32 { +pub(super) const fn u16(val: u16) -> u32 { less_than_5(val as u32) } // 0 < val <= u32::MAX #[inline] -pub const fn u32(mut val: u32) -> u32 { +pub(super) const fn u32(mut val: u32) -> u32 { let mut log = 0; if val >= 100_000 { val /= 100_000; @@ -62,7 +62,7 @@ pub const fn u32(mut val: u32) -> u32 { // 0 < val <= u64::MAX #[inline] -pub const fn u64(mut val: u64) -> u32 { +pub(super) const fn u64(mut val: u64) -> u32 { let mut log = 0; if val >= 10_000_000_000 { val /= 10_000_000_000; @@ -77,7 +77,7 @@ pub const fn u64(mut val: u64) -> u32 { // 0 < val <= u128::MAX #[inline] -pub const fn u128(mut val: u128) -> u32 { +pub(super) const fn u128(mut val: u128) -> u32 { let mut log = 0; if val >= 100_000_000_000_000_000_000_000_000_000_000 { val /= 100_000_000_000_000_000_000_000_000_000_000; @@ -93,49 +93,49 @@ pub const fn u128(mut val: u128) -> u32 { #[cfg(target_pointer_width = "16")] #[inline] -pub const fn usize(val: usize) -> u32 { +pub(super) const fn usize(val: usize) -> u32 { u16(val as _) } #[cfg(target_pointer_width = "32")] #[inline] -pub const fn usize(val: usize) -> u32 { +pub(super) const fn usize(val: usize) -> u32 { u32(val as _) } #[cfg(target_pointer_width = "64")] #[inline] -pub const fn usize(val: usize) -> u32 { +pub(super) const fn usize(val: usize) -> u32 { u64(val as _) } // 0 < val <= i8::MAX #[inline] -pub const fn i8(val: i8) -> u32 { +pub(super) const fn i8(val: i8) -> u32 { u8(val as u8) } // 0 < val <= i16::MAX #[inline] -pub const fn i16(val: i16) -> u32 { +pub(super) const fn i16(val: i16) -> u32 { u16(val as u16) } // 0 < val <= i32::MAX #[inline] -pub const fn i32(val: i32) -> u32 { +pub(super) const fn i32(val: i32) -> u32 { u32(val as u32) } // 0 < val <= i64::MAX #[inline] -pub const fn i64(val: i64) -> u32 { +pub(super) const fn i64(val: i64) -> u32 { u64(val as u64) } // 0 < val <= i128::MAX #[inline] -pub const fn i128(val: i128) -> u32 { +pub(super) const fn i128(val: i128) -> u32 { u128(val as u128) } @@ -143,6 +143,6 @@ pub const fn i128(val: i128) -> u32 { /// on every single primitive type. #[cold] #[track_caller] -pub const fn panic_for_nonpositive_argument() -> ! { +pub(super) const fn panic_for_nonpositive_argument() -> ! { panic!("argument of integer logarithm must be positive") } diff --git a/library/core/src/num/int_sqrt.rs b/library/core/src/num/int_sqrt.rs index 601e81f69930f..c7a322c08c139 100644 --- a/library/core/src/num/int_sqrt.rs +++ b/library/core/src/num/int_sqrt.rs @@ -37,7 +37,7 @@ const U8_ISQRT_WITH_REMAINDER: [(u8, u8); 256] = { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] -pub const fn u8(n: u8) -> u8 { +pub(super) const fn u8(n: u8) -> u8 { U8_ISQRT_WITH_REMAINDER[n as usize].0 } @@ -58,7 +58,7 @@ macro_rules! signed_fn { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn $SignedT(n: $SignedT) -> $SignedT { + pub(super) const unsafe fn $SignedT(n: $SignedT) -> $SignedT { debug_assert!(n >= 0, "Negative input inside `isqrt`."); $UnsignedT(n as $UnsignedT) as $SignedT } @@ -83,7 +83,7 @@ macro_rules! unsigned_fn { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT { + pub(super) const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT { if n <= <$HalfBitsT>::MAX as $UnsignedT { $HalfBitsT(n as $HalfBitsT) as $UnsignedT } else { @@ -311,6 +311,6 @@ unsigned_fn!(u128, u64, u128_stages); /// on every single primitive type. #[cold] #[track_caller] -pub const fn panic_for_negative_argument() -> ! { +pub(super) const fn panic_for_negative_argument() -> ! { panic!("argument of integer square root cannot be negative") } diff --git a/library/core/src/num/overflow_panic.rs b/library/core/src/num/overflow_panic.rs index 203037ffb43ea..e30573dd3f392 100644 --- a/library/core/src/num/overflow_panic.rs +++ b/library/core/src/num/overflow_panic.rs @@ -4,48 +4,48 @@ #[cold] #[track_caller] -pub const fn add() -> ! { +pub(super) const fn add() -> ! { panic!("attempt to add with overflow") } #[cold] #[track_caller] -pub const fn sub() -> ! { +pub(super) const fn sub() -> ! { panic!("attempt to subtract with overflow") } #[cold] #[track_caller] -pub const fn mul() -> ! { +pub(super) const fn mul() -> ! { panic!("attempt to multiply with overflow") } #[cold] #[track_caller] -pub const fn div() -> ! { +pub(super) const fn div() -> ! { panic!("attempt to divide with overflow") } #[cold] #[track_caller] -pub const fn rem() -> ! { +pub(super) const fn rem() -> ! { panic!("attempt to calculate the remainder with overflow") } #[cold] #[track_caller] -pub const fn neg() -> ! { +pub(super) const fn neg() -> ! { panic!("attempt to negate with overflow") } #[cold] #[track_caller] -pub const fn shr() -> ! { +pub(super) const fn shr() -> ! { panic!("attempt to shift right with overflow") } #[cold] #[track_caller] -pub const fn shl() -> ! { +pub(super) const fn shl() -> ! { panic!("attempt to shift left with overflow") } diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 1156b389e2867..55fa91d0b9f49 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -1058,33 +1058,33 @@ mod shift_max { #[cfg(target_pointer_width = "16")] mod platform { - pub const usize: u32 = super::u16; - pub const isize: u32 = super::i16; + pub(crate) const usize: u32 = super::u16; + pub(crate) const isize: u32 = super::i16; } #[cfg(target_pointer_width = "32")] mod platform { - pub const usize: u32 = super::u32; - pub const isize: u32 = super::i32; + pub(crate) const usize: u32 = super::u32; + pub(crate) const isize: u32 = super::i32; } #[cfg(target_pointer_width = "64")] mod platform { - pub const usize: u32 = super::u64; - pub const isize: u32 = super::i64; + pub(crate) const usize: u32 = super::u64; + pub(crate) const isize: u32 = super::i64; } - pub const i8: u32 = (1 << 3) - 1; - pub const i16: u32 = (1 << 4) - 1; - pub const i32: u32 = (1 << 5) - 1; - pub const i64: u32 = (1 << 6) - 1; - pub const i128: u32 = (1 << 7) - 1; - pub use self::platform::isize; - - pub const u8: u32 = i8; - pub const u16: u32 = i16; - pub const u32: u32 = i32; - pub const u64: u32 = i64; - pub const u128: u32 = i128; - pub use self::platform::usize; + pub(super) const i8: u32 = (1 << 3) - 1; + pub(super) const i16: u32 = (1 << 4) - 1; + pub(super) const i32: u32 = (1 << 5) - 1; + pub(super) const i64: u32 = (1 << 6) - 1; + pub(super) const i128: u32 = (1 << 7) - 1; + pub(super) use self::platform::isize; + + pub(super) const u8: u32 = i8; + pub(super) const u16: u32 = i16; + pub(super) const u32: u32 = i32; + pub(super) const u64: u32 = i64; + pub(super) const u128: u32 = i128; + pub(super) use self::platform::usize; } diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index dce3514a1595b..b82184b15b2f5 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -18,7 +18,7 @@ impl IndexRange { /// # Safety /// - `start <= end` #[inline] - pub const unsafe fn new_unchecked(start: usize, end: usize) -> Self { + pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self { ub_checks::assert_unsafe_precondition!( check_library_ub, "IndexRange::new_unchecked requires `start <= end`", @@ -28,22 +28,22 @@ impl IndexRange { } #[inline] - pub const fn zero_to(end: usize) -> Self { + pub(crate) const fn zero_to(end: usize) -> Self { IndexRange { start: 0, end } } #[inline] - pub const fn start(&self) -> usize { + pub(crate) const fn start(&self) -> usize { self.start } #[inline] - pub const fn end(&self) -> usize { + pub(crate) const fn end(&self) -> usize { self.end } #[inline] - pub const fn len(&self) -> usize { + pub(crate) const fn len(&self) -> usize { // SAFETY: By invariant, this cannot wrap // Using the intrinsic because a UB check here impedes LLVM optimization. (#131563) unsafe { crate::intrinsics::unchecked_sub(self.end, self.start) } @@ -79,7 +79,7 @@ impl IndexRange { /// /// This is designed to help implement `Iterator::advance_by`. #[inline] - pub fn take_prefix(&mut self, n: usize) -> Self { + pub(crate) fn take_prefix(&mut self, n: usize) -> Self { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. @@ -99,7 +99,7 @@ impl IndexRange { /// /// This is designed to help implement `Iterator::advance_back_by`. #[inline] - pub fn take_suffix(&mut self, n: usize) -> Self { + pub(crate) fn take_suffix(&mut self, n: usize) -> Self { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the subtraction cannot overflow. diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index cd444c86ed06e..3ba2957526f9c 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -338,6 +338,7 @@ pub trait FromResidual::Residual> { #[inline] #[track_caller] // because `Result::from_residual` has it #[lang = "from_yeet"] +#[allow(unreachable_pub)] // not-exposed but still used via lang-item pub fn from_yeet(yeeted: Y) -> T where T: FromResidual>, @@ -383,12 +384,14 @@ impl NeverShortCircuit { /// This is useful for implementing infallible functions in terms of the `try_` ones, /// without accidentally capturing extra generic parameters in a closure. #[inline] - pub fn wrap_mut_1(mut f: impl FnMut(A) -> T) -> impl FnMut(A) -> NeverShortCircuit { + pub(crate) fn wrap_mut_1( + mut f: impl FnMut(A) -> T, + ) -> impl FnMut(A) -> NeverShortCircuit { move |a| NeverShortCircuit(f(a)) } #[inline] - pub fn wrap_mut_2(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { + pub(crate) fn wrap_mut_2(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { move |a, b| NeverShortCircuit(f(a, b)) } } diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 1e4865a7caad9..d8e0acb565c8c 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -60,7 +60,7 @@ use crate::{cmp, ptr}; /// we cannot swap any more, but a smaller rotation problem is left to solve /// ``` /// when `left < right` the swapping happens from the left instead. -pub unsafe fn ptr_rotate(mut left: usize, mut mid: *mut T, mut right: usize) { +pub(super) unsafe fn ptr_rotate(mut left: usize, mut mid: *mut T, mut right: usize) { type BufType = [usize; 32]; if T::IS_ZST { return; diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 6066aa9921607..49dbdeb1a6d1c 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -17,6 +17,8 @@ pub(crate) use unicode_data::uppercase::lookup as Uppercase; pub(crate) use unicode_data::white_space::lookup as White_Space; pub(crate) mod printable; + +#[allow(unreachable_pub)] mod unicode_data; /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of diff --git a/src/etc/dec2flt_table.py b/src/etc/dec2flt_table.py index 791186de9c190..ecfdacc1f3115 100755 --- a/src/etc/dec2flt_table.py +++ b/src/etc/dec2flt_table.py @@ -43,10 +43,10 @@ def main(): print(HEADER.strip()) print() - print("pub const SMALLEST_POWER_OF_FIVE: i32 = {};".format(min_exp)) - print("pub const LARGEST_POWER_OF_FIVE: i32 = {};".format(max_exp)) - print("pub const N_POWERS_OF_FIVE: usize = ", end="") - print("(LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1) as usize;") + print("pub(super) const SMALLEST_POWER_OF_FIVE: i32 = {};".format(min_exp)) + print("pub(super) const LARGEST_POWER_OF_FIVE: i32 = {};".format(max_exp)) + print("pub(super) const N_POWERS_OF_FIVE: usize =") + print(" (LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1) as usize;") print() print_proper_powers(min_exp, max_exp, bias) @@ -97,7 +97,7 @@ def print_proper_powers(min_exp, max_exp, bias): print(STATIC_WARNING.strip()) print("#[rustfmt::skip]") typ = "[(u64, u64); N_POWERS_OF_FIVE]" - print("pub static POWER_OF_FIVE_128: {} = [".format(typ)) + print("pub(super) static POWER_OF_FIVE_128: {} = [".format(typ)) for c, exp in powers: hi = "0x{:x}".format(c // (1 << 64)) lo = "0x{:x}".format(c % (1 << 64)) From 4a857557563a06a70c1c7533cf4220f42b37198a Mon Sep 17 00:00:00 2001 From: spore Date: Sat, 11 Jan 2025 13:05:15 +0800 Subject: [PATCH 08/13] Minor simplification Apply eta-reduction on map to simplify code and make the style more consistent --- compiler/rustc_lint/src/types/literal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index 4faf345bcd58f..f7a59437bbc27 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -205,7 +205,7 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None, ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), ty::Int(int) => { - let signed = literal_to_i128(val, negative).map(|v| Integer::fit_signed(v)); + let signed = literal_to_i128(val, negative).map(Integer::fit_signed); if negative { signed.map(Integer::int_ty_str) } else { From f52724c917216a8c9126479b0e0c097afe447593 Mon Sep 17 00:00:00 2001 From: spore Date: Sun, 12 Jan 2025 19:50:01 +0800 Subject: [PATCH 09/13] Add comment on case to mark the original issue --- tests/ui/lint/type-overflow.rs | 2 +- tests/ui/lint/type-overflow.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs index 0848d676e237c..102d042773b99 100644 --- a/tests/ui/lint/type-overflow.rs +++ b/tests/ui/lint/type-overflow.rs @@ -28,7 +28,7 @@ fn main() { //~^ WARNING literal out of range for `i32` //~| HELP consider using the type `u128` instead - let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; + let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849 //~^ WARNING literal out of range for `i32` //~| HELP consider using the type `i128` instead diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index dbbe81e5c182d..720044c68ebda 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -77,7 +77,7 @@ LL | let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000; warning: literal out of range for `i32` --> $DIR/type-overflow.rs:31:17 | -LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; +LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` From 74e2e8b59834aede7aafee57e00ede07ae13739b Mon Sep 17 00:00:00 2001 From: spore Date: Sun, 12 Jan 2025 20:18:53 +0800 Subject: [PATCH 10/13] Suggest the smallest fitting type instead Changes the behavior of the `overflowing_literals` suggestion so that it always suggest the smallest type regardless of the original type size. --- compiler/rustc_lint/src/types/literal.rs | 4 ++-- tests/ui/lint/type-overflow.rs | 2 +- tests/ui/lint/type-overflow.stderr | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index f7a59437bbc27..4b5163522f866 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -204,14 +204,14 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static match t.kind() { ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None, ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), - ty::Int(int) => { + ty::Int(_) => { let signed = literal_to_i128(val, negative).map(Integer::fit_signed); if negative { signed.map(Integer::int_ty_str) } else { let unsigned = Integer::fit_unsigned(val); Some(if let Some(signed) = signed { - if Some(unsigned.size().bits()) == int.bit_width() { + if unsigned.size() < signed.size() { unsigned.uint_ty_str() } else { signed.int_ty_str() diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs index 102d042773b99..1e74a8925f621 100644 --- a/tests/ui/lint/type-overflow.rs +++ b/tests/ui/lint/type-overflow.rs @@ -40,7 +40,7 @@ fn main() { //~| HELP consider using the type `u128` instead let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32` - //~| HELP consider using the type `i128` instead + //~| HELP consider using the type `u64` instead //~| HELP let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8` diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index 720044c68ebda..9fdb05ed1c036 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -109,7 +109,7 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; | ^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32` - = help: consider using the type `i128` instead + = help: consider using the type `u64` instead help: to use as a negative number (decimal `-2`), consider using the type `u32` for the literal and cast it to `i32` | LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu32 as i32; From c4a5e12567a4f5b540141c31c87f479bb3e73e63 Mon Sep 17 00:00:00 2001 From: Aeon <165953379+AeonSolstice@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:08:22 -0500 Subject: [PATCH 11/13] Clarify note in `std::sync::LazyLock` example --- library/std/src/sync/lazy_lock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 1e4f9b79e0f4a..98c83d8d326ca 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -31,7 +31,7 @@ union Data { /// ``` /// use std::sync::LazyLock; /// -/// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated. +/// // Note: static items do not call [`Drop`] on program termination, so this won't be deallocated. /// // this is fine, as the OS can deallocate the terminated program faster than we can free memory /// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional. /// static DEEP_THOUGHT: LazyLock = LazyLock::new(|| { From fef3dd4354148e875b4ceb521748773217d39fd9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 15 Jan 2025 15:15:52 +0100 Subject: [PATCH 12/13] use indirect return for `i128` and `f128` on wasm32 --- compiler/rustc_target/src/callconv/wasm.rs | 12 ++++++ tests/codegen/f128-wasm32-callconv.rs | 49 ++++++++++++++++++++++ tests/codegen/i128-wasm32-callconv.rs | 49 ++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 tests/codegen/f128-wasm32-callconv.rs create mode 100644 tests/codegen/i128-wasm32-callconv.rs diff --git a/compiler/rustc_target/src/callconv/wasm.rs b/compiler/rustc_target/src/callconv/wasm.rs index 3c4cd76a75464..d01b59cbb032b 100644 --- a/compiler/rustc_target/src/callconv/wasm.rs +++ b/compiler/rustc_target/src/callconv/wasm.rs @@ -1,3 +1,5 @@ +use rustc_abi::{BackendRepr, Float, Integer, Primitive}; + use crate::abi::call::{ArgAbi, FnAbi}; use crate::abi::{HasDataLayout, TyAbiInterface}; @@ -27,6 +29,16 @@ where if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) { ret.make_indirect(); } + + // `long double`, `__int128_t` and `__uint128_t` use an indirect return + if let BackendRepr::Scalar(scalar) = ret.layout.backend_repr { + match scalar.primitive() { + Primitive::Int(Integer::I128, _) | Primitive::Float(Float::F128) => { + ret.make_indirect(); + } + _ => {} + } + } } fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) diff --git a/tests/codegen/f128-wasm32-callconv.rs b/tests/codegen/f128-wasm32-callconv.rs new file mode 100644 index 0000000000000..55adffd4db3ba --- /dev/null +++ b/tests/codegen/f128-wasm32-callconv.rs @@ -0,0 +1,49 @@ +//! Verify that Rust implements the expected calling convention for `f128` + +//@ add-core-stubs +//@ compile-flags: --target wasm32-wasip1 +//@ needs-llvm-components: webassembly + +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![feature(no_core, lang_items, f128)] + +extern crate minicore; + +extern "C" { + fn extern_call(arg0: f128); + fn extern_ret() -> f128; +} + +#[no_mangle] +pub extern "C" fn pass(_arg0: u32, arg1: f128) { + // CHECK-LABEL: @pass( + // an f128 is passed via registers + // CHECK-SAME: fp128 noundef %arg1 + // CHECK: call void @extern_call + unsafe { extern_call(arg1) }; +} + +// Check that we produce the correct return ABI +#[no_mangle] +pub extern "C" fn ret(_arg0: u32, arg1: f128) -> f128 { + // CHECK-LABEL: @ret( + // but an f128 is returned via the stack + // CHECK-SAME: sret + // CHECK: store fp128 %arg1 + // CHECK-NEXT: ret void + arg1 +} + +// Check that we consume the correct return ABI +#[no_mangle] +pub extern "C" fn forward(dst: *mut f128) { + // CHECK-LABEL: @forward + // CHECK-SAME: ptr{{.*}} %dst) + // without optimizatons, an intermediate alloca is used + // CHECK: call void @extern_ret + // CHECK: store fp128 + // CHECK: ret void + unsafe { *dst = extern_ret() }; +} diff --git a/tests/codegen/i128-wasm32-callconv.rs b/tests/codegen/i128-wasm32-callconv.rs new file mode 100644 index 0000000000000..3dece56a9bb73 --- /dev/null +++ b/tests/codegen/i128-wasm32-callconv.rs @@ -0,0 +1,49 @@ +//! Verify that Rust implements the expected calling convention for `i128`/`u128`. + +//@ add-core-stubs +//@ compile-flags: --target wasm32-wasip1 +//@ needs-llvm-components: webassembly + +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![feature(no_core, lang_items)] + +extern crate minicore; + +extern "C" { + fn extern_call(arg0: i128); + fn extern_ret() -> i128; +} + +#[no_mangle] +pub extern "C" fn pass(_arg0: u32, arg1: i128) { + // CHECK-LABEL: @pass( + // an i128 is passed via registers + // CHECK-SAME: i128 noundef %arg1 + // CHECK: call void @extern_call + unsafe { extern_call(arg1) }; +} + +// Check that we produce the correct return ABI +#[no_mangle] +pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 { + // CHECK-LABEL: @ret( + // but an i128 is returned via the stack + // CHECK-SAME: sret + // CHECK: store i128 %arg1 + // CHECK-NEXT: ret void + arg1 +} + +// Check that we consume the correct return ABI +#[no_mangle] +pub extern "C" fn forward(dst: *mut i128) { + // CHECK-LABEL: @forward + // CHECK-SAME: ptr{{.*}} %dst) + // without optimizatons, an intermediate alloca is used + // CHECK: call void @extern_ret + // CHECK: store i128 + // CHECK: ret void + unsafe { *dst = extern_ret() }; +} From bbeb5e314ef2f3fd15aea4fe3e849e48a5b1d47f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 16 Jan 2025 01:47:15 +0000 Subject: [PATCH 13/13] Update `compiler-builtins` to 0.1.144 The change between 0.1.143 and 0.1.144 includes refactoring that was in compiler-builtins before, but had to be reverted before landing in rust-lang/rust because the traits were leaking into diagnostics [1]. Recently a fix for this issue was merged [2] so the cleanup is reapplied here. This also acts as a regression test for [2]. [1]: https://github.com/rust-lang/rust/pull/128691#issuecomment-2272297610 [2]: https://github.com/rust-lang/rust/pull/135278 --- ...029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch | 4 ++-- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index bf58e48515855..82dd5dcada7f0 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core" } --compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/Cargo.lock b/library/Cargo.lock index c8007dd9be046..13da832c53d8c 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.143" +version = "0.1.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85ba2077e3eab3dd81be4ece6b7fb2ad0887c1fb813e9a45400baf75c6c7c29" +checksum = "d18a7b7b5a56aa131e62314b4d862c9f6aa2860f615f3770094ec9064d7ec572" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 96caac890a35c..edb0aa4df3c1f 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index da58d7c13bd12..0a4fd9f4c7123 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.143" } +compiler_builtins = { version = "=0.1.144" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std',