From 04e7a10af68e6174e42e9ce4a6e81f97722a6032 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Feb 2025 15:15:28 +0100 Subject: [PATCH 01/13] intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic --- .../src/intrinsics/mod.rs | 16 +- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 9 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 22 +-- .../rustc_hir_analysis/src/check/intrinsic.rs | 18 +- compiler/rustc_span/src/symbol.rs | 16 +- library/core/src/intrinsics/mod.rs | 185 +++++++----------- library/std/src/f128.rs | 2 +- library/std/src/f16.rs | 2 +- library/std/src/f32.rs | 2 +- library/std/src/f64.rs | 2 +- src/tools/miri/src/intrinsics/mod.rs | 16 +- tests/codegen/intrinsics/nearby.rs | 18 -- tests/ui/intrinsics/intrinsic-nearby.rs | 11 -- 13 files changed, 111 insertions(+), 208 deletions(-) delete mode 100644 tests/codegen/intrinsics/nearby.rs delete mode 100644 tests/ui/intrinsics/intrinsic-nearby.rs diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 26f14532b45..4d9bed8652c 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>( sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), - sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32), - sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64), + sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32), + sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64), sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), - sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32), - sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64), - sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32), - sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), @@ -399,8 +395,8 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::ceilf64 | sym::truncf32 | sym::truncf64 - | sym::nearbyintf32 - | sym::nearbyintf64 + | sym::round_ties_even_f32 + | sym::round_ties_even_f64 | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { @@ -408,7 +404,9 @@ fn codegen_float_intrinsic_call<'tcx>( sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), - sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]), + sym::round_ties_even_f32 | sym::round_ties_even_f64 => { + fx.bcx.ins().nearest(args[0]) + } sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), _ => unreachable!(), }; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 48606f5f91c..83d0db0fb54 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::ceilf64 => "ceil", sym::truncf32 => "truncf", sym::truncf64 => "trunc", - sym::rintf32 => "rintf", - sym::rintf64 => "rint", - sym::nearbyintf32 => "nearbyintf", - sym::nearbyintf64 => "nearbyint", + // We match the LLVM backend and lower this to `rint`. + sym::round_ties_even_f32 => "rintf", + sym::round_ties_even_f64 => "rint", sym::roundf32 => "roundf", sym::roundf64 => "round", - sym::roundevenf32 => "roundevenf", - sym::roundevenf64 => "roundeven", sym::abort => "abort", _ => return None, }; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 43d6ccfcb4a..464a6ce434d 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -126,15 +126,14 @@ fn get_simple_intrinsic<'ll>( sym::truncf64 => "llvm.trunc.f64", sym::truncf128 => "llvm.trunc.f128", - sym::rintf16 => "llvm.rint.f16", - sym::rintf32 => "llvm.rint.f32", - sym::rintf64 => "llvm.rint.f64", - sym::rintf128 => "llvm.rint.f128", - - sym::nearbyintf16 => "llvm.nearbyint.f16", - sym::nearbyintf32 => "llvm.nearbyint.f32", - sym::nearbyintf64 => "llvm.nearbyint.f64", - sym::nearbyintf128 => "llvm.nearbyint.f128", + // We could use any of `rint`, `nearbyint`, or `roundeven` + // for this -- they are all identical in semantics when + // assuming the default FP environment. + // `rint` is what we used for $forever. + sym::round_ties_even_f16 => "llvm.rint.f16", + sym::round_ties_even_f32 => "llvm.rint.f32", + sym::round_ties_even_f64 => "llvm.rint.f64", + sym::round_ties_even_f128 => "llvm.rint.f128", sym::roundf16 => "llvm.round.f16", sym::roundf32 => "llvm.round.f32", @@ -143,11 +142,6 @@ fn get_simple_intrinsic<'ll>( sym::ptr_mask => "llvm.ptrmask", - sym::roundevenf16 => "llvm.roundeven.f16", - sym::roundevenf32 => "llvm.roundeven.f32", - sym::roundevenf64 => "llvm.roundeven.f64", - sym::roundevenf128 => "llvm.roundeven.f128", - _ => return None, }; Some(cx.get_intrinsic(llvm_name)) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index cf3d4897304..acdd2facc24 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -398,26 +398,16 @@ pub fn check_intrinsic_type( sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), + sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), + sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), + sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::volatile_load | sym::unaligned_volatile_load => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 382b12638f4..0188327fd82 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1337,10 +1337,6 @@ symbols! { native_link_modifiers_whole_archive, natvis_file, ne, - nearbyintf128, - nearbyintf16, - nearbyintf32, - nearbyintf64, needs_allocator, needs_drop, needs_panic_runtime, @@ -1655,20 +1651,16 @@ symbols! { return_position_impl_trait_in_trait, return_type_notation, rhs, - rintf128, - rintf16, - rintf32, - rintf64, riscv_target_feature, rlib, ropi, ropi_rwpi: "ropi-rwpi", rotate_left, rotate_right, - roundevenf128, - roundevenf16, - roundevenf32, - roundevenf64, + round_ties_even_f128, + round_ties_even_f16, + round_ties_even_f32, + round_ties_even_f64, roundf128, roundf16, roundf32, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index bf07632d992..320122a53e9 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2739,110 +2739,112 @@ pub unsafe fn truncf128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. +/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf16(_x: f16) -> f16 { +#[cfg(not(bootstrap))] +pub unsafe fn round_ties_even_f16(_x: f16) -> f16 { unreachable!() } -/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub unsafe fn round_ties_even_f16(x: f16) -> f16 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf16(_x: f16) -> f16 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf16(x) } +} + +/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf32(_x: f32) -> f32 { +#[cfg(not(bootstrap))] +pub unsafe fn round_ties_even_f32(_x: f32) -> f32 { unreachable!() } -/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub unsafe fn round_ties_even_f32(x: f32) -> f32 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf32(_x: f32) -> f32 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf32(x) } +} + +/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf64(_x: f64) -> f64 { +#[cfg(not(bootstrap))] +pub unsafe fn round_ties_even_f64(_x: f64) -> f64 { unreachable!() } -/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub unsafe fn round_ties_even_f64(x: f64) -> f64 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf64(_x: f64) -> f64 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf64(x) } +} + +/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf128(_x: f128) -> f128 { +#[cfg(not(bootstrap))] +pub unsafe fn round_ties_even_f128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf16(_x: f16) -> f16 { - unreachable!() -} -/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf32(_x: f32) -> f32 { - unreachable!() -} -/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf64(_x: f64) -> f64 { - unreachable!() -} -/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf128(_x: f128) -> f128 { - unreachable!() +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub unsafe fn round_ties_even_f128(x: f128) -> f128 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf128(_x: f128) -> f128 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf128(x) } } /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. @@ -2886,47 +2888,6 @@ pub unsafe fn roundf128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf16(_x: f16) -> f16 { - unreachable!() -} -/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf32(_x: f32) -> f32 { - unreachable!() -} -/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf64(_x: f64) -> f64 { - unreachable!() -} -/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf128(_x: f128) -> f128 { - unreachable!() -} - /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index d65f5ed61cf..615c4fd3348 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -129,7 +129,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f128 { - unsafe { intrinsics::rintf128(self) } + unsafe { intrinsics::round_ties_even_f128(self) } } /// Returns the integer part of `self`. diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index 5b0903bceab..85b82b91fab 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -129,7 +129,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f16 { - unsafe { intrinsics::rintf16(self) } + unsafe { intrinsics::round_ties_even_f16(self) } } /// Returns the integer part of `self`. diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index f9b6723788a..da1f000278d 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -125,7 +125,7 @@ impl f32 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f32 { - unsafe { intrinsics::rintf32(self) } + unsafe { intrinsics::round_ties_even_f32(self) } } /// Returns the integer part of `self`. diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 0de55a15d48..8a9f693a7a8 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -125,7 +125,7 @@ impl f64 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f64 { - unsafe { intrinsics::rintf64(self) } + unsafe { intrinsics::round_ties_even_f64(self) } } /// Returns the integer part of `self`. diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index bce78adcaea..0faad0f7621 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -145,7 +145,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => { + "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f16()?; let mode = match intrinsic_name { @@ -153,14 +153,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf16" => Round::TowardPositive, "truncf16" => Round::TowardZero, "roundf16" => Round::NearestTiesToAway, - "rintf16" => Round::NearestTiesToEven, + "round_ties_even_f16" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => { + "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let mode = match intrinsic_name { @@ -168,14 +168,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf32" => Round::TowardPositive, "truncf32" => Round::TowardZero, "roundf32" => Round::NearestTiesToAway, - "rintf32" => Round::NearestTiesToEven, + "round_ties_even_f32" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => { + "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let mode = match intrinsic_name { @@ -183,14 +183,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf64" => Round::TowardPositive, "truncf64" => Round::TowardZero, "roundf64" => Round::NearestTiesToAway, - "rintf64" => Round::NearestTiesToEven, + "round_ties_even_f64" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => { + "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f128()?; let mode = match intrinsic_name { @@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf128" => Round::TowardPositive, "truncf128" => Round::TowardZero, "roundf128" => Round::NearestTiesToAway, - "rintf128" => Round::NearestTiesToEven, + "round_ties_even_f128" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; diff --git a/tests/codegen/intrinsics/nearby.rs b/tests/codegen/intrinsics/nearby.rs deleted file mode 100644 index 520fe2f1886..00000000000 --- a/tests/codegen/intrinsics/nearby.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics; - -// CHECK-LABEL: @nearbyintf32 -#[no_mangle] -pub unsafe fn nearbyintf32(a: f32) -> f32 { - // CHECK: llvm.nearbyint.f32 - intrinsics::nearbyintf32(a) -} - -// CHECK-LABEL: @nearbyintf64 -#[no_mangle] -pub unsafe fn nearbyintf64(a: f64) -> f64 { - // CHECK: llvm.nearbyint.f64 - intrinsics::nearbyintf64(a) -} diff --git a/tests/ui/intrinsics/intrinsic-nearby.rs b/tests/ui/intrinsics/intrinsic-nearby.rs deleted file mode 100644 index 990ecfc2b70..00000000000 --- a/tests/ui/intrinsics/intrinsic-nearby.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![feature(core_intrinsics)] - -use std::intrinsics::*; - -fn main() { - unsafe { - assert_eq!(nearbyintf32(5.234f32), 5f32); - assert_eq!(nearbyintf64(6.777f64), 7f64); - } -} From c930bb2cfbe0ddd99188deed68f6a1a4d22fff3e Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 2 Feb 2025 13:01:10 +0000 Subject: [PATCH 02/13] rustc_codegen_ssa: use slice patterns instead of len-check+indexing --- compiler/rustc_codegen_ssa/src/back/write.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index ce2161a07eb..85e592d5959 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -572,10 +572,10 @@ fn produce_final_output_artifacts( }; let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { - if compiled_modules.modules.len() == 1 { + if let [module] = &compiled_modules.modules[..] { // 1) Only one codegen unit. In this case it's no difficulty // to copy `foo.0.x` to `foo.x`. - let module_name = Some(&compiled_modules.modules[0].name[..]); + let module_name = Some(&module.name[..]); let path = crate_output.temp_path(output_type, module_name); let output = crate_output.path(output_type); if !output_type.is_text_output() && output.is_tty() { @@ -707,8 +707,8 @@ fn produce_final_output_artifacts( } if sess.opts.json_artifact_notifications { - if compiled_modules.modules.len() == 1 { - compiled_modules.modules[0].for_each_output(|_path, ty| { + if let [module] = &compiled_modules.modules[..] { + module.for_each_output(|_path, ty| { if sess.opts.output_types.contains_key(&ty) { let descr = ty.shorthand(); // for single cgu file is renamed to drop cgu specific suffix @@ -864,7 +864,7 @@ pub(crate) fn compute_per_cgu_lto_type( // require LTO so the request for LTO is always unconditionally // passed down to the backend, but we don't actually want to do // anything about it yet until we've got a final product. - let is_rlib = sess_crate_types.len() == 1 && sess_crate_types[0] == CrateType::Rlib; + let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]); match sess_lto { Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, From 9e5e6a9d0fc95d7f5a22ca8da0816d407977c674 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 2 Feb 2025 13:04:38 +0000 Subject: [PATCH 03/13] rustc_codegen_ssa: cleanup nested `if`s and a needless `match` --- compiler/rustc_codegen_ssa/src/back/link.rs | 7 ++-- compiler/rustc_codegen_ssa/src/back/write.rs | 5 +-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 35 ++++++++----------- compiler/rustc_codegen_ssa/src/mir/block.rs | 5 +-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105a4cb81f0..c592cf347b5 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -626,10 +626,9 @@ fn link_staticlib( let mut all_rust_dylibs = vec![]; for &cnum in crates { - match fmts.get(cnum) { - Some(&Linkage::Dynamic) => {} - _ => continue, - } + let Some(Linkage::Dynamic) = fmts.get(cnum) else { + continue; + }; let crate_name = codegen_results.crate_info.crate_name[&cnum]; let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; if let Some((path, _)) = &used_crate_source.dylib { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 85e592d5959..6be7d6fdf84 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1537,8 +1537,9 @@ fn start_executing_work( // Spin up what work we can, only doing this while we've got available // parallelism slots and work left to spawn. if codegen_state != Aborted { - while !work_items.is_empty() && running_with_own_token < tokens.len() { - let (item, _) = work_items.pop().unwrap(); + while running_with_own_token < tokens.len() + && let Some((item, _)) = work_items.pop() + { spawn_work( &cgcx, &mut llvm_start_time, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 1d8f61806f5..a9ec8dba6d5 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -655,25 +655,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // llvm/llvm-project#70563). if !codegen_fn_attrs.target_features.is_empty() && matches!(codegen_fn_attrs.inline, InlineAttr::Always) + && let Some(span) = inline_span { - if let Some(span) = inline_span { - tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`"); - } + tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`"); } - if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() { - if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) { - let hir_id = tcx.local_def_id_to_hir_id(did); - tcx.node_span_lint( - lint::builtin::INLINE_NO_SANITIZE, - hir_id, - no_sanitize_span, - |lint| { - lint.primary_message("`no_sanitize` will have no effect after inlining"); - lint.span_note(inline_span, "inlining requested here"); - }, - ) - } + if !codegen_fn_attrs.no_sanitize.is_empty() + && codegen_fn_attrs.inline.always() + && let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) + { + let hir_id = tcx.local_def_id_to_hir_id(did); + tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| { + lint.primary_message("`no_sanitize` will have no effect after inlining"); + lint.span_note(inline_span, "inlining requested here"); + }) } // Weak lang items have the same semantics as "std internal" symbols in the @@ -703,10 +698,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // Any linkage to LLVM intrinsics for now forcibly marks them all as never // unwinds since LLVM sometimes can't handle codegen which `invoke`s // intrinsic functions. - if let Some(name) = &codegen_fn_attrs.link_name { - if name.as_str().starts_with("llvm.") { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } + if let Some(name) = &codegen_fn_attrs.link_name + && name.as_str().starts_with("llvm.") + { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; } if let Some(features) = check_tied_features( diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 8c571558717..1edc6a51485 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -990,8 +990,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }); // Split the rust-call tupled arguments off. - let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() { - let (tup, args) = args.split_last().unwrap(); + let (first_args, untuple) = if abi == ExternAbi::RustCall + && let Some((tup, args)) = args.split_last() + { (args, Some(tup)) } else { (args, None) From a82178564184c167954472f0079cf8773ee0b485 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 2 Feb 2025 13:08:51 +0000 Subject: [PATCH 04/13] rustc_codegen_ssa: simplify test for incompatible dependency formats thanks @kadiwa4 --- compiler/rustc_codegen_ssa/src/back/link.rs | 25 +++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c592cf347b5..6e30c6c1451 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -244,22 +244,17 @@ pub fn each_linked_rlib( fmts } else { - for combination in info.dependency_formats.iter().combinations(2) { - let (ty1, list1) = &combination[0]; - let (ty2, list2) = &combination[1]; - if list1 != list2 { - return Err(errors::LinkRlibError::IncompatibleDependencyFormats { - ty1: format!("{ty1:?}"), - ty2: format!("{ty2:?}"), - list1: format!("{list1:?}"), - list2: format!("{list2:?}"), - }); - } + let mut dep_formats = info.dependency_formats.iter(); + let (ty1, list1) = dep_formats.next().ok_or(errors::LinkRlibError::MissingFormat)?; + if let Some((ty2, list2)) = dep_formats.find(|(_, list2)| list1 != *list2) { + return Err(errors::LinkRlibError::IncompatibleDependencyFormats { + ty1: format!("{ty1:?}"), + ty2: format!("{ty2:?}"), + list1: format!("{list1:?}"), + list2: format!("{list2:?}"), + }); } - if info.dependency_formats.is_empty() { - return Err(errors::LinkRlibError::MissingFormat); - } - info.dependency_formats.first().unwrap().1 + list1 }; let used_dep_crates = info.used_crates.iter(); From 73d5fe153be5e34f58886afbb801e35fd476b125 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 2 Feb 2025 13:09:03 +0000 Subject: [PATCH 05/13] rustc_codegen_ssa: cleanup codegen attrs --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 118 +++++++++--------- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index a9ec8dba6d5..8aa5c54f1e2 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use rustc_abi::ExternAbi; -use rustc_ast::attr::list_contains_name; use rustc_ast::expand::autodiff_attrs::{ AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, }; @@ -385,24 +384,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let segments = set.path.segments.iter().map(|x| x.ident.name).collect::>(); match segments.as_slice() { - [sym::arm, sym::a32] | [sym::arm, sym::t32] => { - if !tcx.sess.target.has_thumb_interworking { - struct_span_code_err!( - tcx.dcx(), - attr.span, - E0779, - "target does not support `#[instruction_set]`" - ) - .emit(); - None - } else if segments[1] == sym::a32 { - Some(InstructionSetAttr::ArmA32) - } else if segments[1] == sym::t32 { - Some(InstructionSetAttr::ArmT32) - } else { - unreachable!() - } + [sym::arm, sym::a32 | sym::t32] + if !tcx.sess.target.has_thumb_interworking => + { + struct_span_code_err!( + tcx.dcx(), + attr.span, + E0779, + "target does not support `#[instruction_set]`" + ) + .emit(); + None } + [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), + [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), _ => { struct_span_code_err!( tcx.dcx(), @@ -443,7 +438,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some((sym::align, literal)) = item.singleton_lit_list() { rustc_attr_parsing::parse_alignment(&literal.kind) - .map_err(|msg| { + .inspect_err(|msg| { struct_span_code_err!( tcx.dcx(), literal.span, @@ -544,25 +539,27 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } if attr.is_word() { - InlineAttr::Hint - } else if let Some(ref items) = attr.meta_item_list() { - inline_span = Some(attr.span); - if items.len() != 1 { - struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); - InlineAttr::None - } else if list_contains_name(items, sym::always) { - InlineAttr::Always - } else if list_contains_name(items, sym::never) { - InlineAttr::Never - } else { - struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .with_help("valid inline arguments are `always` and `never`") - .emit(); + return InlineAttr::Hint; + } + let Some(ref items) = attr.meta_item_list() else { + return ia; + }; - InlineAttr::None - } + inline_span = Some(attr.span); + let [item] = &items[..] else { + struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); + return InlineAttr::None; + }; + if item.has_name(sym::always) { + InlineAttr::Always + } else if item.has_name(sym::never) { + InlineAttr::Never } else { - ia + struct_span_code_err!(tcx.dcx(), item.span(), E0535, "invalid argument") + .with_help("valid inline arguments are `always` and `never`") + .emit(); + + InlineAttr::None } }); codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| { @@ -594,23 +591,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); if attr.is_word() { err(attr.span, "expected one argument"); - ia - } else if let Some(ref items) = attr.meta_item_list() { - inline_span = Some(attr.span); - if items.len() != 1 { - err(attr.span, "expected one argument"); - OptimizeAttr::Default - } else if list_contains_name(items, sym::size) { - OptimizeAttr::Size - } else if list_contains_name(items, sym::speed) { - OptimizeAttr::Speed - } else if list_contains_name(items, sym::none) { - OptimizeAttr::DoNotOptimize - } else { - err(items[0].span(), "invalid argument"); - OptimizeAttr::Default - } + return ia; + } + let Some(ref items) = attr.meta_item_list() else { + return OptimizeAttr::Default; + }; + + inline_span = Some(attr.span); + let [item] = &items[..] else { + err(attr.span, "expected one argument"); + return OptimizeAttr::Default; + }; + if item.has_name(sym::size) { + OptimizeAttr::Size + } else if item.has_name(sym::speed) { + OptimizeAttr::Speed + } else if item.has_name(sym::none) { + OptimizeAttr::DoNotOptimize } else { + err(item.span(), "invalid argument"); OptimizeAttr::Default } }); @@ -762,18 +761,13 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option { use rustc_ast::{LitIntType, LitKind, MetaItemLit}; - let meta_item_list = attr.meta_item_list(); - let meta_item_list = meta_item_list.as_deref(); - let sole_meta_list = match meta_item_list { - Some([item]) => item.lit(), - Some(_) => { - tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span }); - return None; - } - _ => None, + let meta_item_list = attr.meta_item_list()?; + let [sole_meta_list] = &meta_item_list[..] else { + tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span }); + return None; }; if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = - sole_meta_list + sole_meta_list.lit() { // According to the table at // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the From 2c1f48970cc7954de147d5f71cd718b9035c6788 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 15 Feb 2025 21:12:58 +0000 Subject: [PATCH 06/13] fix rustdoc test directives that were accidentally ignored replace "// @" with "//@ ", and fix the tests so they actually pass, after directives are checked --- .../anchor-id-duplicate-method-name-25001.rs | 4 +-- ...long_typename.extremely_long_typename.html | 2 +- tests/rustdoc/extremely_long_typename.rs | 2 +- tests/rustdoc/unsafe-extern-blocks.rs | 26 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs index e1f19e7e017..d7f4e587d5e 100644 --- a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs +++ b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs @@ -24,14 +24,14 @@ impl Foo { } impl Bar for Foo { - // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T' + //@ has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T' type Item=T; //@ has - '//*[@id="method.quux"]//h4[@class="code-header"]' 'fn quux(self)' fn quux(self) {} } impl<'a, T> Bar for &'a Foo { - // @has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T" + //@ has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T" type Item=&'a T; //@ has - '//*[@id="method.quux-1"]//h4[@class="code-header"]' 'fn quux(self)' diff --git a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html index b20e59866da..64c4d5fb3e3 100644 --- a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html +++ b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html @@ -1 +1 @@ -
  • \ No newline at end of file +
    CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer
    \ No newline at end of file diff --git a/tests/rustdoc/extremely_long_typename.rs b/tests/rustdoc/extremely_long_typename.rs index 212afe2d110..a87c61e38bd 100644 --- a/tests/rustdoc/extremely_long_typename.rs +++ b/tests/rustdoc/extremely_long_typename.rs @@ -3,5 +3,5 @@ // the item table has it line wrapped. // There should be some reasonably-placed `` tags in the snapshot file. -// @snapshot extremely_long_typename "extremely_long_typename/index.html" '//ul[@class="item-table"]/li' +//@ snapshot extremely_long_typename "extremely_long_typename/index.html" '//dl[@class="item-table"]/dt' pub struct CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer; diff --git a/tests/rustdoc/unsafe-extern-blocks.rs b/tests/rustdoc/unsafe-extern-blocks.rs index 829095f300f..9a4e292dc83 100644 --- a/tests/rustdoc/unsafe-extern-blocks.rs +++ b/tests/rustdoc/unsafe-extern-blocks.rs @@ -2,28 +2,28 @@ #![crate_name = "foo"] -// @has 'foo/index.html' +//@ has 'foo/index.html' // First we check that both the static and the function have a "sup" element // to tell they're unsafe. -// @count - '//ul[@class="item-table"]//sup[@title="unsafe static"]' 1 -// @has - '//ul[@class="item-table"]//sup[@title="unsafe static"]' '⚠' -// @count - '//ul[@class="item-table"]//sup[@title="unsafe function"]' 1 -// @has - '//ul[@class="item-table"]//sup[@title="unsafe function"]' '⚠' +//@ count - '//dl[@class="item-table"]//sup[@title="unsafe static"]' 1 +//@ has - '//dl[@class="item-table"]//sup[@title="unsafe static"]' '⚠' +//@ count - '//dl[@class="item-table"]//sup[@title="unsafe function"]' 1 +//@ has - '//dl[@class="item-table"]//sup[@title="unsafe function"]' '⚠' unsafe extern "C" { - // @has 'foo/static.FOO.html' - // @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32' + //@ has 'foo/static.FOO.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32' pub safe static FOO: i32; - // @has 'foo/static.BAR.html' - // @has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32' + //@ has 'foo/static.BAR.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32' pub static BAR: i32; - // @has 'foo/fn.foo.html' - // @has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()' + //@ has 'foo/fn.foo.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()' pub safe fn foo(); - // @has 'foo/fn.bar.html' - // @has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()' + //@ has 'foo/fn.bar.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()' pub fn bar(); } From 17f2928caa78b665989fc48f204bcd9b4327a746 Mon Sep 17 00:00:00 2001 From: Pyrode Date: Fri, 14 Feb 2025 16:58:14 +0530 Subject: [PATCH 07/13] Adds binary_format to rustc target specs --- .../rustc_codegen_ssa/src/back/metadata.rs | 10 +--- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 40 ++++---------- compiler/rustc_target/src/spec/base/aix.rs | 5 +- .../rustc_target/src/spec/base/apple/mod.rs | 5 +- compiler/rustc_target/src/spec/base/cygwin.rs | 5 +- compiler/rustc_target/src/spec/base/msvc.rs | 3 +- compiler/rustc_target/src/spec/base/wasm.rs | 5 +- .../rustc_target/src/spec/base/windows_gnu.rs | 5 +- .../src/spec/base/windows_gnullvm.rs | 5 +- compiler/rustc_target/src/spec/json.rs | 15 ++++++ compiler/rustc_target/src/spec/mod.rs | 52 +++++++++++++++++++ 11 files changed, 102 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index d70413b8a47..236507ac0cd 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -252,15 +252,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option return None, }; - let binary_format = if sess.target.is_like_osx { - BinaryFormat::MachO - } else if sess.target.is_like_windows { - BinaryFormat::Coff - } else if sess.target.is_like_aix { - BinaryFormat::Xcoff - } else { - BinaryFormat::Elf - }; + let binary_format = sess.target.binary_format.to_object(); let mut file = write::Object::new(binary_format, architecture, endianness); file.set_sub_architecture(sub_architecture); diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index eb0711dbb32..0593fb420c3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::sym; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; -use rustc_target::spec::WasmCAbi; +use rustc_target::spec::{BinaryFormat, WasmCAbi}; use crate::common; use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods}; @@ -104,27 +104,6 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } -enum AsmBinaryFormat { - Elf, - Macho, - Coff, - Wasm, -} - -impl AsmBinaryFormat { - fn from_target(target: &rustc_target::spec::Target) -> Self { - if target.is_like_windows { - Self::Coff - } else if target.is_like_osx { - Self::Macho - } else if target.is_like_wasm { - Self::Wasm - } else { - Self::Elf - } - } -} - fn prefix_and_suffix<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, @@ -134,7 +113,7 @@ fn prefix_and_suffix<'tcx>( ) -> (String, String) { use std::fmt::Write; - let asm_binary_format = AsmBinaryFormat::from_target(&tcx.sess.target); + let asm_binary_format = &tcx.sess.target.binary_format; let is_arm = tcx.sess.target.arch == "arm"; let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode); @@ -178,10 +157,13 @@ fn prefix_and_suffix<'tcx>( } Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => { match asm_binary_format { - AsmBinaryFormat::Elf | AsmBinaryFormat::Coff | AsmBinaryFormat::Wasm => { + BinaryFormat::Elf + | BinaryFormat::Coff + | BinaryFormat::Wasm + | BinaryFormat::Xcoff => { writeln!(w, ".weak {asm_name}")?; } - AsmBinaryFormat::Macho => { + BinaryFormat::MachO => { writeln!(w, ".globl {asm_name}")?; writeln!(w, ".weak_definition {asm_name}")?; } @@ -207,7 +189,7 @@ fn prefix_and_suffix<'tcx>( let mut begin = String::new(); let mut end = String::new(); match asm_binary_format { - AsmBinaryFormat::Elf => { + BinaryFormat::Elf | BinaryFormat::Xcoff => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); let progbits = match is_arm { @@ -239,7 +221,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Macho => { + BinaryFormat::MachO => { let section = link_section.unwrap_or("__TEXT,__text".to_string()); writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap(); writeln!(begin, ".balign {align}").unwrap(); @@ -255,7 +237,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Coff => { + BinaryFormat::Coff => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); writeln!(begin, ".pushsection {},\"xr\"", section).unwrap(); writeln!(begin, ".balign {align}").unwrap(); @@ -272,7 +254,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Wasm => { + BinaryFormat::Wasm => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); writeln!(begin, ".section {section},\"\",@").unwrap(); diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs index a92d104f910..aa42b4d1c50 100644 --- a/compiler/rustc_target/src/spec/base/aix.rs +++ b/compiler/rustc_target/src/spec/base/aix.rs @@ -1,6 +1,8 @@ use rustc_abi::Endian; -use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs}; +use crate::spec::{ + BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs, +}; pub(crate) fn opts() -> TargetOptions { TargetOptions { @@ -21,6 +23,7 @@ pub(crate) fn opts() -> TargetOptions { linker: Some("ld".into()), eh_frame_header: false, is_like_aix: true, + binary_format: BinaryFormat::Xcoff, default_dwarf_version: 3, function_sections: true, pre_link_objects: crt_objects::new(&[ diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 1b56143545f..66c85146c29 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use std::env; use crate::spec::{ - Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo, - StackProbeType, StaticCow, TargetOptions, cvs, + BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, + SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs, }; #[cfg(test)] @@ -116,6 +116,7 @@ pub(crate) fn base( dynamic_linking: true, families: cvs!["unix"], is_like_osx: true, + binary_format: BinaryFormat::MachO, // LLVM notes that macOS 10.11+ and iOS 9+ default // to v4, so we do the same. // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203 diff --git a/compiler/rustc_target/src/spec/base/cygwin.rs b/compiler/rustc_target/src/spec/base/cygwin.rs index fe3efb3f46b..819d1d68a71 100644 --- a/compiler/rustc_target/src/spec/base/cygwin.rs +++ b/compiler/rustc_target/src/spec/base/cygwin.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs}; +use crate::spec::{ + BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs, +}; pub(crate) fn opts() -> TargetOptions { let mut pre_link_args = TargetOptions::link_args( @@ -32,6 +34,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["unix"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, late_link_args, diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs index b0fb2ef4b27..486d7158723 100644 --- a/compiler/rustc_target/src/spec/base/msvc.rs +++ b/compiler/rustc_target/src/spec/base/msvc.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; +use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; pub(crate) fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly @@ -12,6 +12,7 @@ pub(crate) fn opts() -> TargetOptions { dll_tls_export: false, is_like_windows: true, is_like_msvc: true, + binary_format: BinaryFormat::Coff, pre_link_args, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index 81b96cd39ff..88e7af5e669 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel, - add_link_args, cvs, + BinaryFormat, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, + TargetOptions, TlsModel, add_link_args, cvs, }; pub(crate) fn options() -> TargetOptions { @@ -53,6 +53,7 @@ pub(crate) fn options() -> TargetOptions { TargetOptions { is_like_wasm: true, + binary_format: BinaryFormat::Wasm, families: cvs!["wasm"], // we allow dynamic linking, but only cdylibs. Basically we allow a diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index 024b10f2faa..4ba11021988 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, - add_link_args, crt_objects, cvs, + BinaryFormat, Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, + TargetOptions, add_link_args, crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -90,6 +90,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["windows"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, pre_link_objects: crt_objects::pre_mingw(), diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 4a6e7c75200..f24ad781e2b 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs}; +use crate::spec::{ + BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs, +}; pub(crate) fn opts() -> TargetOptions { // We cannot use `-nodefaultlibs` because compiler-rt has to be passed @@ -30,6 +32,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["windows"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, late_link_args, diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index f703132e51f..134405f3630 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -103,6 +103,19 @@ impl Target { base.$key_name = Some(s); } } ); + ($key_name:ident, BinaryFormat) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|f| f.as_str().and_then(|s| { + match s.parse::() { + Ok(binary_format) => base.$key_name = binary_format, + _ => return Some(Err(format!( + "'{s}' is not a valid value for binary_format. \ + Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' " + ))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); ($key_name:ident, MergeFunctions) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { @@ -585,6 +598,7 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_wasm, bool); key!(is_like_android, bool); + key!(binary_format, BinaryFormat)?; key!(default_dwarf_version, u32); key!(allows_weak_linkage, bool); key!(has_rpath, bool); @@ -762,6 +776,7 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); target_option_val!(is_like_android); + target_option_val!(binary_format); target_option_val!(default_dwarf_version); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 794d6457cb7..f40af2dce26 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1640,6 +1640,55 @@ impl fmt::Display for StackProtector { } } +#[derive(PartialEq, Clone, Debug)] +pub enum BinaryFormat { + Coff, + Elf, + MachO, + Wasm, + Xcoff, +} + +impl BinaryFormat { + /// Returns [`object::BinaryFormat`] for given `BinaryFormat` + pub fn to_object(&self) -> object::BinaryFormat { + match self { + Self::Coff => object::BinaryFormat::Coff, + Self::Elf => object::BinaryFormat::Elf, + Self::MachO => object::BinaryFormat::MachO, + Self::Wasm => object::BinaryFormat::Wasm, + Self::Xcoff => object::BinaryFormat::Xcoff, + } + } +} + +impl FromStr for BinaryFormat { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "coff" => Ok(Self::Coff), + "elf" => Ok(Self::Elf), + "mach-o" => Ok(Self::MachO), + "wasm" => Ok(Self::Wasm), + "xcoff" => Ok(Self::Xcoff), + _ => Err(()), + } + } +} + +impl ToJson for BinaryFormat { + fn to_json(&self) -> Json { + match self { + Self::Coff => "coff", + Self::Elf => "elf", + Self::MachO => "mach-o", + Self::Wasm => "wasm", + Self::Xcoff => "xcoff", + } + .to_json() + } +} + macro_rules! supported_targets { ( $(($tuple:literal, $module:ident),)+ ) => { mod targets { @@ -2369,6 +2418,8 @@ pub struct TargetOptions { pub is_like_wasm: bool, /// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc pub is_like_android: bool, + /// Target's binary file format. Defaults to BinaryFormat::Elf + pub binary_format: BinaryFormat, /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub default_dwarf_version: u32, @@ -2744,6 +2795,7 @@ impl Default for TargetOptions { is_like_msvc: false, is_like_wasm: false, is_like_android: false, + binary_format: BinaryFormat::Elf, default_dwarf_version: 4, allows_weak_linkage: true, has_rpath: false, From d1b34acb3bfa202704b5ab13e4b35eb569cf7d67 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 22 Feb 2025 14:12:55 +0100 Subject: [PATCH 08/13] make the new intrinsics safe --- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 ++++ library/core/src/intrinsics/mod.rs | 16 ++++++++-------- library/std/src/f128.rs | 2 +- library/std/src/f16.rs | 2 +- library/std/src/f32.rs | 2 +- library/std/src/f64.rs | 2 +- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index acdd2facc24..5c0c7a86a0c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -137,6 +137,10 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::fmul_algebraic | sym::fdiv_algebraic | sym::frem_algebraic + | sym::round_ties_even_f16 + | sym::round_ties_even_f32 + | sym::round_ties_even_f64 + | sym::round_ties_even_f128 | sym::const_eval_select => hir::Safety::Safe, _ => hir::Safety::Unsafe, }; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 320122a53e9..a52f2b20246 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2748,13 +2748,13 @@ pub unsafe fn truncf128(_x: f128) -> f128 { #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub unsafe fn round_ties_even_f16(_x: f16) -> f16 { +pub fn round_ties_even_f16(_x: f16) -> f16 { unreachable!() } /// To be removed on next bootstrap bump. #[cfg(bootstrap)] -pub unsafe fn round_ties_even_f16(x: f16) -> f16 { +pub fn round_ties_even_f16(x: f16) -> f16 { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] @@ -2775,13 +2775,13 @@ pub unsafe fn round_ties_even_f16(x: f16) -> f16 { #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub unsafe fn round_ties_even_f32(_x: f32) -> f32 { +pub fn round_ties_even_f32(_x: f32) -> f32 { unreachable!() } /// To be removed on next bootstrap bump. #[cfg(bootstrap)] -pub unsafe fn round_ties_even_f32(x: f32) -> f32 { +pub fn round_ties_even_f32(x: f32) -> f32 { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] @@ -2802,13 +2802,13 @@ pub unsafe fn round_ties_even_f32(x: f32) -> f32 { #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub unsafe fn round_ties_even_f64(_x: f64) -> f64 { +pub fn round_ties_even_f64(_x: f64) -> f64 { unreachable!() } /// To be removed on next bootstrap bump. #[cfg(bootstrap)] -pub unsafe fn round_ties_even_f64(x: f64) -> f64 { +pub fn round_ties_even_f64(x: f64) -> f64 { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] @@ -2829,13 +2829,13 @@ pub unsafe fn round_ties_even_f64(x: f64) -> f64 { #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub unsafe fn round_ties_even_f128(_x: f128) -> f128 { +pub fn round_ties_even_f128(_x: f128) -> f128 { unreachable!() } /// To be removed on next bootstrap bump. #[cfg(bootstrap)] -pub unsafe fn round_ties_even_f128(x: f128) -> f128 { +pub fn round_ties_even_f128(x: f128) -> f128 { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 615c4fd3348..d4aa174cee5 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -129,7 +129,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f128 { - unsafe { intrinsics::round_ties_even_f128(self) } + intrinsics::round_ties_even_f128(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index 85b82b91fab..c0678732365 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -129,7 +129,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f16 { - unsafe { intrinsics::round_ties_even_f16(self) } + intrinsics::round_ties_even_f16(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index da1f000278d..bdcbd8b30b6 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -125,7 +125,7 @@ impl f32 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f32 { - unsafe { intrinsics::round_ties_even_f32(self) } + intrinsics::round_ties_even_f32(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 8a9f693a7a8..11acc13d657 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -125,7 +125,7 @@ impl f64 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f64 { - unsafe { intrinsics::round_ties_even_f64(self) } + intrinsics::round_ties_even_f64(self) } /// Returns the integer part of `self`. From 506532aad2368b1a62d07fa9950850a2f42966e4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 03:02:46 +0000 Subject: [PATCH 09/13] The sym crate is not a thing --- compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 50d10883d2c..e3260e45bc5 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -186,7 +186,7 @@ fn true_significant_drop_ty<'tcx>( debug!(?name_str); match name_str[..] { // These are the types from Rust core ecosystem - ["sym" | "proc_macro2", ..] + ["syn" | "proc_macro2", ..] | ["core" | "std", "task", "LocalWaker" | "Waker"] | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]), // These are important types from Rust ecosystem From 54dd4c87bea51dca48dc3464df3d489c2a717b09 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 23 Feb 2025 08:37:10 +0530 Subject: [PATCH 10/13] bootstrap: add module docs for core:metadata --- src/bootstrap/src/core/metadata.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 983674d2c68..01cbf662940 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -1,3 +1,10 @@ +//! This module interacts with Cargo metadata to collect and store information about +//! the packages in the Rust workspace. +//! +//! It runs `cargo metadata` to gather details about each package, including its name, +//! source, dependencies, targets, and available features. The collected metadata is then +//! used to update the `Build` structure, ensuring proper dependency resolution and +//! compilation flow. use std::collections::BTreeMap; use std::path::PathBuf; From 08f1086bf06796f95cf83e140b8304d77081535d Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 19 Feb 2025 20:17:02 -0500 Subject: [PATCH 11/13] Update `compiler-builtins` to 0.1.147 Removes an ABI hack that used `<2 x i64>` to return `i128` in `xmm0` on Windows [1]. [1]: https://github.com/rust-lang/compiler-builtins/pull/759 Link: https://github.com/rust-lang/rust/issues/116558 Link: https://github.com/rust-lang/compiler-builtins/issues/758 --- ...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 eb1fc4b0ad5..364a6a035ab 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", public = true } --compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.147", 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 0be2f9a1549..0ad56f3ce47 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.146" +version = "0.1.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97117b1434b79833f39a5fabdf82f890bd98c1988334dea1cb67f7e627fa311" +checksum = "7170335a76fbcba350c3ea795c15df3b2c02934e35e502e82c4dd7837d4d0161" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 395cff13189..6f9074d91b0 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 228ee6eea05..518d4ded92d 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,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.146" } +compiler_builtins = { version = "=0.1.147" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From b9d0555d11736f96b4fbbb83bfed94a7098a9ba7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Feb 2025 10:57:44 +0100 Subject: [PATCH 12/13] add stdarch compatibility hack --- library/core/src/intrinsics/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index a52f2b20246..a6d6ad572dd 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2793,6 +2793,12 @@ pub fn round_ties_even_f32(x: f32) -> f32 { unsafe { rintf32(x) } } +/// Provided for compatibility with stdarch. DO NOT USE. +#[inline(always)] +pub unsafe fn rintf32(x: f32) -> f32 { + round_ties_even_f32(x) +} + /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even /// least significant digit. /// @@ -2820,6 +2826,12 @@ pub fn round_ties_even_f64(x: f64) -> f64 { unsafe { rintf64(x) } } +/// Provided for compatibility with stdarch. DO NOT USE. +#[inline(always)] +pub unsafe fn rintf64(x: f64) -> f64 { + round_ties_even_f64(x) +} + /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even /// least significant digit. /// From c813d8f3e49aa4c85c9eded426b6507701a2ff94 Mon Sep 17 00:00:00 2001 From: bendn Date: Sun, 23 Feb 2025 20:26:28 +0700 Subject: [PATCH 13/13] =?UTF-8?q?rename=20sub=5Fptr=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_serialize/src/opaque.rs | 6 +++--- library/alloc/src/vec/drain.rs | 2 +- library/alloc/src/vec/in_place_collect.rs | 2 +- library/alloc/src/vec/in_place_drop.rs | 2 +- library/alloc/src/vec/into_iter.rs | 4 ++-- library/core/src/ptr/const_ptr.rs | 18 +++++++++--------- library/core/src/ptr/mut_ptr.rs | 16 ++++++++-------- library/core/src/ptr/non_null.rs | 18 +++++++++--------- library/core/src/slice/iter/macros.rs | 2 +- library/core/src/slice/raw.rs | 4 ++-- library/core/src/slice/sort/shared/pivot.rs | 4 ++-- library/core/src/slice/sort/stable/merge.rs | 2 +- .../core/src/slice/sort/unstable/quicksort.rs | 2 +- .../intrinsics/ptr_offset_from_unsigned_neg.rs | 2 +- .../ptr_offset_from_unsigned_neg.stderr | 4 ++-- src/tools/miri/tests/pass/ptr_offset.rs | 6 +++--- tests/ui/const-ptr/forbidden_slices.stderr | 6 +++--- tests/ui/consts/offset_from.rs | 2 +- 18 files changed, 51 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 27e9f817894..d4907b69b72 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -280,13 +280,13 @@ impl<'a> MemDecoder<'a> { #[inline] pub fn len(&self) -> usize { // SAFETY: This recovers the length of the original slice, only using members we never modify. - unsafe { self.end.sub_ptr(self.start) } + unsafe { self.end.offset_from_unsigned(self.start) } } #[inline] pub fn remaining(&self) -> usize { // SAFETY: This type guarantees current <= end. - unsafe { self.end.sub_ptr(self.current) } + unsafe { self.end.offset_from_unsigned(self.current) } } #[cold] @@ -400,7 +400,7 @@ impl<'a> Decoder for MemDecoder<'a> { #[inline] fn position(&self) -> usize { // SAFETY: This type guarantees start <= current - unsafe { self.current.sub_ptr(self.start) } + unsafe { self.current.offset_from_unsigned(self.start) } } } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 9362cef2a1b..8705a9c3d26 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -232,7 +232,7 @@ impl Drop for Drain<'_, T, A> { // it from the original vec but also avoid creating a &mut to the front since that could // invalidate raw pointers to it which some unsafe code might rely on. let vec_ptr = vec.as_mut().as_mut_ptr(); - let drop_offset = drop_ptr.sub_ptr(vec_ptr); + let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr); let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len); ptr::drop_in_place(to_drop); } diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index a7dba16944e..dffd85f13aa 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -379,7 +379,7 @@ where let sink = self.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(end)).into_ok(); // iteration succeeded, don't drop head - unsafe { ManuallyDrop::new(sink).dst.sub_ptr(dst_buf) } + unsafe { ManuallyDrop::new(sink).dst.offset_from_unsigned(dst_buf) } } } diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index 4d5b4e47d39..997c4c7525b 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -14,7 +14,7 @@ pub(super) struct InPlaceDrop { impl InPlaceDrop { fn len(&self) -> usize { - unsafe { self.dst.sub_ptr(self.inner) } + unsafe { self.dst.offset_from_unsigned(self.inner) } } } diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 9a6745fdbc0..52597e41c1c 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -179,7 +179,7 @@ impl IntoIter { // say that they're all at the beginning of the "allocation". 0..this.len() } else { - this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf) + this.ptr.offset_from_unsigned(this.buf)..this.end.offset_from_unsigned(buf) }; let cap = this.cap; let alloc = ManuallyDrop::take(&mut this.alloc); @@ -230,7 +230,7 @@ impl Iterator for IntoIter { let exact = if T::IS_ZST { self.end.addr().wrapping_sub(self.ptr.as_ptr().addr()) } else { - unsafe { non_null!(self.end, T).sub_ptr(self.ptr) } + unsafe { non_null!(self.end, T).offset_from_unsigned(self.ptr) } }; (exact, Some(exact)) } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 14693de0ae0..8db620596dd 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -724,7 +724,7 @@ impl *const T { /// that their safety preconditions are met: /// ```rust /// # unsafe fn blah(ptr: *const i32, origin: *const i32, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -755,20 +755,20 @@ impl *const T { /// let ptr1: *const i32 = &a[1]; /// let ptr2: *const i32 = &a[3]; /// unsafe { - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: - /// // ptr1.sub_ptr(ptr2) + /// // ptr1.offset_from_unsigned(ptr2) /// ``` #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn sub_ptr(self, origin: *const T) -> usize + pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, { @@ -786,7 +786,7 @@ impl *const T { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::sub_ptr requires `self >= origin`", + "ptr::offset_from_unsigned requires `self >= origin`", ( this: *const () = self as *const (), origin: *const () = origin as *const (), @@ -804,7 +804,7 @@ impl *const T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, @@ -813,9 +813,9 @@ impl *const T { #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn byte_sub_ptr(self, origin: *const U) -> usize { + pub const unsafe fn byte_offset_from_unsigned(self, origin: *const U) -> usize { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.cast::().sub_ptr(origin.cast::()) } + unsafe { self.cast::().offset_from_unsigned(origin.cast::()) } } /// Returns whether two pointers are guaranteed to be equal. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 6f9019ae088..5a64f12ca99 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -896,7 +896,7 @@ impl *mut T { /// that their safety preconditions are met: /// ```rust /// # unsafe fn blah(ptr: *mut i32, origin: *mut i32, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -929,10 +929,10 @@ impl *mut T { /// let ptr1: *mut i32 = p.add(1); /// let ptr2: *mut i32 = p.add(3); /// - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: @@ -941,12 +941,12 @@ impl *mut T { #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn sub_ptr(self, origin: *const T) -> usize + pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { (self as *const T).sub_ptr(origin) } + unsafe { (self as *const T).offset_from_unsigned(origin) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -954,7 +954,7 @@ impl *mut T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, @@ -963,9 +963,9 @@ impl *mut T { #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn byte_sub_ptr(self, origin: *mut U) -> usize { + pub const unsafe fn byte_offset_from_unsigned(self, origin: *mut U) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { (self as *const T).byte_sub_ptr(origin) } + unsafe { (self as *const T).byte_offset_from_unsigned(origin) } } /// Adds an unsigned offset to a pointer. diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index befb3ccb14b..7abd3ddaa9e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -857,7 +857,7 @@ impl NonNull { /// that their safety preconditions are met: /// ```rust /// # unsafe fn blah(ptr: std::ptr::NonNull, origin: std::ptr::NonNull, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -890,25 +890,25 @@ impl NonNull { /// let ptr1: NonNull = NonNull::from(&a[1]); /// let ptr2: NonNull = NonNull::from(&a[3]); /// unsafe { - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: - /// // ptr1.sub_ptr(ptr2) + /// // ptr1.offset_from_unsigned(ptr2) /// ``` #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] - pub const unsafe fn sub_ptr(self, subtracted: NonNull) -> usize + pub const unsafe fn offset_from_unsigned(self, subtracted: NonNull) -> usize where T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) } + unsafe { self.as_ptr().offset_from_unsigned(subtracted.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -916,7 +916,7 @@ impl NonNull { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for + /// using [`sub_ptr`][NonNull::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, @@ -925,9 +925,9 @@ impl NonNull { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] - pub const unsafe fn byte_sub_ptr(self, origin: NonNull) -> usize { + pub const unsafe fn byte_offset_from_unsigned(self, origin: NonNull) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) } + unsafe { self.as_ptr().byte_offset_from_unsigned(origin.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b1456a1bc1d..7c1ed3fe8a2 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -54,7 +54,7 @@ macro_rules! len { // To get rid of some bounds checks (see `position`), we use ptr_sub instead of // offset_from (Tested by `codegen/slice-position-bounds-check`.) // SAFETY: by the type invariant pointers are aligned and `start <= end` - unsafe { end.sub_ptr($self.ptr) } + unsafe { end.offset_from_unsigned($self.ptr) } }, ) }}; diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 319b76899bf..e24b52cff82 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -272,7 +272,7 @@ pub const fn from_mut(s: &mut T) -> &mut [T] { #[rustc_const_unstable(feature = "const_slice_from_ptr_range", issue = "89792")] pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { // SAFETY: the caller must uphold the safety contract for `from_ptr_range`. - unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + unsafe { from_raw_parts(range.start, range.end.offset_from_unsigned(range.start)) } } /// Forms a mutable slice from a pointer range. @@ -342,5 +342,5 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { #[rustc_const_unstable(feature = "const_slice_from_mut_ptr_range", issue = "89792")] pub const unsafe fn from_mut_ptr_range<'a, T>(range: Range<*mut T>) -> &'a mut [T] { // SAFETY: the caller must uphold the safety contract for `from_mut_ptr_range`. - unsafe { from_raw_parts_mut(range.start, range.end.sub_ptr(range.start)) } + unsafe { from_raw_parts_mut(range.start, range.end.offset_from_unsigned(range.start)) } } diff --git a/library/core/src/slice/sort/shared/pivot.rs b/library/core/src/slice/sort/shared/pivot.rs index 255a1eb6c88..3aace484b6a 100644 --- a/library/core/src/slice/sort/shared/pivot.rs +++ b/library/core/src/slice/sort/shared/pivot.rs @@ -31,9 +31,9 @@ pub fn choose_pivot bool>(v: &[T], is_less: &mut F) -> us let c = v_base.add(len_div_8 * 7); // [7*floor(n/8), 8*floor(n/8)) if len < PSEUDO_MEDIAN_REC_THRESHOLD { - median3(&*a, &*b, &*c, is_less).sub_ptr(v_base) + median3(&*a, &*b, &*c, is_less).offset_from_unsigned(v_base) } else { - median3_rec(a, b, c, len_div_8, is_less).sub_ptr(v_base) + median3_rec(a, b, c, len_div_8, is_less).offset_from_unsigned(v_base) } } } diff --git a/library/core/src/slice/sort/stable/merge.rs b/library/core/src/slice/sort/stable/merge.rs index 0cb21740795..bb2747bfc78 100644 --- a/library/core/src/slice/sort/stable/merge.rs +++ b/library/core/src/slice/sort/stable/merge.rs @@ -143,7 +143,7 @@ impl Drop for MergeState { // leave the input slice `v` with each original element and all possible // modifications observed. unsafe { - let len = self.end.sub_ptr(self.start); + let len = self.end.offset_from_unsigned(self.start); ptr::copy_nonoverlapping(self.start, self.dst, len); } } diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs index 4feef5deeb0..bb9f90fc881 100644 --- a/library/core/src/slice/sort/unstable/quicksort.rs +++ b/library/core/src/slice/sort/unstable/quicksort.rs @@ -224,7 +224,7 @@ where left = left.add(1); } - left.sub_ptr(v_base) + left.offset_from_unsigned(v_base) // `gap_opt` goes out of scope and overwrites the last wrong-side element on the right side // with the first wrong-side element of the left side that was initially overwritten by the diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs index 13874398f7b..562d72b0ca0 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs @@ -3,5 +3,5 @@ fn main() { let arr = [0u8; 8]; let ptr1 = arr.as_ptr(); let ptr2 = ptr1.wrapping_add(4); - let _val = unsafe { ptr1.sub_ptr(ptr2) }; //~ERROR: first pointer has smaller address than second + let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; //~ERROR: first pointer has smaller address than second } diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr index a0a8e97e7fa..80e3f2c22a1 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR --> tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs:LL:CC | -LL | let _val = unsafe { ptr1.sub_ptr(ptr2) }; - | ^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR +LL | let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/pass/ptr_offset.rs b/src/tools/miri/tests/pass/ptr_offset.rs index a8a0d2836e7..89aff7bf635 100644 --- a/src/tools/miri/tests/pass/ptr_offset.rs +++ b/src/tools/miri/tests/pass/ptr_offset.rs @@ -21,7 +21,7 @@ fn smoke() { let _val = ptr.wrapping_sub(0); let _val = unsafe { ptr.sub(0) }; let _val = unsafe { ptr.offset_from(ptr) }; - let _val = unsafe { ptr.sub_ptr(ptr) }; + let _val = unsafe { ptr.offset_from_unsigned(ptr) }; } fn test_offset_from() { @@ -32,14 +32,14 @@ fn test_offset_from() { let y = x.offset(12); assert_eq!(y.offset_from(x), 12); - assert_eq!(y.sub_ptr(x), 12); + assert_eq!(y.offset_from_unsigned(x), 12); assert_eq!(x.offset_from(y), -12); assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4); assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4); let x = (((x as usize) * 2) / 2) as *const u8; assert_eq!(y.offset_from(x), 12); - assert_eq!(y.sub_ptr(x), 12); + assert_eq!(y.offset_from_unsigned(x), 12); assert_eq!(x.offset_from(y), -12); } } diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index 2e0c04dcf1e..df588fcc5e1 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr @@ -104,7 +104,7 @@ error[E0080]: could not evaluate static initializer | = note: the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, ()>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -192,7 +192,7 @@ error[E0080]: could not evaluate static initializer | = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -207,7 +207,7 @@ error[E0080]: could not evaluate static initializer | = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/tests/ui/consts/offset_from.rs b/tests/ui/consts/offset_from.rs index c06314ac7df..02e8d145f65 100644 --- a/tests/ui/consts/offset_from.rs +++ b/tests/ui/consts/offset_from.rs @@ -44,7 +44,7 @@ pub const OFFSET_EQUAL_INTS: isize = { pub const OFFSET_UNSIGNED: usize = { let a = ['a', 'b', 'c']; let ptr = a.as_ptr(); - unsafe { ptr.add(2).sub_ptr(ptr) } + unsafe { ptr.add(2).offset_from_unsigned(ptr) } }; fn main() {