diff --git a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs index b7491b7e522f3..206c56e887c7d 100644 --- a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs +++ b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs @@ -33,24 +33,24 @@ fn main() { let n = f32x4([nan, nan, nan, nan]); unsafe { - let min0 = simd_fmin(x, y); - let min1 = simd_fmin(y, x); + let min0 = simd_minimum_number_nsz(x, y); + let min1 = simd_minimum_number_nsz(y, x); assert_eq!(min0.into_array(), min1.into_array()); let e = f32x4([1.0, 1.0, 3.0, 3.0]); assert_eq!(min0.into_array(), e.into_array()); - let minn = simd_fmin(x, n); + let minn = simd_minimum_number_nsz(x, n); assert_eq!(minn.into_array(), x.into_array()); - let minn = simd_fmin(y, n); + let minn = simd_minimum_number_nsz(y, n); assert_eq!(minn.into_array(), y.into_array()); - let max0 = simd_fmax(x, y); - let max1 = simd_fmax(y, x); + let max0 = simd_maximum_number_nsz(x, y); + let max1 = simd_maximum_number_nsz(y, x); assert_eq!(max0.into_array(), max1.into_array()); let e = f32x4([2.0, 2.0, 4.0, 4.0]); assert_eq!(max0.into_array(), e.into_array()); - let maxn = simd_fmax(x, n); + let maxn = simd_maximum_number_nsz(x, n); assert_eq!(maxn.into_array(), x.into_array()); - let maxn = simd_fmax(y, n); + let maxn = simd_maximum_number_nsz(y, n); assert_eq!(maxn.into_array(), y.into_array()); } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 8b112e695275a..780550fc4cc74 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -346,10 +346,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), sym::log10f128 => ("log10f128", 1, fx.tcx.types.f128, types::F128), - sym::fabsf16 => ("fabsf16", 1, fx.tcx.types.f16, types::F16), - sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32), - sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64), - sym::fabsf128 => ("fabsf128", 1, fx.tcx.types.f128, types::F128), sym::fmaf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), @@ -441,11 +437,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf32 | sym::copysignf64 => { CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) } - sym::fabsf16 => CValue::by_val(codegen_f16_f128::abs_f16(fx, args[0]), layout), - sym::fabsf128 => CValue::by_val(codegen_f16_f128::abs_f128(fx, args[0]), layout), - sym::fabsf32 - | sym::fabsf64 - | sym::floorf32 + sym::floorf32 | sym::floorf64 | sym::ceilf32 | sym::ceilf64 @@ -456,7 +448,6 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { - sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]), 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]), @@ -1179,6 +1170,28 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, old); } + sym::fabs => { + intrinsic_args!(fx, args => (arg); intrinsic); + let layout = arg.layout(); + let ty::Float(float_ty) = layout.ty.kind() else { + span_bug!( + source_info.span, + "expected float type for fabs intrinsic: {:?}", + layout.ty + ); + }; + let x = arg.load_scalar(fx); + let val = match float_ty { + FloatTy::F32 | FloatTy::F64 => fx.bcx.ins().fabs(x), + // FIXME(bytecodealliance/wasmtime#8312): Use `fabsf16` once Cranelift + // backend lowerings are implemented. + FloatTy::F16 => codegen_f16_f128::abs_f16(fx, x), + FloatTy::F128 => codegen_f16_f128::abs_f128(fx, x), + }; + let val = CValue::by_val(val, layout); + ret.write_cvalue(fx, val); + } + sym::minimumf16 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 200cedf0f6ae0..cc2311a67b5d5 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -493,7 +493,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( } } - sym::simd_fmin | sym::simd_fmax => { + sym::simd_minimum_number_nsz | sym::simd_maximum_number_nsz => { intrinsic_args!(fx, args => (x, y); intrinsic); if !x.layout().ty.is_simd() { @@ -508,8 +508,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => unreachable!("{:?}", lane_ty), } match intrinsic { - sym::simd_fmin => crate::num::codegen_float_min(fx, x_lane, y_lane), - sym::simd_fmax => crate::num::codegen_float_max(fx, x_lane, y_lane), + sym::simd_minimum_number_nsz => { + crate::num::codegen_float_min(fx, x_lane, y_lane) + } + sym::simd_maximum_number_nsz => { + crate::num::codegen_float_max(fx, x_lane, y_lane) + } _ => unreachable!(), } }); diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index 0459644e16aa7..e583f3f2f754a 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -500,8 +500,8 @@ fn codegen_ptr_binop<'tcx>( // In Rust floating point min and max don't propagate NaN (not even SNaN). In Cranelift they do // however. For this reason it is necessary to use `a.is_nan() ? b : (a >= b ? b : a)` for -// `minnumf*` and `a.is_nan() ? b : (a <= b ? b : a)` for `maxnumf*`. NaN checks are done by -// comparing a float against itself. Only in case of NaN is it not equal to itself. +// `minimum_number_nsz` and `a.is_nan() ? b : (a <= b ? b : a)` for `maximum_number_nsz`. NaN checks +// are done by comparing a float against itself. Only in case of NaN is it not equal to itself. pub(crate) fn codegen_float_min(fx: &mut FunctionCx<'_, '_, '_>, a: Value, b: Value) -> Value { // FIXME(bytecodealliance/wasmtime#8312): Replace with Cranelift `fcmp` once // `f16`/`f128` backend lowerings have been added to Cranelift. diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 6add7f05c2abd..3eb0fd95284a1 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -2278,6 +2278,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { }) } + /// Emits a SIMD min/max operation for floats. The semantics for each lane are: if one + /// side is NaN (QNaN or SNaN), the other side is returned. fn vector_extremum( &mut self, a: RValue<'gcc>, @@ -2286,8 +2288,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { ) -> RValue<'gcc> { let vector_type = a.get_type(); - // mask out the NaNs in b and replace them with the corresponding lane in a, so when a and - // b get compared & spliced together, we get the numeric values instead of NaNs. + // Mask out the NaNs (both QNaN and SNaN) in b and replace them with the corresponding lane + // in a, so when a and b get compared & spliced together, we get the numeric values instead + // of NaNs. let b_nan_mask = self.context.new_comparison(self.location, ComparisonOp::NotEquals, b, b); let mask_type = b_nan_mask.get_type(); let b_nan_mask_inverted = @@ -2309,7 +2312,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.context.new_bitcast(self.location, res, vector_type) } - pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_minimum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.vector_extremum(a, b, ExtremumOperation::Min) } @@ -2341,7 +2344,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { unimplemented!(); } - pub fn vector_fmax(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_maximum_number_nsz(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.vector_extremum(a, b, ExtremumOperation::Max) } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 3f1b33c73e638..83ac627d27c54 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -23,11 +23,11 @@ use rustc_codegen_ssa::traits::{ IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; use rustc_data_structures::fx::FxHashSet; -use rustc_middle::bug; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_target::callconv::{ArgAbi, PassMode}; @@ -70,8 +70,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation sym::fmuladdf32 => "fmaf", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f32 sym::fmuladdf64 => "fma", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f64 - sym::fabsf32 => "fabsf", - sym::fabsf64 => "fabs", sym::minimumf32 => "fminimumf", sym::minimumf64 => "fminimum", sym::minimumf128 => { @@ -194,58 +192,29 @@ fn get_simple_function<'gcc, 'tcx>( } fn get_simple_function_f128<'gcc, 'tcx>( + span: Span, cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, -) -> Option> { - if !cx.supports_f128_type { - return None; - } - +) -> Function<'gcc> { let f128_type = cx.type_f128(); let func_name = match name { sym::ceilf128 => "ceilf128", - sym::fabsf128 => "fabsf128", + sym::fabs => "fabsf128", sym::floorf128 => "floorf128", sym::truncf128 => "truncf128", sym::roundf128 => "roundf128", sym::round_ties_even_f128 => "roundevenf128", sym::sqrtf128 => "sqrtf128", - _ => return None, + _ => span_bug!(span, "used get_simple_function_f128 for non-unary f128 intrinsic"), }; - Some(cx.context.new_function( + cx.context.new_function( None, FunctionType::Extern, f128_type, &[cx.context.new_parameter(None, f128_type, "a")], func_name, false, - )) -} - -fn get_simple_function_f128_2args<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, -) -> Option> { - if !cx.supports_f128_type { - return None; - } - - let f128_type = cx.type_f128(); - let func_name = match name { - sym::copysignf128 => "copysignf128", - _ => return None, - }; - Some(cx.context.new_function( - None, - FunctionType::Extern, - f128_type, - &[ - cx.context.new_parameter(None, f128_type, "a"), - cx.context.new_parameter(None, f128_type, "b"), - ], - func_name, - false, - )) + ) } fn f16_builtin<'gcc, 'tcx>( @@ -257,7 +226,7 @@ fn f16_builtin<'gcc, 'tcx>( let builtin_name = match name { sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", - sym::fabsf16 => "fabsf", + sym::fabs => "fabsf", sym::floorf16 => "__builtin_floorf", sym::fmaf16 => "fmaf", sym::powf16 => "__builtin_powf", @@ -297,11 +266,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); - // FIXME(antoyo): Only call get_simple_function_f128 and get_simple_function_f128_2args when - // it is the symbols for the supported f128 builtins. - let simple_func = get_simple_function(self, name) - .or_else(|| get_simple_function_f128(self, name)) - .or_else(|| get_simple_function_f128_2args(self, name)); + let simple_func = get_simple_function(self, name); let value = match name { _ if simple.is_some() => { @@ -322,7 +287,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::ceilf16 | sym::copysignf16 - | sym::fabsf16 | sym::floorf16 | sym::fmaf16 | sym::powf16 @@ -331,6 +295,40 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::round_ties_even_f16 | sym::sqrtf16 | sym::truncf16 => f16_builtin(self, name, args), + sym::ceilf128 + | sym::floorf128 + | sym::truncf128 + | sym::roundf128 + | sym::round_ties_even_f128 + | sym::sqrtf128 + if self.cx.supports_f128_type => + { + let func = get_simple_function_f128(span, self, name); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + sym::copysignf128 if self.cx.supports_f128_type => { + let f128_type = self.cx.type_f128(); + let func = self.cx.context.new_function( + None, + FunctionType::Extern, + f128_type, + &[ + self.cx.context.new_parameter(None, f128_type, "a"), + self.cx.context.new_parameter(None, f128_type, "b"), + ], + "copysignf128", + false, + ); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } sym::fmaf128 => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( @@ -488,6 +486,23 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } } } + sym::fabs => 'fabs: { + let ty = args[0].layout.ty; + let ty::Float(float_ty) = *ty.kind() else { + span_bug!(span, "expected float type for fabs intrinsic: {:?}", ty); + }; + let func = match float_ty { + ty::FloatTy::F16 => break 'fabs f16_builtin(self, name, args), + ty::FloatTy::F32 => self.context.get_builtin_function("fabsf"), + ty::FloatTy::F64 => self.context.get_builtin_function("fabs"), + ty::FloatTy::F128 => get_simple_function_f128(span, self, name), + }; + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } sym::raw_eq => { use rustc_abi::BackendRepr::*; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 1263b2285a8d0..4ca890fee1918 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -811,7 +811,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }}; } let ty::Float(ref f) = *in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { @@ -1222,8 +1222,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( simd_and: Uint, Int => and; simd_or: Uint, Int => or; // FIXME(antoyo): calling `or` might not work on vectors. simd_xor: Uint, Int => xor; - simd_fmin: Float => vector_fmin; - simd_fmax: Float => vector_fmax; + simd_minimum_number_nsz: Float => vector_minimum_number_nsz; + simd_maximum_number_nsz: Float => vector_maximum_number_nsz; } macro_rules! arith_unary { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2d91caf40f3c9..f3508c10d1f61 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1605,12 +1605,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { *self = Self::build(self.cx, next_bb); } - pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.call_intrinsic("llvm.minnum", &[self.val_ty(lhs)], &[lhs, rhs]) + pub(crate) fn minimum_number_nsz(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + let call = self.call_intrinsic("llvm.minimumnum", &[self.val_ty(lhs)], &[lhs, rhs]); + unsafe { llvm::LLVMRustSetNoSignedZeros(call) }; + call } - pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.call_intrinsic("llvm.maxnum", &[self.val_ty(lhs)], &[lhs, rhs]) + pub(crate) fn maximum_number_nsz(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + let call = self.call_intrinsic("llvm.maximumnum", &[self.val_ty(lhs)], &[lhs, rhs]); + unsafe { llvm::LLVMRustSetNoSignedZeros(call) }; + call } pub(crate) fn insert_element( diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index cc6ecee60b0e4..39bf4c10dab18 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -107,11 +107,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::fmuladdf64 => ("llvm.fmuladd", &[bx.type_f64()]), sym::fmuladdf128 => ("llvm.fmuladd", &[bx.type_f128()]), - sym::fabsf16 => ("llvm.fabs", &[bx.type_f16()]), - sym::fabsf32 => ("llvm.fabs", &[bx.type_f32()]), - sym::fabsf64 => ("llvm.fabs", &[bx.type_f64()]), - sym::fabsf128 => ("llvm.fabs", &[bx.type_f128()]), - // FIXME: LLVM currently mis-compile those intrinsics, re-enable them // when llvm/llvm-project#{139380,139381,140445} are fixed. //sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), @@ -502,6 +497,20 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } + sym::fabs => { + let ty = args[0].layout.ty; + let ty::Float(f) = ty.kind() else { + span_bug!(span, "the `fabs` intrinsic requires a floating-point argument, got {:?}", ty); + }; + let llty = self.type_float_from_ty(*f); + let llvm_name = "llvm.fabs"; + self.call_intrinsic( + llvm_name, + &[llty], + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + sym::raw_eq => { use BackendRepr::*; let tp_ty = fn_args.type_at(0); @@ -1936,7 +1945,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } let ty::Float(f) = in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); @@ -2770,8 +2779,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( simd_and: Uint, Int => and; simd_or: Uint, Int => or; simd_xor: Uint, Int => xor; - simd_fmax: Float => maxnum; - simd_fmin: Float => minnum; + simd_maximum_number_nsz: Float => maximum_number_nsz; + simd_minimum_number_nsz: Float => minimum_number_nsz; } macro_rules! arith_unary { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 576df6e1f24f5..cec84f60a7b0e 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -733,14 +733,6 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)] - FloatingPointType { - #[primary_span] - span: Span, - name: Symbol, - in_ty: Ty<'tcx>, - }, - #[diag("invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`", code = E0511)] UnrecognizedIntrinsic { #[primary_span] diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d5f69d78ea6ae..17311188879c1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -575,10 +575,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::copysignf64 => self.float_copysign_intrinsic::(args, dest)?, sym::copysignf128 => self.float_copysign_intrinsic::(args, dest)?, - sym::fabsf16 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf32 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + sym::fabs => { + let arg = self.read_immediate(&args[0])?; + let ty::Float(float_ty) = arg.layout.ty.kind() else { + span_bug!( + self.cur_span(), + "non-float type for float intrinsic: {}", + arg.layout.ty, + ); + }; + let out_val = match float_ty { + FloatTy::F16 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F32 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F64 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F128 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + }; + self.write_scalar(out_val, dest)?; + } sym::floorf16 => self.float_round_intrinsic::( args, @@ -1020,6 +1033,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } + fn unop_float_intrinsic( + &self, + name: Symbol, + arg: ImmTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, Scalar> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = arg.to_scalar().to_float()?; + match name { + // bitwise, no NaN adjustments + sym::fabs => interp_ok(x.abs().into()), + _ => bug!("not a unary float intrinsic: {}", name), + } + } + fn float_minmax( &self, a: Scalar, @@ -1078,20 +1107,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } - fn float_abs_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, - { - let x: F = self.read_scalar(&args[0])?.to_float()?; - // bitwise, no NaN adjustments - self.write_scalar(x.abs(), dest)?; - interp_ok(()) - } - fn float_round( &mut self, x: Scalar, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index c47c512025c08..d6cfc559e0df4 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -174,8 +174,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | sym::simd_le | sym::simd_gt | sym::simd_ge - | sym::simd_fmax - | sym::simd_fmin + | sym::simd_maximum_number_nsz + | sym::simd_minimum_number_nsz | sym::simd_saturating_add | sym::simd_saturating_sub | sym::simd_arith_offset => { @@ -211,8 +211,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::simd_le => Op::MirOp(BinOp::Le), sym::simd_gt => Op::MirOp(BinOp::Gt), sym::simd_ge => Op::MirOp(BinOp::Ge), - sym::simd_fmax => Op::FMinMax(MinMax::MaximumNumberNsz), - sym::simd_fmin => Op::FMinMax(MinMax::MinimumNumberNsz), + sym::simd_maximum_number_nsz => Op::FMinMax(MinMax::MaximumNumberNsz), + sym::simd_minimum_number_nsz => Op::FMinMax(MinMax::MinimumNumberNsz), sym::simd_saturating_add => Op::SaturatingOp(BinOp::Add), sym::simd_saturating_sub => Op::SaturatingOp(BinOp::Sub), sym::simd_arith_offset => Op::WrappingOffset, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 47420997a509a..b1dc593331c6c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -111,10 +111,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::expf32 | sym::expf64 | sym::expf128 - | sym::fabsf16 - | sym::fabsf32 - | sym::fabsf64 - | sym::fabsf128 + | sym::fabs | sym::fadd_algebraic | sym::fdiv_algebraic | sym::field_offset @@ -463,10 +460,7 @@ pub(crate) fn check_intrinsic_type( (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128) } - sym::fabsf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::fabs => (1, 0, vec![param(0)], param(0)), sym::minimum_number_nsz_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::minimum_number_nsz_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), @@ -726,8 +720,8 @@ pub(crate) fn check_intrinsic_type( | sym::simd_and | sym::simd_or | sym::simd_xor - | sym::simd_fmin - | sym::simd_fmax + | sym::simd_minimum_number_nsz + | sym::simd_maximum_number_nsz | sym::simd_saturating_add | sym::simd_saturating_sub | sym::simd_carryless_mul => (1, 0, vec![param(0), param(0)], param(0)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f5a8f1d7ebad4..ccd4516372d26 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -915,10 +915,7 @@ symbols! { f64_nan, f128, f128_nan, - fabsf16, - fabsf32, - fabsf64, - fabsf128, + fabs, fadd_algebraic, fadd_fast, fake_variadic, @@ -1856,8 +1853,6 @@ symbols! { simd_flog10, simd_floor, simd_fma, - simd_fmax, - simd_fmin, simd_fsin, simd_fsqrt, simd_funnel_shl, @@ -1871,6 +1866,8 @@ symbols! { simd_lt, simd_masked_load, simd_masked_store, + simd_maximum_number_nsz, + simd_minimum_number_nsz, simd_mul, simd_ne, simd_neg, diff --git a/library/Cargo.lock b/library/Cargo.lock index 4801f92c63e5a..ffa9a6302ef84 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.178" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 5fc97d9a69efd..62b3d75d7a779 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -716,7 +716,7 @@ impl ops::Index> for CStr { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl ops::Index> for CStr { type Output = CStr; diff --git a/library/core/src/intrinsics/bounds.rs b/library/core/src/intrinsics/bounds.rs index 353908598d40b..21705005ed0ae 100644 --- a/library/core/src/intrinsics/bounds.rs +++ b/library/core/src/intrinsics/bounds.rs @@ -39,3 +39,14 @@ impl ChangePointee for *mut T { impl ChangePointee for *const T { type Output = *const U; } + +/// Built-in float types (f16, f32, f64 and f128). +/// +/// # Safety +/// Must actually *be* such a type. +pub unsafe trait FloatPrimitive: Sized + Copy {} + +unsafe impl FloatPrimitive for f16 {} +unsafe impl FloatPrimitive for f32 {} +unsafe impl FloatPrimitive for f64 {} +unsafe impl FloatPrimitive for f128 {} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 128df654e078d..6f9d351300168 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1573,7 +1573,7 @@ pub const fn roundf128(x: f128) -> f128; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fadd_fast(a: T, b: T) -> T; +pub unsafe fn fadd_fast(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1581,7 +1581,7 @@ pub unsafe fn fadd_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fsub_fast(a: T, b: T) -> T; +pub unsafe fn fsub_fast(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1589,7 +1589,7 @@ pub unsafe fn fsub_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmul_fast(a: T, b: T) -> T; +pub unsafe fn fmul_fast(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1597,7 +1597,7 @@ pub unsafe fn fmul_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fdiv_fast(a: T, b: T) -> T; +pub unsafe fn fdiv_fast(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1605,7 +1605,7 @@ pub unsafe fn fdiv_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn frem_fast(a: T, b: T) -> T; +pub unsafe fn frem_fast(a: T, b: T) -> T; /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range /// () @@ -1613,42 +1613,43 @@ pub unsafe fn frem_fast(a: T, b: T) -> T; /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn float_to_int_unchecked(value: Float) -> Int; +pub unsafe fn float_to_int_unchecked(value: Float) +-> Int; /// Float addition that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fadd_algebraic(a: T, b: T) -> T; +pub const fn fadd_algebraic(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fsub_algebraic(a: T, b: T) -> T; +pub const fn fsub_algebraic(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fmul_algebraic(a: T, b: T) -> T; +pub const fn fmul_algebraic(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fdiv_algebraic(a: T, b: T) -> T; +pub const fn fdiv_algebraic(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn frem_algebraic(a: T, b: T) -> T; +pub const fn frem_algebraic(a: T, b: T) -> T; /// Returns the number of bits set in an integer type `T` /// @@ -3389,39 +3390,14 @@ pub const fn maximumf128(x: f128, y: f128) -> f128 { } } -/// Returns the absolute value of an `f16`. +/// Returns the absolute value of a floating-point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::abs`](../../std/primitive.f16.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf16(x: f16) -> f16; - -/// Returns the absolute value of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::abs`](../../std/primitive.f32.html#method.abs) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `abs` method. For example, [`f32::abs`]. #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn fabsf32(x: f32) -> f32; - -/// Returns the absolute value of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::abs`](../../std/primitive.f64.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -pub const fn fabsf64(x: f64) -> f64; - -/// Returns the absolute value of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::abs`](../../std/primitive.f128.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf128(x: f128) -> f128; +pub const fn fabs(x: T) -> T; /// Copies the sign from `y` to `x` for `f16` values. /// diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 50d8871973792..ae86690dc418d 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -252,19 +252,27 @@ pub const unsafe fn simd_fabs(x: T) -> T; /// /// `T` must be a vector of floating-point primitive types. /// -/// Follows IEEE-754 `minNum` semantics. +/// This behaves like IEEE 754-2019 minimumNumber, *except* that it does not order signed +/// zeros deterministically. In particular, for each vector lane: +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_fmin(x: T, y: T) -> T; +pub const unsafe fn simd_minimum_number_nsz(x: T, y: T) -> T; /// Returns the maximum of two vectors, elementwise. /// /// `T` must be a vector of floating-point primitive types. /// -/// Follows IEEE-754 `maxNum` semantics. +/// This behaves like IEEE 754-2019 maximumNumber, *except* that it does not order signed +/// zeros deterministically. In particular, for each vector lane: +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. #[rustc_intrinsic] #[rustc_nounwind] -pub const unsafe fn simd_fmax(x: T, y: T) -> T; +pub const unsafe fn simd_maximum_number_nsz(x: T, y: T) -> T; /// Tests elementwise equality of two vectors. /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 68c87b48de94d..d833653fdba65 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1409,7 +1409,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf128(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 3412e49c49cd0..b0664abcdc739 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1393,7 +1393,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf16(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index e33cb098e4e8d..b85bd2b271588 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1568,7 +1568,7 @@ impl f32 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f32 { - intrinsics::fabsf32(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 872f567efafdc..3e7c1e792ace6 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1566,7 +1566,7 @@ impl f64 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f64 { - intrinsics::fabsf64(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 3c2c40d492005..2007533e68e54 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -24,12 +24,15 @@ mod iter; #[unstable(feature = "new_range_api", issue = "125687")] pub mod legacy; +#[doc(inline)] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] +pub use iter::RangeFromIter; #[doc(inline)] #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] pub use iter::RangeInclusiveIter; #[doc(inline)] #[unstable(feature = "new_range_api", issue = "125687")] -pub use iter::{RangeFromIter, RangeIter}; +pub use iter::RangeIter; // FIXME(#125687): re-exports temporarily removed // Because re-exports of stable items (Bound, RangeBounds, RangeFull, RangeTo) @@ -416,14 +419,13 @@ impl const From> for RangeInclusive { /// /// The `RangeFrom` `start..` contains all values with `x >= start`. /// -/// *Note*: Overflow in the [`Iterator`] implementation (when the contained +/// *Note*: Overflow in the [`IntoIterator`] implementation (when the contained /// data type reaches its numerical limit) is allowed to panic, wrap, or /// saturate. This behavior is defined by the implementation of the [`Step`] /// trait. For primitive integers, this follows the normal rules, and respects -/// the overflow checks profile (panic in debug, wrap in release). Note also -/// that overflow happens earlier than you might assume: the overflow happens -/// in the call to `next` that yields the maximum value, as the range must be -/// set to a state to yield the next value. +/// the overflow checks profile (panic in debug, wrap in release). Unlike +/// its legacy counterpart, the iterator will only panic after yielding the +/// maximum value when overflow checks are enabled. /// /// [`Step`]: crate::iter::Step /// @@ -432,7 +434,6 @@ impl const From> for RangeInclusive { /// The `start..` syntax is a `RangeFrom`: /// /// ``` -/// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); @@ -441,14 +442,14 @@ impl const From> for RangeInclusive { #[lang = "RangeFromCopy"] #[derive(Copy, Hash)] #[derive_const(Clone, PartialEq, Eq)] -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] pub struct RangeFrom { /// The lower bound of the range (inclusive). - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] pub start: Idx, } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for RangeFrom { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; @@ -465,7 +466,6 @@ impl RangeFrom { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n); @@ -473,7 +473,7 @@ impl RangeFrom { /// assert_eq!(i.next(), Some(16)); /// assert_eq!(i.next(), Some(25)); /// ``` - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn iter(&self) -> RangeFromIter { self.clone().into_iter() @@ -486,7 +486,6 @@ impl> RangeFrom { /// # Examples /// /// ``` - /// #![feature(new_range_api)] /// use core::range::RangeFrom; /// /// assert!(!RangeFrom::from(3..).contains(&2)); @@ -498,7 +497,7 @@ impl> RangeFrom { /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5)); /// ``` #[inline] - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] pub const fn contains(&self, item: &U) -> bool where @@ -509,7 +508,7 @@ impl> RangeFrom { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const RangeBounds for RangeFrom { fn start_bound(&self) -> Bound<&T> { @@ -526,7 +525,7 @@ impl const RangeBounds for RangeFrom { /// If you need to use this implementation where `T` is unsized, /// consider using the `RangeBounds` impl for a 2-tuple of [`Bound<&T>`][Bound], /// i.e. replace `start..` with `(Bound::Included(start), Bound::Unbounded)`. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const RangeBounds for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { @@ -537,8 +536,7 @@ impl const RangeBounds for RangeFrom<&T> { } } -// #[unstable(feature = "range_into_bounds", issue = "136903")] -#[unstable(feature = "new_range_api", issue = "125687")] +#[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const IntoBounds for RangeFrom { fn into_bounds(self) -> (Bound, Bound) { @@ -547,7 +545,6 @@ impl const IntoBounds for RangeFrom { } #[unstable(feature = "one_sided_range", issue = "69780")] -// #[unstable(feature = "new_range_api", issue = "125687")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const OneSidedRange for RangeFrom where @@ -558,7 +555,7 @@ where } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] impl const From> for legacy::RangeFrom { #[inline] @@ -566,7 +563,7 @@ impl const From> for legacy::RangeFrom { Self { start: value.start } } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] impl const From> for RangeFrom { #[inline] @@ -697,7 +694,6 @@ impl const RangeBounds for RangeToInclusive<&T> { } } -// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[unstable(feature = "range_into_bounds", issue = "136903")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const IntoBounds for RangeToInclusive { @@ -706,7 +702,6 @@ impl const IntoBounds for RangeToInclusive { } } -// #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] #[unstable(feature = "one_sided_range", issue = "69780")] #[rustc_const_unstable(feature = "const_range", issue = "none")] impl const OneSidedRange for RangeToInclusive diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index 23ace6e1ba253..0cddfff4022df 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs @@ -13,6 +13,18 @@ pub struct RangeIter(legacy::Range); impl RangeIter { #[unstable(feature = "new_range_api", issue = "125687")] /// Returns the remainder of the range being iterated over. + /// + /// # Examples + /// ``` + /// #![feature(new_range_api)] + /// let range = core::range::Range::from(3..11); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder(), range); + /// iter.next(); + /// assert_eq!(iter.clone().remainder(), core::range::Range::from(4..11)); + /// iter.by_ref().for_each(drop); + /// assert!(iter.remainder().is_empty()); + /// ``` pub fn remainder(self) -> Range { Range { start: self.0.start, end: self.0.end } } @@ -161,6 +173,17 @@ impl RangeInclusiveIter { /// Returns the remainder of the range being iterated over. /// /// If the iterator is exhausted or empty, returns `None`. + /// + /// # Examples + /// ``` + /// let range = core::range::RangeInclusive::from(3..=11); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder().unwrap(), range); + /// iter.next(); + /// assert_eq!(iter.clone().remainder().unwrap(), core::range::RangeInclusive::from(4..=11)); + /// iter.by_ref().for_each(drop); + /// assert!(iter.remainder().is_none()); + /// ``` #[stable(feature = "new_range_inclusive_api", since = "1.95.0")] pub fn remainder(self) -> Option> { if self.0.is_empty() { @@ -294,7 +317,7 @@ range_incl_exact_iter_impl! { } /// By-value [`RangeFrom`] iterator. -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug, Clone)] pub struct RangeFromIter { start: A, @@ -305,6 +328,16 @@ pub struct RangeFromIter { impl RangeFromIter { /// Returns the remainder of the range being iterated over. + /// + /// # Examples + /// ``` + /// #![feature(new_range_api)] + /// let range = core::range::RangeFrom::from(3..); + /// let mut iter = range.into_iter(); + /// assert_eq!(iter.clone().remainder(), range); + /// iter.next(); + /// assert_eq!(iter.remainder(), core::range::RangeFrom::from(4..)); + /// ``` #[inline] #[rustc_inherit_overflow_checks] #[unstable(feature = "new_range_api", issue = "125687")] @@ -321,7 +354,7 @@ impl RangeFromIter { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl Iterator for RangeFromIter { type Item = A; @@ -392,10 +425,10 @@ impl Iterator for RangeFromIter { #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for RangeFromIter {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl FusedIterator for RangeFromIter {} -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl IntoIterator for RangeFrom { type Item = A; type IntoIter = RangeFromIter; diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 1709bc7c09843..b30f82a5783ad 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -131,7 +131,7 @@ mod private_slice_index { impl Sealed for range::RangeInclusive {} #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeToInclusive {} - #[unstable(feature = "new_range_api", issue = "125687")] + #[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] impl Sealed for range::RangeFrom {} impl Sealed for ops::IndexRange {} @@ -588,7 +588,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeFrom { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex<[T]> for range::RangeFrom { type Output = [T]; diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 88a8a9764cbc5..336f074883d25 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -555,7 +555,7 @@ unsafe impl const SliceIndex for ops::RangeFrom { } } -#[unstable(feature = "new_range_api", issue = "125687")] +#[stable(feature = "new_range_from_api", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_index", issue = "143775")] unsafe impl const SliceIndex for range::RangeFrom { type Output = str; diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index efd7c2469512b..175cbce4f58be 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -385,13 +385,13 @@ macro_rules! impl_trait { #[inline] fn simd_min(self, other: Self) -> Self { // Safety: `self` and `other` are float vectors - unsafe { core::intrinsics::simd::simd_fmin(self, other) } + unsafe { core::intrinsics::simd::simd_minimum_number_nsz(self, other) } } #[inline] fn simd_max(self, other: Self) -> Self { // Safety: `self` and `other` are floating point vectors - unsafe { core::intrinsics::simd::simd_fmax(self, other) } + unsafe { core::intrinsics::simd::simd_maximum_number_nsz(self, other) } } #[inline] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 7a8ccdbc5043b..f7bc729598cd3 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -33,7 +33,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false } addr2line = { version = "0.25.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.178", default-features = false, features = [ +libc = { version = "0.2.183", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index c0a77ef0b05c0..6b894f6bf4243 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2725,6 +2725,41 @@ impl Path { self._strip_prefix(base.as_ref()) } + /// Returns a path with the optional prefix removed. + /// + /// If `base` is not a prefix of `self` (i.e., [`starts_with`] returns `false`), returns the original path (`self`) + /// + /// [`starts_with`]: Path::starts_with + /// + /// # Examples + /// + /// ``` + /// #![feature(trim_prefix_suffix)] + /// use std::path::Path; + /// + /// let path = Path::new("/test/haha/foo.txt"); + /// + /// // Prefix present - remove it + /// assert_eq!(path.trim_prefix("/"), Path::new("test/haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test"), Path::new("haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test/"), Path::new("haha/foo.txt")); + /// assert_eq!(path.trim_prefix("/test/haha/foo.txt"), Path::new("")); + /// assert_eq!(path.trim_prefix("/test/haha/foo.txt/"), Path::new("")); + /// + /// // Prefix absent - return original + /// assert_eq!(path.trim_prefix("test"), path); + /// assert_eq!(path.trim_prefix("/te"), path); + /// assert_eq!(path.trim_prefix("/haha"), path); + /// ``` + #[must_use = "this returns the remaining path as a new path, without modifying the original"] + #[unstable(feature = "trim_prefix_suffix", issue = "142312")] + pub fn trim_prefix

(&self, base: P) -> &Path + where + P: AsRef, + { + self._strip_prefix(base.as_ref()).unwrap_or(self) + } + fn _strip_prefix(&self, base: &Path) -> Result<&Path, StripPrefixError> { iter_after(self.components(), base.components()) .map(|c| c.as_path()) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 2a8571871b732..9b0ef5539d32b 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1872,7 +1872,12 @@ fn file_time_to_timespec(time: Option) -> io::Result io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time", )), - None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), + None => Ok({ + let mut ts = libc::timespec::default(); + ts.tv_sec = 0; + ts.tv_nsec = libc::UTIME_OMIT as _; + ts + }), } } diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 9acc7786b2edd..26fb6d3d7cf2d 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -1,3 +1,4 @@ +use core::mem; use core::num::niche_types::Nanoseconds; use crate::io; @@ -6,8 +7,12 @@ use crate::time::Duration; const NSEC_PER_SEC: u64 = 1_000_000_000; #[allow(dead_code)] // Used for pthread condvar timeouts -pub const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; +pub const TIMESPEC_MAX: libc::timespec = { + let mut ts = unsafe { mem::zeroed::() }; + ts.tv_sec = ::MAX; + ts.tv_nsec = 1_000_000_000 - 1; + ts +}; // This additional constant is only used when calling // `libc::pthread_cond_timedwait`. @@ -164,9 +169,11 @@ impl Timespec { #[allow(dead_code)] pub fn to_timespec(&self) -> Option { - Some(libc::timespec { - tv_sec: self.tv_sec.try_into().ok()?, - tv_nsec: self.tv_nsec.as_inner().try_into().ok()?, + Some({ + let mut ts = libc::timespec::default(); + ts.tv_sec = self.tv_sec.try_into().ok()?; + ts.tv_nsec = self.tv_nsec.as_inner().try_into().ok()?; + ts }) } diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 5d4eabc226ed7..2f3ef1741cdfc 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -570,10 +570,10 @@ pub fn sleep(dur: Duration) { // nanosleep will fill in `ts` with the remaining time. unsafe { while secs > 0 || nsecs > 0 { - let mut ts = libc::timespec { - tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t, - tv_nsec: nsecs, - }; + let mut ts = libc::timespec::default(); + ts.tv_sec = cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t; + ts.tv_nsec = nsecs; + secs -= ts.tv_sec as u64; let ts_ptr = &raw mut ts; let r = nanosleep(ts_ptr, ts_ptr); diff --git a/library/std/src/sys/time/unsupported.rs b/library/std/src/sys/time/unsupported.rs index 9bdd57268fd5b..1c5c037560a09 100644 --- a/library/std/src/sys/time/unsupported.rs +++ b/library/std/src/sys/time/unsupported.rs @@ -1,5 +1,3 @@ -use crate::time::Duration; - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Duration); diff --git a/library/stdarch/crates/core_arch/src/nvptx/packed.rs b/library/stdarch/crates/core_arch/src/nvptx/packed.rs index 856aeea4b686c..1c7e81268fc99 100644 --- a/library/stdarch/crates/core_arch/src/nvptx/packed.rs +++ b/library/stdarch/crates/core_arch/src/nvptx/packed.rs @@ -99,7 +99,7 @@ pub unsafe fn f16x2_neg(a: f16x2) -> f16x2 { #[cfg_attr(test, assert_instr(min.f16x2))] #[unstable(feature = "stdarch_nvptx", issue = "111199")] pub unsafe fn f16x2_min(a: f16x2, b: f16x2) -> f16x2 { - simd_fmin(a, b) + simd_minimum_number_nsz(a, b) } /// Find the minimum of two values, NaNs pass through. @@ -123,7 +123,7 @@ pub unsafe fn f16x2_min_nan(a: f16x2, b: f16x2) -> f16x2 { #[cfg_attr(test, assert_instr(max.f16x2))] #[unstable(feature = "stdarch_nvptx", issue = "111199")] pub unsafe fn f16x2_max(a: f16x2, b: f16x2) -> f16x2 { - simd_fmax(a, b) + simd_maximum_number_nsz(a, b) } /// Find the maximum of two values, NaNs pass through. diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 3f7781cc7dc4c..9183eabd530ca 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -208,7 +208,7 @@ pub fn _mm_min_ss(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(minps))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_ps(a: __m128, b: __m128) -> __m128 { - // See the `test_mm_min_ps` test why this can't be implemented using `simd_fmin`. + // See the `test_mm_min_ps` test why this can't be implemented using `simd_minimum_number_nsz`. unsafe { minps(a, b) } } @@ -234,7 +234,7 @@ pub fn _mm_max_ss(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(maxps))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_ps(a: __m128, b: __m128) -> __m128 { - // See the `test_mm_min_ps` test why this can't be implemented using `simd_fmax`. + // See the `test_mm_min_ps` test why this can't be implemented using `simd_maximum_number_nsz`. unsafe { maxps(a, b) } } @@ -2227,11 +2227,11 @@ mod tests { let r = _mm_min_ps(a, b); assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0)); - // `_mm_min_ps` can **not** be implemented using the `simd_min` rust intrinsic. `simd_min` - // is lowered by the llvm codegen backend to `llvm.minnum.v*` llvm intrinsic. This intrinsic - // doesn't specify how -0.0 is handled. Unfortunately it happens to behave different from - // the `minps` x86 instruction on x86. The `llvm.minnum.v*` llvm intrinsic equals - // `r1` to `a` and `r2` to `b`. + // `_mm_min_ps` can **not** be implemented using the `simd_minimum_number_nsz` rust + // intrinsic. That intrinsic is lowered by the llvm codegen backend to `llvm.minimumnum.v*` + // llvm intrinsic with the `nsz` attribute. The `nsz` attribute means -0.0 is handled + // non-deterministically. The `minps` x86 instruction however has a deterministic semantics + // for signed zeros. let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0); let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0); let r1 = _mm_min_ps(a, b).as_f32x4().to_bits(); diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index f42e6f770ebe8..e62aa74662bed 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -35,10 +35,9 @@ ENV \ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS \ - --enable-full-tools \ +ENV RUST_CONFIGURE_ARGS="--enable-full-tools \ --enable-extended \ --enable-profiler \ --enable-sanitizers \ - --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS + --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile index 37a8dc56a5fa6..0675c3cafd9e7 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile @@ -36,5 +36,5 @@ ENV \ ENV HOSTS=x86_64-unknown-illumos -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python2.7 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index cb57478761994..b168c739c9793 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -80,8 +80,7 @@ ENV PGO_HOST=x86_64-unknown-linux-gnu ENV HOSTS=x86_64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS \ - --enable-full-tools \ +ENV RUST_CONFIGURE_ARGS="--enable-full-tools \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs \ @@ -94,23 +93,23 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.jemalloc \ --set rust.bootstrap-override-lld=true \ --set rust.lto=thin \ - --set rust.codegen-units=1 + --set rust.codegen-units=1" COPY host-x86_64/dist-x86_64-linux/dist.sh /scripts/ COPY host-x86_64/dist-x86_64-linux/dist-alt.sh /scripts/ -ENV SCRIPT "Must specify DOCKER_SCRIPT for this image" +ENV SCRIPT="Must specify DOCKER_SCRIPT for this image" ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs -ENV DIST_SRC 1 +ENV DIST_SRC="1" # When we build cargo in this container, we don't want it to use the system # libcurl, instead it should compile its own. -ENV LIBCURL_NO_PKG_CONFIG 1 +ENV LIBCURL_NO_PKG_CONFIG="1" -ENV DIST_REQUIRE_ALL_TOOLS 1 +ENV DIST_REQUIRE_ALL_TOOLS="1" # FIXME: Without this, LLVMgold.so incorrectly resolves to the system # libstdc++, instead of the one we build. diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index 32b5058bce703..68f914a81552d 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile @@ -35,14 +35,13 @@ RUN sh /scripts/sccache.sh ENV HOSTS=x86_64-unknown-linux-musl -ENV RUST_CONFIGURE_ARGS \ - --musl-root-x86_64=/usr/local/x86_64-linux-musl \ +ENV RUST_CONFIGURE_ARGS="--musl-root-x86_64=/usr/local/x86_64-linux-musl \ --enable-extended \ --enable-sanitizers \ --enable-profiler \ --enable-lld \ --set target.x86_64-unknown-linux-musl.crt-static=false \ - --build $HOSTS + --build $HOSTS" # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our @@ -54,4 +53,4 @@ ENV CFLAGS_x86_64_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wa,--compress- -Wl,--compress-debug-sections=none" # To run native tests replace `dist` below with `test` -ENV SCRIPT python3 ../x.py dist --build $HOSTS +ENV SCRIPT="python3 ../x.py dist --build $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile index effdc99d9a650..3bb2c7433e03c 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile @@ -22,5 +22,5 @@ ENV \ ENV HOSTS=x86_64-unknown-netbsd -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile index 4d77f0aad26be..b11e8cdeaa732 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-solaris/Dockerfile @@ -32,5 +32,5 @@ ENV \ ENV HOSTS=x86_64-pc-solaris -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3e68ed950ce16..8b66672cfa5ed 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1067,17 +1067,27 @@ impl LinkCollector<'_, '_> { #[instrument(level = "debug", skip_all)] fn resolve_links(&mut self, item: &Item) { let tcx = self.cx.tcx; - if !self.cx.document_private() - && let Some(def_id) = item.item_id.as_def_id() - && let Some(def_id) = def_id.as_local() - && !tcx.effective_visibilities(()).is_exported(def_id) - && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs) + let document_private = self.cx.document_private(); + let effective_visibilities = tcx.effective_visibilities(()); + let should_skip_link_resolution = |item_id: DefId| { + !document_private + && item_id + .as_local() + .is_some_and(|local_def_id| !effective_visibilities.is_exported(local_def_id)) + && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs) + }; + + if let Some(def_id) = item.item_id.as_def_id() + && should_skip_link_resolution(def_id) { // Skip link resolution for non-exported items. return; } - let mut insert_links = |item_id, doc: &str| { + let mut try_insert_links = |item_id, doc: &str| { + if should_skip_link_resolution(item_id) { + return; + } let module_id = match tcx.def_kind(item_id) { DefKind::Mod if item.inner_docs(tcx) => item_id, _ => find_nearest_parent_module(tcx, item_id).unwrap(), @@ -1108,7 +1118,7 @@ impl LinkCollector<'_, '_> { // NOTE: if there are links that start in one crate and end in another, this will not resolve them. // This is a degenerate case and it's not supported by rustdoc. let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id()); - insert_links(item_id, &doc) + try_insert_links(item_id, &doc) } // Also resolve links in the note text of `#[deprecated]`. @@ -1137,7 +1147,7 @@ impl LinkCollector<'_, '_> { } else { item.item_id.expect_def_id() }; - insert_links(item_id, note) + try_insert_links(item_id, note) } } diff --git a/src/tools/miri/tests/pass/float_nan.rs b/src/tools/miri/tests/pass/float_nan.rs index 6b39c2db3587a..4ec5a7e9c2090 100644 --- a/src/tools/miri/tests/pass/float_nan.rs +++ b/src/tools/miri/tests/pass/float_nan.rs @@ -513,10 +513,10 @@ fn test_simd() { F32::from(unsafe { simd_div(f32x4::splat(0.0), f32x4::splat(0.0)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { - F32::from(unsafe { simd_fmin(f32x4::splat(nan), f32x4::splat(nan)) }[0]) + F32::from(unsafe { simd_minimum_number_nsz(f32x4::splat(nan), f32x4::splat(nan)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { - F32::from(unsafe { simd_fmax(f32x4::splat(nan), f32x4::splat(nan)) }[0]) + F32::from(unsafe { simd_maximum_number_nsz(f32x4::splat(nan), f32x4::splat(nan)) }[0]) }); check_all_outcomes([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)], || { F32::from(unsafe { simd_fma(f32x4::splat(nan), f32x4::splat(nan), f32x4::splat(nan)) }[0]) diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index b4fd8e2165336..1e86c458ac21c 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -90,11 +90,11 @@ fn simd_ops_f16() { assert_eq!(simd_rem(a, b), f16x4::from_array([0.0, 0.0, 1.0, 2.0])); assert_eq!(simd_fabs(b), f16x4::from_array([1.0, 2.0, 3.0, 4.0])); assert_eq!( - simd_fmax(a, simd_mul(b, f16x4::splat(4.0))), + simd_maximum_number_nsz(a, simd_mul(b, f16x4::splat(4.0))), f16x4::from_array([10.0, 10.0, 12.0, 10.0]) ); assert_eq!( - simd_fmin(a, simd_mul(b, f16x4::splat(4.0))), + simd_minimum_number_nsz(a, simd_mul(b, f16x4::splat(4.0))), f16x4::from_array([4.0, 8.0, 10.0, -16.0]) ); @@ -134,13 +134,13 @@ fn simd_ops_f16() { assert_eq!(simd_reduce_min(b), -4.0f16); assert_eq!( - simd_fmax(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + simd_maximum_number_nsz(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), f16x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_max(f16x2::from_array([0.0, f16::NAN])), 0.0f16); assert_eq!(simd_reduce_max(f16x2::from_array([f16::NAN, 0.0])), 0.0f16); assert_eq!( - simd_fmin(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), + simd_minimum_number_nsz(f16x2::from_array([0.0, f16::NAN]), f16x2::from_array([f16::NAN, 0.0])), f16x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_min(f16x2::from_array([0.0, f16::NAN])), 0.0f16); @@ -304,11 +304,11 @@ fn simd_ops_f128() { assert_eq!(simd_rem(a, b), f128x4::from_array([0.0, 0.0, 1.0, 2.0])); assert_eq!(simd_fabs(b), f128x4::from_array([1.0, 2.0, 3.0, 4.0])); assert_eq!( - simd_fmax(a, simd_mul(b, f128x4::splat(4.0))), + simd_maximum_number_nsz(a, simd_mul(b, f128x4::splat(4.0))), f128x4::from_array([10.0, 10.0, 12.0, 10.0]) ); assert_eq!( - simd_fmin(a, simd_mul(b, f128x4::splat(4.0))), + simd_minimum_number_nsz(a, simd_mul(b, f128x4::splat(4.0))), f128x4::from_array([4.0, 8.0, 10.0, -16.0]) ); @@ -348,13 +348,13 @@ fn simd_ops_f128() { assert_eq!(simd_reduce_min(b), -4.0f128); assert_eq!( - simd_fmax(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + simd_maximum_number_nsz(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), f128x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_max(f128x2::from_array([0.0, f128::NAN])), 0.0f128); assert_eq!(simd_reduce_max(f128x2::from_array([f128::NAN, 0.0])), 0.0f128); assert_eq!( - simd_fmin(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), + simd_minimum_number_nsz(f128x2::from_array([0.0, f128::NAN]), f128x2::from_array([f128::NAN, 0.0])), f128x2::from_array([0.0, 0.0]) ); assert_eq!(simd_reduce_min(f128x2::from_array([0.0, f128::NAN])), 0.0f128); diff --git a/tests/codegen-llvm/fromrangeiter-overflow-checks.rs b/tests/codegen-llvm/fromrangeiter-overflow-checks.rs index e1e521103b574..0d640178f459a 100644 --- a/tests/codegen-llvm/fromrangeiter-overflow-checks.rs +++ b/tests/codegen-llvm/fromrangeiter-overflow-checks.rs @@ -11,6 +11,7 @@ #![crate_type = "lib"] #![feature(new_range_api)] + use std::range::RangeFrom; // CHECK-LABEL: @rangefrom_increments( diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs index 8dd464a1bffb6..94f7e160f8daf 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-float-minmax.rs @@ -8,18 +8,18 @@ mod minisimd; use minisimd::*; -use std::intrinsics::simd::{simd_fmax, simd_fmin}; +use std::intrinsics::simd::*; // CHECK-LABEL: @fmin #[no_mangle] pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.minnum.v4f32 - simd_fmin(a, b) + // CHECK: call nsz <4 x float> @llvm.minimumnum.v4f32 + simd_minimum_number_nsz(a, b) } // CHECK-LABEL: @fmax #[no_mangle] pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.maxnum.v4f32 - simd_fmax(a, b) + // CHECK: call nsz <4 x float> @llvm.maximumnum.v4f32 + simd_maximum_number_nsz(a, b) } diff --git a/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs b/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs new file mode 100644 index 0000000000000..1c736785933e5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/doc-link-private-reexport-issue-154383.rs @@ -0,0 +1,10 @@ +//@ check-pass + +// Regression test for . +// Rustdoc used to ICE on the doc link attached to a `pub use` inside a +// private module. + +mod inner { + /// [std::vec::Vec] + pub use std::vec::Vec as MyVec; +} diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs new file mode 100644 index 0000000000000..6a32cd97c50b7 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.rs @@ -0,0 +1,18 @@ +//@ check-fail + +#![feature(repr_simd, intrinsics, core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +// Bad monomorphizations could previously cause LLVM asserts even though the +// error was caught in the compiler. + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); + +pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { + intrinsics::fadd_fast(a, b) + //~^ ERROR the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied +} diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr new file mode 100644 index 0000000000000..db2a222c8f2c4 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-bounds.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied + --> $DIR/bad-intrinsic-monomorphization-bounds.rs:16:5 + | +LL | intrinsics::fadd_fast(a, b) + | ^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | +help: the nightly-only, unstable trait `intrinsics::bounds::FloatPrimitive` is not implemented for `Foo` + --> $DIR/bad-intrinsic-monomorphization-bounds.rs:13:1 + | +LL | pub struct Foo(i64); + | ^^^^^^^^^^^^^^ +help: the following other types implement trait `intrinsics::bounds::FloatPrimitive` + --> $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f16` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f32` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f64` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f128` +note: required by a bound in `fadd_fast` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs index d68cbf26ef110..8849ed2a67add 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs @@ -17,11 +17,6 @@ pub fn test_cttz(v: Foo) -> u32 { //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo` } -pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { - intrinsics::fadd_fast(a, b) - //~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo` -} - pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { intrinsics::simd::simd_add(a, b) //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr index 51ef71c9e2988..329bf214c03d7 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr @@ -1,21 +1,15 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:26:5 + --> $DIR/bad-intrinsic-monomorphization.rs:21:5 | LL | intrinsics::simd::simd_add(a, b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:21:5 - | -LL | intrinsics::fadd_fast(a, b) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo` --> $DIR/bad-intrinsic-monomorphization.rs:16:5 | LL | intrinsics::cttz(v) | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs index ebba4ae92c47f..e2aa817699a0e 100644 --- a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs +++ b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocno.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C overflow-checks=no #![crate_type = "lib"] -#![feature(new_range_api)] use std::range::RangeFromIter; diff --git a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs index 8eb5392c7bac7..b37f6985a0ea7 100644 --- a/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs +++ b/tests/ui/iterators/auxiliary/rangefrom-overflow-2crates-ocyes.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C overflow-checks=yes #![crate_type = "lib"] -#![feature(new_range_api)] use std::range::RangeFromIter; diff --git a/tests/ui/iterators/fromrangeiter.rs b/tests/ui/iterators/fromrangeiter.rs index 54d8f522a2c88..c672f1348437c 100644 --- a/tests/ui/iterators/fromrangeiter.rs +++ b/tests/ui/iterators/fromrangeiter.rs @@ -1,8 +1,6 @@ //@ run-pass //@ compile-flags: -C overflow-checks=yes -#![feature(new_range_api)] - use std::{iter, range}; fn main() { diff --git a/tests/ui/iterators/rangefrom-overflow-2crates.rs b/tests/ui/iterators/rangefrom-overflow-2crates.rs index c35c96f99322e..56b642b2c548e 100644 --- a/tests/ui/iterators/rangefrom-overflow-2crates.rs +++ b/tests/ui/iterators/rangefrom-overflow-2crates.rs @@ -7,8 +7,6 @@ // Test that two crates with different overflow-checks have the same results, // even when the iterator is passed between them. -#![feature(new_range_api)] - extern crate rangefrom_overflow_2crates_ocno; extern crate rangefrom_overflow_2crates_ocyes; diff --git a/tests/ui/range/new_range_stability.rs b/tests/ui/range/new_range_stability.rs index 2d129fb6815f5..0b2965ecba237 100644 --- a/tests/ui/range/new_range_stability.rs +++ b/tests/ui/range/new_range_stability.rs @@ -1,6 +1,12 @@ // Stable -use std::range::{RangeInclusive, RangeInclusiveIter, RangeToInclusive}; +use std::range::{ + RangeInclusive, + RangeInclusiveIter, + RangeToInclusive, + RangeFrom, + RangeFromIter, +}; fn range_inclusive(mut r: RangeInclusive) { &[1, 2, 3][r]; // Indexing @@ -23,15 +29,27 @@ fn range_to_inclusive(mut r: RangeToInclusive) { r.contains(&5); } +fn range_from(mut r: RangeFrom) { + &[1, 2, 3][r]; // Indexing + + r.start; + r.contains(&5); + r.iter(); + + let mut i = r.into_iter(); + i.next(); + + // Left unstable + i.remainder(); //~ ERROR unstable +} + // Unstable module use std::range::legacy; //~ ERROR unstable // Unstable types -use std::range::RangeFrom; //~ ERROR unstable use std::range::Range; //~ ERROR unstable -use std::range::RangeFromIter; //~ ERROR unstable use std::range::RangeIter; //~ ERROR unstable fn main() {} diff --git a/tests/ui/range/new_range_stability.stderr b/tests/ui/range/new_range_stability.stderr index b5a7e06e5f2ea..747c39d001eb4 100644 --- a/tests/ui/range/new_range_stability.stderr +++ b/tests/ui/range/new_range_stability.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:28:5 + --> $DIR/new_range_stability.rs:48:5 | LL | use std::range::legacy; | ^^^^^^^^^^^^^^^^^^ @@ -9,17 +9,7 @@ LL | use std::range::legacy; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:32:5 - | -LL | use std::range::RangeFrom; - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #125687 for more information - = help: add `#![feature(new_range_api)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:33:5 + --> $DIR/new_range_stability.rs:52:5 | LL | use std::range::Range; | ^^^^^^^^^^^^^^^^^ @@ -29,25 +19,25 @@ LL | use std::range::Range; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:34:5 + --> $DIR/new_range_stability.rs:53:5 | -LL | use std::range::RangeFromIter; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | use std::range::RangeIter; + | ^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #125687 for more information = help: add `#![feature(new_range_api)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `new_range_api` - --> $DIR/new_range_stability.rs:35:5 + --> $DIR/new_range_stability.rs:43:7 | -LL | use std::range::RangeIter; - | ^^^^^^^^^^^^^^^^^^^^^ +LL | i.remainder(); + | ^^^^^^^^^ | = note: see issue #125687 for more information = help: add `#![feature(new_range_api)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/resolve/filter-intrinsics.rs b/tests/ui/resolve/filter-intrinsics.rs index 8d6d22817dc5c..9998bec1ad4fe 100644 --- a/tests/ui/resolve/filter-intrinsics.rs +++ b/tests/ui/resolve/filter-intrinsics.rs @@ -3,8 +3,8 @@ fn main() { let _ = transmute::(); //~^ ERROR cannot find - // Should suggest `std::intrinsics::fabsf64`, + // Should suggest `std::intrinsics::fabs`, // since there is no non-intrinsic to suggest. - let _ = fabsf64(1.0); + let _ = fabs(1.0); //~^ ERROR cannot find } diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 9c9e92f6d4f83..3870cfcb1080a 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr @@ -9,15 +9,15 @@ help: consider importing this function LL + use std::mem::transmute; | -error[E0425]: cannot find function `fabsf64` in this scope +error[E0425]: cannot find function `fabs` in this scope --> $DIR/filter-intrinsics.rs:8:13 | -LL | let _ = fabsf64(1.0); - | ^^^^^^^ not found in this scope +LL | let _ = fabs(1.0); + | ^^^^ not found in this scope | help: consider importing this function | -LL + use std::intrinsics::fabsf64; +LL + use std::intrinsics::fabs; | error: aborting due to 2 previous errors diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs index d9dc291de63d4..8ef5d85385a41 100644 --- a/tests/ui/simd/intrinsic/float-minmax-pass.rs +++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs @@ -1,8 +1,8 @@ //@ run-pass //@ ignore-emscripten -//@ compile-flags: --cfg minisimd_const +//@ compile-flags: --cfg minisimd_const -O -// Test that the simd_f{min,max} intrinsics produce the correct results. +// Test that the simd_{min,max}imum_number_nsz intrinsics produce the correct results. #![feature(repr_simd, core_intrinsics, const_trait_impl, const_cmp, const_index)] #![allow(non_camel_case_types)] @@ -12,41 +12,38 @@ mod minisimd; use minisimd::*; use std::intrinsics::simd::*; +use std::hint::black_box; const fn minmax() { let x = f32x4::from_array([1.0, 2.0, 3.0, 4.0]); let y = f32x4::from_array([2.0, 1.0, 4.0, 3.0]); - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] let nan = f32::NAN; - // MIPS hardware except MIPS R6 treats f32::NAN as SNAN. Clear the signaling bit. - // See https://github.com/rust-lang/rust/issues/52746. // The "-1" works because we rely on `NAN` to have an all-0 payload, so the signaling // bit is the least significant non-zero bit. - #[cfg(any(target_arch = "mips", target_arch = "mips64"))] - let nan = f32::from_bits(f32::NAN.to_bits() - 1); + let snan = f32::from_bits(f32::NAN.to_bits() - 1); - let n = f32x4::from_array([nan, nan, nan, nan]); + let n = f32x4::from_array([nan, nan, snan, snan]); unsafe { - let min0 = simd_fmin(x, y); - let min1 = simd_fmin(y, x); + let min0 = simd_minimum_number_nsz(x, y); + let min1 = simd_minimum_number_nsz(y, black_box(x)); assert_eq!(min0, min1); let e = f32x4::from_array([1.0, 1.0, 3.0, 3.0]); assert_eq!(min0, e); - let minn = simd_fmin(x, n); + let minn = simd_minimum_number_nsz(x, n); assert_eq!(minn, x); - let minn = simd_fmin(y, n); + let minn = simd_minimum_number_nsz(black_box(y), n); assert_eq!(minn, y); - let max0 = simd_fmax(x, y); - let max1 = simd_fmax(y, x); + let max0 = simd_maximum_number_nsz(x, y); + let max1 = simd_maximum_number_nsz(y, black_box(x)); assert_eq!(max0, max1); let e = f32x4::from_array([2.0, 2.0, 4.0, 4.0]); assert_eq!(max0, e); - let maxn = simd_fmax(x, n); + let maxn = simd_maximum_number_nsz(x, n); assert_eq!(maxn, x); - let maxn = simd_fmax(y, n); + let maxn = simd_maximum_number_nsz(n, black_box(y)); assert_eq!(maxn, y); } } diff --git a/triagebot.toml b/triagebot.toml index 01d047cdae553..f99d700310dfe 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1073,6 +1073,10 @@ instead. """ cc = ["@Amanieu", "@folkertdev", "@sayantn"] +[mentions."library/std_detect"] +message = "Some changes occurred in `std_detect`" +cc = ["@Amanieu", "@folkertdev", "@sayantn"] + [mentions."library/core/src/intrinsics/simd.rs"] message = """ Some changes occurred to the platform-builtins intrinsics. Make sure the @@ -1412,6 +1416,15 @@ cc = ["@m-ou-se"] [mentions."compiler/rustc_ast_lowering/src/format.rs"] cc = ["@m-ou-se"] +[mentions."src/ci/github-actions/jobs.yml"] +message = """ +> [!WARNING] +> +> If you are changing how CI LLVM is built or linked, make sure to bump +> `src/bootstrap/download-ci-llvm-stamp`. +""" +cc = ["@jieyouxu"] + # Content-based mentions [mentions."#[miri::intrinsic_fallback_is_spec]"] @@ -1592,6 +1605,7 @@ dep-bumps = [ "/library/std" = ["libs", "@ChrisDenton"] "/library/std/src/sys/pal/windows" = ["@ChrisDenton"] "/library/stdarch" = ["libs"] +"/library/std_detect" = ["libs"] "/library/test" = ["libs"] "/src/bootstrap" = ["bootstrap"] "/src/ci" = ["infra-ci"]