diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 7c84530abbee2..c2260a4590975 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -986,16 +986,6 @@ impl<'a> MethodDef<'a> { f(cx, span, &substructure) } - fn get_ret_ty( - &self, - cx: &ExtCtxt<'_>, - trait_: &TraitDef<'_>, - generics: &Generics, - type_ident: Ident, - ) -> Box { - self.ret_ty.to_ty(cx, trait_.span, type_ident, generics) - } - fn is_static(&self) -> bool { !self.explicit_self } @@ -1068,10 +1058,14 @@ impl<'a> MethodDef<'a> { self_arg.into_iter().chain(nonself_args).collect() }; - let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); + let ret_type = if let Ty::Unit = &self.ret_ty { + ast::FnRetTy::Default(span) + } else { + ast::FnRetTy::Ty(self.ret_ty.to_ty(cx, span, type_ident, generics)) + }; let method_ident = Ident::new(self.name, span); - let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type)); + let fn_decl = cx.fn_decl(args, ret_type); let body_block = body.into_block(cx, span); let trait_lo_sp = span.shrink_to_lo(); diff --git a/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch b/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch new file mode 100644 index 0000000000000..382f1177f36b0 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch @@ -0,0 +1,133 @@ +From aacbac292e8b470c8be0e284f3005192f94a0481 Mon Sep 17 00:00:00 2001 +From: xonx <119700621+xonx4l@users.noreply.github.com> +Date: Tue, 13 Jan 2026 17:20:06 +0000 +Subject: [PATCH] Disable f16 math tests for cranelift + +--- + coretests/tests/floats/mod.rs | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/coretests/tests/floats/mod.rs b/coretests/tests/floats/mod.rs +index 58892b3daa6..dc3da4a3311 100644 +--- a/coretests/tests/floats/mod.rs ++++ b/coretests/tests/floats/mod.rs +@@ -1536,7 +1536,7 @@ fn s_nan() -> Float { + name: powf, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1559,7 +1559,7 @@ fn s_nan() -> Float { + name: exp, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1580,7 +1580,7 @@ fn s_nan() -> Float { + name: exp2, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1600,7 +1600,7 @@ fn s_nan() -> Float { + name: ln, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1622,7 +1622,7 @@ fn s_nan() -> Float { + name: log, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1647,7 +1647,7 @@ fn s_nan() -> Float { + name: log2, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1670,7 +1670,7 @@ fn s_nan() -> Float { + name: log10, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1694,7 +1694,7 @@ fn s_nan() -> Float { + name: asinh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1725,7 +1725,7 @@ fn s_nan() -> Float { + name: acosh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1752,7 +1752,7 @@ fn s_nan() -> Float { + name: atanh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1778,7 +1778,7 @@ fn s_nan() -> Float { + name: gamma, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1804,7 +1804,7 @@ fn s_nan() -> Float { + name: ln_gamma, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1942,7 +1942,7 @@ fn s_nan() -> Float { + attrs: { + // FIXME(f16_f128): add math tests when available + const: #[cfg(false)], +- f16: #[cfg(any(miri, target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +-- +2.50.1 + diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 9379faf1156fc..ca4805a93e017 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1397,12 +1397,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn call( &mut self, llty: &'ll Type, - fn_call_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], funclet: Option<&Funclet<'ll>>, - instance: Option>, + callee_instance: Option>, ) -> &'ll Value { debug!("call {:?} with args ({:?})", llfn, args); @@ -1414,10 +1414,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } // Emit CFI pointer type membership test - self.cfi_type_test(fn_call_attrs, fn_abi, instance, llfn); + self.cfi_type_test(caller_attrs, fn_abi, callee_instance, llfn); // Emit KCFI operand bundle - let kcfi_bundle = self.kcfi_operand_bundle(fn_call_attrs, fn_abi, instance, llfn); + let kcfi_bundle = self.kcfi_operand_bundle(caller_attrs, fn_abi, callee_instance, llfn); if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) { bundles.push(kcfi_bundle); } @@ -1435,17 +1435,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ) }; - if let Some(instance) = instance { + if let Some(callee_instance) = callee_instance { // Attributes on the function definition being called - let fn_defn_attrs = self.cx.tcx.codegen_fn_attrs(instance.def_id()); - if let Some(fn_call_attrs) = fn_call_attrs + let callee_attrs = self.cx.tcx.codegen_fn_attrs(callee_instance.def_id()); + if let Some(caller_attrs) = caller_attrs // If there is an inline attribute and a target feature that matches // we will add the attribute to the callsite otherwise we'll omit // this and not add the attribute to prevent soundness issues. - && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, instance) + && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, callee_instance) && self.cx.tcx.is_target_feature_call_safe( - &fn_defn_attrs.target_features, - &fn_call_attrs.target_features.iter().cloned().chain( + &callee_attrs.target_features, + &caller_attrs.target_features.iter().cloned().chain( self.cx.tcx.sess.target_features.iter().map(|feat| TargetFeature { name: *feat, kind: TargetFeatureKind::Implied, @@ -1470,14 +1470,15 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) { - let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance); + let call = + self.call(llty, caller_attrs, Some(fn_abi), llfn, args, funclet, callee_instance); llvm::LLVMSetTailCallKind(call, llvm::TailCallKind::MustTail); match &fn_abi.ret.mode { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d22546dee5654..35de8b5e1486b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -199,12 +199,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // do an invoke, otherwise do a call. let fn_ty = bx.fn_decl_backend_type(fn_abi); - let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { + let caller_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { Some(bx.tcx().codegen_instance_attrs(fx.instance.def)) } else { None }; - let fn_attrs = fn_attrs.as_deref(); + let caller_attrs = caller_attrs.as_deref(); if !fn_abi.can_unwind { unwind = mir::UnwindAction::Unreachable; @@ -233,7 +233,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; if kind == CallKind::Tail { - bx.tail_call(fn_ty, fn_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); + bx.tail_call(fn_ty, caller_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); return MergingSucc::False; } @@ -245,7 +245,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; let invokeret = bx.invoke( fn_ty, - fn_attrs, + caller_attrs, Some(fn_abi), fn_ptr, llargs, @@ -268,8 +268,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } MergingSucc::False } else { - let llret = - bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance); + let llret = bx.call( + fn_ty, + caller_attrs, + Some(fn_abi), + fn_ptr, + llargs, + self.funclet(fx), + instance, + ); if fx.mir[self.bb].is_cleanup { bx.apply_attrs_to_cleanup_callsite(llret); } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index ba36188f05d15..3486bd140eceb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -600,10 +600,13 @@ pub trait BuilderMethods<'a, 'tcx>: /// /// ## Arguments /// - /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. - /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. - /// Any ABI-related transformations should be handled by different, earlier stages of codegen. - /// For instance, in the caller of `BuilderMethods::call`. + /// `caller_attrs` are the attributes of the surrounding caller; they have nothing to do with + /// the callee. + /// + /// The `caller_attrs`, `fn_abi`, and `callee_instance` arguments are Options because they are + /// advisory. They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI + /// per se. Any ABI-related transformations should be handled by different, earlier stages of + /// codegen. For instance, in the caller of `BuilderMethods::call`. /// /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` /// should still do correct codegen, and code should not be miscompiled if they are omitted. @@ -620,23 +623,23 @@ pub trait BuilderMethods<'a, 'tcx>: fn call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) -> Self::Value; fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ); fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 02615e3bbc18c..fe3891d0dd7e0 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -343,17 +343,18 @@ where // Check the qualifs of the value of `const` items. let uneval = match constant.const_ { - Const::Ty(_, ct) - if matches!( - ct.kind(), - ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_) - ) => - { - None - } - Const::Ty(_, c) => { - bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c) - } + Const::Ty(_, ct) => match ct.kind() { + ty::ConstKind::Param(_) | ty::ConstKind::Error(_) => None, + // Unevaluated consts in MIR bodies don't have associated MIR (e.g. `#[type_const]`). + ty::ConstKind::Unevaluated(_) => None, + // FIXME(mgca): Investigate whether using `None` for `ConstKind::Value` is overly + // strict, and if instead we should be doing some kind of value-based analysis. + ty::ConstKind::Value(_) => None, + _ => bug!( + "expected ConstKind::Param, ConstKind::Value, ConstKind::Unevaluated, or ConstKind::Error here, found {:?}", + ct + ), + }, Const::Unevaluated(uv, _) => Some(uv), Const::Val(..) => None, }; @@ -364,10 +365,8 @@ where // check performed after the promotion. Verify that with an assertion. assert!(promoted.is_none() || Q::ALLOW_PROMOTED); - // Don't peak inside trait associated constants, also `#[type_const] const` items - // don't have bodies so there's nothing to look at - if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !cx.tcx.is_type_const(def) - { + // Don't peak inside trait associated constants. + if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() { let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 599f79d011989..f68f4e71520b3 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -527,6 +527,12 @@ LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) { *unwrap(C), CaptureInfo(CaptureComponents::Address | CaptureComponents::ReadProvenance))); } +#endif +#if LLVM_VERSION_GE(23, 0) + if (RustAttr == LLVMRustAttributeKind::DeadOnReturn) { + return wrap(Attribute::getWithDeadOnReturnInfo(*unwrap(C), + llvm::DeadOnReturnInfo())); + } #endif return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr))); } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ce17046969184..81d46e3b5b0d4 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1563,11 +1563,22 @@ impl<'v> RootCollector<'_, 'v> { // If we're collecting items eagerly, then recurse into all constants. // Otherwise the value is only collected when explicitly mentioned in other items. if self.strategy == MonoItemCollectionStrategy::Eager { - if !self.tcx.generics_of(id.owner_id).own_requires_monomorphization() - && let Ok(val) = self.tcx.const_eval_poly(id.owner_id.to_def_id()) - { - collect_const_value(self.tcx, val, self.output); + let def_id = id.owner_id.to_def_id(); + // Type Consts don't have bodies to evaluate + // nor do they make sense as a static. + if self.tcx.is_type_const(def_id) { + // FIXME(mgca): Is this actually what we want? We may want to + // normalize to a ValTree then convert to a const allocation and + // collect that? + return; + } + if self.tcx.generics_of(id.owner_id).own_requires_monomorphization() { + return; } + let Ok(val) = self.tcx.const_eval_poly(def_id) else { + return; + }; + collect_const_value(self.tcx, val, self.output); } } DefKind::Impl { of_trait: true } => { diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 64bdb8e85e03d..051dda731881f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -54,7 +54,7 @@ )] use crate::ffi::va_list::{VaArgSafe, VaList}; -use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; use crate::{mem, ptr}; mod bounds; @@ -483,11 +483,14 @@ pub const fn unlikely(b: bool) -> bool { #[rustc_nounwind] #[miri::intrinsic_fallback_is_spec] #[inline] -pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T -where - T: [const] Destruct, -{ - if b { true_val } else { false_val } +pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { + if b { + forget(false_val); + true_val + } else { + forget(true_val); + false_val + } } /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ed31d4efaa754..eb4f978b7c19d 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2103,10 +2103,7 @@ impl Option<&T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.map(T::clone) } } @@ -2154,10 +2151,7 @@ impl Option<&mut T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.as_deref().map(T::clone) } } diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index 87e21b21f310d..1fa425a1f6865 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -1,6 +1,7 @@ use std::num::FpCategory as Fp; use std::ops::{Add, Div, Mul, Rem, Sub}; +#[doc(hidden)] trait TestableFloat: Sized { /// Unsigned int with the same size, for converting to/from bits. type Int; @@ -8,13 +9,28 @@ trait TestableFloat: Sized { const APPROX: Self; /// Allow looser tolerance for f32 on miri const POWI_APPROX: Self = Self::APPROX; + /// Tolerance for `powf` tests; some types need looser bounds + const POWF_APPROX: Self = Self::APPROX; /// Allow looser tolerance for f16 const _180_TO_RADIANS_APPROX: Self = Self::APPROX; /// Allow for looser tolerance for f16 const PI_TO_DEGREES_APPROX: Self = Self::APPROX; + /// Tolerance for math tests + const EXP_APPROX: Self = Self::APPROX; + const LN_APPROX: Self = Self::APPROX; + const LOG_APPROX: Self = Self::APPROX; + const LOG2_APPROX: Self = Self::APPROX; + const LOG10_APPROX: Self = Self::APPROX; + const ASINH_APPROX: Self = Self::APPROX; + const ACOSH_APPROX: Self = Self::APPROX; + const ATANH_APPROX: Self = Self::APPROX; + const GAMMA_APPROX: Self = Self::APPROX; + const GAMMA_APPROX_LOOSE: Self = Self::APPROX; + const LNGAMMA_APPROX: Self = Self::APPROX; + const LNGAMMA_APPROX_LOOSE: Self = Self::APPROX; const ZERO: Self; const ONE: Self; - const PI: Self; + const MIN_POSITIVE_NORMAL: Self; const MAX_SUBNORMAL: Self; /// Smallest number @@ -45,11 +61,23 @@ trait TestableFloat: Sized { impl TestableFloat for f16 { type Int = u16; const APPROX: Self = 1e-3; + const POWF_APPROX: Self = 5e-1; const _180_TO_RADIANS_APPROX: Self = 1e-2; const PI_TO_DEGREES_APPROX: Self = 0.125; + const EXP_APPROX: Self = 1e-2; + const LN_APPROX: Self = 1e-2; + const LOG_APPROX: Self = 1e-2; + const LOG2_APPROX: Self = 1e-2; + const LOG10_APPROX: Self = 1e-2; + const ASINH_APPROX: Self = 1e-2; + const ACOSH_APPROX: Self = 1e-2; + const ATANH_APPROX: Self = 1e-2; + const GAMMA_APPROX: Self = 1e-2; + const GAMMA_APPROX_LOOSE: Self = 1e-1; + const LNGAMMA_APPROX: Self = 1e-2; + const LNGAMMA_APPROX_LOOSE: Self = 1e-1; const ZERO: Self = 0.0; const ONE: Self = 1.0; - const PI: Self = std::f16::consts::PI; const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); const TINY: Self = Self::from_bits(0x1); @@ -76,9 +104,21 @@ impl TestableFloat for f32 { /// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. /// They serve as a way to get an idea of the real precision of floating point operations on different platforms. const POWI_APPROX: Self = if cfg!(miri) { 1e-4 } else { Self::APPROX }; + const POWF_APPROX: Self = if cfg!(miri) { 1e-3 } else { 1e-4 }; + const EXP_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const LN_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const LOG_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const LOG2_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const LOG10_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const ASINH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const ACOSH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const ATANH_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const GAMMA_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const GAMMA_APPROX_LOOSE: Self = if cfg!(miri) { 1e-2 } else { 1e-4 }; + const LNGAMMA_APPROX: Self = if cfg!(miri) { 1e-3 } else { Self::APPROX }; + const LNGAMMA_APPROX_LOOSE: Self = if cfg!(miri) { 1e-2 } else { 1e-4 }; const ZERO: Self = 0.0; const ONE: Self = 1.0; - const PI: Self = std::f32::consts::PI; const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); const TINY: Self = Self::from_bits(0x1); @@ -101,9 +141,10 @@ impl TestableFloat for f32 { impl TestableFloat for f64 { type Int = u64; const APPROX: Self = 1e-6; + const GAMMA_APPROX_LOOSE: Self = 1e-4; + const LNGAMMA_APPROX_LOOSE: Self = 1e-4; const ZERO: Self = 0.0; const ONE: Self = 1.0; - const PI: Self = std::f64::consts::PI; const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); const TINY: Self = Self::from_bits(0x1); @@ -126,9 +167,20 @@ impl TestableFloat for f64 { impl TestableFloat for f128 { type Int = u128; const APPROX: Self = 1e-9; + const EXP_APPROX: Self = 1e-12; + const LN_APPROX: Self = 1e-12; + const LOG_APPROX: Self = 1e-12; + const LOG2_APPROX: Self = 1e-12; + const LOG10_APPROX: Self = 1e-12; + const ASINH_APPROX: Self = 1e-10; + const ACOSH_APPROX: Self = 1e-10; + const ATANH_APPROX: Self = 1e-10; + const GAMMA_APPROX: Self = 1e-12; + const GAMMA_APPROX_LOOSE: Self = 1e-10; + const LNGAMMA_APPROX: Self = 1e-12; + const LNGAMMA_APPROX_LOOSE: Self = 1e-10; const ZERO: Self = 0.0; const ONE: Self = 1.0; - const PI: Self = std::f128::consts::PI; const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); const TINY: Self = Self::from_bits(0x1); @@ -287,6 +339,8 @@ macro_rules! float_test { #[test] $( $( #[$f16_meta] )+ )? fn test_f16() { + #[allow(unused_imports)] + use core::f16::consts; type $fty = f16; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -296,6 +350,8 @@ macro_rules! float_test { #[test] $( $( #[$f32_meta] )+ )? fn test_f32() { + #[allow(unused_imports)] + use core::f32::consts; type $fty = f32; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -305,6 +361,8 @@ macro_rules! float_test { #[test] $( $( #[$f64_meta] )+ )? fn test_f64() { + #[allow(unused_imports)] + use core::f64::consts; type $fty = f64; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -314,6 +372,8 @@ macro_rules! float_test { #[test] $( $( #[$f128_meta] )+ )? fn test_f128() { + #[allow(unused_imports)] + use core::f128::consts; type $fty = f128; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -338,6 +398,8 @@ macro_rules! float_test { #[test] $( $( #[$f16_const_meta] )+ )? fn test_f16() { + #[allow(unused_imports)] + use core::f16::consts; type $fty = f16; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -347,6 +409,8 @@ macro_rules! float_test { #[test] $( $( #[$f32_const_meta] )+ )? fn test_f32() { + #[allow(unused_imports)] + use core::f32::consts; type $fty = f32; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -356,6 +420,8 @@ macro_rules! float_test { #[test] $( $( #[$f64_const_meta] )+ )? fn test_f64() { + #[allow(unused_imports)] + use core::f64::consts; type $fty = f64; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -365,6 +431,8 @@ macro_rules! float_test { #[test] $( $( #[$f128_const_meta] )+ )? fn test_f128() { + #[allow(unused_imports)] + use core::f128::consts; type $fty = f128; #[allow(unused)] const fn flt (x: $fty) -> $fty { x } @@ -631,25 +699,25 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((0.0 as Float).min(0.0), 0.0); - assert_biteq!((-0.0 as Float).min(-0.0), -0.0); - assert_biteq!((9.0 as Float).min(9.0), 9.0); - assert_biteq!((-9.0 as Float).min(0.0), -9.0); - assert_biteq!((0.0 as Float).min(9.0), 0.0); - assert_biteq!((-0.0 as Float).min(9.0), -0.0); - assert_biteq!((-0.0 as Float).min(-9.0), -9.0); + assert_biteq!(flt(0.0).min(0.0), 0.0); + assert_biteq!(flt(-0.0).min(-0.0), -0.0); + assert_biteq!(flt(9.0).min(9.0), 9.0); + assert_biteq!(flt(-9.0).min(0.0), -9.0); + assert_biteq!(flt(0.0).min(9.0), 0.0); + assert_biteq!(flt(-0.0).min(9.0), -0.0); + assert_biteq!(flt(-0.0).min(-9.0), -9.0); assert_biteq!(Float::INFINITY.min(9.0), 9.0); - assert_biteq!((9.0 as Float).min(Float::INFINITY), 9.0); + assert_biteq!(flt(9.0).min(Float::INFINITY), 9.0); assert_biteq!(Float::INFINITY.min(-9.0), -9.0); - assert_biteq!((-9.0 as Float).min(Float::INFINITY), -9.0); + assert_biteq!(flt(-9.0).min(Float::INFINITY), -9.0); assert_biteq!(Float::NEG_INFINITY.min(9.0), Float::NEG_INFINITY); - assert_biteq!((9.0 as Float).min(Float::NEG_INFINITY), Float::NEG_INFINITY); + assert_biteq!(flt(9.0).min(Float::NEG_INFINITY), Float::NEG_INFINITY); assert_biteq!(Float::NEG_INFINITY.min(-9.0), Float::NEG_INFINITY); - assert_biteq!((-9.0 as Float).min(Float::NEG_INFINITY), Float::NEG_INFINITY); + assert_biteq!(flt(-9.0).min(Float::NEG_INFINITY), Float::NEG_INFINITY); assert_biteq!(Float::NAN.min(9.0), 9.0); assert_biteq!(Float::NAN.min(-9.0), -9.0); - assert_biteq!((9.0 as Float).min(Float::NAN), 9.0); - assert_biteq!((-9.0 as Float).min(Float::NAN), -9.0); + assert_biteq!(flt(9.0).min(Float::NAN), 9.0); + assert_biteq!(flt(-9.0).min(Float::NAN), -9.0); assert!(Float::NAN.min(Float::NAN).is_nan()); } } @@ -661,26 +729,26 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((0.0 as Float).max(0.0), 0.0); - assert_biteq!((-0.0 as Float).max(-0.0), -0.0); - assert_biteq!((9.0 as Float).max(9.0), 9.0); - assert_biteq!((-9.0 as Float).max(0.0), 0.0); - assert_biteq!((-9.0 as Float).max(-0.0), -0.0); - assert_biteq!((0.0 as Float).max(9.0), 9.0); - assert_biteq!((0.0 as Float).max(-9.0), 0.0); - assert_biteq!((-0.0 as Float).max(-9.0), -0.0); + assert_biteq!(flt(0.0).max(0.0), 0.0); + assert_biteq!(flt(-0.0).max(-0.0), -0.0); + assert_biteq!(flt(9.0).max(9.0), 9.0); + assert_biteq!(flt(-9.0).max(0.0), 0.0); + assert_biteq!(flt(-9.0).max(-0.0), -0.0); + assert_biteq!(flt(0.0).max(9.0), 9.0); + assert_biteq!(flt(0.0).max(-9.0), 0.0); + assert_biteq!(flt(-0.0).max(-9.0), -0.0); assert_biteq!(Float::INFINITY.max(9.0), Float::INFINITY); - assert_biteq!((9.0 as Float).max(Float::INFINITY), Float::INFINITY); + assert_biteq!(flt(9.0).max(Float::INFINITY), Float::INFINITY); assert_biteq!(Float::INFINITY.max(-9.0), Float::INFINITY); - assert_biteq!((-9.0 as Float).max(Float::INFINITY), Float::INFINITY); + assert_biteq!(flt(-9.0).max(Float::INFINITY), Float::INFINITY); assert_biteq!(Float::NEG_INFINITY.max(9.0), 9.0); - assert_biteq!((9.0 as Float).max(Float::NEG_INFINITY), 9.0); + assert_biteq!(flt(9.0).max(Float::NEG_INFINITY), 9.0); assert_biteq!(Float::NEG_INFINITY.max(-9.0), -9.0); - assert_biteq!((-9.0 as Float).max(Float::NEG_INFINITY), -9.0); + assert_biteq!(flt(-9.0).max(Float::NEG_INFINITY), -9.0); assert_biteq!(Float::NAN.max(9.0), 9.0); assert_biteq!(Float::NAN.max(-9.0), -9.0); - assert_biteq!((9.0 as Float).max(Float::NAN), 9.0); - assert_biteq!((-9.0 as Float).max(Float::NAN), -9.0); + assert_biteq!(flt(9.0).max(Float::NAN), 9.0); + assert_biteq!(flt(-9.0).max(Float::NAN), -9.0); assert!(Float::NAN.max(Float::NAN).is_nan()); } } @@ -692,26 +760,26 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((0.0 as Float).minimum(0.0), 0.0); - assert_biteq!((-0.0 as Float).minimum(0.0), -0.0); - assert_biteq!((-0.0 as Float).minimum(-0.0), -0.0); - assert_biteq!((9.0 as Float).minimum(9.0), 9.0); - assert_biteq!((-9.0 as Float).minimum(0.0), -9.0); - assert_biteq!((0.0 as Float).minimum(9.0), 0.0); - assert_biteq!((-0.0 as Float).minimum(9.0), -0.0); - assert_biteq!((-0.0 as Float).minimum(-9.0), -9.0); + assert_biteq!(flt(0.0).minimum(0.0), 0.0); + assert_biteq!(flt(-0.0).minimum(0.0), -0.0); + assert_biteq!(flt(-0.0).minimum(-0.0), -0.0); + assert_biteq!(flt(9.0).minimum(9.0), 9.0); + assert_biteq!(flt(-9.0).minimum(0.0), -9.0); + assert_biteq!(flt(0.0).minimum(9.0), 0.0); + assert_biteq!(flt(-0.0).minimum(9.0), -0.0); + assert_biteq!(flt(-0.0).minimum(-9.0), -9.0); assert_biteq!(Float::INFINITY.minimum(9.0), 9.0); - assert_biteq!((9.0 as Float).minimum(Float::INFINITY), 9.0); + assert_biteq!(flt(9.0).minimum(Float::INFINITY), 9.0); assert_biteq!(Float::INFINITY.minimum(-9.0), -9.0); - assert_biteq!((-9.0 as Float).minimum(Float::INFINITY), -9.0); + assert_biteq!(flt(-9.0).minimum(Float::INFINITY), -9.0); assert_biteq!(Float::NEG_INFINITY.minimum(9.0), Float::NEG_INFINITY); - assert_biteq!((9.0 as Float).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY); + assert_biteq!(flt(9.0).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY); assert_biteq!(Float::NEG_INFINITY.minimum(-9.0), Float::NEG_INFINITY); - assert_biteq!((-9.0 as Float).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY); + assert_biteq!(flt(-9.0).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY); assert!(Float::NAN.minimum(9.0).is_nan()); assert!(Float::NAN.minimum(-9.0).is_nan()); - assert!((9.0 as Float).minimum(Float::NAN).is_nan()); - assert!((-9.0 as Float).minimum(Float::NAN).is_nan()); + assert!(flt(9.0).minimum(Float::NAN).is_nan()); + assert!(flt(-9.0).minimum(Float::NAN).is_nan()); assert!(Float::NAN.minimum(Float::NAN).is_nan()); } } @@ -723,27 +791,27 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((0.0 as Float).maximum(0.0), 0.0); - assert_biteq!((-0.0 as Float).maximum(0.0), 0.0); - assert_biteq!((-0.0 as Float).maximum(-0.0), -0.0); - assert_biteq!((9.0 as Float).maximum(9.0), 9.0); - assert_biteq!((-9.0 as Float).maximum(0.0), 0.0); - assert_biteq!((-9.0 as Float).maximum(-0.0), -0.0); - assert_biteq!((0.0 as Float).maximum(9.0), 9.0); - assert_biteq!((0.0 as Float).maximum(-9.0), 0.0); - assert_biteq!((-0.0 as Float).maximum(-9.0), -0.0); + assert_biteq!(flt(0.0).maximum(0.0), 0.0); + assert_biteq!(flt(-0.0).maximum(0.0), 0.0); + assert_biteq!(flt(-0.0).maximum(-0.0), -0.0); + assert_biteq!(flt(9.0).maximum(9.0), 9.0); + assert_biteq!(flt(-9.0).maximum(0.0), 0.0); + assert_biteq!(flt(-9.0).maximum(-0.0), -0.0); + assert_biteq!(flt(0.0).maximum(9.0), 9.0); + assert_biteq!(flt(0.0).maximum(-9.0), 0.0); + assert_biteq!(flt(-0.0).maximum(-9.0), -0.0); assert_biteq!(Float::INFINITY.maximum(9.0), Float::INFINITY); - assert_biteq!((9.0 as Float).maximum(Float::INFINITY), Float::INFINITY); + assert_biteq!(flt(9.0).maximum(Float::INFINITY), Float::INFINITY); assert_biteq!(Float::INFINITY.maximum(-9.0), Float::INFINITY); - assert_biteq!((-9.0 as Float).maximum(Float::INFINITY), Float::INFINITY); + assert_biteq!(flt(-9.0).maximum(Float::INFINITY), Float::INFINITY); assert_biteq!(Float::NEG_INFINITY.maximum(9.0), 9.0); - assert_biteq!((9.0 as Float).maximum(Float::NEG_INFINITY), 9.0); + assert_biteq!(flt(9.0).maximum(Float::NEG_INFINITY), 9.0); assert_biteq!(Float::NEG_INFINITY.maximum(-9.0), -9.0); - assert_biteq!((-9.0 as Float).maximum(Float::NEG_INFINITY), -9.0); + assert_biteq!(flt(-9.0).maximum(Float::NEG_INFINITY), -9.0); assert!(Float::NAN.maximum(9.0).is_nan()); assert!(Float::NAN.maximum(-9.0).is_nan()); - assert!((9.0 as Float).maximum(Float::NAN).is_nan()); - assert!((-9.0 as Float).maximum(Float::NAN).is_nan()); + assert!(flt(9.0).maximum(Float::NAN).is_nan()); + assert!(flt(-9.0).maximum(Float::NAN).is_nan()); assert!(Float::NAN.maximum(Float::NAN).is_nan()); } } @@ -755,15 +823,15 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((0.5 as Float).midpoint(0.5), 0.5); - assert_biteq!((0.5 as Float).midpoint(2.5), 1.5); - assert_biteq!((3.0 as Float).midpoint(4.0), 3.5); - assert_biteq!((-3.0 as Float).midpoint(4.0), 0.5); - assert_biteq!((3.0 as Float).midpoint(-4.0), -0.5); - assert_biteq!((-3.0 as Float).midpoint(-4.0), -3.5); - assert_biteq!((0.0 as Float).midpoint(0.0), 0.0); - assert_biteq!((-0.0 as Float).midpoint(-0.0), -0.0); - assert_biteq!((-5.0 as Float).midpoint(5.0), 0.0); + assert_biteq!(flt(0.5).midpoint(0.5), 0.5); + assert_biteq!(flt(0.5).midpoint(2.5), 1.5); + assert_biteq!(flt(3.0).midpoint(4.0), 3.5); + assert_biteq!(flt(-3.0).midpoint(4.0), 0.5); + assert_biteq!(flt(3.0).midpoint(-4.0), -0.5); + assert_biteq!(flt(-3.0).midpoint(-4.0), -3.5); + assert_biteq!(flt(0.0).midpoint(0.0), 0.0); + assert_biteq!(flt(-0.0).midpoint(-0.0), -0.0); + assert_biteq!(flt(-5.0).midpoint(5.0), 0.0); assert_biteq!(Float::MAX.midpoint(Float::MIN), 0.0); assert_biteq!(Float::MIN.midpoint(Float::MAX), 0.0); assert_biteq!(Float::MAX.midpoint(Float::MIN_POSITIVE), Float::MAX / 2.); @@ -793,7 +861,7 @@ float_test! { assert!(Float::NEG_INFINITY.midpoint(Float::INFINITY).is_nan()); assert!(Float::INFINITY.midpoint(Float::NEG_INFINITY).is_nan()); assert!(Float::NAN.midpoint(1.0).is_nan()); - assert!((1.0 as Float).midpoint(Float::NAN).is_nan()); + assert!(flt(1.0).midpoint(Float::NAN).is_nan()); assert!(Float::NAN.midpoint(Float::NAN).is_nan()); } } @@ -815,10 +883,10 @@ float_test! { // be safely doubled, while j is significantly smaller. for i in Float::MAX_EXP.saturating_sub(64)..Float::MAX_EXP { for j in 0..64u8 { - let large = (2.0 as Float).powi(i); + let large = flt(2.0).powi(i); // a much smaller number, such that there is no chance of overflow to test // potential double rounding in midpoint's implementation. - let small = (2.0 as Float).powi(Float::MAX_EXP - 1) + let small = flt(2.0).powi(Float::MAX_EXP - 1) * Float::EPSILON * Float::from(j); @@ -856,8 +924,8 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((1.0 as Float).copysign(-2.0), -1.0); - assert_biteq!((-1.0 as Float).copysign(2.0), 1.0); + assert_biteq!(flt(1.0).copysign(-2.0), -1.0); + assert_biteq!(flt(-1.0).copysign(2.0), 1.0); assert_biteq!(Float::INFINITY.copysign(-0.0), Float::NEG_INFINITY); assert_biteq!(Float::NEG_INFINITY.copysign(0.0), Float::INFINITY); } @@ -871,9 +939,9 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert!(Float::INFINITY.rem_euclid(42.0 as Float).is_nan()); - assert_biteq!((42.0 as Float).rem_euclid(Float::INFINITY), 42.0 as Float); - assert!((42.0 as Float).rem_euclid(Float::NAN).is_nan()); + assert!(Float::INFINITY.rem_euclid(42.0).is_nan()); + assert_biteq!(flt(42.0).rem_euclid(Float::INFINITY), 42.0); + assert!(flt(42.0).rem_euclid(Float::NAN).is_nan()); assert!(Float::INFINITY.rem_euclid(Float::INFINITY).is_nan()); assert!(Float::INFINITY.rem_euclid(Float::NAN).is_nan()); assert!(Float::NAN.rem_euclid(Float::INFINITY).is_nan()); @@ -888,8 +956,8 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((42.0 as Float).div_euclid(Float::INFINITY), 0.0); - assert!((42.0 as Float).div_euclid(Float::NAN).is_nan()); + assert_biteq!(flt(42.0).div_euclid(Float::INFINITY), 0.0); + assert!(flt(42.0).div_euclid(Float::NAN).is_nan()); assert!(Float::INFINITY.div_euclid(Float::INFINITY).is_nan()); assert!(Float::INFINITY.div_euclid(Float::NAN).is_nan()); assert!(Float::NAN.div_euclid(Float::INFINITY).is_nan()); @@ -903,18 +971,18 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((1.0 as Float).floor(), 1.0); - assert_biteq!((1.3 as Float).floor(), 1.0); - assert_biteq!((1.5 as Float).floor(), 1.0); - assert_biteq!((1.7 as Float).floor(), 1.0); - assert_biteq!((0.5 as Float).floor(), 0.0); - assert_biteq!((0.0 as Float).floor(), 0.0); - assert_biteq!((-0.0 as Float).floor(), -0.0); - assert_biteq!((-0.5 as Float).floor(), -1.0); - assert_biteq!((-1.0 as Float).floor(), -1.0); - assert_biteq!((-1.3 as Float).floor(), -2.0); - assert_biteq!((-1.5 as Float).floor(), -2.0); - assert_biteq!((-1.7 as Float).floor(), -2.0); + assert_biteq!(flt(1.0).floor(), 1.0); + assert_biteq!(flt(1.3).floor(), 1.0); + assert_biteq!(flt(1.5).floor(), 1.0); + assert_biteq!(flt(1.7).floor(), 1.0); + assert_biteq!(flt(0.5).floor(), 0.0); + assert_biteq!(flt(0.0).floor(), 0.0); + assert_biteq!(flt(-0.0).floor(), -0.0); + assert_biteq!(flt(-0.5).floor(), -1.0); + assert_biteq!(flt(-1.0).floor(), -1.0); + assert_biteq!(flt(-1.3).floor(), -2.0); + assert_biteq!(flt(-1.5).floor(), -2.0); + assert_biteq!(flt(-1.7).floor(), -2.0); assert_biteq!(Float::MAX.floor(), Float::MAX); assert_biteq!(Float::MIN.floor(), Float::MIN); assert_biteq!(Float::MIN_POSITIVE.floor(), 0.0); @@ -932,18 +1000,18 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((1.0 as Float).ceil(), 1.0); - assert_biteq!((1.3 as Float).ceil(), 2.0); - assert_biteq!((1.5 as Float).ceil(), 2.0); - assert_biteq!((1.7 as Float).ceil(), 2.0); - assert_biteq!((0.5 as Float).ceil(), 1.0); - assert_biteq!((0.0 as Float).ceil(), 0.0); - assert_biteq!((-0.0 as Float).ceil(), -0.0); - assert_biteq!((-0.5 as Float).ceil(), -0.0); - assert_biteq!((-1.0 as Float).ceil(), -1.0); - assert_biteq!((-1.3 as Float).ceil(), -1.0); - assert_biteq!((-1.5 as Float).ceil(), -1.0); - assert_biteq!((-1.7 as Float).ceil(), -1.0); + assert_biteq!(flt(1.0).ceil(), 1.0); + assert_biteq!(flt(1.3).ceil(), 2.0); + assert_biteq!(flt(1.5).ceil(), 2.0); + assert_biteq!(flt(1.7).ceil(), 2.0); + assert_biteq!(flt(0.5).ceil(), 1.0); + assert_biteq!(flt(0.0).ceil(), 0.0); + assert_biteq!(flt(-0.0).ceil(), -0.0); + assert_biteq!(flt(-0.5).ceil(), -0.0); + assert_biteq!(flt(-1.0).ceil(), -1.0); + assert_biteq!(flt(-1.3).ceil(), -1.0); + assert_biteq!(flt(-1.5).ceil(), -1.0); + assert_biteq!(flt(-1.7).ceil(), -1.0); assert_biteq!(Float::MAX.ceil(), Float::MAX); assert_biteq!(Float::MIN.ceil(), Float::MIN); assert_biteq!(Float::MIN_POSITIVE.ceil(), 1.0); @@ -961,19 +1029,19 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((2.5 as Float).round(), 3.0); - assert_biteq!((1.0 as Float).round(), 1.0); - assert_biteq!((1.3 as Float).round(), 1.0); - assert_biteq!((1.5 as Float).round(), 2.0); - assert_biteq!((1.7 as Float).round(), 2.0); - assert_biteq!((0.5 as Float).round(), 1.0); - assert_biteq!((0.0 as Float).round(), 0.0); - assert_biteq!((-0.0 as Float).round(), -0.0); - assert_biteq!((-0.5 as Float).round(), -1.0); - assert_biteq!((-1.0 as Float).round(), -1.0); - assert_biteq!((-1.3 as Float).round(), -1.0); - assert_biteq!((-1.5 as Float).round(), -2.0); - assert_biteq!((-1.7 as Float).round(), -2.0); + assert_biteq!(flt(2.5).round(), 3.0); + assert_biteq!(flt(1.0).round(), 1.0); + assert_biteq!(flt(1.3).round(), 1.0); + assert_biteq!(flt(1.5).round(), 2.0); + assert_biteq!(flt(1.7).round(), 2.0); + assert_biteq!(flt(0.5).round(), 1.0); + assert_biteq!(flt(0.0).round(), 0.0); + assert_biteq!(flt(-0.0).round(), -0.0); + assert_biteq!(flt(-0.5).round(), -1.0); + assert_biteq!(flt(-1.0).round(), -1.0); + assert_biteq!(flt(-1.3).round(), -1.0); + assert_biteq!(flt(-1.5).round(), -2.0); + assert_biteq!(flt(-1.7).round(), -2.0); assert_biteq!(Float::MAX.round(), Float::MAX); assert_biteq!(Float::MIN.round(), Float::MIN); assert_biteq!(Float::MIN_POSITIVE.round(), 0.0); @@ -991,19 +1059,19 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((2.5 as Float).round_ties_even(), 2.0); - assert_biteq!((1.0 as Float).round_ties_even(), 1.0); - assert_biteq!((1.3 as Float).round_ties_even(), 1.0); - assert_biteq!((1.5 as Float).round_ties_even(), 2.0); - assert_biteq!((1.7 as Float).round_ties_even(), 2.0); - assert_biteq!((0.5 as Float).round_ties_even(), 0.0); - assert_biteq!((0.0 as Float).round_ties_even(), 0.0); - assert_biteq!((-0.0 as Float).round_ties_even(), -0.0); - assert_biteq!((-0.5 as Float).round_ties_even(), -0.0); - assert_biteq!((-1.0 as Float).round_ties_even(), -1.0); - assert_biteq!((-1.3 as Float).round_ties_even(), -1.0); - assert_biteq!((-1.5 as Float).round_ties_even(), -2.0); - assert_biteq!((-1.7 as Float).round_ties_even(), -2.0); + assert_biteq!(flt(2.5).round_ties_even(), 2.0); + assert_biteq!(flt(1.0).round_ties_even(), 1.0); + assert_biteq!(flt(1.3).round_ties_even(), 1.0); + assert_biteq!(flt(1.5).round_ties_even(), 2.0); + assert_biteq!(flt(1.7).round_ties_even(), 2.0); + assert_biteq!(flt(0.5).round_ties_even(), 0.0); + assert_biteq!(flt(0.0).round_ties_even(), 0.0); + assert_biteq!(flt(-0.0).round_ties_even(), -0.0); + assert_biteq!(flt(-0.5).round_ties_even(), -0.0); + assert_biteq!(flt(-1.0).round_ties_even(), -1.0); + assert_biteq!(flt(-1.3).round_ties_even(), -1.0); + assert_biteq!(flt(-1.5).round_ties_even(), -2.0); + assert_biteq!(flt(-1.7).round_ties_even(), -2.0); assert_biteq!(Float::MAX.round_ties_even(), Float::MAX); assert_biteq!(Float::MIN.round_ties_even(), Float::MIN); assert_biteq!(Float::MIN_POSITIVE.round_ties_even(), 0.0); @@ -1021,18 +1089,18 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((1.0 as Float).trunc(), 1.0); - assert_biteq!((1.3 as Float).trunc(), 1.0); - assert_biteq!((1.5 as Float).trunc(), 1.0); - assert_biteq!((1.7 as Float).trunc(), 1.0); - assert_biteq!((0.5 as Float).trunc(), 0.0); - assert_biteq!((0.0 as Float).trunc(), 0.0); - assert_biteq!((-0.0 as Float).trunc(), -0.0); - assert_biteq!((-0.5 as Float).trunc(), -0.0); - assert_biteq!((-1.0 as Float).trunc(), -1.0); - assert_biteq!((-1.3 as Float).trunc(), -1.0); - assert_biteq!((-1.5 as Float).trunc(), -1.0); - assert_biteq!((-1.7 as Float).trunc(), -1.0); + assert_biteq!(flt(1.0).trunc(), 1.0); + assert_biteq!(flt(1.3).trunc(), 1.0); + assert_biteq!(flt(1.5).trunc(), 1.0); + assert_biteq!(flt(1.7).trunc(), 1.0); + assert_biteq!(flt(0.5).trunc(), 0.0); + assert_biteq!(flt(0.0).trunc(), 0.0); + assert_biteq!(flt(-0.0).trunc(), -0.0); + assert_biteq!(flt(-0.5).trunc(), -0.0); + assert_biteq!(flt(-1.0).trunc(), -1.0); + assert_biteq!(flt(-1.3).trunc(), -1.0); + assert_biteq!(flt(-1.5).trunc(), -1.0); + assert_biteq!(flt(-1.7).trunc(), -1.0); assert_biteq!(Float::MAX.trunc(), Float::MAX); assert_biteq!(Float::MIN.trunc(), Float::MIN); assert_biteq!(Float::MIN_POSITIVE.trunc(), 0.0); @@ -1050,18 +1118,18 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - assert_biteq!((1.0 as Float).fract(), 0.0); - assert_approx_eq!((1.3 as Float).fract(), 0.3); // rounding differs between float types - assert_biteq!((1.5 as Float).fract(), 0.5); - assert_approx_eq!((1.7 as Float).fract(), 0.7); - assert_biteq!((0.5 as Float).fract(), 0.5); - assert_biteq!((0.0 as Float).fract(), 0.0); - assert_biteq!((-0.0 as Float).fract(), 0.0); - assert_biteq!((-0.5 as Float).fract(), -0.5); - assert_biteq!((-1.0 as Float).fract(), 0.0); - assert_approx_eq!((-1.3 as Float).fract(), -0.3); // rounding differs between float types - assert_biteq!((-1.5 as Float).fract(), -0.5); - assert_approx_eq!((-1.7 as Float).fract(), -0.7); + assert_biteq!(flt(1.0).fract(), 0.0); + assert_approx_eq!(flt(1.3).fract(), 0.3); // rounding differs between float types + assert_biteq!(flt(1.5).fract(), 0.5); + assert_approx_eq!(flt(1.7).fract(), 0.7); + assert_biteq!(flt(0.5).fract(), 0.5); + assert_biteq!(flt(0.0).fract(), 0.0); + assert_biteq!(flt(-0.0).fract(), 0.0); + assert_biteq!(flt(-0.5).fract(), -0.5); + assert_biteq!(flt(-1.0).fract(), 0.0); + assert_approx_eq!(flt(-1.3).fract(), -0.3); // rounding differs between float types + assert_biteq!(flt(-1.5).fract(), -0.5); + assert_approx_eq!(flt(-1.7).fract(), -0.7); assert_biteq!(Float::MAX.fract(), 0.0); assert_biteq!(Float::MIN.fract(), 0.0); assert_biteq!(Float::MIN_POSITIVE.fract(), Float::MIN_POSITIVE); @@ -1429,10 +1497,10 @@ float_test! { let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; let max: Float = Float::MAX; - assert_biteq!((1.0 as Float).recip(), 1.0); - assert_biteq!((2.0 as Float).recip(), 0.5); - assert_biteq!((-0.4 as Float).recip(), -2.5); - assert_biteq!((0.0 as Float).recip(), inf); + assert_biteq!(flt(1.0).recip(), 1.0); + assert_biteq!(flt(2.0).recip(), 0.5); + assert_biteq!(flt(-0.4).recip(), -2.5); + assert_biteq!(flt(0.0).recip(), inf); assert!(nan.recip().is_nan()); assert_biteq!(inf.recip(), 0.0); assert_biteq!(neg_inf.recip(), -0.0); @@ -1453,51 +1521,338 @@ float_test! { let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; assert_approx_eq!(Float::ONE.powi(1), Float::ONE); - assert_approx_eq!((-3.1 as Float).powi(2), 9.6100000000000005506706202140776519387, Float::POWI_APPROX); - assert_approx_eq!((5.9 as Float).powi(-2), 0.028727377190462507313100483690639638451); - assert_biteq!((8.3 as Float).powi(0), Float::ONE); + assert_approx_eq!(flt(-3.1).powi(2), 9.6100000000000005506706202140776519387, Float::POWI_APPROX); + assert_approx_eq!(flt(5.9).powi(-2), 0.028727377190462507313100483690639638451); + assert_biteq!(flt(8.3).powi(0), Float::ONE); assert!(nan.powi(2).is_nan()); assert_biteq!(inf.powi(3), inf); assert_biteq!(neg_inf.powi(2), inf); } } +float_test! { + name: powf, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_biteq!(flt(1.0).powf(1.0), 1.0); + assert_approx_eq!(flt(3.4).powf(4.5), 246.40818323761892815995637964326426756, Float::POWF_APPROX); + assert_approx_eq!(flt(2.7).powf(-3.2), 0.041652009108526178281070304373500889273, Float::POWF_APPROX); + assert_approx_eq!(flt(-3.1).powf(2.0), 9.6100000000000005506706202140776519387, Float::POWF_APPROX); + assert_approx_eq!(flt(5.9).powf(-2.0), 0.028727377190462507313100483690639638451, Float::POWF_APPROX); + assert_biteq!(flt(8.3).powf(0.0), 1.0); + assert!(nan.powf(2.0).is_nan()); + assert_biteq!(inf.powf(2.0), inf); + assert_biteq!(neg_inf.powf(3.0), neg_inf); + } +} + +float_test! { + name: exp, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_biteq!(1.0, flt(0.0).exp()); + assert_approx_eq!(consts::E, flt(1.0).exp(), Float::EXP_APPROX); + assert_approx_eq!(148.41315910257660342111558004055227962348775, flt(5.0).exp(), Float::EXP_APPROX); + + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let nan: Float = Float::NAN; + assert_biteq!(inf, inf.exp()); + assert_biteq!(0.0, neg_inf.exp()); + assert!(nan.exp().is_nan()); + } +} + +float_test! { + name: exp2, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_biteq!(32.0, flt(5.0).exp2()); + assert_biteq!(1.0, flt(0.0).exp2()); + + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let nan: Float = Float::NAN; + assert_biteq!(inf, inf.exp2()); + assert_biteq!(0.0, neg_inf.exp2()); + assert!(nan.exp2().is_nan()); + } +} + +float_test! { + name: ln, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_approx_eq!(flt(1.0).exp().ln(), 1.0, Float::LN_APPROX); + assert!(nan.ln().is_nan()); + assert_biteq!(inf.ln(), inf); + assert!(neg_inf.ln().is_nan()); + assert!(flt(-2.3).ln().is_nan()); + assert_biteq!(flt(-0.0).ln(), neg_inf); + assert_biteq!(flt(0.0).ln(), neg_inf); + assert_approx_eq!(flt(4.0).ln(), 1.3862943611198906188344642429163531366, Float::LN_APPROX); + } +} + +float_test! { + name: log, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_biteq!(flt(10.0).log(10.0), 1.0); + assert_approx_eq!(flt(2.3).log(3.5), 0.66485771361478710036766645911922010272, Float::LOG_APPROX); + assert_approx_eq!(flt(1.0).exp().log(flt(1.0).exp()), 1.0, Float::LOG_APPROX); + assert!(flt(1.0).log(1.0).is_nan()); + assert!(flt(1.0).log(-13.9).is_nan()); + assert!(nan.log(2.3).is_nan()); + assert_biteq!(inf.log(10.0), inf); + assert!(neg_inf.log(8.8).is_nan()); + assert!(flt(-2.3).log(0.1).is_nan()); + assert_biteq!(flt(-0.0).log(2.0), neg_inf); + assert_biteq!(flt(0.0).log(7.0), neg_inf); + } +} + +float_test! { + name: log2, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_approx_eq!(flt(10.0).log2(), 3.32192809488736234787031942948939017, Float::LOG2_APPROX); + assert_approx_eq!(flt(2.3).log2(), 1.2016338611696504130002982471978765921, Float::LOG2_APPROX); + assert_approx_eq!(flt(1.0).exp().log2(), 1.4426950408889634073599246810018921381, Float::LOG2_APPROX); + assert!(nan.log2().is_nan()); + assert_biteq!(inf.log2(), inf); + assert!(neg_inf.log2().is_nan()); + assert!(flt(-2.3).log2().is_nan()); + assert_biteq!(flt(-0.0).log2(), neg_inf); + assert_biteq!(flt(0.0).log2(), neg_inf); + } +} + +float_test! { + name: log10, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_biteq!(flt(10.0).log10(), 1.0); + assert_approx_eq!(flt(2.3).log10(), 0.36172783601759284532595218865859309898, Float::LOG10_APPROX); + assert_approx_eq!(flt(1.0).exp().log10(), 0.43429448190325182765112891891660508222, Float::LOG10_APPROX); + assert_biteq!(flt(1.0).log10(), 0.0); + assert!(nan.log10().is_nan()); + assert_biteq!(inf.log10(), inf); + assert!(neg_inf.log10().is_nan()); + assert!(flt(-2.3).log10().is_nan()); + assert_biteq!(flt(-0.0).log10(), neg_inf); + assert_biteq!(flt(0.0).log10(), neg_inf); + } +} + +float_test! { + name: asinh, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_biteq!(flt(0.0).asinh(), 0.0); + assert_biteq!(flt(-0.0).asinh(), -0.0); + + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let nan: Float = Float::NAN; + assert_biteq!(inf.asinh(), inf); + assert_biteq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_nan()); + assert!(flt(-0.0).asinh().is_sign_negative()); + + // issue 63271 + assert_approx_eq!(flt(2.0).asinh(), 1.443635475178810342493276740273105, Float::ASINH_APPROX); + assert_approx_eq!(flt(-2.0).asinh(), -1.443635475178810342493276740273105, Float::ASINH_APPROX); + + assert_approx_eq!(flt(-200.0).asinh(), -5.991470797049389, Float::ASINH_APPROX); + if Float::MAX > flt(66000.0) { + // regression test for the catastrophic cancellation fixed in 72486 + assert_approx_eq!(flt(-67452098.07139316).asinh(), -18.720075426274544393985484294000831757220, Float::ASINH_APPROX); + } + } +} + +float_test! { + name: acosh, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_biteq!(flt(1.0).acosh(), 0.0); + assert!(flt(0.999).acosh().is_nan()); + + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let nan: Float = Float::NAN; + assert_biteq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_nan()); + assert!(nan.acosh().is_nan()); + assert_approx_eq!(flt(2.0).acosh(), 1.31695789692481670862504634730796844, Float::ACOSH_APPROX); + assert_approx_eq!(flt(3.0).acosh(), 1.76274717403908605046521864995958461, Float::ACOSH_APPROX); + + if Float::MAX > flt(66000.0) { + // test for low accuracy from issue 104548 + assert_approx_eq!(flt(60.0), flt(60.0).cosh().acosh(), Float::ACOSH_APPROX); + } + } +} + +float_test! { + name: atanh, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_biteq!(flt(0.0).atanh(), 0.0); + assert_biteq!(flt(-0.0).atanh(), -0.0); + + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + assert_biteq!(flt(1.0).atanh(), inf); + assert_biteq!(flt(-1.0).atanh(), neg_inf); + + let nan: Float = Float::NAN; + assert!(inf.atanh().is_nan()); + assert!(neg_inf.atanh().is_nan()); + assert!(nan.atanh().is_nan()); + + assert_approx_eq!(flt(0.5).atanh(), 0.54930614433405484569762261846126285, Float::ATANH_APPROX); + assert_approx_eq!(flt(-0.5).atanh(), -0.54930614433405484569762261846126285, Float::ATANH_APPROX); + } +} + +float_test! { + name: gamma, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_approx_eq!(flt(1.0).gamma(), 1.0, Float::GAMMA_APPROX); + assert_approx_eq!(flt(2.0).gamma(), 1.0, Float::GAMMA_APPROX); + assert_approx_eq!(flt(3.0).gamma(), 2.0, Float::GAMMA_APPROX); + assert_approx_eq!(flt(4.0).gamma(), 6.0, Float::GAMMA_APPROX); + assert_approx_eq!(flt(5.0).gamma(), 24.0, Float::GAMMA_APPROX_LOOSE); + assert_approx_eq!(flt(0.5).gamma(), consts::PI.sqrt(), Float::GAMMA_APPROX); + assert_approx_eq!(flt(-0.5).gamma(), flt(-2.0) * consts::PI.sqrt(), Float::GAMMA_APPROX_LOOSE); + assert_biteq!(flt(0.0).gamma(), Float::INFINITY); + assert_biteq!(flt(-0.0).gamma(), Float::NEG_INFINITY); + assert!(flt(-1.0).gamma().is_nan()); + assert!(flt(-2.0).gamma().is_nan()); + assert!(Float::NAN.gamma().is_nan()); + assert!(Float::NEG_INFINITY.gamma().is_nan()); + assert_biteq!(Float::INFINITY.gamma(), Float::INFINITY); + assert_biteq!(flt(1760.9).gamma(), Float::INFINITY); + } +} + +float_test! { + name: ln_gamma, + attrs: { + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + assert_approx_eq!(flt(1.0).ln_gamma().0, 0.0, Float::LNGAMMA_APPROX); + assert_eq!(flt(1.0).ln_gamma().1, 1); + assert_approx_eq!(flt(2.0).ln_gamma().0, 0.0, Float::LNGAMMA_APPROX); + assert_eq!(flt(2.0).ln_gamma().1, 1); + assert_approx_eq!(flt(3.0).ln_gamma().0, flt(2.0).ln(), Float::LNGAMMA_APPROX); + assert_eq!(flt(3.0).ln_gamma().1, 1); + assert_approx_eq!(flt(-0.5).ln_gamma().0, (flt(2.0) * consts::PI.sqrt()).ln(), Float::LNGAMMA_APPROX_LOOSE); + assert_eq!(flt(-0.5).ln_gamma().1, -1); + } +} + float_test! { name: to_degrees, attrs: { - f16: #[cfg(any(miri, target_has_reliable_f16))], - f128: #[cfg(any(miri, target_has_reliable_f128))], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - let pi: Float = Float::PI; + let pi: Float = consts::PI; let nan: Float = Float::NAN; let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; - assert_biteq!((0.0 as Float).to_degrees(), 0.0); - assert_approx_eq!((-5.8 as Float).to_degrees(), -332.31552117587745090765431723855668471); + assert_biteq!(flt(0.0).to_degrees(), 0.0); + assert_approx_eq!(flt(-5.8).to_degrees(), -332.31552117587745090765431723855668471); assert_approx_eq!(pi.to_degrees(), 180.0, Float::PI_TO_DEGREES_APPROX); assert!(nan.to_degrees().is_nan()); assert_biteq!(inf.to_degrees(), inf); assert_biteq!(neg_inf.to_degrees(), neg_inf); - assert_biteq!((1.0 as Float).to_degrees(), 57.2957795130823208767981548141051703); + assert_biteq!(flt(1.0).to_degrees(), 57.2957795130823208767981548141051703); } } float_test! { name: to_radians, attrs: { - f16: #[cfg(any(miri, target_has_reliable_f16))], - f128: #[cfg(any(miri, target_has_reliable_f128))], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(any(miri, target_has_reliable_f128_math))], }, test { - let pi: Float = Float::PI; + let pi: Float = consts::PI; let nan: Float = Float::NAN; let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; - assert_biteq!((0.0 as Float).to_radians(), 0.0); - assert_approx_eq!((154.6 as Float).to_radians(), 2.6982790235832334267135442069489767804); - assert_approx_eq!((-332.31 as Float).to_radians(), -5.7999036373023566567593094812182763013); - assert_approx_eq!((180.0 as Float).to_radians(), pi, Float::_180_TO_RADIANS_APPROX); + assert_biteq!(flt(0.0).to_radians(), 0.0); + assert_approx_eq!(flt(154.6).to_radians(), 2.6982790235832334267135442069489767804); + assert_approx_eq!(flt(-332.31).to_radians(), -5.7999036373023566567593094812182763013); + assert_approx_eq!(flt(180.0).to_radians(), pi, Float::_180_TO_RADIANS_APPROX); assert!(nan.to_radians().is_nan()); assert_biteq!(inf.to_radians(), inf); assert_biteq!(neg_inf.to_radians(), neg_inf); @@ -1511,8 +1866,8 @@ float_test! { f128: #[cfg(any(miri, target_has_reliable_f128))], }, test { - let a: Float = 123.0; - let b: Float = 456.0; + let a: Float = flt(123.0); + let b: Float = flt(456.0); // Check that individual operations match their primitive counterparts. // @@ -1568,8 +1923,8 @@ float_test! { let nan: Float = Float::NAN; let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; - assert_biteq!(flt(12.3).mul_add(4.5, 6.7), Float::MUL_ADD_RESULT); - assert_biteq!((flt(-12.3)).mul_add(-4.5, -6.7), Float::NEG_MUL_ADD_RESULT); + assert_biteq!(flt(12.3).mul_add(flt(4.5), flt(6.7)), Float::MUL_ADD_RESULT); + assert_biteq!((flt(-12.3)).mul_add(flt(-4.5), flt(-6.7)), Float::NEG_MUL_ADD_RESULT); assert_biteq!(flt(0.0).mul_add(8.9, 1.2), 1.2); assert_biteq!(flt(3.4).mul_add(-0.0, 5.6), 5.6); assert!(nan.mul_add(7.8, 9.0).is_nan()); @@ -1654,3 +2009,30 @@ float_test! { // assert_biteq!(Float::from(i64::MAX), 9223372036854775807.0); // } // } + +float_test! { + name: real_consts, + attrs: { + // FIXME(f16_f128): add math tests when available + const: #[cfg(false)], + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { + let pi: Float = consts::PI; + assert_approx_eq!(consts::FRAC_PI_2, pi / 2.0); + assert_approx_eq!(consts::FRAC_PI_3, pi / 3.0, Float::APPROX); + assert_approx_eq!(consts::FRAC_PI_4, pi / 4.0); + assert_approx_eq!(consts::FRAC_PI_6, pi / 6.0); + assert_approx_eq!(consts::FRAC_PI_8, pi / 8.0); + assert_approx_eq!(consts::FRAC_1_PI, 1.0 / pi); + assert_approx_eq!(consts::FRAC_2_PI, 2.0 / pi); + assert_approx_eq!(consts::FRAC_2_SQRT_PI, 2.0 / pi.sqrt()); + assert_approx_eq!(consts::SQRT_2, flt(2.0).sqrt()); + assert_approx_eq!(consts::FRAC_1_SQRT_2, 1.0 / flt(2.0).sqrt()); + assert_approx_eq!(consts::LOG2_E, consts::E.log2()); + assert_approx_eq!(consts::LOG10_E, consts::E.log10()); + assert_approx_eq!(consts::LN_2, flt(2.0).ln()); + assert_approx_eq!(consts::LN_10, flt(10.0).ln(), Float::APPROX); + } +} diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 5c9ae52d9e6c0..d5a84fa76f1f1 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -147,10 +147,6 @@ harness = false name = "sync" path = "tests/sync/lib.rs" -[[test]] -name = "floats" -path = "tests/floats/lib.rs" - [[test]] name = "thread_local" path = "tests/thread_local/lib.rs" diff --git a/library/std/tests/floats/f128.rs b/library/std/tests/floats/f128.rs deleted file mode 100644 index e7c90faa05c23..0000000000000 --- a/library/std/tests/floats/f128.rs +++ /dev/null @@ -1,321 +0,0 @@ -// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy -#![cfg(target_has_reliable_f128)] - -use std::f128::consts; -use std::ops::{Add, Div, Mul, Sub}; - -// Note these tolerances make sense around zero, but not for more extreme exponents. - -/// Default tolerances. Works for values that should be near precise but not exact. Roughly -/// the precision carried by `100 * 100`. -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -const TOL: f128 = 1e-12; - -/// For operations that are near exact, usually not involving math of different -/// signs. -const TOL_PRECISE: f128 = 1e-28; - -/// Tolerances for math that is allowed to be imprecise, usually due to multiple chained -/// operations. -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -const TOL_IMPR: f128 = 1e-10; - -/// Compare by representation -#[allow(unused_macros)] -macro_rules! assert_f128_biteq { - ($a:expr, $b:expr) => { - let (l, r): (&f128, &f128) = (&$a, &$b); - let lb = l.to_bits(); - let rb = r.to_bits(); - assert_eq!(lb, rb, "float {l:?} is not bitequal to {r:?}.\na: {lb:#034x}\nb: {rb:#034x}"); - }; -} - -#[test] -fn test_num_f128() { - // FIXME(f16_f128): replace with a `test_num` call once the required `fmodl`/`fmodf128` - // function is available on all platforms. - let ten = 10f128; - let two = 2f128; - assert_eq!(ten.add(two), ten + two); - assert_eq!(ten.sub(two), ten - two); - assert_eq!(ten.mul(two), ten * two); - assert_eq!(ten.div(two), ten / two); -} - -// Many math functions allow for less accurate results, so the next tolerance up is used - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_powf() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_eq!(1.0f128.powf(1.0), 1.0); - assert_approx_eq!(3.4f128.powf(4.5), 246.40818323761892815995637964326426756, TOL_IMPR); - assert_approx_eq!(2.7f128.powf(-3.2), 0.041652009108526178281070304373500889273, TOL_IMPR); - assert_approx_eq!((-3.1f128).powf(2.0), 9.6100000000000005506706202140776519387, TOL_IMPR); - assert_approx_eq!(5.9f128.powf(-2.0), 0.028727377190462507313100483690639638451, TOL_IMPR); - assert_eq!(8.3f128.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_exp() { - assert_eq!(1.0, 0.0f128.exp()); - assert_approx_eq!(consts::E, 1.0f128.exp(), TOL); - assert_approx_eq!(148.41315910257660342111558004055227962348775, 5.0f128.exp(), TOL); - - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let nan: f128 = f128::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_exp2() { - assert_eq!(32.0, 5.0f128.exp2()); - assert_eq!(1.0, 0.0f128.exp2()); - - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let nan: f128 = f128::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_ln() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_approx_eq!(1.0f128.exp().ln(), 1.0, TOL); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f128).ln().is_nan()); - assert_eq!((-0.0f128).ln(), neg_inf); - assert_eq!(0.0f128.ln(), neg_inf); - assert_approx_eq!(4.0f128.ln(), 1.3862943611198906188344642429163531366, TOL); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_log() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_eq!(10.0f128.log(10.0), 1.0); - assert_approx_eq!(2.3f128.log(3.5), 0.66485771361478710036766645911922010272, TOL); - assert_eq!(1.0f128.exp().log(1.0f128.exp()), 1.0); - assert!(1.0f128.log(1.0).is_nan()); - assert!(1.0f128.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f128).log(0.1).is_nan()); - assert_eq!((-0.0f128).log(2.0), neg_inf); - assert_eq!(0.0f128.log(7.0), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_log2() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_approx_eq!(10.0f128.log2(), 3.32192809488736234787031942948939017, TOL); - assert_approx_eq!(2.3f128.log2(), 1.2016338611696504130002982471978765921, TOL); - assert_approx_eq!(1.0f128.exp().log2(), 1.4426950408889634073599246810018921381, TOL); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f128).log2().is_nan()); - assert_eq!((-0.0f128).log2(), neg_inf); - assert_eq!(0.0f128.log2(), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_log10() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert_eq!(10.0f128.log10(), 1.0); - assert_approx_eq!(2.3f128.log10(), 0.36172783601759284532595218865859309898, TOL); - assert_approx_eq!(1.0f128.exp().log10(), 0.43429448190325182765112891891660508222, TOL); - assert_eq!(1.0f128.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f128).log10().is_nan()); - assert_eq!((-0.0f128).log10(), neg_inf); - assert_eq!(0.0f128.log10(), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_asinh() { - // Lower accuracy results are allowed, use increased tolerances - assert_eq!(0.0f128.asinh(), 0.0f128); - assert_eq!((-0.0f128).asinh(), -0.0f128); - - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let nan: f128 = f128::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f128).asinh().is_sign_negative()); - - // issue 63271 - assert_approx_eq!(2.0f128.asinh(), 1.443635475178810342493276740273105f128, TOL_IMPR); - assert_approx_eq!((-2.0f128).asinh(), -1.443635475178810342493276740273105f128, TOL_IMPR); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!( - (-67452098.07139316f128).asinh(), - -18.720075426274544393985484294000831757220, - TOL_IMPR - ); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f128, 60.0f128.sinh().asinh(), TOL_IMPR); - // mul needed for approximate comparison to be meaningful - assert_approx_eq!(1.0f128, 1e-15f128.sinh().asinh() * 1e15f128, TOL_IMPR); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_acosh() { - assert_eq!(1.0f128.acosh(), 0.0f128); - assert!(0.999f128.acosh().is_nan()); - - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let nan: f128 = f128::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f128.acosh(), 1.31695789692481670862504634730796844f128, TOL_IMPR); - assert_approx_eq!(3.0f128.acosh(), 1.76274717403908605046521864995958461f128, TOL_IMPR); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f128, 60.0f128.cosh().acosh(), TOL_IMPR); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_atanh() { - assert_eq!(0.0f128.atanh(), 0.0f128); - assert_eq!((-0.0f128).atanh(), -0.0f128); - - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let nan: f128 = f128::NAN; - assert_eq!(1.0f128.atanh(), inf); - assert_eq!((-1.0f128).atanh(), neg_inf); - assert!(2f128.atanh().atanh().is_nan()); - assert!((-2f128).atanh().atanh().is_nan()); - assert!(inf.atanh().is_nan()); - assert!(neg_inf.atanh().is_nan()); - assert!(nan.atanh().is_nan()); - assert_approx_eq!(0.5f128.atanh(), 0.54930614433405484569762261846126285f128, TOL_IMPR); - assert_approx_eq!((-0.5f128).atanh(), -0.54930614433405484569762261846126285f128, TOL_IMPR); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_gamma() { - // precision can differ among platforms - assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR); - assert_approx_eq!(2.0f128.gamma(), 1.0f128, TOL_IMPR); - assert_approx_eq!(3.0f128.gamma(), 2.0f128, TOL_IMPR); - assert_approx_eq!(4.0f128.gamma(), 6.0f128, TOL_IMPR); - assert_approx_eq!(5.0f128.gamma(), 24.0f128, TOL_IMPR); - assert_approx_eq!(0.5f128.gamma(), consts::PI.sqrt(), TOL_IMPR); - assert_approx_eq!((-0.5f128).gamma(), -2.0 * consts::PI.sqrt(), TOL_IMPR); - assert_eq!(0.0f128.gamma(), f128::INFINITY); - assert_eq!((-0.0f128).gamma(), f128::NEG_INFINITY); - assert!((-1.0f128).gamma().is_nan()); - assert!((-2.0f128).gamma().is_nan()); - assert!(f128::NAN.gamma().is_nan()); - assert!(f128::NEG_INFINITY.gamma().is_nan()); - assert_eq!(f128::INFINITY.gamma(), f128::INFINITY); - assert_eq!(1760.9f128.gamma(), f128::INFINITY); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f128_math)] -fn test_ln_gamma() { - assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR); - assert_eq!(1.0f128.ln_gamma().1, 1); - assert_approx_eq!(2.0f128.ln_gamma().0, 0.0f128, TOL_IMPR); - assert_eq!(2.0f128.ln_gamma().1, 1); - assert_approx_eq!(3.0f128.ln_gamma().0, 2.0f128.ln(), TOL_IMPR); - assert_eq!(3.0f128.ln_gamma().1, 1); - assert_approx_eq!((-0.5f128).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_IMPR); - assert_eq!((-0.5f128).ln_gamma().1, -1); -} - -#[test] -fn test_real_consts() { - let pi: f128 = consts::PI; - let frac_pi_2: f128 = consts::FRAC_PI_2; - let frac_pi_3: f128 = consts::FRAC_PI_3; - let frac_pi_4: f128 = consts::FRAC_PI_4; - let frac_pi_6: f128 = consts::FRAC_PI_6; - let frac_pi_8: f128 = consts::FRAC_PI_8; - let frac_1_pi: f128 = consts::FRAC_1_PI; - let frac_2_pi: f128 = consts::FRAC_2_PI; - - assert_approx_eq!(frac_pi_2, pi / 2f128, TOL_PRECISE); - assert_approx_eq!(frac_pi_3, pi / 3f128, TOL_PRECISE); - assert_approx_eq!(frac_pi_4, pi / 4f128, TOL_PRECISE); - assert_approx_eq!(frac_pi_6, pi / 6f128, TOL_PRECISE); - assert_approx_eq!(frac_pi_8, pi / 8f128, TOL_PRECISE); - assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE); - assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE); - - #[cfg(not(miri))] - #[cfg(target_has_reliable_f128_math)] - { - let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI; - let sqrt2: f128 = consts::SQRT_2; - let frac_1_sqrt2: f128 = consts::FRAC_1_SQRT_2; - let e: f128 = consts::E; - let log2_e: f128 = consts::LOG2_E; - let log10_e: f128 = consts::LOG10_E; - let ln_2: f128 = consts::LN_2; - let ln_10: f128 = consts::LN_10; - - assert_approx_eq!(frac_2_sqrtpi, 2f128 / pi.sqrt(), TOL_PRECISE); - assert_approx_eq!(sqrt2, 2f128.sqrt(), TOL_PRECISE); - assert_approx_eq!(frac_1_sqrt2, 1f128 / 2f128.sqrt(), TOL_PRECISE); - assert_approx_eq!(log2_e, e.log2(), TOL_PRECISE); - assert_approx_eq!(log10_e, e.log10(), TOL_PRECISE); - assert_approx_eq!(ln_2, 2f128.ln(), TOL_PRECISE); - assert_approx_eq!(ln_10, 10f128.ln(), TOL_PRECISE); - } -} diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs deleted file mode 100644 index 0f8b4138d2266..0000000000000 --- a/library/std/tests/floats/f16.rs +++ /dev/null @@ -1,300 +0,0 @@ -// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy -#![cfg(target_has_reliable_f16)] - -use std::f16::consts; - -/// Tolerance for results on the order of 10.0e-2 -#[allow(unused)] -const TOL_N2: f16 = 0.0001; - -/// Tolerance for results on the order of 10.0e+0 -#[allow(unused)] -const TOL_0: f16 = 0.01; - -/// Tolerance for results on the order of 10.0e+2 -#[allow(unused)] -const TOL_P2: f16 = 0.5; - -/// Tolerance for results on the order of 10.0e+4 -#[allow(unused)] -const TOL_P4: f16 = 10.0; - -/// Compare by representation -#[allow(unused_macros)] -macro_rules! assert_f16_biteq { - ($a:expr, $b:expr) => { - let (l, r): (&f16, &f16) = (&$a, &$b); - let lb = l.to_bits(); - let rb = r.to_bits(); - assert_eq!(lb, rb, "float {l:?} ({lb:#04x}) is not bitequal to {r:?} ({rb:#04x})"); - }; -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_powf() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_eq!(1.0f16.powf(1.0), 1.0); - assert_approx_eq!(3.4f16.powf(4.5), 246.408183, TOL_P2); - assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, TOL_N2); - assert_approx_eq!((-3.1f16).powf(2.0), 9.61, TOL_P2); - assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, TOL_N2); - assert_eq!(8.3f16.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_exp() { - assert_eq!(1.0, 0.0f16.exp()); - assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0); - assert_approx_eq!(148.413159, 5.0f16.exp(), TOL_0); - - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let nan: f16 = f16::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_exp2() { - assert_eq!(32.0, 5.0f16.exp2()); - assert_eq!(1.0, 0.0f16.exp2()); - - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let nan: f16 = f16::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_ln() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_approx_eq!(1.0f16.exp().ln(), 1.0, TOL_0); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f16).ln().is_nan()); - assert_eq!((-0.0f16).ln(), neg_inf); - assert_eq!(0.0f16.ln(), neg_inf); - assert_approx_eq!(4.0f16.ln(), 1.386294, TOL_0); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_log() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_eq!(10.0f16.log(10.0), 1.0); - assert_approx_eq!(2.3f16.log(3.5), 0.664858, TOL_0); - assert_eq!(1.0f16.exp().log(1.0f16.exp()), 1.0); - assert!(1.0f16.log(1.0).is_nan()); - assert!(1.0f16.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f16).log(0.1).is_nan()); - assert_eq!((-0.0f16).log(2.0), neg_inf); - assert_eq!(0.0f16.log(7.0), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_log2() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_approx_eq!(10.0f16.log2(), 3.321928, TOL_0); - assert_approx_eq!(2.3f16.log2(), 1.201634, TOL_0); - assert_approx_eq!(1.0f16.exp().log2(), 1.442695, TOL_0); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f16).log2().is_nan()); - assert_eq!((-0.0f16).log2(), neg_inf); - assert_eq!(0.0f16.log2(), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_log10() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert_eq!(10.0f16.log10(), 1.0); - assert_approx_eq!(2.3f16.log10(), 0.361728, TOL_0); - assert_approx_eq!(1.0f16.exp().log10(), 0.434294, TOL_0); - assert_eq!(1.0f16.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f16).log10().is_nan()); - assert_eq!((-0.0f16).log10(), neg_inf); - assert_eq!(0.0f16.log10(), neg_inf); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_asinh() { - assert_eq!(0.0f16.asinh(), 0.0f16); - assert_eq!((-0.0f16).asinh(), -0.0f16); - - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let nan: f16 = f16::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f16).asinh().is_sign_negative()); - // issue 63271 - assert_approx_eq!(2.0f16.asinh(), 1.443635475178810342493276740273105f16, TOL_0); - assert_approx_eq!((-2.0f16).asinh(), -1.443635475178810342493276740273105f16, TOL_0); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!((-200.0f16).asinh(), -5.991470797049389, TOL_0); - - // test for low accuracy from issue 104548 - assert_approx_eq!(10.0f16, 10.0f16.sinh().asinh(), TOL_0); - // mul needed for approximate comparison to be meaningful - assert_approx_eq!(1.0f16, 1e-3f16.sinh().asinh() * 1e3f16, TOL_0); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_acosh() { - assert_eq!(1.0f16.acosh(), 0.0f16); - assert!(0.999f16.acosh().is_nan()); - - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let nan: f16 = f16::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f16.acosh(), 1.31695789692481670862504634730796844f16, TOL_0); - assert_approx_eq!(3.0f16.acosh(), 1.76274717403908605046521864995958461f16, TOL_0); - - // test for low accuracy from issue 104548 - assert_approx_eq!(10.0f16, 10.0f16.cosh().acosh(), TOL_P2); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_atanh() { - assert_eq!(0.0f16.atanh(), 0.0f16); - assert_eq!((-0.0f16).atanh(), -0.0f16); - - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let nan: f16 = f16::NAN; - assert_eq!(1.0f16.atanh(), inf); - assert_eq!((-1.0f16).atanh(), neg_inf); - assert!(2f16.atanh().atanh().is_nan()); - assert!((-2f16).atanh().atanh().is_nan()); - assert!(inf.atanh().is_nan()); - assert!(neg_inf.atanh().is_nan()); - assert!(nan.atanh().is_nan()); - assert_approx_eq!(0.5f16.atanh(), 0.54930614433405484569762261846126285f16, TOL_0); - assert_approx_eq!((-0.5f16).atanh(), -0.54930614433405484569762261846126285f16, TOL_0); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_gamma() { - // precision can differ among platforms - assert_approx_eq!(1.0f16.gamma(), 1.0f16, TOL_0); - assert_approx_eq!(2.0f16.gamma(), 1.0f16, TOL_0); - assert_approx_eq!(3.0f16.gamma(), 2.0f16, TOL_0); - assert_approx_eq!(4.0f16.gamma(), 6.0f16, TOL_0); - assert_approx_eq!(5.0f16.gamma(), 24.0f16, TOL_0); - assert_approx_eq!(0.5f16.gamma(), consts::PI.sqrt(), TOL_0); - assert_approx_eq!((-0.5f16).gamma(), -2.0 * consts::PI.sqrt(), TOL_0); - assert_eq!(0.0f16.gamma(), f16::INFINITY); - assert_eq!((-0.0f16).gamma(), f16::NEG_INFINITY); - assert!((-1.0f16).gamma().is_nan()); - assert!((-2.0f16).gamma().is_nan()); - assert!(f16::NAN.gamma().is_nan()); - assert!(f16::NEG_INFINITY.gamma().is_nan()); - assert_eq!(f16::INFINITY.gamma(), f16::INFINITY); - assert_eq!(171.71f16.gamma(), f16::INFINITY); -} - -#[test] -#[cfg(not(miri))] -#[cfg(target_has_reliable_f16_math)] -fn test_ln_gamma() { - assert_approx_eq!(1.0f16.ln_gamma().0, 0.0f16, TOL_0); - assert_eq!(1.0f16.ln_gamma().1, 1); - assert_approx_eq!(2.0f16.ln_gamma().0, 0.0f16, TOL_0); - assert_eq!(2.0f16.ln_gamma().1, 1); - assert_approx_eq!(3.0f16.ln_gamma().0, 2.0f16.ln(), TOL_0); - assert_eq!(3.0f16.ln_gamma().1, 1); - assert_approx_eq!((-0.5f16).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_0); - assert_eq!((-0.5f16).ln_gamma().1, -1); -} - -#[test] -fn test_real_consts() { - // FIXME(f16_f128): add math tests when available - - let pi: f16 = consts::PI; - let frac_pi_2: f16 = consts::FRAC_PI_2; - let frac_pi_3: f16 = consts::FRAC_PI_3; - let frac_pi_4: f16 = consts::FRAC_PI_4; - let frac_pi_6: f16 = consts::FRAC_PI_6; - let frac_pi_8: f16 = consts::FRAC_PI_8; - let frac_1_pi: f16 = consts::FRAC_1_PI; - let frac_2_pi: f16 = consts::FRAC_2_PI; - - assert_approx_eq!(frac_pi_2, pi / 2f16, TOL_0); - assert_approx_eq!(frac_pi_3, pi / 3f16, TOL_0); - assert_approx_eq!(frac_pi_4, pi / 4f16, TOL_0); - assert_approx_eq!(frac_pi_6, pi / 6f16, TOL_0); - assert_approx_eq!(frac_pi_8, pi / 8f16, TOL_0); - assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0); - assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0); - - #[cfg(not(miri))] - #[cfg(target_has_reliable_f16_math)] - { - let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI; - let sqrt2: f16 = consts::SQRT_2; - let frac_1_sqrt2: f16 = consts::FRAC_1_SQRT_2; - let e: f16 = consts::E; - let log2_e: f16 = consts::LOG2_E; - let log10_e: f16 = consts::LOG10_E; - let ln_2: f16 = consts::LN_2; - let ln_10: f16 = consts::LN_10; - - assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), TOL_0); - assert_approx_eq!(sqrt2, 2f16.sqrt(), TOL_0); - assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), TOL_0); - assert_approx_eq!(log2_e, e.log2(), TOL_0); - assert_approx_eq!(log10_e, e.log10(), TOL_0); - assert_approx_eq!(ln_2, 2f16.ln(), TOL_0); - assert_approx_eq!(ln_10, 10f16.ln(), TOL_0); - } -} diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs deleted file mode 100644 index 3acd067091415..0000000000000 --- a/library/std/tests/floats/f32.rs +++ /dev/null @@ -1,258 +0,0 @@ -use std::f32::consts; - -/// Miri adds some extra errors to float functions; make sure the tests still pass. -/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. -/// They serve as a way to get an idea of the real precision of floating point operations on different platforms. -const APPROX_DELTA: f32 = if cfg!(miri) { 1e-3 } else { 1e-6 }; - -#[allow(unused_macros)] -macro_rules! assert_f32_biteq { - ($left : expr, $right : expr) => { - let l: &f32 = &$left; - let r: &f32 = &$right; - let lb = l.to_bits(); - let rb = r.to_bits(); - assert_eq!(lb, rb, "float {l} ({lb:#010x}) is not bitequal to {r} ({rb:#010x})"); - }; -} - -#[test] -fn test_powf() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.powf(1.0), 1.0); - assert_approx_eq!(3.4f32.powf(4.5), 246.408218, APPROX_DELTA); - assert_approx_eq!(2.7f32.powf(-3.2), 0.041652); - assert_approx_eq!((-3.1f32).powf(2.0), 9.61, APPROX_DELTA); - assert_approx_eq!(5.9f32.powf(-2.0), 0.028727); - assert_eq!(8.3f32.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); -} - -#[test] -fn test_exp() { - assert_eq!(1.0, 0.0f32.exp()); - assert_approx_eq!(2.718282, 1.0f32.exp(), APPROX_DELTA); - assert_approx_eq!(148.413162, 5.0f32.exp(), APPROX_DELTA); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); -} - -#[test] -fn test_exp2() { - assert_approx_eq!(32.0, 5.0f32.exp2(), APPROX_DELTA); - assert_eq!(1.0, 0.0f32.exp2()); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); -} - -#[test] -fn test_ln() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(1.0f32.exp().ln(), 1.0); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f32).ln().is_nan()); - assert_eq!((-0.0f32).ln(), neg_inf); - assert_eq!(0.0f32.ln(), neg_inf); - assert_approx_eq!(4.0f32.ln(), 1.386294, APPROX_DELTA); -} - -#[test] -fn test_log() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(10.0f32.log(10.0), 1.0); - assert_approx_eq!(2.3f32.log(3.5), 0.664858); - assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0, APPROX_DELTA); - assert!(1.0f32.log(1.0).is_nan()); - assert!(1.0f32.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f32).log(0.1).is_nan()); - assert_eq!((-0.0f32).log(2.0), neg_inf); - assert_eq!(0.0f32.log(7.0), neg_inf); -} - -#[test] -fn test_log2() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(10.0f32.log2(), 3.321928, APPROX_DELTA); - assert_approx_eq!(2.3f32.log2(), 1.201634); - assert_approx_eq!(1.0f32.exp().log2(), 1.442695, APPROX_DELTA); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f32).log2().is_nan()); - assert_eq!((-0.0f32).log2(), neg_inf); - assert_eq!(0.0f32.log2(), neg_inf); -} - -#[test] -fn test_log10() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(10.0f32.log10(), 1.0); - assert_approx_eq!(2.3f32.log10(), 0.361728); - assert_approx_eq!(1.0f32.exp().log10(), 0.434294); - assert_eq!(1.0f32.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f32).log10().is_nan()); - assert_eq!((-0.0f32).log10(), neg_inf); - assert_eq!(0.0f32.log10(), neg_inf); -} - -#[test] -fn test_asinh() { - assert_eq!(0.0f32.asinh(), 0.0f32); - assert_eq!((-0.0f32).asinh(), -0.0f32); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271 - assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); - assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32, APPROX_DELTA); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh(), APPROX_DELTA); - // mul needed for approximate comparison to be meaningful - assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32); -} - -#[test] -fn test_acosh() { - assert_eq!(1.0f32.acosh(), 0.0f32); - assert!(0.999f32.acosh().is_nan()); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32); - assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh(), APPROX_DELTA); -} - -#[test] -fn test_atanh() { - assert_eq!(0.0f32.atanh(), 0.0f32); - assert_eq!((-0.0f32).atanh(), -0.0f32); - - let inf32: f32 = f32::INFINITY; - let neg_inf32: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.atanh(), inf32); - assert_eq!((-1.0f32).atanh(), neg_inf32); - - assert!(2f64.atanh().atanh().is_nan()); - assert!((-2f64).atanh().atanh().is_nan()); - - let inf64: f32 = f32::INFINITY; - let neg_inf64: f32 = f32::NEG_INFINITY; - let nan32: f32 = f32::NAN; - assert!(inf64.atanh().is_nan()); - assert!(neg_inf64.atanh().is_nan()); - assert!(nan32.atanh().is_nan()); - - assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); - assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32); -} - -#[test] -fn test_gamma() { - // precision can differ between platforms - assert_approx_eq!(1.0f32.gamma(), 1.0f32, APPROX_DELTA); - assert_approx_eq!(2.0f32.gamma(), 1.0f32, APPROX_DELTA); - assert_approx_eq!(3.0f32.gamma(), 2.0f32, APPROX_DELTA); - assert_approx_eq!(4.0f32.gamma(), 6.0f32, APPROX_DELTA); - assert_approx_eq!(5.0f32.gamma(), 24.0f32, APPROX_DELTA); - assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt(), APPROX_DELTA); - assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt(), APPROX_DELTA); - assert_eq!(0.0f32.gamma(), f32::INFINITY); - assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY); - assert!((-1.0f32).gamma().is_nan()); - assert!((-2.0f32).gamma().is_nan()); - assert!(f32::NAN.gamma().is_nan()); - assert!(f32::NEG_INFINITY.gamma().is_nan()); - assert_eq!(f32::INFINITY.gamma(), f32::INFINITY); - assert_eq!(171.71f32.gamma(), f32::INFINITY); -} - -#[test] -fn test_ln_gamma() { - assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32); - assert_eq!(1.0f32.ln_gamma().1, 1); - assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32); - assert_eq!(2.0f32.ln_gamma().1, 1); - assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln()); - assert_eq!(3.0f32.ln_gamma().1, 1); - assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), APPROX_DELTA); - assert_eq!((-0.5f32).ln_gamma().1, -1); -} - -#[test] -fn test_real_consts() { - let pi: f32 = consts::PI; - let frac_pi_2: f32 = consts::FRAC_PI_2; - let frac_pi_3: f32 = consts::FRAC_PI_3; - let frac_pi_4: f32 = consts::FRAC_PI_4; - let frac_pi_6: f32 = consts::FRAC_PI_6; - let frac_pi_8: f32 = consts::FRAC_PI_8; - let frac_1_pi: f32 = consts::FRAC_1_PI; - let frac_2_pi: f32 = consts::FRAC_2_PI; - let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI; - let sqrt2: f32 = consts::SQRT_2; - let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2; - let e: f32 = consts::E; - let log2_e: f32 = consts::LOG2_E; - let log10_e: f32 = consts::LOG10_E; - let ln_2: f32 = consts::LN_2; - let ln_10: f32 = consts::LN_10; - - assert_approx_eq!(frac_pi_2, pi / 2f32); - assert_approx_eq!(frac_pi_3, pi / 3f32, APPROX_DELTA); - assert_approx_eq!(frac_pi_4, pi / 4f32); - assert_approx_eq!(frac_pi_6, pi / 6f32); - assert_approx_eq!(frac_pi_8, pi / 8f32); - assert_approx_eq!(frac_1_pi, 1f32 / pi); - assert_approx_eq!(frac_2_pi, 2f32 / pi); - assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt()); - assert_approx_eq!(sqrt2, 2f32.sqrt()); - assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt()); - assert_approx_eq!(log2_e, e.log2()); - assert_approx_eq!(log10_e, e.log10()); - assert_approx_eq!(ln_2, 2f32.ln()); - assert_approx_eq!(ln_10, 10f32.ln(), APPROX_DELTA); -} diff --git a/library/std/tests/floats/f64.rs b/library/std/tests/floats/f64.rs deleted file mode 100644 index fccf20097278b..0000000000000 --- a/library/std/tests/floats/f64.rs +++ /dev/null @@ -1,249 +0,0 @@ -use std::f64::consts; - -#[allow(unused_macros)] -macro_rules! assert_f64_biteq { - ($left : expr, $right : expr) => { - let l: &f64 = &$left; - let r: &f64 = &$right; - let lb = l.to_bits(); - let rb = r.to_bits(); - assert_eq!(lb, rb, "float {l} ({lb:#018x}) is not bitequal to {r} ({rb:#018x})"); - }; -} - -#[test] -fn test_powf() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(1.0f64.powf(1.0), 1.0); - assert_approx_eq!(3.4f64.powf(4.5), 246.408183); - assert_approx_eq!(2.7f64.powf(-3.2), 0.041652); - assert_approx_eq!((-3.1f64).powf(2.0), 9.61); - assert_approx_eq!(5.9f64.powf(-2.0), 0.028727); - assert_eq!(8.3f64.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); -} - -#[test] -fn test_exp() { - assert_eq!(1.0, 0.0f64.exp()); - assert_approx_eq!(2.718282, 1.0f64.exp()); - assert_approx_eq!(148.413159, 5.0f64.exp()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); -} - -#[test] -fn test_exp2() { - assert_approx_eq!(32.0, 5.0f64.exp2()); - assert_eq!(1.0, 0.0f64.exp2()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); -} - -#[test] -fn test_ln() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(1.0f64.exp().ln(), 1.0); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f64).ln().is_nan()); - assert_eq!((-0.0f64).ln(), neg_inf); - assert_eq!(0.0f64.ln(), neg_inf); - assert_approx_eq!(4.0f64.ln(), 1.386294); -} - -#[test] -fn test_log() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(10.0f64.log(10.0), 1.0); - assert_approx_eq!(2.3f64.log(3.5), 0.664858); - assert_approx_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); - assert!(1.0f64.log(1.0).is_nan()); - assert!(1.0f64.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f64).log(0.1).is_nan()); - assert_eq!((-0.0f64).log(2.0), neg_inf); - assert_eq!(0.0f64.log(7.0), neg_inf); -} - -#[test] -fn test_log2() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(10.0f64.log2(), 3.321928); - assert_approx_eq!(2.3f64.log2(), 1.201634); - assert_approx_eq!(1.0f64.exp().log2(), 1.442695); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f64).log2().is_nan()); - assert_eq!((-0.0f64).log2(), neg_inf); - assert_eq!(0.0f64.log2(), neg_inf); -} - -#[test] -fn test_log10() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(10.0f64.log10(), 1.0); - assert_approx_eq!(2.3f64.log10(), 0.361728); - assert_approx_eq!(1.0f64.exp().log10(), 0.434294); - assert_eq!(1.0f64.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f64).log10().is_nan()); - assert_eq!((-0.0f64).log10(), neg_inf); - assert_eq!(0.0f64.log10(), neg_inf); -} - -#[test] -fn test_asinh() { - assert_eq!(0.0f64.asinh(), 0.0f64); - assert_eq!((-0.0f64).asinh(), -0.0f64); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f64).asinh().is_sign_negative()); - // issue 63271 - assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64); - assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh()); - // mul needed for approximate comparison to be meaningful - assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64); -} - -#[test] -fn test_acosh() { - assert_eq!(1.0f64.acosh(), 0.0f64); - assert!(0.999f64.acosh().is_nan()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64); - assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64); - - // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh()); -} - -#[test] -fn test_atanh() { - assert_eq!(0.0f64.atanh(), 0.0f64); - assert_eq!((-0.0f64).atanh(), -0.0f64); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(1.0f64.atanh(), inf); - assert_eq!((-1.0f64).atanh(), neg_inf); - assert!(2f64.atanh().atanh().is_nan()); - assert!((-2f64).atanh().atanh().is_nan()); - assert!(inf.atanh().is_nan()); - assert!(neg_inf.atanh().is_nan()); - assert!(nan.atanh().is_nan()); - assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); - assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64); -} - -#[test] -fn test_gamma() { - // precision can differ between platforms - assert_approx_eq!(1.0f64.gamma(), 1.0f64); - assert_approx_eq!(2.0f64.gamma(), 1.0f64); - assert_approx_eq!(3.0f64.gamma(), 2.0f64); - assert_approx_eq!(4.0f64.gamma(), 6.0f64); - assert_approx_eq!(5.0f64.gamma(), 24.0f64); - assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt()); - assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt()); - assert_eq!(0.0f64.gamma(), f64::INFINITY); - assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY); - assert!((-1.0f64).gamma().is_nan()); - assert!((-2.0f64).gamma().is_nan()); - assert!(f64::NAN.gamma().is_nan()); - assert!(f64::NEG_INFINITY.gamma().is_nan()); - assert_eq!(f64::INFINITY.gamma(), f64::INFINITY); - assert_eq!(171.71f64.gamma(), f64::INFINITY); -} - -#[test] -fn test_ln_gamma() { - assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64); - assert_eq!(1.0f64.ln_gamma().1, 1); - assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64); - assert_eq!(2.0f64.ln_gamma().1, 1); - assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln()); - assert_eq!(3.0f64.ln_gamma().1, 1); - assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln()); - assert_eq!((-0.5f64).ln_gamma().1, -1); -} - -#[test] -fn test_real_consts() { - let pi: f64 = consts::PI; - let frac_pi_2: f64 = consts::FRAC_PI_2; - let frac_pi_3: f64 = consts::FRAC_PI_3; - let frac_pi_4: f64 = consts::FRAC_PI_4; - let frac_pi_6: f64 = consts::FRAC_PI_6; - let frac_pi_8: f64 = consts::FRAC_PI_8; - let frac_1_pi: f64 = consts::FRAC_1_PI; - let frac_2_pi: f64 = consts::FRAC_2_PI; - let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI; - let sqrt2: f64 = consts::SQRT_2; - let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2; - let e: f64 = consts::E; - let log2_e: f64 = consts::LOG2_E; - let log10_e: f64 = consts::LOG10_E; - let ln_2: f64 = consts::LN_2; - let ln_10: f64 = consts::LN_10; - - assert_approx_eq!(frac_pi_2, pi / 2f64); - assert_approx_eq!(frac_pi_3, pi / 3f64); - assert_approx_eq!(frac_pi_4, pi / 4f64); - assert_approx_eq!(frac_pi_6, pi / 6f64); - assert_approx_eq!(frac_pi_8, pi / 8f64); - assert_approx_eq!(frac_1_pi, 1f64 / pi); - assert_approx_eq!(frac_2_pi, 2f64 / pi); - assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt()); - assert_approx_eq!(sqrt2, 2f64.sqrt()); - assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt()); - assert_approx_eq!(log2_e, e.log2()); - assert_approx_eq!(log10_e, e.log10()); - assert_approx_eq!(ln_2, 2f64.ln()); - assert_approx_eq!(ln_10, 10f64.ln()); -} diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs deleted file mode 100644 index 8bb8eb4bfc1ae..0000000000000 --- a/library/std/tests/floats/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![feature(f16, f128, float_gamma, float_minimum_maximum, cfg_target_has_reliable_f16_f128)] -#![expect(internal_features)] // for reliable_f16_f128 - -use std::fmt; -use std::ops::{Add, Div, Mul, Rem, Sub}; - -/// Verify that floats are within a tolerance of each other, 1.0e-6 by default. -macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }}; - ($a:expr, $b:expr, $lim:expr) => {{ - let (a, b) = (&$a, &$b); - let diff = (*a - *b).abs(); - assert!( - diff <= $lim, - "{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})", - lim = $lim - ); - }}; -} - -/// Helper function for testing numeric operations -pub fn test_num(ten: T, two: T) -where - T: PartialEq - + Add - + Sub - + Mul - + Div - + Rem - + fmt::Debug - + Copy, -{ - assert_eq!(ten.add(two), ten + two); - assert_eq!(ten.sub(two), ten - two); - assert_eq!(ten.mul(two), ten * two); - assert_eq!(ten.div(two), ten / two); - assert_eq!(ten.rem(two), ten % two); -} - -mod f128; -mod f16; -mod f32; -mod f64; diff --git a/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs new file mode 100644 index 0000000000000..ecf9f4b92058b --- /dev/null +++ b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs @@ -0,0 +1,19 @@ +//! Check that `select_unpredictable` properly forgets the value it does not select. +#![feature(core_intrinsics)] +use std::cell::Cell; +use std::intrinsics::select_unpredictable; + +fn main() { + let (true_val, false_val) = (Cell::new(false), Cell::new(false)); + _ = select_unpredictable(true, TraceDrop(&true_val), TraceDrop(&false_val)); + assert!(true_val.get()); + assert!(!false_val.get()); +} + +struct TraceDrop<'a>(&'a Cell); + +impl<'a> Drop for TraceDrop<'a> { + fn drop(&mut self) { + self.0.set(true); + } +} diff --git a/tests/codegen-llvm/addr-of-mutate.rs b/tests/codegen-llvm/addr-of-mutate.rs index d59d85af62a91..d1939391b25de 100644 --- a/tests/codegen-llvm/addr-of-mutate.rs +++ b/tests/codegen-llvm/addr-of-mutate.rs @@ -5,7 +5,7 @@ // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`. // See . -// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}} dereferenceable(128) %x) +// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}}{{( dead_on_return)?}} dereferenceable(128) %x) #[no_mangle] pub fn foo(x: [u8; 128]) -> u8 { let ptr = core::ptr::addr_of!(x).cast_mut(); @@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 { x[0] } -// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}}{{( dead_on_return)?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut(); @@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { } // If going through a deref (and there are no other mutating accesses), then `readonly` is fine. -// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(none\))?}}{{( dead_on_return)?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut(); diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs index 4d557470504e0..b5febca3b87b5 100644 --- a/tests/codegen-llvm/function-arguments.rs +++ b/tests/codegen-llvm/function-arguments.rs @@ -134,7 +134,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {} #[no_mangle] pub fn notunpin_borrow(_: &NotUnpin) {} -// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1) +// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(none\))?}}{{( dead_on_return)?}} dereferenceable(32) %_1) #[no_mangle] pub fn indirect_struct(_: S) {} diff --git a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs index 546007ab0f2cf..4c61224ac6d8f 100644 --- a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs @@ -256,7 +256,7 @@ pub struct IntDoubleInt { c: i32, } -// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}} dereferenceable(24) %a) +// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}}{{( dead_on_return)?}} dereferenceable(24) %a) #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} diff --git a/tests/ui/const-generics/mgca/type_const-incemental-compile.rs b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs new file mode 100644 index 0000000000000..60e6968363db3 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs @@ -0,0 +1,11 @@ +//@ check-pass +//@compile-flags: -Clink-dead-code=true +// link-dead-code tries to eagerly monomorphize and collect items +// This lead to collector.rs to try and evaluate a type_const +// which will fail since they do not have bodies. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +const TYPE_CONST: usize = 0; +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-pub.rs b/tests/ui/const-generics/mgca/type_const-pub.rs index fc5b1ce36a14b..f443562394df3 100644 --- a/tests/ui/const-generics/mgca/type_const-pub.rs +++ b/tests/ui/const-generics/mgca/type_const-pub.rs @@ -7,4 +7,6 @@ #[type_const] pub const TYPE_CONST : usize = 1; -fn main() {} +fn main() { + print!("{}", TYPE_CONST) +} diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index b778eab605961..2a05d77f8f6da 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -51,7 +51,7 @@ impl ::core::default::Default for Empty { #[automatically_derived] impl ::core::hash::Hash for Empty { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Empty { } @@ -65,7 +65,7 @@ impl ::core::cmp::Eq for Empty { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Empty { @@ -123,7 +123,7 @@ impl ::core::default::Default for Point { #[automatically_derived] impl ::core::hash::Hash for Point { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.x, state); ::core::hash::Hash::hash(&self.y, state) } @@ -142,7 +142,7 @@ impl ::core::cmp::Eq for Point { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -211,7 +211,7 @@ impl ::core::default::Default for PackedPoint { #[automatically_derived] impl ::core::hash::Hash for PackedPoint { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.x }, state); ::core::hash::Hash::hash(&{ self.y }, state) } @@ -230,7 +230,7 @@ impl ::core::cmp::Eq for PackedPoint { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -297,7 +297,7 @@ impl ::core::convert::From for TupleSingleField { #[automatically_derived] impl ::core::hash::Hash for TupleSingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -313,7 +313,7 @@ impl ::core::cmp::Eq for TupleSingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -372,7 +372,7 @@ impl ::core::convert::From for SingleField { #[automatically_derived] impl ::core::hash::Hash for SingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.foo, state) } } @@ -388,7 +388,7 @@ impl ::core::cmp::Eq for SingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -465,7 +465,7 @@ impl ::core::default::Default for Big { #[automatically_derived] impl ::core::hash::Hash for Big { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.b1, state); ::core::hash::Hash::hash(&self.b2, state); ::core::hash::Hash::hash(&self.b3, state); @@ -493,7 +493,7 @@ impl ::core::cmp::Eq for Big { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -741,7 +741,7 @@ impl ::core::convert::From<[u32]> for Unsized { #[automatically_derived] impl ::core::hash::Hash for Unsized { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -757,7 +757,7 @@ impl ::core::cmp::Eq for Unsized { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq<[u32]>; } } @@ -829,7 +829,7 @@ impl impl ::core::hash::Hash for Generic where T::A: ::core::hash::Hash { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.t, state); ::core::hash::Hash::hash(&self.ta, state); ::core::hash::Hash::hash(&self.u, state) @@ -852,7 +852,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -946,7 +946,7 @@ impl where T::A: ::core::hash::Hash + ::core::marker::Copy { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.0 }, state); ::core::hash::Hash::hash(&{ self.1 }, state); ::core::hash::Hash::hash(&{ self.2 }, state) @@ -974,7 +974,7 @@ impl () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -1043,7 +1043,7 @@ impl ::core::fmt::Debug for Enum0 { #[automatically_derived] impl ::core::hash::Hash for Enum0 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match *self {} } } @@ -1059,7 +1059,7 @@ impl ::core::cmp::Eq for Enum0 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Enum0 { @@ -1105,7 +1105,7 @@ impl ::core::fmt::Debug for Enum1 { #[automatically_derived] impl ::core::hash::Hash for Enum1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match self { Enum1::Single { x: __self_0 } => ::core::hash::Hash::hash(__self_0, state), @@ -1129,7 +1129,7 @@ impl ::core::cmp::Eq for Enum1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -1181,7 +1181,7 @@ impl ::core::default::Default for Fieldless1 { #[automatically_derived] impl ::core::hash::Hash for Fieldless1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Fieldless1 { } @@ -1195,7 +1195,7 @@ impl ::core::cmp::Eq for Fieldless1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless1 { @@ -1251,7 +1251,7 @@ impl ::core::default::Default for Fieldless { #[automatically_derived] impl ::core::hash::Hash for Fieldless { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state) } @@ -1272,7 +1272,7 @@ impl ::core::cmp::Eq for Fieldless { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless { @@ -1345,7 +1345,7 @@ impl ::core::default::Default for Mixed { #[automatically_derived] impl ::core::hash::Hash for Mixed { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1382,7 +1382,7 @@ impl ::core::cmp::Eq for Mixed { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; let _: ::core::cmp::AssertParamIsEq>; @@ -1545,7 +1545,7 @@ impl ::core::fmt::Debug for Fielded { #[automatically_derived] impl ::core::hash::Hash for Fielded { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1580,7 +1580,7 @@ impl ::core::cmp::Eq for Fielded { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; @@ -1666,7 +1666,7 @@ impl ::core::fmt::Debug for impl ::core::hash::Hash for EnumGeneric { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1702,7 +1702,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; } diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index 11a6bfdfcd292..a48940460f91e 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -4,11 +4,11 @@ macro-stats Macro Name Uses Lines Avg Lines B macro-stats ----------------------------------------------------------------------------------- macro-stats #[derive(Clone)] 8 67 8.4 1_879 234.9 macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0 -macro-stats #[derive(Hash)] 2 17 8.5 577 288.5 +macro-stats #[derive(Hash)] 2 17 8.5 565 282.5 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 503 503.0 macro-stats #[derive(Default)] 2 16 8.0 403 201.5 -macro-stats #[derive(Eq)] 1 11 11.0 325 325.0 +macro-stats #[derive(Eq)] 1 11 11.0 319 319.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0 macro-stats #[derive(Copy)] 1 2 2.0 61 61.0