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_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 937031324f57f..883391a2b60ef 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -308,7 +308,7 @@ impl TraitBoundModifiers {
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum GenericBound {
- Trait(PolyTraitRef, TraitBoundModifiers),
+ Trait(PolyTraitRef),
Outlives(Lifetime),
/// Precise capturing syntax: `impl Sized + use<'a>`
Use(ThinVec, Span),
@@ -1213,10 +1213,12 @@ impl Expr {
pub fn to_bound(&self) -> Option {
match &self.kind {
- ExprKind::Path(None, path) => Some(GenericBound::Trait(
- PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
+ ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
+ ThinVec::new(),
+ path.clone(),
TraitBoundModifiers::NONE,
- )),
+ self.span,
+ ))),
_ => None,
}
}
@@ -2965,6 +2967,9 @@ pub struct PolyTraitRef {
/// The `'a` in `for<'a> Foo<&'a T>`.
pub bound_generic_params: ThinVec,
+ // Optional constness, asyncness, or polarity.
+ pub modifiers: TraitBoundModifiers,
+
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
pub trait_ref: TraitRef,
@@ -2972,9 +2977,15 @@ pub struct PolyTraitRef {
}
impl PolyTraitRef {
- pub fn new(generic_params: ThinVec, path: Path, span: Span) -> Self {
+ pub fn new(
+ generic_params: ThinVec,
+ path: Path,
+ modifiers: TraitBoundModifiers,
+ span: Span,
+ ) -> Self {
PolyTraitRef {
bound_generic_params: generic_params,
+ modifiers,
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
span,
}
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 1a7da46913d7e..b03c8aaa53b94 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -913,7 +913,7 @@ fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) {
match pb {
- GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
+ GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
GenericBound::Use(args, span) => {
for arg in args {
@@ -1034,7 +1034,7 @@ fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
}
fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) {
- let PolyTraitRef { bound_generic_params, trait_ref, span } = p;
+ let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p;
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
vis.visit_trait_ref(trait_ref);
vis.visit_span(span);
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index a517f17c82c34..695ebd168ee07 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -263,7 +263,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
match bounds.last() {
- Some(ast::GenericBound::Trait(bound, _)) => {
+ Some(ast::GenericBound::Trait(bound)) => {
match path_return_type(&bound.trait_ref.path) {
Some(trailing_ty) => ty = trailing_ty,
None => break None,
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 4dcadb8517eb4..6593d5dbb5c59 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef)
where
V: Visitor<'a>,
{
- let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref;
+ let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
walk_list!(visitor, visit_generic_param, bound_generic_params);
visitor.visit_trait_ref(trait_ref)
}
@@ -720,7 +720,7 @@ impl WalkItemKind for ForeignItemKind {
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
match bound {
- GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
+ GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref),
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
GenericBound::Use(args, _span) => {
walk_list!(visitor, visit_precise_capturing_arg, args);
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 1273b50dff816..ce744cc56e1ab 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
for bound in &bound_pred.bounds {
if !matches!(
*bound,
- GenericBound::Trait(_, TraitBoundModifiers {
- polarity: BoundPolarity::Maybe(_),
+ GenericBound::Trait(PolyTraitRef {
+ modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
..
})
) {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 365924ef782e8..cc15a48ddc6a5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1219,13 +1219,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let bound = this.lower_poly_trait_ref(
&PolyTraitRef {
bound_generic_params: ThinVec::new(),
+ modifiers: TraitBoundModifiers::NONE,
trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
span: t.span,
},
itctx,
- TraitBoundModifiers::NONE,
);
- let bound = (bound, hir::TraitBoundModifier::None);
let bounds = this.arena.alloc_from_iter([bound]);
let lifetime_bound = this.elided_dyn_bound(t.span);
(bounds, lifetime_bound)
@@ -1326,10 +1325,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// We can safely ignore constness here since AST validation
// takes care of rejecting invalid modifier combinations and
// const trait bounds in trait object types.
- GenericBound::Trait(ty, modifiers) => {
- let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers);
- let polarity = this.lower_trait_bound_modifiers(*modifiers);
- Some((trait_ref, polarity))
+ GenericBound::Trait(ty) => {
+ let trait_ref = this.lower_poly_trait_ref(ty, itctx);
+ Some(trait_ref)
}
GenericBound::Outlives(lifetime) => {
if lifetime_bound.is_none() {
@@ -1958,21 +1956,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span_ext: DUMMY_SP,
});
- hir::GenericBound::Trait(
- hir::PolyTraitRef {
- bound_generic_params: &[],
- trait_ref: hir::TraitRef {
- path: self.make_lang_item_path(
- trait_lang_item,
- opaque_ty_span,
- Some(bound_args),
- ),
- hir_ref_id: self.next_id(),
- },
- span: opaque_ty_span,
+ hir::GenericBound::Trait(hir::PolyTraitRef {
+ bound_generic_params: &[],
+ modifiers: hir::TraitBoundModifier::None,
+ trait_ref: hir::TraitRef {
+ path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
+ hir_ref_id: self.next_id(),
},
- hir::TraitBoundModifier::None,
- )
+ span: opaque_ty_span,
+ })
}
#[instrument(level = "trace", skip(self))]
@@ -1982,10 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
itctx: ImplTraitContext,
) -> hir::GenericBound<'hir> {
match tpb {
- GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait(
- self.lower_poly_trait_ref(p, itctx, *modifiers),
- self.lower_trait_bound_modifiers(*modifiers),
- ),
+ GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
GenericBound::Outlives(lifetime) => {
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
}
@@ -2189,12 +2178,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
p: &PolyTraitRef,
itctx: ImplTraitContext,
- modifiers: ast::TraitBoundModifiers,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
- let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx);
- hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
+ let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
+ let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
+ hir::PolyTraitRef {
+ bound_generic_params,
+ modifiers,
+ trait_ref,
+ span: self.lower_span(p.span),
+ }
}
fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
@@ -2634,10 +2628,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
let principal = hir::PolyTraitRef {
bound_generic_params: &[],
+ modifiers: hir::TraitBoundModifier::None,
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
span: self.lower_span(span),
};
- let principal = (principal, hir::TraitBoundModifier::None);
// The original ID is taken by the `PolyTraitRef`,
// so the `Ty` itself needs a different one.
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a36a9f11c0f15..20a4f2120dcdf 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1263,7 +1263,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if !bound_pred.bound_generic_params.is_empty() {
for bound in &bound_pred.bounds {
match bound {
- GenericBound::Trait(t, _) => {
+ GenericBound::Trait(t) => {
if !t.bound_generic_params.is_empty() {
self.dcx()
.emit_err(errors::NestedLifetimes { span: t.span });
@@ -1283,8 +1283,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
match bound {
- GenericBound::Trait(trait_ref, modifiers) => {
- match (ctxt, modifiers.constness, modifiers.polarity) {
+ GenericBound::Trait(trait_ref) => {
+ match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) {
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
if !self.features.more_maybe_bounds =>
{
@@ -1324,7 +1324,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
// Negative trait bounds are not allowed to have associated constraints
- if let BoundPolarity::Negative(_) = modifiers.polarity
+ if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
{
match segment.args.as_deref() {
@@ -1672,7 +1672,9 @@ fn deny_equality_constraints(
}),
) {
for bound in bounds {
- if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
+ if let GenericBound::Trait(poly) = bound
+ && poly.modifiers == TraitBoundModifiers::NONE
+ {
if full_path.segments[..full_path.segments.len() - 1]
.iter()
.map(|segment| segment.ident.name)
@@ -1700,7 +1702,9 @@ fn deny_equality_constraints(
) {
if ident == potential_param.ident {
for bound in bounds {
- if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
+ if let ast::GenericBound::Trait(poly) = bound
+ && poly.modifiers == TraitBoundModifiers::NONE
+ {
suggest(poly, potential_assoc, predicate);
}
}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 44a5a2d0baf28..f1f2784ad6051 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -8,7 +8,6 @@ mod item;
use std::borrow::Cow;
-use ast::TraitBoundModifiers;
use rustc_ast::attr::AttrIdGenerator;
use rustc_ast::ptr::P;
use rustc_ast::token::{
@@ -1253,6 +1252,27 @@ impl<'a> State<'a> {
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
self.print_formal_generic_params(&t.bound_generic_params);
+
+ let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers;
+ match constness {
+ ast::BoundConstness::Never => {}
+ ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
+ self.word_space(constness.as_str());
+ }
+ }
+ match asyncness {
+ ast::BoundAsyncness::Normal => {}
+ ast::BoundAsyncness::Async(_) => {
+ self.word_space(asyncness.as_str());
+ }
+ }
+ match polarity {
+ ast::BoundPolarity::Positive => {}
+ ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
+ self.word(polarity.as_str());
+ }
+ }
+
self.print_trait_ref(&t.trait_ref)
}
@@ -1740,31 +1760,7 @@ impl<'a> State<'a> {
}
match bound {
- GenericBound::Trait(
- tref,
- TraitBoundModifiers { constness, asyncness, polarity },
- ) => {
- match constness {
- ast::BoundConstness::Never => {}
- ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
- self.word_space(constness.as_str());
- }
- }
-
- match asyncness {
- ast::BoundAsyncness::Normal => {}
- ast::BoundAsyncness::Async(_) => {
- self.word_space(asyncness.as_str());
- }
- }
-
- match polarity {
- ast::BoundPolarity::Positive => {}
- ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
- self.word(polarity.as_str());
- }
- }
-
+ GenericBound::Trait(tref) => {
self.print_poly_trait_ref(tref);
}
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 39175b406a4aa..6333d59a1bc8d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -254,7 +254,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
debug!(?hrtb_bounds);
hrtb_bounds.iter().for_each(|bound| {
- let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else {
+ let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }) = bound else {
return;
};
diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
@@ -277,7 +277,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
return;
};
bounds.iter().for_each(|bd| {
- if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }, _) = bd
+ if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }) = bd
&& let Def(_, res_defid) = tr_ref.path.res
&& res_defid == trait_res_defid // trait id matches
&& let TyKind::Path(Resolved(_, path)) = bounded_ty.kind
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 1a5f9bdb154c0..b4b8373ac9747 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -837,7 +837,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
hir_ty
);
};
- if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty
+ if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref)], .. } = opaque_ty
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(args) = segment.args
&& let [constraint] = args.constraints
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index e3878d90e4143..731945f5cbfbf 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee:
}
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
- if let GenericBound::Trait(
- trait_ref,
- TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. },
- ) = bound
+ if let GenericBound::Trait(trait_ref) = bound
+ && let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } =
+ trait_ref.modifiers
+ && is_sized_marker(&trait_ref.trait_ref.path)
{
- is_sized_marker(&trait_ref.trait_ref.path)
+ true
} else {
false
}
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_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index b5945759d43a0..2c1ee004e1d65 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> {
ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
}
- pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
+ pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef {
ast::PolyTraitRef {
bound_generic_params: ThinVec::new(),
+ modifiers: ast::TraitBoundModifiers {
+ polarity: ast::BoundPolarity::Positive,
+ constness: if is_const {
+ ast::BoundConstness::Maybe(DUMMY_SP)
+ } else {
+ ast::BoundConstness::Never
+ },
+ asyncness: ast::BoundAsyncness::Normal,
+ },
trait_ref: self.trait_ref(path),
span,
}
}
pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound {
- ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers {
- polarity: ast::BoundPolarity::Positive,
- constness: if is_const {
- ast::BoundConstness::Maybe(DUMMY_SP)
- } else {
- ast::BoundConstness::Never
- },
- asyncness: ast::BoundAsyncness::Normal,
- })
+ ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const))
}
pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 2ef6fa53f4edd..1e9cbba94c773 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -520,7 +520,7 @@ pub enum TraitBoundModifier {
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum GenericBound<'hir> {
- Trait(PolyTraitRef<'hir>, TraitBoundModifier),
+ Trait(PolyTraitRef<'hir>),
Outlives(&'hir Lifetime),
Use(&'hir [PreciseCapturingArg<'hir>], Span),
}
@@ -528,7 +528,7 @@ pub enum GenericBound<'hir> {
impl GenericBound<'_> {
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
match self {
- GenericBound::Trait(data, _) => Some(&data.trait_ref),
+ GenericBound::Trait(data) => Some(&data.trait_ref),
_ => None,
}
}
@@ -2874,11 +2874,7 @@ pub enum TyKind<'hir> {
OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
- TraitObject(
- &'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
- &'hir Lifetime,
- TraitObjectSyntax,
- ),
+ TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
/// Unused for now.
Typeof(&'hir AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
@@ -3182,6 +3178,11 @@ pub struct PolyTraitRef<'hir> {
/// The `'a` in `for<'a> Foo<&'a T>`.
pub bound_generic_params: &'hir [GenericParam<'hir>],
+ /// The constness and polarity of the trait ref.
+ ///
+ /// The `async` modifier is lowered directly into a different trait for now.
+ pub modifiers: TraitBoundModifier,
+
/// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
pub trait_ref: TraitRef<'hir>,
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 58916d0586593..ffe519b0e7dd0 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -905,7 +905,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
try_visit!(visitor.visit_array_length(length));
}
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
- for (bound, _modifier) in bounds {
+ for bound in bounds {
try_visit!(visitor.visit_poly_trait_ref(bound));
}
try_visit!(visitor.visit_lifetime(lifetime));
@@ -1160,7 +1160,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(
bound: &'v GenericBound<'v>,
) -> V::Result {
match *bound {
- GenericBound::Trait(ref typ, _modifier) => visitor.visit_poly_trait_ref(typ),
+ GenericBound::Trait(ref typ) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
GenericBound::Use(args, _) => {
walk_list!(visitor, visit_precise_capturing_arg, args);
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_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3a9d2640eee93..607068f162aa3 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -531,7 +531,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
debug!(?required_bounds);
let param_env = tcx.param_env(gat_def_id);
- let mut unsatisfied_bounds: Vec<_> = required_bounds
+ let unsatisfied_bounds: Vec<_> = required_bounds
.into_iter()
.filter(|clause| match clause.kind().skip_binder() {
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
@@ -552,9 +552,6 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
.map(|clause| clause.to_string())
.collect();
- // We sort so that order is predictable
- unsatisfied_bounds.sort();
-
if !unsatisfied_bounds.is_empty() {
let plural = pluralize!(unsatisfied_bounds.len());
let suggestion = format!(
@@ -832,7 +829,7 @@ impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> {
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
match ty.kind {
- hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments {
+ hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
_ => false,
},
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index d1c888a185ed9..5127e73d9784d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -319,9 +319,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
// List of connected regions is built. Now, run the overlap check
// for each pair of impl blocks in the same connected region.
for region in connected_regions.into_iter().flatten() {
- let mut impl_blocks =
- region.impl_blocks.into_iter().collect::>();
- impl_blocks.sort_unstable();
+ let impl_blocks = region.impl_blocks.into_iter().collect::>();
for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() {
let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx];
res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id));
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 6d30f7c7b9d07..a87b29b3093d2 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -866,7 +866,7 @@ impl<'tcx> ItemCtxt<'tcx> {
#[instrument(level = "trace", skip(self))]
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
match b {
- hir::GenericBound::Trait(poly_trait_ref, _) => {
+ hir::GenericBound::Trait(poly_trait_ref) => {
let trait_ref = &poly_trait_ref.trait_ref;
if let Some(trait_did) = trait_ref.trait_def_id() {
self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index c8852a3a3695a..cb7f0901c7e4a 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -644,7 +644,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
debug!(?bounds, ?lifetime, "TraitObject");
let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |this| {
- for (bound, _) in bounds {
+ for bound in bounds {
this.visit_poly_trait_ref_inner(
bound,
NonLifetimeBinderAllowed::Deny("trait object types"),
@@ -1918,7 +1918,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
return None;
}
predicate.bounds.iter().find_map(|bound| {
- let hir::GenericBound::Trait(trait_, _) = bound else {
+ let hir::GenericBound::Trait(trait_) = bound else {
return None;
};
BoundVarContext::supertrait_hrtb_vars(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 45cd46e3df296..8f7ca089c9184 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -44,10 +44,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for hir_bound in hir_bounds {
- let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
+ let hir::GenericBound::Trait(ptr) = hir_bound else {
continue;
};
- match modifier {
+ match ptr.modifiers {
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
hir::TraitBoundModifier::Negative => {
if let Some(sized_def_id) = sized_def_id
@@ -156,8 +156,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
{
for hir_bound in hir_bounds {
match hir_bound {
- hir::GenericBound::Trait(poly_trait_ref, modifier) => {
- let (constness, polarity) = match modifier {
+ hir::GenericBound::Trait(poly_trait_ref) => {
+ let (constness, polarity) = match poly_trait_ref.modifiers {
hir::TraitBoundModifier::Const => {
(ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 394a263fbb595..98822eec2ac4d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&self,
span: Span,
hir_id: hir::HirId,
- hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
+ hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
lifetime: &hir::Lifetime,
representation: DynKind,
) -> Ty<'tcx> {
@@ -39,8 +39,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let mut bounds = Bounds::default();
let mut potential_assoc_types = Vec::new();
let dummy_self = self.tcx().types.trait_object_dummy_self;
- for (trait_bound, modifier) in hir_trait_bounds.iter().rev() {
- if *modifier == hir::TraitBoundModifier::Maybe {
+ for trait_bound in hir_trait_bounds.iter().rev() {
+ // FIXME: This doesn't handle `? const`.
+ if trait_bound.modifiers == hir::TraitBoundModifier::Maybe {
continue;
}
if let GenericArgCountResult {
@@ -263,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let args = tcx.mk_args(&args);
let span = i.bottom().1;
- let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| {
+ let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
&& hir_bound.span.contains(span)
});
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index a735b8cc2a451..01768c89cca89 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -718,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&self,
associated_types: FxIndexMap>,
potential_assoc_types: Vec,
- trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)],
+ trait_bounds: &[hir::PolyTraitRef<'_>],
) {
if associated_types.values().all(|v| v.is_empty()) {
return;
@@ -764,12 +764,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// related to issue #91997, turbofishes added only when in an expr or pat
let mut in_expr_or_pat = false;
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
- let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.0.trait_ref.hir_ref_id));
+ let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
in_expr_or_pat = match grandparent {
hir::Node::Expr(_) | hir::Node::Pat(_) => true,
_ => false,
};
- match bound.0.trait_ref.path.segments {
+ match bound.trait_ref.path.segments {
// FIXME: `trait_ref.path.span` can point to a full path with multiple
// segments, even though `trait_ref.path.segments` is of length `1`. Work
// around that bug here, even though it should be fixed elsewhere.
@@ -810,7 +810,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// and we can then use their span to indicate this to the user.
let bound_names = trait_bounds
.iter()
- .filter_map(|(poly_trait_ref, _)| {
+ .filter_map(|poly_trait_ref| {
let path = poly_trait_ref.trait_ref.path.segments.last()?;
let args = path.args?;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 11c0450bfe211..fd49e7e44398b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -50,7 +50,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.ok()
.is_some_and(|s| s.trim_end().ends_with('<'));
- let is_global = poly_trait_ref.0.trait_ref.path.is_global();
+ let is_global = poly_trait_ref.trait_ref.path.is_global();
let mut sugg = vec![(
self_ty.span.shrink_to_lo(),
@@ -211,7 +211,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Check if trait object is safe for suggesting dynamic dispatch.
let is_dyn_compatible = match self_ty.kind {
hir::TyKind::TraitObject(objects, ..) => {
- objects.iter().all(|(o, _)| match o.trait_ref.path.res {
+ objects.iter().all(|o| match o.trait_ref.path.res {
Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
_ => false,
})
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 9fe6a8ee3425a..9ebfd4f15abd3 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -301,16 +301,13 @@ impl<'a> State<'a> {
self.word_space("dyn");
}
let mut first = true;
- for (bound, modifier) in bounds {
+ for bound in bounds {
if first {
first = false;
} else {
self.nbsp();
self.word_space("+");
}
- if *modifier == TraitBoundModifier::Maybe {
- self.word("?");
- }
self.print_poly_trait_ref(bound);
}
if !lifetime.is_elided() {
@@ -679,6 +676,10 @@ impl<'a> State<'a> {
}
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) {
+ // FIXME: This isn't correct!
+ if t.modifiers == TraitBoundModifier::Maybe {
+ self.word("?");
+ }
self.print_formal_generic_params(t.bound_generic_params);
self.print_trait_ref(&t.trait_ref);
}
@@ -2077,10 +2078,7 @@ impl<'a> State<'a> {
}
match bound {
- GenericBound::Trait(tref, modifier) => {
- if modifier == &TraitBoundModifier::Maybe {
- self.word("?");
- }
+ GenericBound::Trait(tref) => {
self.print_poly_trait_ref(tref);
}
GenericBound::Outlives(lt) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1df4d32f3cbac..3e9e53261562c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -849,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::FnRetTy::Return(hir_ty) => {
if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
// FIXME: account for RPITIT.
- && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
+ && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
trait_ref.trait_ref.path.segments.last()
&& let [constraint] = generic_args.constraints
@@ -1035,7 +1035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// extract all bounds from the source code using their spans
let all_matching_bounds_strs = predicates_from_where
.filter_map(|bound| match bound {
- GenericBound::Trait(_, _) => {
+ GenericBound::Trait(_) => {
self.tcx.sess.source_map().span_to_snippet(bound.span()).ok()
}
_ => None,
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index c0a01b0065ef9..5a3666dcbd432 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -112,10 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
- for (bound, modifier) in &bounds[..] {
+ for bound in &bounds[..] {
let def_id = bound.trait_ref.trait_def_id();
if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop))
- && *modifier != hir::TraitBoundModifier::Maybe
+ // FIXME: ?Drop is not a thing.
+ && bound.modifiers != hir::TraitBoundModifier::Maybe
{
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
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/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 354ca746b466a..4f408ee157481 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -192,7 +192,8 @@ fn suggest_changing_unsized_bound(
.iter()
.enumerate()
.filter(|(_, bound)| {
- if let hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) = bound
+ if let hir::GenericBound::Trait(poly) = bound
+ && poly.modifiers == hir::TraitBoundModifier::Maybe
&& poly.trait_ref.trait_def_id() == def_id
{
true
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index f32307f6ed4d8..a9384501547e8 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> {
&& let Some(poly) = bounds
.iter()
.filter_map(|bound| match bound {
- ast::GenericBound::Trait(poly, _) => Some(poly),
+ ast::GenericBound::Trait(poly) => Some(poly),
_ => None,
})
.last()
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 162ff3b94de52..2f19a9b6b20b4 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -948,8 +948,8 @@ impl<'a> Parser<'a> {
{
return Ok((false, seg.ident, seg.args.as_deref().cloned()));
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
- && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] =
- bounds.as_slice()
+ && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice()
+ && trait_ref.modifiers == ast::TraitBoundModifiers::NONE
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
{
return Ok((true, seg.ident, seg.args.as_deref().cloned()));
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 625a4cabdf273..6820ccaa18b04 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -419,8 +419,13 @@ impl<'a> Parser<'a> {
lo: Span,
parse_plus: bool,
) -> PResult<'a, TyKind> {
- let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
- let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)];
+ let poly_trait_ref = PolyTraitRef::new(
+ generic_params,
+ path,
+ TraitBoundModifiers::NONE,
+ lo.to(self.prev_token.span),
+ );
+ let bounds = vec![GenericBound::Trait(poly_trait_ref)];
self.parse_remaining_bounds(bounds, parse_plus)
}
@@ -1085,8 +1090,9 @@ impl<'a> Parser<'a> {
}
}
- let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
- Ok(GenericBound::Trait(poly_trait, modifiers))
+ let poly_trait =
+ PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
+ Ok(GenericBound::Trait(poly_trait))
}
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index fce5ec36c661b..5fbc817b91a7f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
continue;
};
for bound in bounds {
- let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound
- else {
+ let ast::GenericBound::Trait(trait_ref) = bound else {
continue;
};
- if base_error.span == trait_ref.span {
+ if trait_ref.modifiers == ast::TraitBoundModifiers::NONE
+ && base_error.span == trait_ref.span
+ {
err.span_suggestion_verbose(
constraint.ident.span.between(trait_ref.span),
"you might have meant to write a path instead of an associated type bound",
@@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
);
if bounds.iter().all(|bound| match bound {
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
- ast::GenericBound::Trait(tr, _) => tr.span == base_error.span,
+ ast::GenericBound::Trait(tr) => tr.span == base_error.span,
}) {
let mut sugg = vec![];
if base_error.span != start_span {
@@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let param = generics.params.iter().find_map(|param| {
// Only consider type params with exactly one trait bound.
if let [bound] = &*param.bounds
- && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound
+ && let ast::GenericBound::Trait(tref) = bound
+ && tref.modifiers == ast::TraitBoundModifiers::NONE
&& tref.span == span
&& param.ident.span.eq_ctxt(span)
{
@@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
if let (
[ast::PathSegment { args: None, .. }],
- [ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)],
+ [ast::GenericBound::Trait(poly_trait_ref)],
) = (&type_param_path.segments[..], &bounds[..])
+ && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE
{
if let [ast::PathSegment { ident, args: None, .. }] =
&poly_trait_ref.trait_ref.path.segments[..]
@@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
&& bounded_ty.id == binder
{
for bound in bounds {
- if let ast::GenericBound::Trait(poly_trait_ref, _) = bound
+ if let ast::GenericBound::Trait(poly_trait_ref) = bound
&& let span = poly_trait_ref
.span
.with_hi(poly_trait_ref.trait_ref.path.span.lo())
@@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let mut lt_finder =
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
for bound in arg_refs {
- if let ast::GenericBound::Trait(trait_ref, _) = bound {
+ if let ast::GenericBound::Trait(trait_ref) = bound {
lt_finder.visit_trait_ref(&trait_ref.trait_ref);
}
}
@@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate(
span: DUMMY_SP,
bound_generic_params: ThinVec::new(),
bounded_ty: ast::ptr::P(ty.clone()),
- bounds: vec![ast::GenericBound::Trait(
- ast::PolyTraitRef {
- bound_generic_params: ThinVec::new(),
- trait_ref: ast::TraitRef {
- path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
- ref_id: DUMMY_NODE_ID,
- },
- span: DUMMY_SP,
+ bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
+ bound_generic_params: ThinVec::new(),
+ modifiers: ast::TraitBoundModifiers::NONE,
+ trait_ref: ast::TraitRef {
+ path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
+ ref_id: DUMMY_NODE_ID,
},
- ast::TraitBoundModifiers::NONE,
- )],
+ span: DUMMY_SP,
+ })],
};
Some(new_where_bound_predicate)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index 7a44c2ad661dc..2ecd28f48681d 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
@@ -86,7 +86,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
}
hir::TyKind::TraitObject(bounds, ..) => {
- for (bound, _) in bounds {
+ for bound in bounds {
self.current_index.shift_in(1);
self.visit_poly_trait_ref(bound);
self.current_index.shift_out(1);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index a6ecd1cc9871b..8541621b23b87 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -599,7 +599,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
_,
) = t.kind
{
- for (ptr, _) in poly_trait_refs {
+ for ptr in poly_trait_refs {
if Some(self.1) == ptr.trait_ref.trait_def_id() {
self.0.push(ptr.span);
}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index cf0ab630f2e21..62204f63dd09a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -894,7 +894,9 @@ fn foo(&self) -> Self::T { String::new() }
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
let trait_bounds = bounds.iter().filter_map(|bound| match bound {
- hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
+ hir::GenericBound::Trait(ptr) if ptr.modifiers == hir::TraitBoundModifier::None => {
+ Some(ptr)
+ }
_ => None,
});
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 709b6eb18e35f..fc2d0ba36f04e 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -740,9 +740,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
left, right,
) {
- (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr))
+ // FIXME: Suspicious
+ (hir::GenericBound::Trait(tl), hir::GenericBound::Trait(tr))
if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
- && ml == mr =>
+ && tl.modifiers == tr.modifiers =>
{
true
}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index becc1acfb6641..ba57909fc23a6 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -439,7 +439,7 @@ pub fn report_dyn_incompatibility<'tcx>(
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
// Do not suggest `impl Trait` when dealing with things like super-traits.
err.span_suggestion_verbose(
- ty.span.until(trait_ref.0.span),
+ ty.span.until(trait_ref.span),
"consider using an opaque type instead",
"impl ",
Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 87834c329e19f..733baaa99e52a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3074,11 +3074,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
match ty.kind {
hir::TyKind::TraitObject(traits, _, _) => {
let (span, kw) = match traits {
- [(first, _), ..] if first.span.lo() == ty.span.lo() => {
+ [first, ..] if first.span.lo() == ty.span.lo() => {
// Missing `dyn` in front of trait object.
(ty.span.shrink_to_lo(), "dyn ")
}
- [(first, _), ..] => (ty.span.until(first.span), ""),
+ [first, ..] => (ty.span.until(first.span), ""),
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
};
let needs_parens = traits.len() != 1;
@@ -5162,7 +5162,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
- let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
+ let [hir::GenericBound::Trait(trait_ref)] = future.bounds else {
// `async fn` should always lower to a single bound... but don't ICE.
return None;
};
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 45e7de942fb61..364a13b3a7599 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -125,7 +125,7 @@ fn sized_trait_bound_spans<'tcx>(
bounds: hir::GenericBounds<'tcx>,
) -> impl 'tcx + Iterator- {
bounds.iter().filter_map(move |b| match b {
- hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
+ hir::GenericBound::Trait(trait_ref)
if trait_has_sized_self(
tcx,
trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
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/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/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fa73733360ca1..1ddad917b783c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -214,15 +214,15 @@ fn clean_generic_bound<'tcx>(
) -> Option {
Some(match *bound {
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
- hir::GenericBound::Trait(ref t, modifier) => {
+ hir::GenericBound::Trait(ref t) => {
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
- if modifier == hir::TraitBoundModifier::MaybeConst
+ if t.modifiers == hir::TraitBoundModifier::MaybeConst
&& cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap())
{
return None;
}
- GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier)
+ GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers)
}
hir::GenericBound::Use(args, ..) => {
GenericBound::Use(args.iter().map(|arg| arg.name()).collect())
@@ -1833,7 +1833,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
}
TyKind::Path(_) => clean_qpath(ty, cx),
TyKind::TraitObject(bounds, lifetime, _) => {
- let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect();
+ let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
let lifetime =
if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None };
DynTrait(bounds, lifetime)
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 5f349d780537b..590d9afd1b437 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -242,7 +242,8 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
bounds
.iter()
.filter_map(|bound| {
- if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+ if let GenericBound::Trait(poly_trait) = bound
+ && let TraitBoundModifier::None = poly_trait.modifiers
&& let [.., path] = poly_trait.trait_ref.path.segments
&& poly_trait.bound_generic_params.is_empty()
&& let Some(trait_def_id) = path.res.opt_def_id()
@@ -307,7 +308,8 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
// This involves some extra logic when generic arguments are present, since
// simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
for (index, bound) in bounds.iter().enumerate() {
- if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+ if let GenericBound::Trait(poly_trait) = bound
+ && let TraitBoundModifier::None = poly_trait.modifiers
&& let [.., path] = poly_trait.trait_ref.path.segments
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 311bbce14bd7e..035ee40348c77 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -310,7 +310,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
if let ty::Alias(_, alias_ty) = ty.kind()
&& let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
&& let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
- && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
+ && let [GenericBound::Trait(trait_ref)] = &opaque.bounds
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(generic_args) = segment.args
&& let [constraint] = generic_args.constraints
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index ec28671a061e4..a7c48eb216aa4 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -163,7 +163,7 @@ fn check_fn_inner<'tcx>(
if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) {
return;
}
- if let GenericBound::Trait(ref trait_ref, _) = *bound {
+ if let GenericBound::Trait(ref trait_ref) = *bound {
let params = &trait_ref
.trait_ref
.path
@@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
if !lt.is_elided() {
self.unelided_trait_object_lifetime = true;
}
- for (bound, _) in bounds {
+ for bound in bounds {
self.visit_poly_trait_ref(bound);
}
},
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 81115cffdca88..67255c1af7933 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -107,7 +107,7 @@ fn future_trait_ref<'tcx>(
) -> Option<(&'tcx TraitRef<'tcx>, Vec)> {
if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
&& let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
- if let GenericBound::Trait(poly, _) = bound {
+ if let GenericBound::Trait(poly) = bound {
Some(&poly.trait_ref)
} else {
None
diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
index bb44ff37b203b..a56024f08d509 100644
--- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
@@ -40,7 +40,6 @@ struct Bound<'tcx> {
ident: Ident,
trait_bound: &'tcx PolyTraitRef<'tcx>,
- modifier: TraitBoundModifier,
predicate_pos: usize,
bound_pos: usize,
@@ -65,11 +64,10 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator
- Some(Bound {
+ &GenericBound::Trait(ref trait_bound) => Some(Bound {
param,
ident,
trait_bound,
- modifier,
predicate_pos,
bound_pos,
}),
@@ -120,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized {
let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
.filter(|bound| {
bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)
- && bound.modifier == TraitBoundModifier::Maybe
+ && bound.trait_bound.modifiers == TraitBoundModifier::Maybe
})
.map(|bound| (bound.param, bound))
.collect();
for bound in type_param_bounds(generics) {
- if bound.modifier == TraitBoundModifier::None
+ if bound.trait_bound.modifiers == TraitBoundModifier::None
&& let Some(sized_bound) = maybe_sized_params.get(&bound.param)
&& let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
{
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 3c3973857e796..38befdee57478 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
// Iterate the bounds and add them to our seen hash
// If we haven't yet seen it, add it to the fixed traits
- for (bound, _) in bounds {
+ for bound in bounds {
let Some(def_id) = bound.trait_ref.trait_def_id() else {
continue;
};
@@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
// If the number of unique traits isn't the same as the number of traits in the bounds,
// there must be 1 or more duplicates
if bounds.len() != unique_traits.len() {
- let mut bounds_span = bounds[0].0.span;
+ let mut bounds_span = bounds[0].span;
- for (bound, _) in bounds.iter().skip(1) {
+ for bound in bounds.iter().skip(1) {
bounds_span = bounds_span.to(bound.span);
}
@@ -229,7 +229,8 @@ impl TraitBounds {
/// this MSRV? See for details.
fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE)
- && let GenericBound::Trait(tr, TraitBoundModifier::Maybe) = bound
+ && let GenericBound::Trait(tr) = bound
+ && let TraitBoundModifier::Maybe = tr.modifiers
{
cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()
} else {
@@ -375,11 +376,11 @@ impl Default for ComparableTraitRef {
}
fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> {
- if let GenericBound::Trait(t, tbm) = bound {
+ if let GenericBound::Trait(t) = bound {
let trait_path = t.trait_ref.path;
let trait_span = {
let path_span = trait_path.span;
- if let TraitBoundModifier::Maybe = tbm {
+ if let TraitBoundModifier::Maybe = t.modifiers {
path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?`
} else {
path_span
@@ -430,7 +431,7 @@ fn rollup_traits(
let mut repeated_res = false;
let only_comparable_trait_refs = |bound: &GenericBound<'_>| {
- if let GenericBound::Trait(t, _) = bound {
+ if let GenericBound::Trait(t) = bound {
Some((into_comparable_trait_ref(&t.trait_ref), t.span))
} else {
None
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index 2fcfc71a8c768..eb7ffbbe360d5 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -82,7 +82,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
// Returns true if given type is `Any` trait.
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
if let TyKind::TraitObject(traits, ..) = t.kind {
- return traits.iter().any(|(bound, _)| {
+ return traits.iter().any(|bound| {
if let Some(trait_did) = bound.trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::Any, trait_did)
{
diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
index 0b64fddb447b5..b89bd6a8d0589 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -55,7 +55,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
TyKind::TraitObject(param_bounds, _, _) => {
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
bound
- .0
.bound_generic_params
.iter()
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 68f74e52ed7b7..315856984751f 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -783,7 +783,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool {
}
pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {
- eq_path(&l.trait_ref.path, &r.trait_ref.path)
+ l.modifiers == r.modifiers
+ && eq_path(&l.trait_ref.path, &r.trait_ref.path)
&& over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
eq_generic_param(l, r)
})
@@ -817,7 +818,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
use GenericBound::*;
match (l, r) {
- (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2),
+ (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2),
(Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
_ => false,
}
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/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 555a924079879..4d684f3c6350d 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg {
impl Spanned for ast::GenericBound {
fn span(&self) -> Span {
match *self {
- ast::GenericBound::Trait(ref ptr, _) => ptr.span,
+ ast::GenericBound::Trait(ref ptr) => ptr.span,
ast::GenericBound::Outlives(ref l) => l.ident.span,
ast::GenericBound::Use(_, span) => span,
}
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index f75c4f0fad741..a7bd8312bb8d4 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound {
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
match *self {
- ast::GenericBound::Trait(
- ref poly_trait_ref,
- ast::TraitBoundModifiers {
+ ast::GenericBound::Trait(ref poly_trait_ref) => {
+ let snippet = context.snippet(self.span());
+ let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
+ let ast::TraitBoundModifiers {
constness,
asyncness,
polarity,
- },
- ) => {
- let snippet = context.snippet(self.span());
- let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
+ } = poly_trait_ref.modifiers;
let mut constness = constness.as_str().to_string();
if !constness.is_empty() {
constness.push(' ');
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);
+}