diff --git a/RELEASES.md b/RELEASES.md index b49470c307569..1213a596024c0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,180 @@ +Version 1.82.0 (2024-10-17) +========================== + + + +Language +-------- +- [Don't make statement nonterminals match pattern nonterminals](https://github.com/rust-lang/rust/pull/120221/) +- [Patterns matching empty types can now be omitted in common cases](https://github.com/rust-lang/rust/pull/122792) +- [Enforce supertrait outlives obligations when using trait impls](https://github.com/rust-lang/rust/pull/124336) +- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) +- [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/) +- [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/) +- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672) +- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679) +- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921) +- [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284) +- [Do not require `T` to be live when dropping `[T; 0]`](https://github.com/rust-lang/rust/pull/128438) +- [Stabilize `const` operands in inline assembly](https://github.com/rust-lang/rust/pull/128570) +- [Stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596) +- [Stabilize explicit opt-in to unsafe attributes](https://github.com/rust-lang/rust/pull/128771) +- [Document NaN bit patterns guarantees](https://github.com/rust-lang/rust/pull/129559) + + + + +Compiler +-------- +- [Promote riscv64gc-unknown-linux-musl to tier 2](https://github.com/rust-lang/rust/pull/122049) +- [Promote Mac Catalyst targets `aarch64-apple-ios-macabi` and `x86_64-apple-ios-macabi` to Tier 2, and ship them with rustup](https://github.com/rust-lang/rust/pull/126450) +- [Add tier 3 NuttX based targets for RISC-V and ARM](https://github.com/rust-lang/rust/pull/127755) +- [Add tier 3 powerpc-unknown-linux-muslspe target](https://github.com/rust-lang/rust/pull/127905) +- [Improved diagnostics to explain why a pattern is unreachable](https://github.com/rust-lang/rust/pull/128034) +- [The compiler now triggers the unreachable code warning properly for async functions that don't return/are `-> !`](https://github.com/rust-lang/rust/pull/128443) +- [Promote `aarch64-apple-darwin` to Tier 1](https://github.com/rust-lang/rust/pull/128592) +- [Add Trusty OS target `aarch64-unknown-trusty` and `armv7-unknown-trusty` as tier 3 targets](https://github.com/rust-lang/rust/pull/129490) +- [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/) + + + + +Libraries +--------- +- [Generalize `{Rc,Arc}::make_mut()` to `Path`, `OsStr`, and `CStr`.](https://github.com/rust-lang/rust/pull/126877) + + + +Stabilized APIs +--------------- + +- [`std::thread::Builder::spawn_unchecked`](https://doc.rust-lang.org/stable/std/thread/struct.Builder.html#method.spawn_unchecked) +- [`std::str::CharIndices::offset`](https://doc.rust-lang.org/nightly/std/str/struct.CharIndices.html#method.offset) +- [`std::option::Option::is_none_or`](https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.is_none_or) +- [`[T]::is_sorted`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted) +- [`[T]::is_sorted_by`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by) +- [`[T]::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by_key) +- [`Iterator::is_sorted`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted) +- [`Iterator::is_sorted_by`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by) +- [`Iterator::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by_key) +- [`std::future::Ready::into_inner`](https://doc.rust-lang.org/nightly/std/future/struct.Ready.html#method.into_inner) +- [`std::iter::repeat_n`](https://doc.rust-lang.org/nightly/std/iter/fn.repeat_n.html) +- [`impl DoubleEndedIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-DoubleEndedIterator-for-Take%3CRepeat%3CT%3E%3E) +- [`impl ExactSizeIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeat%3CT%3E%3E) +- [`impl ExactSizeIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeatWith%3CF%3E%3E) +- [`impl Default for std::collections::binary_heap::Iter`](https://doc.rust-lang.org/nightly/std/collections/binary_heap/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E) +- [`impl Default for std::collections::btree_map::RangeMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.RangeMut.html#impl-Default-for-RangeMut%3C'_,+K,+V%3E) +- [`impl Default for std::collections::btree_map::ValuesMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.ValuesMut.html#impl-Default-for-ValuesMut%3C'_,+K,+V%3E) +- [`impl Default for std::collections::vec_deque::Iter`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E) +- [`impl Default for std::collections::vec_deque::IterMut`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.IterMut.html#impl-Default-for-IterMut%3C'_,+T%3E) +- [`Rc::new_uninit`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit) +- [`Rc::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init) +- [`Rc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit_slice) +- [`Rc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init-1) +- [`Arc::new_uninit`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit) +- [`Arc::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init) +- [`Arc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit_slice) +- [`Arc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init-1) +- [`Box::new_uninit`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit) +- [`Box::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init) +- [`Box<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit_slice) +- [`Box<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init-1) +- [`core::arch::x86_64::_bextri_u64`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u64.html) +- [`core::arch::x86_64::_bextri_u32`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u32.html) +- [`core::arch::x86::_mm_broadcastsi128_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_broadcastsi128_si256.html) +- [`core::arch::x86::_mm256_stream_load_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm256_stream_load_si256.html) +- [`core::arch::x86::_tzcnt_u16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._tzcnt_u16.html) +- [`core::arch::x86::_mm_extracti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_extracti_si64.html) +- [`core::arch::x86::_mm_inserti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_inserti_si64.html) +- [`core::arch::x86::_mm_storeu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si16.html) +- [`core::arch::x86::_mm_storeu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si32.html) +- [`core::arch::x86::_mm_storeu_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si64.html) +- [`core::arch::x86::_mm_loadu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si16.html) +- [`core::arch::x86::_mm_loadu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si32.html) +- [`core::arch::wasm32::u8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_swizzle.html) +- [`core::arch::wasm32::i8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_swizzle.html) +- [`core::arch::wasm32::i32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f32x4.html) +- [`core::arch::wasm32::u32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f32x4.html) +- [`core::arch::wasm32::i32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f64x2_zero.html) +- [`core::arch::wasm32::u32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f64x2_zero.html) +- [`core::arch::wasm32::f32x4_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_madd.html) +- [`core::arch::wasm32::f32x4_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_nmadd.html) +- [`core::arch::wasm32::f64x2_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_madd.html) +- [`core::arch::wasm32::f64x2_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_nmadd.html) +- [`core::arch::wasm32::i8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_laneselect.html) +- [`core::arch::wasm32::u8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_laneselect.html) +- [`core::arch::wasm32::i16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_laneselect.html) +- [`core::arch::wasm32::u16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_laneselect.html) +- [`core::arch::wasm32::i32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_laneselect.html) +- [`core::arch::wasm32::u32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_laneselect.html) +- [`core::arch::wasm32::i64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i64x2_relaxed_laneselect.html) +- [`core::arch::wasm32::u64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u64x2_relaxed_laneselect.html) +- [`core::arch::wasm32::f32x4_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_min.html) +- [`core::arch::wasm32::f32x4_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_max.html) +- [`core::arch::wasm32::f64x2_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_min.html) +- [`core::arch::wasm32::f64x2_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_max.html) +- [`core::arch::wasm32::i16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_q15mulr.html) +- [`core::arch::wasm32::u16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_q15mulr.html) +- [`core::arch::wasm32::i16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_dot_i8x16_i7x16.html) +- [`core::arch::wasm32::u16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_dot_i8x16_i7x16.html) +- [`core::arch::wasm32::i32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_dot_i8x16_i7x16_add.html) +- [`core::arch::wasm32::u32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_dot_i8x16_i7x16_add.html) + +These APIs are now stable in const contexts: + +- [`std::task::Waker::from_raw`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw) +- [`std::task::Waker::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw) +- [`std::task::Context::from_waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.from_waker) +- [`std::task::Context::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.waker) +- [`$integer::from_str_radix`](https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.from_str_radix) +- [`std::num::ParseIntError::kind`](https://doc.rust-lang.org/nightly/std/num/struct.ParseIntError.html#method.kind) + + + +Cargo +----- +- [feat: Add `info` cargo subcommand](https://github.com/rust-lang/cargo/pull/14141/) + + + +Compatibility Notes +------------------- + - We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead. +- The standard library has a new implementation of `binary_search` which is significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. +- [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets. +- [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400) +- The WebAssembly target features `multivalue` and `reference-types` are now + both enabled by default. These two features both have subtle changes implied + for generated WebAssembly binaries. For the `multivalue` feature, WebAssembly + target support has changed when upgrading to LLVM 19. Support for generating + functions with multiple returns no longer works and + `-Ctarget-feature=+multivalue` has a different meaning than it did in LLVM 18 + and prior. There is no longer any supported means to generate a module that has + a function with multiple returns in WebAssembly from Rust source code. For the + `reference-types` feature the encoding of immediates in the `call_indirect`, a + commonly used instruction by the WebAssembly backend, has changed. Validators + and parsers which don't understand the `reference-types` proposal will no + longer accept modules produced by LLVM due to this change in encoding of + immediates. Additionally these features being enabled are encoded in the + `target_features` custom section and may affect downstream tooling such as + `wasm-opt` consuming the module. Generating a WebAssembly module that disables + default features requires `-Zbuild-std` support from Cargo and more information + can be found at + [rust-lang/rust#128511](https://github.com/rust-lang/rust/pull/128511). +- [Rust now raises unsafety errors for union patterns in parameter-position](https://github.com/rust-lang/rust/pull/130531) + + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Update to LLVM 19](https://github.com/rust-lang/rust/pull/127513) + Version 1.81.0 (2024-09-05) ========================== diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 25583cda5a20d..43e2bf1796fc7 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use thin_vec::thin_vec; use crate::errors; -use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts}; +use crate::util::{expr_to_string, get_exprs_from_tts, get_single_expr_from_tts}; fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result { let var = var.as_str(); @@ -32,19 +32,28 @@ pub(crate) fn expand_option_env<'cx>( sp: Span, tts: TokenStream, ) -> MacroExpanderResult<'cx> { - let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "option_env!") else { + let ExpandResult::Ready(mac_expr) = get_single_expr_from_tts(cx, sp, tts, "option_env!") else { + return ExpandResult::Retry(()); + }; + let var_expr = match mac_expr { + Ok(var_expr) => var_expr, + Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), + }; + let ExpandResult::Ready(mac) = + expr_to_string(cx, var_expr.clone(), "argument must be a string literal") + else { return ExpandResult::Retry(()); }; let var = match mac { - Ok(var) => var, + Ok((var, _)) => var, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; let sp = cx.with_def_site_ctxt(sp); - let value = lookup_env(cx, var).ok(); - cx.sess.psess.env_depinfo.borrow_mut().insert((var, value)); + let value = lookup_env(cx, var); + cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); let e = match value { - None => { + Err(VarError::NotPresent) => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); cx.expr_path(cx.path_all( sp, @@ -58,7 +67,18 @@ pub(crate) fn expand_option_env<'cx>( ))], )) } - Some(value) => { + Err(VarError::NotUnicode(_)) => { + let ExprKind::Lit(token::Lit { + kind: LitKind::Str | LitKind::StrRaw(..), symbol, .. + }) = &var_expr.kind + else { + unreachable!("`expr_to_string` ensures this is a string lit") + }; + + let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol }); + return ExpandResult::Ready(DummyResult::any(sp, guar)); + } + Ok(value) => { cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![ cx.expr_str(sp, value) ]) diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index d7b03a43ecb0d..2a28dfaf3c430 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -171,6 +171,30 @@ pub(crate) fn get_single_str_spanned_from_tts( tts: TokenStream, name: &str, ) -> ExpandResult, ()> { + let ExpandResult::Ready(ret) = get_single_expr_from_tts(cx, span, tts, name) else { + return ExpandResult::Retry(()); + }; + let ret = match ret { + Ok(ret) => ret, + Err(e) => return ExpandResult::Ready(Err(e)), + }; + expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, _style, span)| (symbol, span)) + }) +} + +/// Interpreting `tts` as a comma-separated sequence of expressions, +/// expect exactly one expression, or emit an error and return `Err`. +pub(crate) fn get_single_expr_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ErrorGuaranteed>, ()> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); @@ -185,13 +209,7 @@ pub(crate) fn get_single_str_spanned_from_tts( if p.token != token::Eof { cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); } - expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { - res.map_err(|err| match err { - Ok((err, _)) => err.emit(), - Err(guar) => guar, - }) - .map(|(symbol, _style, span)| (symbol, span)) - }) + ExpandResult::Ready(Ok(ret)) } /// Extracts comma-separated expressions from `tts`. diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 30b5a8d70bc33..1def3d08328ac 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -334,19 +334,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { { use rustc_type_ir::TyKind::*; - fn adjust_nan< - 'tcx, - M: Machine<'tcx>, - F1: rustc_apfloat::Float + FloatConvert, - F2: rustc_apfloat::Float, - >( - ecx: &InterpCx<'tcx, M>, - f1: F1, - f2: F2, - ) -> F2 { - if f2.is_nan() { M::generate_nan(ecx, &[f1]) } else { f2 } - } - match *dest_ty.kind() { // float -> uint Uint(t) => { @@ -367,11 +354,17 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // float -> float Float(fty) => match fty { - FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F16 => { + Scalar::from_f16(self.adjust_nan(f.convert(&mut false).value, &[f])) + } + FloatTy::F32 => { + Scalar::from_f32(self.adjust_nan(f.convert(&mut false).value, &[f])) + } + FloatTy::F64 => { + Scalar::from_f64(self.adjust_nan(f.convert(&mut false).value, &[f])) + } FloatTy::F128 => { - Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value)) + Scalar::from_f128(self.adjust_nan(f.convert(&mut false).value, &[f])) } }, // That's it. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 5165f95afd5b7..02dd7821ef667 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -599,6 +599,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn generate_stacktrace(&self) -> Vec> { Frame::generate_stacktrace_from_stack(self.stack()) } + + pub fn adjust_nan(&self, f: F2, inputs: &[F1]) -> F2 + where + F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert, + F2: rustc_apfloat::Float, + { + if f.is_nan() { M::generate_nan(self, inputs) } else { f } + } } #[doc(hidden)] diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 52780cc6a3a6f..540898ec6456c 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -4,6 +4,7 @@ use std::assert_matches::assert_matches; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_hir::def_id::DefId; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement}; @@ -438,6 +439,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } + sym::minnumf16 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf32 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf64 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf128 => self.float_min_intrinsic::(args, dest)?, + + sym::maxnumf16 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf32 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf64 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf128 => self.float_max_intrinsic::(args, dest)?, + + sym::copysignf16 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf32 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf64 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf128 => self.float_copysign_intrinsic::(args, dest)?, + + sym::fabsf16 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf32 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), } @@ -697,4 +718,63 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let rhs_bytes = get_bytes(self, rhs)?; interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } + + fn float_min_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = self.adjust_nan(a.min(b), &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_max_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = self.adjust_nan(a.max(b), &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_copysign_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + // bitwise, no NaN adjustments + self.write_scalar(a.copy_sign(b), dest)?; + interp_ok(()) + } + + fn float_abs_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = self.read_scalar(&args[0])?.to_float()?; + // bitwise, no NaN adjustments + self.write_scalar(x.abs(), dest)?; + interp_ok(()) + } } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 52cd9b898bb72..b28ac68ac54ae 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -64,8 +64,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { use rustc_middle::mir::BinOp::*; // Performs appropriate non-deterministic adjustments of NaN results. - let adjust_nan = - |f: F| -> F { if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f } }; + let adjust_nan = |f: F| -> F { self.adjust_nan(f, &[l, r]) }; match bin_op { Eq => ImmTy::from_bool(l == r, *self.tcx), diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4429f6346e88a..94da3d4ea8406 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -61,9 +61,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab Some(true) => (), Some(false) | None => { tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.primary_message( - "use of calling convention not supported on this target on function pointer", - ); + lint.primary_message(format!( + "the calling convention {abi} is not supported on this target" + )); }); } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 23dc5214fe2ea..da603df9a9a9f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3859,7 +3859,7 @@ declare_lint! { /// This will produce: /// /// ```text - /// warning: use of calling convention not supported on this target on function pointer + /// warning: the calling convention `"stdcall"` is not supported on this target /// --> $DIR/unsupported.rs:34:15 /// | /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) { diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index d496899e72bcd..d7e99f4a1a638 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -7,7 +7,7 @@ use core::borrow::Borrow; use core::ffi::{CStr, c_char}; use core::num::NonZero; use core::slice::memchr; -use core::str::{self, Utf8Error}; +use core::str::{self, FromStr, Utf8Error}; use core::{fmt, mem, ops, ptr, slice}; use crate::borrow::{Cow, ToOwned}; @@ -817,6 +817,30 @@ impl From>> for CString { } } +impl FromStr for CString { + type Err = NulError; + + /// Converts a string `s` into a [`CString`]. + /// + /// This method is equivalent to [`CString::new`]. + #[inline] + fn from_str(s: &str) -> Result { + Self::new(s) + } +} + +impl TryFrom for String { + type Error = IntoStringError; + + /// Converts a [`CString`] into a [`String`] if it contains valid UTF-8 data. + /// + /// This method is equivalent to [`CString::into_string`]. + #[inline] + fn try_from(value: CString) -> Result { + value.into_string() + } +} + #[cfg(not(test))] #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 0cc8f61b4c6c9..e8f5af863c1d7 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1849,154 +1849,6 @@ extern "rust-intrinsic" { #[cfg(not(bootstrap))] pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; - /// Returns the absolute value of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::abs`](../../std/primitive.f16.html#method.abs) - #[rustc_nounwind] - pub fn fabsf16(x: f16) -> f16; - /// Returns the absolute value of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::abs`](../../std/primitive.f32.html#method.abs) - #[rustc_nounwind] - pub fn fabsf32(x: f32) -> f32; - /// Returns the absolute value of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::abs`](../../std/primitive.f64.html#method.abs) - #[rustc_nounwind] - pub fn fabsf64(x: f64) -> f64; - /// Returns the absolute value of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::abs`](../../std/primitive.f128.html#method.abs) - #[rustc_nounwind] - pub fn fabsf128(x: f128) -> f128; - - /// Returns the minimum of two `f16` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f16::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf16(x: f16, y: f16) -> f16; - /// Returns the minimum of two `f32` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f32::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf32(x: f32, y: f32) -> f32; - /// Returns the minimum of two `f64` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f64::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf64(x: f64, y: f64) -> f64; - /// Returns the minimum of two `f128` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f128::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf128(x: f128, y: f128) -> f128; - - /// Returns the maximum of two `f16` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f16::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf16(x: f16, y: f16) -> f16; - /// Returns the maximum of two `f32` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f32::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf32(x: f32, y: f32) -> f32; - /// Returns the maximum of two `f64` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f64::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf64(x: f64, y: f64) -> f64; - /// Returns the maximum of two `f128` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f128::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf128(x: f128, y: f128) -> f128; - - /// Copies the sign from `y` to `x` for `f16` values. - /// - /// The stabilized version of this intrinsic is - /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf16(x: f16, y: f16) -> f16; - /// Copies the sign from `y` to `x` for `f32` values. - /// - /// The stabilized version of this intrinsic is - /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf32(x: f32, y: f32) -> f32; - /// Copies the sign from `y` to `x` for `f64` values. - /// - /// The stabilized version of this intrinsic is - /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf64(x: f64, y: f64) -> f64; - /// Copies the sign from `y` to `x` for `f128` values. - /// - /// The stabilized version of this intrinsic is - /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf128(x: f128, y: f128) -> f128; - /// Returns the largest integer less than or equal to an `f16`. /// /// The stabilized version of this intrinsic is @@ -3555,6 +3407,245 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { } } +/// Returns the minimum of two `f16` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f16::min`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Returns the minimum of two `f32` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f32::min`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} + +/// Returns the minimum of two `f64` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f64::min`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Returns the minimum of two `f128` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f128::min`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + +/// Returns the maximum of two `f16` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f16::max`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Returns the maximum of two `f32` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f32::max`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} + +/// Returns the maximum of two `f64` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f64::max`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Returns the maximum of two `f128` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f128::max`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + +/// Returns the absolute value of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::abs`](../../std/primitive.f16.html#method.abs) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf16(_x: f16) -> f16 { + unimplemented!(); +} + +/// Returns the absolute value of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::abs`](../../std/primitive.f32.html#method.abs) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf32(_x: f32) -> f32 { + unimplemented!(); +} + +/// Returns the absolute value of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::abs`](../../std/primitive.f64.html#method.abs) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf64(_x: f64) -> f64 { + unimplemented!(); +} + +/// Returns the absolute value of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::abs`](../../std/primitive.f128.html#method.abs) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf128(_x: f128) -> f128 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f16` values. +/// +/// The stabilized version of this intrinsic is +/// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f32` values. +/// +/// The stabilized version of this intrinsic is +/// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} +/// Copies the sign from `y` to `x` for `f64` values. +/// +/// The stabilized version of this intrinsic is +/// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f128` values. +/// +/// The stabilized version of this intrinsic is +/// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + /// Inform Miri that a given pointer definitely has a certain alignment. #[cfg(miri)] pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 08c0d6e34cd02..71439188266b8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -120,6 +120,7 @@ #![feature(const_char_encode_utf16)] #![feature(const_eval_select)] #![feature(const_exact_div)] +#![feature(const_float_methods)] #![feature(const_fmt_arguments_new)] #![feature(const_hash)] #![feature(const_heap)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index aa0646846e43e..2839a242a901e 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1107,17 +1107,19 @@ pub(crate) mod builtin { /// /// If the named environment variable is present at compile time, this will /// expand into an expression of type `Option<&'static str>` whose value is - /// `Some` of the value of the environment variable. If the environment - /// variable is not present, then this will expand to `None`. See - /// [`Option`][Option] for more information on this type. Use - /// [`std::env::var`] instead if you want to read the value at runtime. + /// `Some` of the value of the environment variable (a compilation error + /// will be emitted if the environment variable is not a valid Unicode + /// string). If the environment variable is not present, then this will + /// expand to `None`. See [`Option`][Option] for more information on this + /// type. Use [`std::env::var`] instead if you want to read the value at + /// runtime. /// /// [`std::env::var`]: ../std/env/fn.var.html /// - /// A compile time error is never emitted when using this macro regardless - /// of whether the environment variable is present or not. - /// To emit a compile error if the environment variable is not present, - /// use the [`env!`] macro instead. + /// A compile time error is only emitted when using this macro if the + /// environment variable exists and is not a valid Unicode string. To also + /// emit a compile error if the environment variable is not present, use the + /// [`env!`] macro instead. /// /// # Examples /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 764df4fe4b058..95e0f979abe60 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -471,7 +471,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -497,7 +497,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. // SAFETY: This is just transmuting to get the sign bit, it's fine. @@ -538,7 +538,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_up(self) -> Self { + pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -592,7 +592,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_down(self) -> Self { + pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -627,8 +627,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn recip(self) -> Self { + pub const fn recip(self) -> Self { 1.0 / self } @@ -647,8 +648,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_degrees(self) -> Self { + pub const fn to_degrees(self) -> Self { // Use a literal for better precision. const PIS_IN_180: f128 = 57.2957795130823208767981548141051703324054724665643215491602_f128; self * PIS_IN_180 @@ -670,8 +672,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_radians(self) -> f128 { + pub const fn to_radians(self) -> f128 { // Use a literal for better precision. const RADS_PER_DEG: f128 = 0.0174532925199432957692369076848861271344287188854172545609719_f128; @@ -698,8 +701,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn max(self, other: f128) -> f128 { + pub const fn max(self, other: f128) -> f128 { intrinsics::maxnumf128(self, other) } @@ -723,8 +727,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn min(self, other: f128) -> f128 { + pub const fn min(self, other: f128) -> f128 { intrinsics::minnumf128(self, other) } @@ -757,7 +762,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn maximum(self, other: f128) -> f128 { + pub const fn maximum(self, other: f128) -> f128 { if self > other { self } else if other > self { @@ -798,7 +803,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn minimum(self, other: f128) -> f128 { + pub const fn minimum(self, other: f128) -> f128 { if self < other { self } else if other < self { @@ -1269,9 +1274,19 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn clamp(mut self, min: f128, max: f128) -> f128 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f128, max: f128) -> f128 { + const fn assert_at_const(min: f128, max: f128) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f128, max: f128) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 897fc8c105d46..7151d0c029194 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -459,7 +459,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -488,7 +488,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. // SAFETY: This is just transmuting to get the sign bit, it's fine. @@ -529,7 +529,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_up(self) -> Self { + pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -583,7 +583,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_down(self) -> Self { + pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -618,8 +618,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn recip(self) -> Self { + pub const fn recip(self) -> Self { 1.0 / self } @@ -638,8 +639,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_degrees(self) -> Self { + pub const fn to_degrees(self) -> Self { // Use a literal for better precision. const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16; self * PIS_IN_180 @@ -661,8 +663,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_radians(self) -> f16 { + pub const fn to_radians(self) -> f16 { // Use a literal for better precision. const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16; self * RADS_PER_DEG @@ -687,8 +690,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn max(self, other: f16) -> f16 { + pub const fn max(self, other: f16) -> f16 { intrinsics::maxnumf16(self, other) } @@ -711,8 +715,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn min(self, other: f16) -> f16 { + pub const fn min(self, other: f16) -> f16 { intrinsics::minnumf16(self, other) } @@ -744,7 +749,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn maximum(self, other: f16) -> f16 { + pub const fn maximum(self, other: f16) -> f16 { if self > other { self } else if other > self { @@ -784,7 +789,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn minimum(self, other: f16) -> f16 { + pub const fn minimum(self, other: f16) -> f16 { if self < other { self } else if other < self { @@ -1244,9 +1249,19 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn clamp(mut self, min: f16, max: f16) -> f16 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f16, max: f16) -> f16 { + const fn assert_at_const(min: f16, max: f16) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f16, max: f16) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index a9a2595c25c29..05f5a08ad0acf 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -828,8 +828,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn recip(self) -> f32 { + pub const fn recip(self) -> f32 { 1.0 / self } @@ -845,8 +846,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_degrees(self) -> f32 { + pub const fn to_degrees(self) -> f32 { // Use a constant for better precision. const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32; self * PIS_IN_180 @@ -864,8 +866,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_radians(self) -> f32 { + pub const fn to_radians(self) -> f32 { const RADS_PER_DEG: f32 = consts::PI / 180.0; self * RADS_PER_DEG } @@ -885,8 +888,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn max(self, other: f32) -> f32 { + pub const fn max(self, other: f32) -> f32 { intrinsics::maxnumf32(self, other) } @@ -905,8 +909,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn min(self, other: f32) -> f32 { + pub const fn min(self, other: f32) -> f32 { intrinsics::minnumf32(self, other) } @@ -933,7 +938,7 @@ impl f32 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn maximum(self, other: f32) -> f32 { + pub const fn maximum(self, other: f32) -> f32 { if self > other { self } else if other > self { @@ -968,7 +973,7 @@ impl f32 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn minimum(self, other: f32) -> f32 { + pub const fn minimum(self, other: f32) -> f32 { if self < other { self } else if other < self { @@ -1401,9 +1406,19 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn clamp(mut self, min: f32, max: f32) -> f32 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f32, max: f32) -> f32 { + const fn assert_at_const(min: f32, max: f32) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f32, max: f32) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index aa7a54ca65080..89c6726d985e1 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -845,8 +845,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn recip(self) -> f64 { + pub const fn recip(self) -> f64 { 1.0 / self } @@ -862,8 +863,9 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_degrees(self) -> f64 { + pub const fn to_degrees(self) -> f64 { // The division here is correctly rounded with respect to the true // value of 180/π. (This differs from f32, where a constant must be // used to ensure a correctly rounded result.) @@ -882,8 +884,9 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_radians(self) -> f64 { + pub const fn to_radians(self) -> f64 { const RADS_PER_DEG: f64 = consts::PI / 180.0; self * RADS_PER_DEG } @@ -903,8 +906,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn max(self, other: f64) -> f64 { + pub const fn max(self, other: f64) -> f64 { intrinsics::maxnumf64(self, other) } @@ -923,8 +927,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn min(self, other: f64) -> f64 { + pub const fn min(self, other: f64) -> f64 { intrinsics::minnumf64(self, other) } @@ -951,7 +956,7 @@ impl f64 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn maximum(self, other: f64) -> f64 { + pub const fn maximum(self, other: f64) -> f64 { if self > other { self } else if other > self { @@ -986,7 +991,7 @@ impl f64 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn minimum(self, other: f64) -> f64 { + pub const fn minimum(self, other: f64) -> f64 { if self < other { self } else if other < self { @@ -1401,9 +1406,19 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn clamp(mut self, min: f64, max: f64) -> f64 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f64, max: f64) -> f64 { + const fn assert_at_const(min: f64, max: f64) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f64, max: f64) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c9af7f13e46c4..0b0449d617490 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -63,21 +63,22 @@ impl *const T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -91,6 +92,26 @@ impl *const T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let x = 0u32; + /// let y = 1u32; + /// + /// let x = (&x) as *const u32; + /// let y = (&y) as *const u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); + /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index ced6cb7d520de..8b61da74d02e7 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -45,21 +45,22 @@ impl *mut T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -73,6 +74,25 @@ impl *mut T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let mut x = 0u32; + /// let mut y = 1u32; + /// + /// let x = (&mut x) as *mut u32; + /// let y = (&mut y) as *mut u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/library/core/src/time.rs b/library/core/src/time.rs index f7ea7e06e9cdb..51005ff795c6f 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -213,11 +213,9 @@ impl Duration { // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } } else { - // FIXME(const-hack): use `.expect` once that is possible. - let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { - Some(secs) => secs, - None => panic!("overflow in Duration::new"), - }; + let secs = secs + .checked_add((nanos / NANOS_PER_SEC) as u64) + .expect("overflow in Duration::new"); let nanos = nanos % NANOS_PER_SEC; // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index b436fe9929c36..229f979b5b10b 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -210,8 +210,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn abs(self) -> Self { + pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available // We don't do this now because LLVM has lowering bugs for f128 math. Self::from_bits(self.to_bits() & !(1 << 127)) @@ -240,8 +241,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn signum(self) -> f128 { + pub const fn signum(self) -> f128 { if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } } @@ -278,8 +280,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn copysign(self, sign: f128) -> f128 { + pub const fn copysign(self, sign: f128) -> f128 { unsafe { intrinsics::copysignf128(self, sign) } } diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index b2cd5fae9d04a..bed21cda1cd91 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -210,8 +210,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn abs(self) -> Self { + pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available Self::from_bits(self.to_bits() & !(1 << 15)) } @@ -239,8 +240,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn signum(self) -> f16 { + pub const fn signum(self) -> f16 { if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } } @@ -277,8 +279,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn copysign(self, sign: f16) -> f16 { + pub const fn copysign(self, sign: f16) -> f16 { unsafe { intrinsics::copysignf16(self, sign) } } diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index fa0b3ef6484f7..30cf4e1f756e0 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -194,8 +194,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn abs(self) -> f32 { + pub const fn abs(self) -> f32 { unsafe { intrinsics::fabsf32(self) } } @@ -218,8 +219,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn signum(self) -> f32 { + pub const fn signum(self) -> f32 { if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } } @@ -253,7 +255,8 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "copysign", since = "1.35.0")] - pub fn copysign(self, sign: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + pub const fn copysign(self, sign: f32) -> f32 { unsafe { intrinsics::copysignf32(self, sign) } } diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 9fa43a6742ea6..51d5476b372d2 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -194,8 +194,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn abs(self) -> f64 { + pub const fn abs(self) -> f64 { unsafe { intrinsics::fabsf64(self) } } @@ -218,8 +219,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn signum(self) -> f64 { + pub const fn signum(self) -> f64 { if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } } @@ -252,8 +254,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn copysign(self, sign: f64) -> f64 { + pub const fn copysign(self, sign: f64) -> f64 { unsafe { intrinsics::copysignf64(self, sign) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 057a57f799772..f8117c4e18aec 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -288,6 +288,7 @@ #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] #![feature(concat_idents)] +#![feature(const_float_methods)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] #![feature(doc_cfg)] diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs index 848632ec2a7e3..e9fc19bcb99c1 100644 --- a/library/std/src/sys/pal/windows/args.rs +++ b/library/std/src/sys/pal/windows/args.rs @@ -18,17 +18,6 @@ use crate::sys_common::AsInner; use crate::sys_common::wstr::WStrUnits; use crate::{fmt, io, iter, vec}; -/// This is the const equivalent to `NonZero::new(n).unwrap()` -/// -/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const. -/// See the `const_option` feature (#67441). -const fn non_zero_u16(n: u16) -> NonZero { - match NonZero::new(n) { - Some(n) => n, - None => panic!("called `unwrap` on a `None` value"), - } -} - pub fn args() -> Args { // SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16 // string so it's safe for `WStrUnits` to use. @@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( lp_cmd_line: Option>, exe_name: F, ) -> Vec { - const BACKSLASH: NonZero = non_zero_u16(b'\\' as u16); - const QUOTE: NonZero = non_zero_u16(b'"' as u16); - const TAB: NonZero = non_zero_u16(b'\t' as u16); - const SPACE: NonZero = non_zero_u16(b' ' as u16); + const BACKSLASH: NonZero = NonZero::new(b'\\' as u16).unwrap(); + const QUOTE: NonZero = NonZero::new(b'"' as u16).unwrap(); + const TAB: NonZero = NonZero::new(b'\t' as u16).unwrap(); + const SPACE: NonZero = NonZero::new(b' ' as u16).unwrap(); let mut ret_val = Vec::new(); // If the cmd line pointer is null or it points to an empty string then diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d5bc2a93fa807..7b2a5eb3d637a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -643,8 +643,7 @@ fn run_test( } else { cmd = Command::new(&output_file); if doctest.is_multiple_tests { - cmd.arg("*doctest-bin-path"); - cmd.arg(&output_file); + cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file); } } if let Some(run_directory) = &rustdoc_options.test_run_directory { diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 942ec8d9936cf..093755103f36a 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -112,8 +112,7 @@ mod __doctest_mod {{ use std::path::PathBuf; pub static BINARY_PATH: OnceLock = OnceLock::new(); - pub const RUN_OPTION: &str = \"*doctest-inner-test\"; - pub const BIN_OPTION: &str = \"*doctest-bin-path\"; + pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\"; #[allow(unused)] pub fn doctest_path() -> Option<&'static PathBuf> {{ @@ -123,8 +122,8 @@ mod __doctest_mod {{ #[allow(unused)] pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{ let out = std::process::Command::new(bin) - .arg(self::RUN_OPTION) - .arg(test_nb.to_string()) + .env(self::RUN_OPTION, test_nb.to_string()) + .args(std::env::args().skip(1).collect::>()) .output() .expect(\"failed to run command\"); if !out.status.success() {{ @@ -138,36 +137,27 @@ mod __doctest_mod {{ #[rustc_main] fn main() -> std::process::ExitCode {{ const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}]; -let bin_marker = std::ffi::OsStr::new(__doctest_mod::BIN_OPTION); let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION); let test_args = &[{test_args}]; +const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; -let mut args = std::env::args_os().skip(1); -while let Some(arg) = args.next() {{ - if arg == bin_marker {{ - let Some(binary) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::BIN_OPTION); - }}; - if crate::__doctest_mod::BINARY_PATH.set(binary.into()).is_err() {{ - panic!(\"`{{}}` option was used more than once\", bin_marker.to_string_lossy()); - }} - return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); - }} else if arg == test_marker {{ - let Some(nb_test) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION); - }}; - if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::().ok()) {{ - if let Some(test) = TESTS.get(nb_test) {{ - if let test::StaticTestFn(f) = test.testfn {{ - return std::process::Termination::report(f()); - }} +if let Ok(binary) = std::env::var(ENV_BIN) {{ + let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into()); + unsafe {{ std::env::remove_var(ENV_BIN); }} + return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); +}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{ + if let Ok(nb_test) = nb_test.parse::() {{ + if let Some(test) = TESTS.get(nb_test) {{ + if let test::StaticTestFn(f) = test.testfn {{ + return std::process::Termination::report(f()); }} }} - panic!(\"Unexpected value after `{{}}`\", __doctest_mod::RUN_OPTION); }} + panic!(\"Unexpected value for `{{}}`\", __doctest_mod::RUN_OPTION); }} -eprintln!(\"WARNING: No argument provided so doctests will be run in the same process\"); +eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \ +the same process\"); std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) }}", nb_tests = self.nb_tests, diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a5418ad838488..1ee00a3a4e8ff 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -759,14 +759,8 @@ pub fn output_testname_unique( /// test/revision should reside. Example: /// /path/to/build/host-triple/test/ui/relative/testname.revision.mode/ pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf { - // In run-make tests, constructing a relative path + unique testname causes a double layering - // since revisions are not supported, causing unnecessary nesting. - if config.mode == Mode::RunMake { - output_relative_path(config, &testpaths.relative_dir) - } else { - output_relative_path(config, &testpaths.relative_dir) - .join(output_testname_unique(config, testpaths, revision)) - } + output_relative_path(config, &testpaths.relative_dir) + .join(output_testname_unique(config, testpaths, revision)) } /// Absolute path to the base filename used as output for the given diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 9f772cfa982d8..e0d27f21dae9c 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -145,20 +145,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - // Floating-point operations - "fabsf32" => { - let [f] = check_arg_count(args)?; - let f = this.read_scalar(f)?.to_f32()?; - // This is a "bitwise" operation, so there's no NaN non-determinism. - this.write_scalar(Scalar::from_f32(f.abs()), dest)?; - } - "fabsf64" => { - let [f] = check_arg_count(args)?; - let f = this.read_scalar(f)?.to_f64()?; - // This is a "bitwise" operation, so there's no NaN non-determinism. - this.write_scalar(Scalar::from_f64(f.abs()), dest)?; - } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; @@ -249,31 +235,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } - "minnumf32" | "maxnumf32" | "copysignf32" => { - let [a, b] = check_arg_count(args)?; - let a = this.read_scalar(a)?.to_f32()?; - let b = this.read_scalar(b)?.to_f32()?; - let res = match intrinsic_name { - "minnumf32" => this.adjust_nan(a.min(b), &[a, b]), - "maxnumf32" => this.adjust_nan(a.max(b), &[a, b]), - "copysignf32" => a.copy_sign(b), // bitwise, no NaN adjustments - _ => bug!(), - }; - this.write_scalar(Scalar::from_f32(res), dest)?; - } - "minnumf64" | "maxnumf64" | "copysignf64" => { - let [a, b] = check_arg_count(args)?; - let a = this.read_scalar(a)?.to_f64()?; - let b = this.read_scalar(b)?.to_f64()?; - let res = match intrinsic_name { - "minnumf64" => this.adjust_nan(a.min(b), &[a, b]), - "maxnumf64" => this.adjust_nan(a.max(b), &[a, b]), - "copysignf64" => a.copy_sign(b), // bitwise, no NaN adjustments - _ => bug!(), - }; - this.write_scalar(Scalar::from_f64(res), dest)?; - } - "fmaf32" => { let [a, b, c] = check_arg_count(args)?; let a = this.read_scalar(a)?.to_f32()?; diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index c0911fa717f50..8e06f4258d614 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -115,8 +115,4 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { nan } } - - fn adjust_nan, F2: Float>(&self, f: F2, inputs: &[F1]) -> F2 { - if f.is_nan() { self.generate_nan(inputs) } else { f } - } } diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 860d21876de0f..328b48e04d2e6 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -235,7 +235,9 @@ def update_latest( exit(0) cur_commit = sys.argv[1] - cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') + cur_datetime = datetime.datetime.now(datetime.timezone.utc).strftime( + '%Y-%m-%dT%H:%M:%SZ' + ) cur_commit_msg = sys.argv[2] save_message_to_path = sys.argv[3] github_token = sys.argv[4] diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 4035990347389..9e1eaa881c946 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process: structure within `build//test/run-make/` ``` - / + // rmake.exe # recipe binary rmake_out/ # sources from test sources copied over ``` diff --git a/tests/run-make/non-unicode-env/non_unicode_env.rs b/tests/run-make/non-unicode-env/non_unicode_env.rs index 865fc93736578..3efa4842d94a5 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.rs +++ b/tests/run-make/non-unicode-env/non_unicode_env.rs @@ -1,3 +1,4 @@ fn main() { let _ = env!("NON_UNICODE_VAR"); + let _ = option_env!("NON_UNICODE_VAR"); } diff --git a/tests/run-make/non-unicode-env/non_unicode_env.stderr b/tests/run-make/non-unicode-env/non_unicode_env.stderr index c4dcd7b2eb707..1f260ac9c07bd 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.stderr +++ b/tests/run-make/non-unicode-env/non_unicode_env.stderr @@ -6,5 +6,13 @@ error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string | = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string + --> non_unicode_env.rs:3:13 + | +3 | let _ = option_env!("NON_UNICODE_VAR"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `option_env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 00a5b4b2ee142..82908ef88a8b7 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -104,7 +104,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -123,7 +123,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -132,7 +132,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index dfb5ceb0c3370..39ec5d16fcd0d 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 6537ce6605770..1dc01a66aabc4 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -83,7 +83,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index a53f85f28bcee..e7d5197feebbe 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index a53f85f28bcee..e7d5197feebbe 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 45ba9a6649c51..bbca754dd41f4 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/consts/const-eval/float_methods.rs b/tests/ui/consts/const-eval/float_methods.rs new file mode 100644 index 0000000000000..49c31f68c5fa2 --- /dev/null +++ b/tests/ui/consts/const-eval/float_methods.rs @@ -0,0 +1,47 @@ +//@ run-pass +//! Tests the float intrinsics: min, max, abs, copysign + +#![feature(const_float_methods)] +#![feature(f16, f128)] + +const F16_MIN: f16 = 1.0_f16.min(0.5_f16); +const F16_MAX: f16 = 1.0_f16.max(0.5_f16); +const F16_ABS: f16 = (-1.0_f16).abs(); +const F16_COPYSIGN: f16 = 1.0_f16.copysign(-2.0_f16); + +const F32_MIN: f32 = 1.0_f32.min(0.5_f32); +const F32_MAX: f32 = 1.0_f32.max(0.5_f32); +const F32_ABS: f32 = (-1.0_f32).abs(); +const F32_COPYSIGN: f32 = 1.0_f32.copysign(-2.0_f32); + +const F64_MIN: f64 = 1.0_f64.min(0.5_f64); +const F64_MAX: f64 = 1.0_f64.max(0.5_f64); +const F64_ABS: f64 = (-1.0_f64).abs(); +const F64_COPYSIGN: f64 = 1.0_f64.copysign(-2.0_f64); + +const F128_MIN: f128 = 1.0_f128.min(0.5_f128); +const F128_MAX: f128 = 1.0_f128.max(0.5_f128); +const F128_ABS: f128 = (-1.0_f128).abs(); +const F128_COPYSIGN: f128 = 1.0_f128.copysign(-2.0_f128); + +fn main() { + assert_eq!(F16_MIN, 0.5); + assert_eq!(F16_MAX, 1.0); + assert_eq!(F16_ABS, 1.0); + assert_eq!(F16_COPYSIGN, -1.0); + + assert_eq!(F32_MIN, 0.5); + assert_eq!(F32_MAX, 1.0); + assert_eq!(F32_ABS, 1.0); + assert_eq!(F32_COPYSIGN, -1.0); + + assert_eq!(F64_MIN, 0.5); + assert_eq!(F64_MAX, 1.0); + assert_eq!(F64_ABS, 1.0); + assert_eq!(F64_COPYSIGN, -1.0); + + assert_eq!(F128_MIN, 0.5); + assert_eq!(F128_MAX, 1.0); + assert_eq!(F128_ABS, 1.0); + assert_eq!(F128_COPYSIGN, -1.0); +}