diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 72d5f004194a8..e2193a97a0f43 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -59,11 +59,16 @@ macro_rules! already_send { // These structures are already `Send`. already_send!( - [std::backtrace::Backtrace][std::io::Stdout][std::io::Stderr][std::io::Error][std::fs::File][std::panic::Location<'_>] - [rustc_arena::DroplessArena][jobserver_crate::Client][jobserver_crate::HelperThread] - [crate::memmap::Mmap][crate::profiling::SelfProfiler][crate::owned_slice::OwnedSlice] + [std::sync::atomic::AtomicBool][std::sync::atomic::AtomicUsize][std::sync::atomic::AtomicU8] + [std::sync::atomic::AtomicU32][std::backtrace::Backtrace][std::io::Stdout][std::io::Stderr] + [std::io::Error][std::fs::File][std::panic::Location<'_>][rustc_arena::DroplessArena] + [jobserver_crate::Client][jobserver_crate::HelperThread][crate::memmap::Mmap] + [crate::profiling::SelfProfiler][crate::owned_slice::OwnedSlice] ); +#[cfg(target_has_atomic = "64")] +already_send!([std::sync::atomic::AtomicU64]); + macro_rules! impl_dyn_send { ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => { $(unsafe impl<$($generics2)*> DynSend for $ty {})* diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a2427d9ca5889..6f9795db17ebe 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1036,31 +1036,13 @@ impl InvalidAtomicOrdering { expr: &Expr<'hir>, recognized_names: &[Symbol], // used for fast path calculation ) -> Option<(Symbol, &'hir [Expr<'hir>])> { - const ATOMIC_TYPES: &[Symbol] = &[ - sym::AtomicBool, - sym::AtomicPtr, - sym::AtomicUsize, - sym::AtomicU8, - sym::AtomicU16, - sym::AtomicU32, - sym::AtomicU64, - sym::AtomicU128, - sym::AtomicIsize, - sym::AtomicI8, - sym::AtomicI16, - sym::AtomicI32, - sym::AtomicI64, - sym::AtomicI128, - ]; if let ExprKind::MethodCall(method_path, _, args, _) = &expr.kind && recognized_names.contains(&method_path.ident.name) && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) // skip extension traits, only lint functions from the standard library && let Some(impl_did) = cx.tcx.inherent_impl_of_assoc(m_def_id) && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() - && let parent = cx.tcx.parent(adt.did()) - && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent) - && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did())) + && cx.tcx.is_diagnostic_item(sym::Atomic, adt.did()) { return Some((method_path.ident.name, args)); } diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index f37cf4c8dc8c0..9eb45666442fc 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -108,13 +108,6 @@ impl IsTyMustUse { _ => self, } } - - fn yes(self) -> Option { - match self { - Self::Yes(must_use_path) => Some(must_use_path), - _ => None, - } - } } /// A path through a type to a `must_use` source. Contains useful info for the lint. @@ -254,16 +247,23 @@ pub fn is_ty_must_use<'tcx>( // Default to `expr`. let elem_exprs = elem_exprs.iter().chain(iter::repeat(expr)); - let nested_must_use = tys - .iter() - .zip(elem_exprs) - .enumerate() - .filter_map(|(i, (ty, expr))| { - is_ty_must_use(cx, ty, expr, simplify_uninhabited).yes().map(|path| (i, path)) - }) - .collect::>(); + let mut all_trivial = true; + let mut nested_must_use = Vec::new(); + + tys.iter().zip(elem_exprs).enumerate().for_each(|(i, (ty, expr))| { + let must_use = is_ty_must_use(cx, ty, expr, simplify_uninhabited); + + all_trivial &= matches!(must_use, IsTyMustUse::Trivial); + if let IsTyMustUse::Yes(path) = must_use { + nested_must_use.push((i, path)); + } + }); - if !nested_must_use.is_empty() { + if all_trivial { + // If all tuple elements are trivial, mark the whole tuple as such. + // i.e. don't emit `unused_results` for types such as `((), ())` + IsTyMustUse::Trivial + } else if !nested_must_use.is_empty() { IsTyMustUse::Yes(MustUsePath::TupleElement(nested_must_use)) } else { IsTyMustUse::No diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index cd9c53134ae20..721cc7fe4d9b3 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -10,6 +10,7 @@ use syn::{ }; mod kw { + syn::custom_keyword!(non_query); syn::custom_keyword!(query); } @@ -54,12 +55,37 @@ struct Query { modifiers: QueryModifiers, } -impl Parse for Query { +/// Declaration of a non-query dep kind. +/// ```ignore (illustrative) +/// /// Doc comment for `MyNonQuery`. +/// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doc_comments +/// non_query MyNonQuery +/// // ^^^^^^^^^^ name +/// ``` +struct NonQuery { + doc_comments: Vec, + name: Ident, +} + +enum QueryEntry { + Query(Query), + NonQuery(NonQuery), +} + +impl Parse for QueryEntry { fn parse(input: ParseStream<'_>) -> Result { let mut doc_comments = check_attributes(input.call(Attribute::parse_outer)?)?; + // Try the non-query case first. + if input.parse::().is_ok() { + let name: Ident = input.parse()?; + return Ok(QueryEntry::NonQuery(NonQuery { doc_comments, name })); + } + // Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>` - input.parse::()?; + if input.parse::().is_err() { + return Err(input.error("expected `query` or `non_query`")); + } let name: Ident = input.parse()?; // `(key: DefId)` @@ -84,7 +110,7 @@ impl Parse for Query { doc_comments.push(doc_comment_from_desc(&modifiers.desc.expr_list)?); } - Ok(Query { doc_comments, modifiers, name, key_pat, key_ty, return_ty }) + Ok(QueryEntry::Query(Query { doc_comments, modifiers, name, key_pat, key_ty, return_ty })) } } @@ -375,9 +401,9 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke // macro producing a higher order macro that has all its token in the macro declaration we lose // any meaningful spans, resulting in rust-analyzer being unable to make the connection between // the query name and the corresponding providers field. The trick to fix this is to have - // `rustc_queries` emit a field access with the given name's span which allows it to successfully - // show references / go to definition to the corresponding provider assignment which is usually - // the more interesting place. + // `rustc_queries` emit a field access with the given name's span which allows it to + // successfully show references / go to definition to the corresponding provider assignment + // which is usually the more interesting place. let ra_hint = quote! { let crate::query::Providers { #name: _, .. }; }; @@ -393,9 +419,10 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke } pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { - let queries = parse_macro_input!(input as List); + let queries = parse_macro_input!(input as List); let mut query_stream = quote! {}; + let mut non_query_stream = quote! {}; let mut helpers = HelperTokenStreams::default(); let mut analyzer_stream = quote! {}; let mut errors = quote! {}; @@ -411,6 +438,18 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { } for query in queries.0 { + let query = match query { + QueryEntry::Query(query) => query, + QueryEntry::NonQuery(NonQuery { doc_comments, name }) => { + // Get the exceptional non-query case out of the way first. + non_query_stream.extend(quote! { + #(#doc_comments)* + #name, + }); + continue; + } + }; + let Query { doc_comments, name, key_ty, return_ty, modifiers, .. } = &query; // Normalize an absent return type into `-> ()` to make macro-rules parsing easier. @@ -486,24 +525,18 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { let HelperTokenStreams { description_fns_stream, cache_on_disk_if_fns_stream } = helpers; TokenStream::from(quote! { - /// Higher-order macro that invokes the specified macro with a prepared - /// list of all query signatures (including modifiers). - /// - /// This allows multiple simpler macros to each have access to the list - /// of queries. + /// Higher-order macro that invokes the specified macro with (a) a list of all query + /// signatures (including modifiers), and (b) a list of non-query names. This allows + /// multiple simpler macros to each have access to these lists. #[macro_export] macro_rules! rustc_with_all_queries { ( - // The macro to invoke once, on all queries (plus extras). + // The macro to invoke once, on all queries and non-queries. $macro:ident! - - // Within [], an optional list of extra "query" signatures to - // pass to the given macro, in addition to the actual queries. - $( [$($extra_fake_queries:tt)*] )? ) => { $macro! { - $( $($extra_fake_queries)* )? - #query_stream + queries { #query_stream } + non_queries { #non_query_stream } } } } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index c356d566626d1..7efa013c3d999 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -265,18 +265,20 @@ impl StableOrd for WorkProductId { // Note: `$K` and `$V` are unused but present so this can be called by `rustc_with_all_queries`. macro_rules! define_dep_nodes { ( - $( - $(#[$attr:meta])* - [$($modifiers:tt)*] fn $variant:ident($K:ty) -> $V:ty, - )* - ) => { - - #[macro_export] - macro_rules! make_dep_kind_array { - ($mod:ident) => {[ $($mod::$variant()),* ]}; + queries { + $( + $(#[$q_attr:meta])* + [$($modifiers:tt)*] + fn $q_name:ident($K:ty) -> $V:ty, + )* } - - /// This enum serves as an index into arrays built by `make_dep_kind_array`. + non_queries { + $( + $(#[$nq_attr:meta])* + $nq_name:ident, + )* + } + ) => { // This enum has more than u8::MAX variants so we need some kind of multi-byte // encoding. The derived Encodable/Decodable uses leb128 encoding which is // dense when only considering this enum. But DepKind is encoded in a larger @@ -285,14 +287,18 @@ macro_rules! define_dep_nodes { #[allow(non_camel_case_types)] #[repr(u16)] // Must be kept in sync with the rest of `DepKind`. pub enum DepKind { - $( $( #[$attr] )* $variant),* + $( $(#[$nq_attr])* $nq_name, )* + $( $(#[$q_attr])* $q_name, )* } // This computes the number of dep kind variants. Along the way, it sanity-checks that the // discriminants of the variants have been assigned consecutively from 0 so that they can // be used as a dense index, and that all discriminants fit in a `u16`. pub(crate) const DEP_KIND_NUM_VARIANTS: u16 = { - let deps = &[$(DepKind::$variant,)*]; + let deps = &[ + $(DepKind::$nq_name,)* + $(DepKind::$q_name,)* + ]; let mut i = 0; while i < deps.len() { if i != deps[i].as_usize() { @@ -306,7 +312,8 @@ macro_rules! define_dep_nodes { pub(super) fn dep_kind_from_label_string(label: &str) -> Result { match label { - $( stringify!($variant) => Ok(self::DepKind::$variant), )* + $( stringify!($nq_name) => Ok(self::DepKind::$nq_name), )* + $( stringify!($q_name) => Ok(self::DepKind::$q_name), )* _ => Err(()), } } @@ -315,27 +322,14 @@ macro_rules! define_dep_nodes { /// DepNode groups for tests. #[expect(non_upper_case_globals)] pub mod label_strs { - $( pub const $variant: &str = stringify!($variant); )* + $( pub const $nq_name: &str = stringify!($nq_name); )* + $( pub const $q_name: &str = stringify!($q_name); )* } }; } -// Create various data structures for each query, and also for a few things -// that aren't queries. The key and return types aren't used, hence the use of `()`. -rustc_with_all_queries!(define_dep_nodes![ - /// We use this for most things when incr. comp. is turned off. - [] fn Null(()) -> (), - /// We use this to create a forever-red node. - [] fn Red(()) -> (), - /// We use this to create a side effect node. - [] fn SideEffect(()) -> (), - /// We use this to create the anon node with zero dependencies. - [] fn AnonZeroDeps(()) -> (), - [] fn TraitSelect(()) -> (), - [] fn CompileCodegenUnit(()) -> (), - [] fn CompileMonoItem(()) -> (), - [] fn Metadata(()) -> (), -]); +// Create various data structures for each query, and also for a few things that aren't queries. +rustc_with_all_queries! { define_dep_nodes! } // WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys. // Be very careful changing this type signature! diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index f54b291a2024f..932d0855c6016 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -2771,6 +2771,23 @@ rustc_queries! { cache_on_disk_if { *cnum == LOCAL_CRATE } separate_provide_extern } + + //----------------------------------------------------------------------------- + // "Non-queries" are special dep kinds that are not queries. + //----------------------------------------------------------------------------- + + /// We use this for most things when incr. comp. is turned off. + non_query Null + /// We use this to create a forever-red node. + non_query Red + /// We use this to create a side effect node. + non_query SideEffect + /// We use this to create the anon node with zero dependencies. + non_query AnonZeroDeps + non_query TraitSelect + non_query CompileCodegenUnit + non_query CompileMonoItem + non_query Metadata } rustc_with_all_queries! { define_callbacks! } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index e1a19e5ffec7f..ff6d87298028f 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -375,11 +375,15 @@ macro_rules! define_callbacks { ( // You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that // `query_helper_param_ty!` can match on specific type names. - $( - $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($($K:tt)*) -> $V:ty, - )* + queries { + $( + $(#[$attr:meta])* + [$($modifiers:tt)*] + fn $name:ident($($K:tt)*) -> $V:ty, + )* + } + // Non-queries are unused here. + non_queries { $($_:tt)* } ) => { $( #[allow(unused_lifetimes)] diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index 01e37ca3e3ee1..ceddef5385a58 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -1,3 +1,4 @@ +use rustc_middle::arena::Arena; use rustc_middle::bug; use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle}; use rustc_middle::query::QueryCache; @@ -124,24 +125,51 @@ where } } -/// Helper module containing a [`DepKindVTable`] constructor for each dep kind, -/// for use with [`rustc_middle::make_dep_kind_array`]. -/// -/// That macro will check that we gave it a constructor for every known dep kind. -mod _dep_kind_vtable_ctors { - // Re-export all of the vtable constructors for non-query and query dep kinds. - - // Non-query vtable constructors are defined in normal code. - pub(crate) use super::non_query::*; - // Query vtable constructors are defined via a macro. - pub(crate) use crate::_dep_kind_vtable_ctors_for_queries::*; +macro_rules! define_dep_kind_vtables { + ( + queries { + $( + $(#[$attr:meta])* + [$($modifiers:tt)*] + fn $name:ident($K:ty) -> $V:ty, + )* + } + non_queries { + $( + $(#[$nq_attr:meta])* + $nq_name:ident, + )* + } + ) => {{ + // The small number of non-query vtables: `Null`, `Red`, etc. + let nq_vtables = [ + $( + non_query::$nq_name(), + )* + ]; + + // The large number of query vtables. + let q_vtables: [DepKindVTable<'tcx>; _] = [ + $( + $crate::dep_kind_vtables::make_dep_kind_vtable_for_query::< + $crate::query_impl::$name::VTableGetter, + >( + is_anon!([$($modifiers)*]), + if_cache_on_disk!([$($modifiers)*] true false), + is_eval_always!([$($modifiers)*]), + ) + ),* + ]; + + (nq_vtables, q_vtables) + }} } -pub fn make_dep_kind_vtables<'tcx>( - arena: &'tcx rustc_middle::arena::Arena<'tcx>, -) -> &'tcx [DepKindVTable<'tcx>] { - // Create an array of vtables, one for each dep kind (non-query and query). - let dep_kind_vtables: [DepKindVTable<'tcx>; _] = - rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors); - arena.alloc_from_iter(dep_kind_vtables) +// Create an array of vtables, one for each dep kind (non-query and query). +pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] { + let (nq_vtables, q_vtables) = + rustc_middle::rustc_with_all_queries! { define_dep_kind_vtables! }; + + // Non-query vtables must come before query vtables, to match the order of `DepKind`. + arena.alloc_from_iter(nq_vtables.into_iter().chain(q_vtables.into_iter())) } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index f22b5be75cafa..17e6fba8ac9a5 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -414,15 +414,20 @@ pub(crate) fn force_from_dep_node_inner<'tcx, Q: GetQueryVTable<'tcx>>( } } -// Note: `$K` and `$V` are unused but present so this can be called by `rustc_with_all_queries`. macro_rules! define_queries { ( - $( - $(#[$attr:meta])* - [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty, - )* + // Note: `$K` and `$V` are unused but present so this can be called by + // `rustc_with_all_queries`. + queries { + $( + $(#[$attr:meta])* + [$($modifiers:tt)*] + fn $name:ident($K:ty) -> $V:ty, + )* + } + // Non-queries are unused here. + non_queries { $($_:tt)* } ) => { - pub(crate) mod query_impl { $(pub(crate) mod $name { use super::super::*; use ::rustc_middle::query::erase::{self, Erased}; @@ -689,23 +694,5 @@ macro_rules! define_queries { }) } } - - /// Declares a dep-kind vtable constructor for each query. - mod _dep_kind_vtable_ctors_for_queries { - use ::rustc_middle::dep_graph::DepKindVTable; - use $crate::dep_kind_vtables::make_dep_kind_vtable_for_query; - - $( - /// `DepKindVTable` constructor for this query. - pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { - use $crate::query_impl::$name::VTableGetter; - make_dep_kind_vtable_for_query::( - is_anon!([$($modifiers)*]), - if_cache_on_disk!([$($modifiers)*] true false), - is_eval_always!([$($modifiers)*]), - ) - } - )* - } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9a2d68fc6639f..b7255ba67dfdb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -171,20 +171,7 @@ symbols! { AsyncGenFinished, AsyncGenPending, AsyncGenReady, - AtomicBool, - AtomicI8, - AtomicI16, - AtomicI32, - AtomicI64, - AtomicI128, - AtomicIsize, - AtomicPtr, - AtomicU8, - AtomicU16, - AtomicU32, - AtomicU64, - AtomicU128, - AtomicUsize, + Atomic, BTreeMap, Bool, Borrow, @@ -485,7 +472,6 @@ symbols! { atomic_load, atomic_max, atomic_min, - atomic_mod, atomic_nand, atomic_or, atomic_singlethreadfence, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 4f51435290e49..364152475e94d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2632,6 +2632,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_def_id != def_id && trait_name == self.tcx.item_name(def_id) && trait_has_same_params(def_id) + // `PointeeSized` is removed during lowering. + && !self.tcx.is_lang_item(def_id, LangItem::PointeeSized) && self.predicate_must_hold_modulo_regions(&Obligation::new( self.tcx, obligation.cause.clone(), diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 4e3a5a7325b4f..3d4f5dd758e13 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -556,7 +556,7 @@ impl Vec { /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be /// allocated and deallocated with the same layout.) - /// * The size of `T` times the `capacity` (ie. the allocated size in bytes), if + /// * The size of `T` times the `capacity` (i.e. the allocated size in bytes), if /// nonzero, needs to be the same size as the pointer was allocated with. /// (Because similar to alignment, [`dealloc`] must be called with the same /// layout `size`.) @@ -658,7 +658,7 @@ impl Vec { /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be /// allocated and deallocated with the same layout.) - /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs + /// * The size of `T` times the `capacity` (i.e. the allocated size in bytes) needs /// to be the same size as the pointer was allocated with. (Because similar to /// alignment, [`dealloc`] must be called with the same layout `size`.) /// * `length` needs to be less than or equal to `capacity`. @@ -1090,7 +1090,7 @@ impl Vec { /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be /// allocated and deallocated with the same layout.) - /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs + /// * The size of `T` times the `capacity` (i.e. the allocated size in bytes) needs /// to be the same size as the pointer was allocated with. (Because similar to /// alignment, [`dealloc`] must be called with the same layout `size`.) /// * `length` needs to be less than or equal to `capacity`. @@ -1201,7 +1201,7 @@ impl Vec { /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be /// allocated and deallocated with the same layout.) - /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs + /// * The size of `T` times the `capacity` (i.e. the allocated size in bytes) needs /// to be the same size as the pointer was allocated with. (Because similar to /// alignment, [`dealloc`] must be called with the same layout `size`.) /// * `length` needs to be less than or equal to `capacity`. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index adc2bbcde51b0..18b05c36fd441 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -238,7 +238,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))] -#![rustc_diagnostic_item = "atomic_mod"] // Clippy complains about the pattern of "safe function calling unsafe function taking pointers". // This happens with AtomicPtr intrinsics but is fine, as the pointers clippy is concerned about // are just normal values that get loaded/stored, but not dereferenced. @@ -248,40 +247,60 @@ use self::Ordering::*; use crate::cell::UnsafeCell; use crate::hint::spin_loop; use crate::intrinsics::AtomicOrdering as AO; +use crate::mem::transmute; use crate::{fmt, intrinsics}; -trait Sealed {} +#[unstable( + feature = "atomic_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +#[expect(missing_debug_implementations)] +mod private { + pub(super) trait Sealed {} + + #[cfg(target_has_atomic_load_store = "8")] + #[repr(C, align(1))] + pub struct Align1(T); + #[cfg(target_has_atomic_load_store = "16")] + #[repr(C, align(2))] + pub struct Align2(T); + #[cfg(target_has_atomic_load_store = "32")] + #[repr(C, align(4))] + pub struct Align4(T); + #[cfg(target_has_atomic_load_store = "64")] + #[repr(C, align(8))] + pub struct Align8(T); + #[cfg(target_has_atomic_load_store = "128")] + #[repr(C, align(16))] + pub struct Align16(T); +} /// A marker trait for primitive types which can be modified atomically. /// /// This is an implementation detail for [Atomic]\ which may disappear or be replaced at any time. -/// -/// # Safety -/// -/// Types implementing this trait must be primitives that can be modified atomically. -/// -/// The associated `Self::AtomicInner` type must have the same size and bit validity as `Self`, -/// but may have a higher alignment requirement, so the following `transmute`s are sound: -/// -/// - `&mut Self::AtomicInner` as `&mut Self` -/// - `Self` as `Self::AtomicInner` or the reverse +// +// # Safety +// +// Types implementing this trait must be primitives that can be modified atomically. +// +// The associated `Self::Storage` type must have the same size, but may have fewer validity +// invariants or a higher alignment requirement than `Self`. #[unstable( feature = "atomic_internals", reason = "implementation detail which may disappear or be replaced at any time", issue = "none" )] #[expect(private_bounds)] -pub unsafe trait AtomicPrimitive: Sized + Copy + Sealed { +pub unsafe trait AtomicPrimitive: Sized + Copy + private::Sealed { /// Temporary implementation detail. - type AtomicInner: Sized; + type Storage: Sized; } macro impl_atomic_primitive( - $Atom:ident $(<$T:ident>)? ($Primitive:ty), - size($size:literal), - align($align:literal) $(,)? + [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>, size($size:literal) ) { - impl $(<$T>)? Sealed for $Primitive {} + impl $(<$T>)? private::Sealed for $Primitive {} #[unstable( feature = "atomic_internals", @@ -290,42 +309,42 @@ macro impl_atomic_primitive( )] #[cfg(target_has_atomic_load_store = $size)] unsafe impl $(<$T>)? AtomicPrimitive for $Primitive { - type AtomicInner = $Atom $(<$T>)?; + type Storage = private::$Storage<$Operand>; } } -impl_atomic_primitive!(AtomicBool(bool), size("8"), align(1)); -impl_atomic_primitive!(AtomicI8(i8), size("8"), align(1)); -impl_atomic_primitive!(AtomicU8(u8), size("8"), align(1)); -impl_atomic_primitive!(AtomicI16(i16), size("16"), align(2)); -impl_atomic_primitive!(AtomicU16(u16), size("16"), align(2)); -impl_atomic_primitive!(AtomicI32(i32), size("32"), align(4)); -impl_atomic_primitive!(AtomicU32(u32), size("32"), align(4)); -impl_atomic_primitive!(AtomicI64(i64), size("64"), align(8)); -impl_atomic_primitive!(AtomicU64(u64), size("64"), align(8)); -impl_atomic_primitive!(AtomicI128(i128), size("128"), align(16)); -impl_atomic_primitive!(AtomicU128(u128), size("128"), align(16)); +impl_atomic_primitive!([] bool as Align1, size("8")); +impl_atomic_primitive!([] i8 as Align1, size("8")); +impl_atomic_primitive!([] u8 as Align1, size("8")); +impl_atomic_primitive!([] i16 as Align2, size("16")); +impl_atomic_primitive!([] u16 as Align2, size("16")); +impl_atomic_primitive!([] i32 as Align4, size("32")); +impl_atomic_primitive!([] u32 as Align4, size("32")); +impl_atomic_primitive!([] i64 as Align8, size("64")); +impl_atomic_primitive!([] u64 as Align8, size("64")); +impl_atomic_primitive!([] i128 as Align16, size("128")); +impl_atomic_primitive!([] u128 as Align16, size("128")); #[cfg(target_pointer_width = "16")] -impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(2)); +impl_atomic_primitive!([] isize as Align2, size("ptr")); #[cfg(target_pointer_width = "32")] -impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(4)); +impl_atomic_primitive!([] isize as Align4, size("ptr")); #[cfg(target_pointer_width = "64")] -impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(8)); +impl_atomic_primitive!([] isize as Align8, size("ptr")); #[cfg(target_pointer_width = "16")] -impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(2)); +impl_atomic_primitive!([] usize as Align2, size("ptr")); #[cfg(target_pointer_width = "32")] -impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(4)); +impl_atomic_primitive!([] usize as Align4, size("ptr")); #[cfg(target_pointer_width = "64")] -impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(8)); +impl_atomic_primitive!([] usize as Align8, size("ptr")); #[cfg(target_pointer_width = "16")] -impl_atomic_primitive!(AtomicPtr(*mut T), size("ptr"), align(2)); +impl_atomic_primitive!([T] *mut T as Align2<*mut T>, size("ptr")); #[cfg(target_pointer_width = "32")] -impl_atomic_primitive!(AtomicPtr(*mut T), size("ptr"), align(4)); +impl_atomic_primitive!([T] *mut T as Align4<*mut T>, size("ptr")); #[cfg(target_pointer_width = "64")] -impl_atomic_primitive!(AtomicPtr(*mut T), size("ptr"), align(8)); +impl_atomic_primitive!([T] *mut T as Align8<*mut T>, size("ptr")); /// A memory location which can be safely modified from multiple threads. /// @@ -342,7 +361,16 @@ impl_atomic_primitive!(AtomicPtr(*mut T), size("ptr"), align(8)); /// /// [module-level documentation]: crate::sync::atomic #[unstable(feature = "generic_atomic", issue = "130539")] -pub type Atomic = ::AtomicInner; +#[repr(C)] +#[rustc_diagnostic_item = "Atomic"] +pub struct Atomic { + v: UnsafeCell, +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Send for Atomic {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for Atomic {} // Some architectures don't have byte-sized atomics, which results in LLVM // emulating them using a LL/SC loop. However for AtomicBool we can take @@ -367,11 +395,7 @@ const EMULATE_ATOMIC_BOOL: bool = cfg!(any( /// loads and stores of `u8`. #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_diagnostic_item = "AtomicBool"] -#[repr(C, align(1))] -pub struct AtomicBool { - v: UnsafeCell, -} +pub type AtomicBool = Atomic; #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] @@ -383,11 +407,6 @@ impl Default for AtomicBool { } } -// Send is implicitly implemented for AtomicBool. -#[cfg(target_has_atomic_load_store = "8")] -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for AtomicBool {} - /// A raw pointer type which can be safely shared between threads. /// /// This type has the same size and bit validity as a `*mut T`. @@ -396,13 +415,7 @@ unsafe impl Sync for AtomicBool {} /// loads and stores of pointers. Its size depends on the target pointer's size. #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_diagnostic_item = "AtomicPtr"] -#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] -#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] -#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] -pub struct AtomicPtr { - p: UnsafeCell<*mut T>, -} +pub type AtomicPtr = Atomic<*mut T>; #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] @@ -413,13 +426,6 @@ impl Default for AtomicPtr { } } -#[cfg(target_has_atomic_load_store = "ptr")] -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for AtomicPtr {} -#[cfg(target_has_atomic_load_store = "ptr")] -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for AtomicPtr {} - /// Atomic memory orderings /// /// Memory orderings specify the way atomic operations synchronize memory. @@ -528,7 +534,9 @@ impl AtomicBool { #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")] #[must_use] pub const fn new(v: bool) -> AtomicBool { - AtomicBool { v: UnsafeCell::new(v as u8) } + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { transmute(v) } } /// Creates a new `AtomicBool` from a pointer. @@ -597,7 +605,7 @@ impl AtomicBool { #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut bool { // SAFETY: the mutable reference guarantees unique ownership. - unsafe { &mut *(self.v.get() as *mut bool) } + unsafe { &mut *self.as_ptr() } } /// Gets atomic access to a `&mut bool`. @@ -699,7 +707,11 @@ impl AtomicBool { #[stable(feature = "atomic_access", since = "1.15.0")] #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")] pub const fn into_inner(self) -> bool { - self.v.into_inner() != 0 + // SAFETY: + // * `Atomic` is essentially a transparent wrapper around `T`. + // * all operations on `Atomic` ensure that `T::Storage` remains + // a valid `bool`. + unsafe { transmute(self) } } /// Loads a value from the bool. @@ -726,7 +738,7 @@ impl AtomicBool { pub fn load(&self, order: Ordering) -> bool { // SAFETY: any data races are prevented by atomic intrinsics and the raw // pointer passed in is valid because we got it from a reference. - unsafe { atomic_load(self.v.get(), order) != 0 } + unsafe { atomic_load(self.v.get().cast::(), order) != 0 } } /// Stores a value into the bool. @@ -756,7 +768,7 @@ impl AtomicBool { // SAFETY: any data races are prevented by atomic intrinsics and the raw // pointer passed in is valid because we got it from a reference. unsafe { - atomic_store(self.v.get(), val as u8, order); + atomic_store(self.v.get().cast::(), val as u8, order); } } @@ -790,7 +802,7 @@ impl AtomicBool { if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) } } else { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } + unsafe { atomic_swap(self.v.get().cast::(), val as u8, order) != 0 } } } @@ -950,7 +962,13 @@ impl AtomicBool { } else { // SAFETY: data races are prevented by atomic intrinsics. match unsafe { - atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) + atomic_compare_exchange( + self.v.get().cast::(), + current as u8, + new as u8, + success, + failure, + ) } { Ok(x) => Ok(x != 0), Err(x) => Err(x != 0), @@ -1024,7 +1042,13 @@ impl AtomicBool { // SAFETY: data races are prevented by atomic intrinsics. match unsafe { - atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) + atomic_compare_exchange_weak( + self.v.get().cast::(), + current as u8, + new as u8, + success, + failure, + ) } { Ok(x) => Ok(x != 0), Err(x) => Err(x != 0), @@ -1070,7 +1094,7 @@ impl AtomicBool { #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } + unsafe { atomic_and(self.v.get().cast::(), val as u8, order) != 0 } } /// Logical "nand" with a boolean value. @@ -1166,7 +1190,7 @@ impl AtomicBool { #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } + unsafe { atomic_or(self.v.get().cast::(), val as u8, order) != 0 } } /// Logical "xor" with a boolean value. @@ -1208,7 +1232,7 @@ impl AtomicBool { #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } + unsafe { atomic_xor(self.v.get().cast::(), val as u8, order) != 0 } } /// Logical "not" with a boolean value. @@ -1457,7 +1481,9 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")] pub const fn new(p: *mut T) -> AtomicPtr { - AtomicPtr { p: UnsafeCell::new(p) } + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { transmute(p) } } /// Creates a new `AtomicPtr` from a pointer. @@ -1544,7 +1570,9 @@ impl AtomicPtr { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut *mut T { - self.p.get_mut() + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { &mut *self.as_ptr() } } /// Gets atomic access to a pointer. @@ -1672,7 +1700,9 @@ impl AtomicPtr { #[stable(feature = "atomic_access", since = "1.15.0")] #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")] pub const fn into_inner(self) -> *mut T { - self.p.into_inner() + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { transmute(self) } } /// Loads a value from the pointer. @@ -1699,7 +1729,7 @@ impl AtomicPtr { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn load(&self, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_load(self.p.get(), order) } + unsafe { atomic_load(self.as_ptr(), order) } } /// Stores a value into the pointer. @@ -1730,7 +1760,7 @@ impl AtomicPtr { pub fn store(&self, ptr: *mut T, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. unsafe { - atomic_store(self.p.get(), ptr, order); + atomic_store(self.as_ptr(), ptr, order); } } @@ -1763,7 +1793,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_swap(self.p.get(), ptr, order) } + unsafe { atomic_swap(self.as_ptr(), ptr, order) } } /// Stores a value into the pointer if the current value is the same as the `current` value. @@ -1887,7 +1917,7 @@ impl AtomicPtr { failure: Ordering, ) -> Result<*mut T, *mut T> { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_compare_exchange(self.p.get(), current, new, success, failure) } + unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) } } /// Stores a value into the pointer if the current value is the same as the `current` value. @@ -1954,7 +1984,7 @@ impl AtomicPtr { // but we know for sure that the pointer is valid (we just got it from // an `UnsafeCell` that we have by reference) and the atomic operation // itself allows us to safely mutate the `UnsafeCell` contents. - unsafe { atomic_compare_exchange_weak(self.p.get(), current, new, success, failure) } + unsafe { atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure) } } /// An alias for [`AtomicPtr::try_update`]. @@ -2243,7 +2273,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_add(self.p.get(), val, order).cast() } + unsafe { atomic_add(self.as_ptr(), val, order).cast() } } /// Offsets the pointer's address by subtracting `val` *bytes*, returning the @@ -2279,7 +2309,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_sub(self.p.get(), val, order).cast() } + unsafe { atomic_sub(self.as_ptr(), val, order).cast() } } /// Performs a bitwise "or" operation on the address of the current pointer, @@ -2330,7 +2360,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_or(self.p.get(), val, order).cast() } + unsafe { atomic_or(self.as_ptr(), val, order).cast() } } /// Performs a bitwise "and" operation on the address of the current @@ -2380,7 +2410,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_and(self.p.get(), val, order).cast() } + unsafe { atomic_and(self.as_ptr(), val, order).cast() } } /// Performs a bitwise "xor" operation on the address of the current @@ -2428,7 +2458,7 @@ impl AtomicPtr { #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_xor(self.p.get(), val, order).cast() } + unsafe { atomic_xor(self.as_ptr(), val, order).cast() } } /// Returns a mutable pointer to the underlying pointer. @@ -2467,7 +2497,7 @@ impl AtomicPtr { #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut *mut T { - self.p.get() + self.v.get().cast() } } @@ -2520,7 +2550,6 @@ macro_rules! atomic_int { $stable_nand:meta, $const_stable_new:meta, $const_stable_into_inner:meta, - $diagnostic_item:meta, $s_int_type:literal, $extra_feature:expr, $min_fn:ident, $max_fn:ident, @@ -2557,11 +2586,7 @@ macro_rules! atomic_int { /// /// [module-level documentation]: crate::sync::atomic #[$stable] - #[$diagnostic_item] - #[repr(C, align($align))] - pub struct $atomic_type { - v: UnsafeCell<$int_type>, - } + pub type $atomic_type = Atomic<$int_type>; #[$stable] impl Default for $atomic_type { @@ -2586,10 +2611,6 @@ macro_rules! atomic_int { } } - // Send is implicitly implemented. - #[$stable] - unsafe impl Sync for $atomic_type {} - impl $atomic_type { /// Creates a new atomic integer. /// @@ -2605,7 +2626,9 @@ macro_rules! atomic_int { #[$const_stable_new] #[must_use] pub const fn new(v: $int_type) -> Self { - Self {v: UnsafeCell::new(v)} + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { transmute(v) } } /// Creates a new reference to an atomic integer from a pointer. @@ -2667,7 +2690,6 @@ macro_rules! atomic_int { unsafe { &*ptr.cast() } } - /// Returns a mutable reference to the underlying integer. /// /// This is safe because the mutable reference guarantees that no other threads are @@ -2686,7 +2708,9 @@ macro_rules! atomic_int { #[inline] #[$stable_access] pub fn get_mut(&mut self) -> &mut $int_type { - self.v.get_mut() + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { &mut *self.as_ptr() } } #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")] @@ -2815,7 +2839,9 @@ macro_rules! atomic_int { #[$stable_access] #[$const_stable_into_inner] pub const fn into_inner(self) -> $int_type { - self.v.into_inner() + // SAFETY: + // `Atomic` is essentially a transparent wrapper around `T`. + unsafe { transmute(self) } } /// Loads a value from the atomic integer. @@ -2841,7 +2867,7 @@ macro_rules! atomic_int { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn load(&self, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_load(self.v.get(), order) } + unsafe { atomic_load(self.as_ptr(), order) } } /// Stores a value into the atomic integer. @@ -2869,7 +2895,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn store(&self, val: $int_type, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_store(self.v.get(), val, order); } + unsafe { atomic_store(self.as_ptr(), val, order); } } /// Stores a value into the atomic integer, returning the previous value. @@ -2898,7 +2924,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_swap(self.v.get(), val, order) } + unsafe { atomic_swap(self.as_ptr(), val, order) } } /// Stores a value into the atomic integer if the current value is the same as @@ -3036,7 +3062,7 @@ macro_rules! atomic_int { success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) } } /// Stores a value into the atomic integer if the current value is the same as @@ -3101,7 +3127,7 @@ macro_rules! atomic_int { failure: Ordering) -> Result<$int_type, $int_type> { // SAFETY: data races are prevented by atomic intrinsics. unsafe { - atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) + atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure) } } @@ -3133,7 +3159,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_add(self.v.get(), val, order) } + unsafe { atomic_add(self.as_ptr(), val, order) } } /// Subtracts from the current value, returning the previous value. @@ -3164,7 +3190,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_sub(self.v.get(), val, order) } + unsafe { atomic_sub(self.as_ptr(), val, order) } } /// Bitwise "and" with the current value. @@ -3198,7 +3224,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_and(self.v.get(), val, order) } + unsafe { atomic_and(self.as_ptr(), val, order) } } /// Bitwise "nand" with the current value. @@ -3232,7 +3258,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_nand(self.v.get(), val, order) } + unsafe { atomic_nand(self.as_ptr(), val, order) } } /// Bitwise "or" with the current value. @@ -3266,7 +3292,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_or(self.v.get(), val, order) } + unsafe { atomic_or(self.as_ptr(), val, order) } } /// Bitwise "xor" with the current value. @@ -3300,7 +3326,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_xor(self.v.get(), val, order) } + unsafe { atomic_xor(self.as_ptr(), val, order) } } /// An alias for @@ -3499,7 +3525,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { $max_fn(self.v.get(), val, order) } + unsafe { $max_fn(self.as_ptr(), val, order) } } /// Minimum with the current value. @@ -3546,7 +3572,7 @@ macro_rules! atomic_int { #[rustc_should_not_be_called_on_const_items] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. - unsafe { $min_fn(self.v.get(), val, order) } + unsafe { $min_fn(self.as_ptr(), val, order) } } /// Returns a mutable pointer to the underlying integer. @@ -3586,7 +3612,7 @@ macro_rules! atomic_int { #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut $int_type { - self.v.get() + self.v.get().cast() } } } @@ -3604,7 +3630,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicI8", "i8", "", atomic_min, atomic_max, @@ -3623,7 +3648,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicU8", "u8", "", atomic_umin, atomic_umax, @@ -3642,7 +3666,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicI16", "i16", "", atomic_min, atomic_max, @@ -3661,7 +3684,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicU16", "u16", "", atomic_umin, atomic_umax, @@ -3680,7 +3702,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicI32", "i32", "", atomic_min, atomic_max, @@ -3699,7 +3720,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicU32", "u32", "", atomic_umin, atomic_umax, @@ -3718,7 +3738,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicI64", "i64", "", atomic_min, atomic_max, @@ -3737,7 +3756,6 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicU64", "u64", "", atomic_umin, atomic_umax, @@ -3756,7 +3774,6 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_diagnostic_item = "AtomicI128", "i128", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -3775,7 +3792,6 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_diagnostic_item = "AtomicU128", "u128", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -3798,7 +3814,6 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicIsize", "isize", "", atomic_min, atomic_max, @@ -3817,7 +3832,6 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - rustc_diagnostic_item = "AtomicUsize", "usize", "", atomic_umin, atomic_umax, diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 1199403b1d5ab..a682873f969c8 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -156,6 +156,7 @@ target_env = "sgx", target_os = "xous", target_os = "trusty", + target_os = "hermit", )) ))] mod tests; diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index b0b6682f5279e..bd27998b37706 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -18,6 +18,12 @@ def unwrap_unique_or_non_null(unique_or_nonnull): return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]] +def unwrap_scalar_wrappers(wrapper): + while not wrapper.type.is_scalar: + wrapper = wrapper[wrapper.type.fields()[0]] + return wrapper + + # GDB 14 has a tag class that indicates that extension methods are ok # to call. Use of this tag only requires that printers hide local # attributes and methods by prefixing them with "_". @@ -197,8 +203,8 @@ def __init__(self, valobj, is_atomic=False): self._is_atomic = is_atomic self._ptr = unwrap_unique_or_non_null(valobj["ptr"]) self._value = self._ptr["data" if is_atomic else "value"] - self._strong = self._ptr["strong"]["v" if is_atomic else "value"]["value"] - self._weak = self._ptr["weak"]["v" if is_atomic else "value"]["value"] - 1 + self._strong = unwrap_scalar_wrappers(self._ptr["strong"]) + self._weak = unwrap_scalar_wrappers(self._ptr["weak"]) - 1 def to_string(self): if self._is_atomic: diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 582471622baa6..88d210691d00e 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -9,6 +9,7 @@ eBasicTypeUnsignedLong, eBasicTypeUnsignedChar, eFormatChar, + eTypeIsInteger, ) from rust_types import is_tuple_fields @@ -90,6 +91,12 @@ def unwrap_unique_or_non_null(unique_or_nonnull: SBValue) -> SBValue: return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0) +def unwrap_scalar_wrappers(wrapper: SBValue) -> SBValue: + while (wrapper.type.GetTypeFlags() & eTypeIsInteger) == 0: + wrapper = wrapper.GetChildAtIndex(0) + return wrapper + + class DefaultSyntheticProvider: def __init__(self, valobj: SBValue, _dict: LLDBOpaque): # logger = Logger.Logger() @@ -1246,12 +1253,9 @@ class StdRcSyntheticProvider: rust 1.33.0: struct NonNull { pointer: *const T } struct NonZero(T) struct RcInner { strong: Cell, weak: Cell, value: T } - struct Cell { value: UnsafeCell } - struct UnsafeCell { value: T } struct Arc { ptr: NonNull>, ... } - struct ArcInner { strong: atomic::AtomicUsize, weak: atomic::AtomicUsize, data: T } - struct AtomicUsize { v: UnsafeCell } + struct ArcInner { strong: atomic::Atomic, weak: atomic::Atomic, data: T } """ def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_atomic: bool = False): @@ -1261,16 +1265,8 @@ def __init__(self, valobj: SBValue, _dict: LLDBOpaque, is_atomic: bool = False): self.value = self.ptr.GetChildMemberWithName("data" if is_atomic else "value") - self.strong = ( - self.ptr.GetChildMemberWithName("strong") - .GetChildAtIndex(0) - .GetChildMemberWithName("value") - ) - self.weak = ( - self.ptr.GetChildMemberWithName("weak") - .GetChildAtIndex(0) - .GetChildMemberWithName("value") - ) + self.strong = unwrap_scalar_wrappers(self.ptr.GetChildMemberWithName("strong")) + self.weak = unwrap_scalar_wrappers(self.ptr.GetChildMemberWithName("weak")) self.value_builder = ValueBuilder(valobj) diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index d09f0d635692a..4e2f09743a031 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -89,38 +89,38 @@ - - {(bool)v.value} + + {(bool)v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} - - {v.value} + + {v.value.__0} diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs index d5dbcbe9dc701..ca8383070d70f 100644 --- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs @@ -40,7 +40,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &' && let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind && [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name) && let callee_ty = cx.typeck_results().expr_ty(callee) - && callee_ty.is_diag_item(cx, sym::AtomicBool) + && callee_ty.is_diag_item(cx, sym::Atomic) && let Some(std_or_core) = std_or_core(cx) { span_lint_and_sugg( diff --git a/src/tools/clippy/tests/ui/mut_key.stderr b/src/tools/clippy/tests/ui/mut_key.stderr index 0d504584fbae8..e7a1d6833847e 100644 --- a/src/tools/clippy/tests/ui/mut_key.stderr +++ b/src/tools/clippy/tests/ui/mut_key.stderr @@ -5,8 +5,8 @@ LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> Hash | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: ... because it contains `Key`, which has interior mutability - = note: ... because it contains `AtomicUsize`, which has interior mutability - = note: ... because it contains `UnsafeCell`, which has interior mutability + = note: ... because it contains `Atomic`, which has interior mutability + = note: ... because it contains `UnsafeCell<::Storage>`, which has interior mutability = note: `-D clippy::mutable-key-type` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mutable_key_type)]` @@ -17,8 +17,8 @@ LL | fn should_not_take_this_arg(m: &mut HashMap, _n: usize) -> Hash | ^^^^^^^^^^^^ | = note: ... because it contains `Key`, which has interior mutability - = note: ... because it contains `AtomicUsize`, which has interior mutability - = note: ... because it contains `UnsafeCell`, which has interior mutability + = note: ... because it contains `Atomic`, which has interior mutability + = note: ... because it contains `UnsafeCell<::Storage>`, which has interior mutability error: mutable key type --> tests/ui/mut_key.rs:35:5 @@ -27,8 +27,8 @@ LL | let _other: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: ... because it contains `Key`, which has interior mutability - = note: ... because it contains `AtomicUsize`, which has interior mutability - = note: ... because it contains `UnsafeCell`, which has interior mutability + = note: ... because it contains `Atomic`, which has interior mutability + = note: ... because it contains `UnsafeCell<::Storage>`, which has interior mutability error: mutable key type --> tests/ui/mut_key.rs:64:22 @@ -38,8 +38,8 @@ LL | fn tuples_bad(_m: &mut HashMap<(Key, U), bool>) {} | = note: ... because it contains `(Key, U)`, which has interior mutability = note: ... because it contains `Key`, which has interior mutability - = note: ... because it contains `AtomicUsize`, which has interior mutability - = note: ... because it contains `UnsafeCell`, which has interior mutability + = note: ... because it contains `Atomic`, which has interior mutability + = note: ... because it contains `UnsafeCell<::Storage>`, which has interior mutability error: mutable key type --> tests/ui/mut_key.rs:77:5 diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 230578d79ffbe..d2a71a42e076d 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -218,6 +218,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-eabihf", "only-elf", "only-emscripten", + "only-endian-big", "only-gnu", "only-i686-pc-windows-gnu", "only-i686-pc-windows-msvc", diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index 939160d9f41d8..70bed5a471ab2 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -302,6 +302,12 @@ impl LlvmFilecheck { self.cmd.arg(input_file.as_ref()); self } + + /// Set a single `--check-prefix`. + pub fn check_prefix>(&mut self, prefix: S) -> &mut Self { + self.cmd.arg(format!("--check-prefix={}", prefix.as_ref())); + self + } } impl LlvmObjdump { @@ -324,6 +330,12 @@ impl LlvmObjdump { self.cmd.arg("-d"); self } + + /// Demangle symbols. + pub fn demangle(&mut self) -> &mut Self { + self.cmd.arg("--demangle"); + self + } } impl LlvmAr { diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs index 9ec4ec8eeb159..8756d45eaa03e 100644 --- a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -1,4 +1,7 @@ // Tests output of multiple permutations of `Option::or` +//@ revisions: LITTLE BIG +//@ [BIG] only-endian-big +//@ [LITTLE] ignore-endian-big //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled #![crate_type = "lib"] @@ -70,8 +73,16 @@ pub fn if_some_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 - // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // LITTLE-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // LITTLE-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[OPT_A:%.+]] = lshr i16 %0, 8 + // BIG-NEXT: [[SOME_A:%.+]] = trunc i16 [[OPT_A]] to i1 + // BIG-NEXT: [[OPT_B:%.+]] = lshr i16 %1, 8 + // BIG-NEXT: [[A_OR_B:%.+]] = select i1 [[SOME_A]], i16 [[OPT_A]], i16 [[OPT_B]] + // BIG-NEXT: [[AGGREGATE:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[R_LOWER:%.+]] = and i16 [[AGGREGATE]], 255 + // BIG-NEXT: [[R_UPPER:%.+]] = shl nuw i16 [[A_OR_B]], 8 + // BIG-NEXT: [[R:%.+]] = or disjoint i16 [[R_UPPER]], [[R_LOWER]] // CHECK: ret i16 [[R]] match opta { Some(x) => Some(x), @@ -84,8 +95,16 @@ pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option #[no_mangle] pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 - // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // LITTLE-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // LITTLE-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[OPT_A:%.+]] = lshr i16 %0, 8 + // BIG-NEXT: [[SOME_A:%.+]] = trunc i16 [[OPT_A]] to i1 + // BIG-NEXT: [[OPT_B:%.+]] = lshr i16 %1, 8 + // BIG-NEXT: [[A_OR_B:%.+]] = select i1 [[SOME_A]], i16 [[OPT_A]], i16 [[OPT_B]] + // BIG-NEXT: [[AGGREGATE:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[R_LOWER:%.+]] = and i16 [[AGGREGATE]], 255 + // BIG-NEXT: [[R_UPPER:%.+]] = shl nuw i16 [[A_OR_B]], 8 + // BIG-NEXT: [[R:%.+]] = or disjoint i16 [[R_UPPER]], [[R_LOWER]] // CHECK: ret i16 [[R]] match opta { Some(_) => opta, @@ -98,8 +117,16 @@ pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Op #[no_mangle] pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 - // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // LITTLE-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // LITTLE-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[OPT_A:%.+]] = lshr i16 %0, 8 + // BIG-NEXT: [[SOME_A:%.+]] = trunc i16 [[OPT_A]] to i1 + // BIG-NEXT: [[OPT_B:%.+]] = lshr i16 %1, 8 + // BIG-NEXT: [[A_OR_B:%.+]] = select i1 [[SOME_A]], i16 [[OPT_A]], i16 [[OPT_B]] + // BIG-NEXT: [[AGGREGATE:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[R_LOWER:%.+]] = and i16 [[AGGREGATE]], 255 + // BIG-NEXT: [[R_UPPER:%.+]] = shl nuw i16 [[A_OR_B]], 8 + // BIG-NEXT: [[R:%.+]] = or disjoint i16 [[R_UPPER]], [[R_LOWER]] // CHECK: ret i16 [[R]] opta.or(optb) } @@ -109,8 +136,16 @@ pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Optio #[no_mangle] pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 - // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // LITTLE-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // LITTLE-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[OPT_A:%.+]] = lshr i16 %0, 8 + // BIG-NEXT: [[SOME_A:%.+]] = trunc i16 [[OPT_A]] to i1 + // BIG-NEXT: [[OPT_B:%.+]] = lshr i16 %1, 8 + // BIG-NEXT: [[A_OR_B:%.+]] = select i1 [[SOME_A]], i16 [[OPT_A]], i16 [[OPT_B]] + // BIG-NEXT: [[AGGREGATE:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // BIG-NEXT: [[R_LOWER:%.+]] = and i16 [[AGGREGATE]], 255 + // BIG-NEXT: [[R_UPPER:%.+]] = shl nuw i16 [[A_OR_B]], 8 + // BIG-NEXT: [[R:%.+]] = or disjoint i16 [[R_UPPER]], [[R_LOWER]] // CHECK: ret i16 [[R]] if opta.is_some() { opta } else { optb } } diff --git a/tests/codegen-llvm/vec-calloc.rs b/tests/codegen-llvm/vec-calloc.rs index b02b858f966b0..4e893cc736c90 100644 --- a/tests/codegen-llvm/vec-calloc.rs +++ b/tests/codegen-llvm/vec-calloc.rs @@ -199,4 +199,4 @@ pub fn vec_array(n: usize) -> Vec<[u32; 1_000_000]> { // Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away. // CHECK: declare noalias noundef ptr @{{.*}}__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef range(i64 1, -9223372036854775807)) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]] -// CHECK-DAG: attributes [[RUST_ALLOC_ZEROED_ATTRS]] = { {{.*}} allockind("alloc,zeroed,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} } +// CHECK-DAG: attributes [[RUST_ALLOC_ZEROED_ATTRS]] = { {{.*}} allockind("alloc,zeroed,aligned") allocsize(0) {{(uwtable )?}}"alloc-family"="__rust_alloc" {{.*}} } diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs index 81fa7900c5faf..dbbc4ee6e8614 100644 --- a/tests/debuginfo/numeric-types.rs +++ b/tests/debuginfo/numeric-types.rs @@ -114,52 +114,40 @@ //@ cdb-check: [+0x000] __0 : 0x78 [Type: unsigned __int64] //@ cdb-command: dx a_bool_t -//@ cdb-check:a_bool_t : true [Type: core::sync::atomic::AtomicBool] -//@ cdb-check: [+0x000] v : 0x1 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_bool_t : true [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_bool_f -//@ cdb-check:a_bool_f : false [Type: core::sync::atomic::AtomicBool] -//@ cdb-check: [+0x000] v : 0x0 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_bool_f : false [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_i8 -//@ cdb-check:a_i8 : 2 [Type: core::sync::atomic::AtomicI8] -//@ cdb-check: [+0x000] v : 2 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_i8 : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_i16 -//@ cdb-check:a_i16 : 4 [Type: core::sync::atomic::AtomicI16] -//@ cdb-check: [+0x000] v : 4 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_i16 : 4 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_i32 -//@ cdb-check:a_i32 : 8 [Type: core::sync::atomic::AtomicI32] -//@ cdb-check: [+0x000] v : 8 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_i32 : 8 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_i64 -//@ cdb-check:a_i64 : 16 [Type: core::sync::atomic::AtomicI64] -//@ cdb-check: [+0x000] v : 16 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_i64 : 16 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_isize -//@ cdb-check:a_isize : 32 [Type: core::sync::atomic::AtomicIsize] -//@ cdb-check: [+0x000] v : 32 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_isize : 32 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_u8 -//@ cdb-check:a_u8 : 0x40 [Type: core::sync::atomic::AtomicU8] -//@ cdb-check: [+0x000] v : 0x40 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_u8 : 0x40 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_u16 -//@ cdb-check:a_u16 : 0x80 [Type: core::sync::atomic::AtomicU16] -//@ cdb-check: [+0x000] v : 0x80 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_u16 : 0x80 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_u32 -//@ cdb-check:a_u32 : 0x100 [Type: core::sync::atomic::AtomicU32] -//@ cdb-check: [+0x000] v : 0x100 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_u32 : 0x100 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_u64 -//@ cdb-check:a_u64 : 0x200 [Type: core::sync::atomic::AtomicU64] -//@ cdb-check: [+0x000] v : 0x200 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_u64 : 0x200 [Type: core::sync::atomic::Atomic] //@ cdb-command: dx a_usize -//@ cdb-check:a_usize : 0x400 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [+0x000] v : 0x400 [Type: core::cell::UnsafeCell] +//@ cdb-check:a_usize : 0x400 [Type: core::sync::atomic::Atomic] // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/rc_arc.rs b/tests/debuginfo/rc_arc.rs index a2eeeaad6aa8b..b22b7e0d1611d 100644 --- a/tests/debuginfo/rc_arc.rs +++ b/tests/debuginfo/rc_arc.rs @@ -38,13 +38,13 @@ //@ cdb-command:dx arc,d //@ cdb-check:arc,d : 222 [Type: alloc::sync::Arc] -//@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx weak_arc,d //@ cdb-check:weak_arc,d : 222 [Type: alloc::sync::Weak] -//@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 21 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx dyn_rc,d //@ cdb-check:dyn_rc,d [Type: alloc::rc::Rc,alloc::alloc::Global>] @@ -76,19 +76,19 @@ //@ cdb-command:dx dyn_arc,d //@ cdb-check:dyn_arc,d [Type: alloc::sync::Arc,alloc::alloc::Global>] -//@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx dyn_arc_weak,d //@ cdb-check:dyn_arc_weak,d [Type: alloc::sync::Weak,alloc::alloc::Global>] -//@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 51 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-command:dx slice_arc,d //@ cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] -//@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-check: [0] : 4 [Type: u32] //@ cdb-check: [1] : 5 [Type: u32] //@ cdb-check: [2] : 6 [Type: u32] @@ -96,8 +96,8 @@ //@ cdb-command:dx slice_arc_weak,d //@ cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak,alloc::alloc::Global>] //@ cdb-check: [Length] : 3 [Type: [...]] -//@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize] -//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize] +//@ cdb-check: [Reference count] : 61 [Type: core::sync::atomic::Atomic] +//@ cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::Atomic] //@ cdb-check: [0] : 4 [Type: u32] //@ cdb-check: [1] : 5 [Type: u32] //@ cdb-check: [2] : 6 [Type: u32] diff --git a/tests/run-make/thumb-interworking/link.ld b/tests/run-make/thumb-interworking/link.ld new file mode 100644 index 0000000000000..b08e0fb66eaf0 --- /dev/null +++ b/tests/run-make/thumb-interworking/link.ld @@ -0,0 +1 @@ +ENTRY(entry); diff --git a/tests/run-make/thumb-interworking/main.rs b/tests/run-make/thumb-interworking/main.rs new file mode 100644 index 0000000000000..86099b0ee63fc --- /dev/null +++ b/tests/run-make/thumb-interworking/main.rs @@ -0,0 +1,118 @@ +#![feature(no_core)] +#![no_core] +#![no_main] + +extern crate minicore; +use minicore::*; + +#[unsafe(no_mangle)] +fn entry() { + arm(); + thumb(); +} + +#[unsafe(no_mangle)] +pub fn arm() { + // thumbv5te-LABEL: : + // thumbv5te: blx {{0x[0-9a-f]+}} + // thumbv5te: blx {{0x[0-9a-f]+}} + // thumbv5te: blx {{0x[0-9a-f]+}} + + // thumbv4t-LABEL: : + // thumbv4t: bl {{0x[0-9a-f]+}} <__Thumbv4ABSLongBXThunk__{{.*}}arm_normalfn> + // thumbv4t: bl {{0x[0-9a-f]+}} <__Thumbv4ABSLongBXThunk_arm_globalfn> + // thumbv4t: bl {{0x[0-9a-f]+}} <__Thumbv4ABSLongBXThunk__{{.*}}arm_nakedfn> + + // armv5te-LABEL: : + // armv5te: bl {{0x[0-9a-f]+}} + // armv5te: bl {{0x[0-9a-f]+}} + // armv5te: bl {{0x[0-9a-f]+}} + + // armv4t-LABEL: : + // armv4t: bl {{0x[0-9a-f]+}} + // armv4t: bl {{0x[0-9a-f]+}} + // armv4t: bl {{0x[0-9a-f]+}} + arm_normalfn(); + arm_globalfn(); + arm_nakedfn(); +} + +#[unsafe(no_mangle)] +pub fn thumb() { + // thumbv5te-LABEL: : + // thumbv5te: bl {{0x[0-9a-f]+}} + // thumbv5te: bl {{0x[0-9a-f]+}} + // thumbv5te: bl {{0x[0-9a-f]+}} + + // thumbv4t-LABEL: : + // thumbv4t: bl {{0x[0-9a-f]+}} + // thumbv4t: bl {{0x[0-9a-f]+}} + // thumbv4t: bl {{0x[0-9a-f]+}} + + // armv5te-LABEL: : + // armv5te: blx {{0x[0-9a-f]+}} + // armv5te: blx {{0x[0-9a-f]+}} + // armv5te: blx {{0x[0-9a-f]+}} + + // armv4t-LABEL: : + // armv4t: bl {{0x[0-9a-f]+}} <__ARMv4ABSLongBXThunk__{{.*}}thumb_normalfn> + // armv4t: bl {{0x[0-9a-f]+}} <__ARMv4ABSLongBXThunk_thumb_globalfn> + // armv4t: bl {{0x[0-9a-f]+}} <__ARMv4ABSLongBXThunk__{{.*}}thumb_nakedfn> + thumb_normalfn(); + thumb_globalfn(); + thumb_nakedfn(); +} + +#[instruction_set(arm::t32)] +extern "C" fn thumb_normalfn() { + unsafe { asm!("nop") } +} + +unsafe extern "C" { + safe fn thumb_globalfn(); +} + +global_asm!( + r#" + .thumb + .global thumb_globalfn + .type thumb_globalfn, %function + thumb_globalfn: + nop + bx lr + .size thumb_globalfn, . - thumb_globalfn +"# +); + +#[unsafe(naked)] +#[instruction_set(arm::t32)] +extern "C" fn thumb_nakedfn() { + naked_asm!("nop", "bx lr",); +} + +#[instruction_set(arm::a32)] +extern "C" fn arm_normalfn() { + unsafe { asm!("nop") } +} + +unsafe extern "C" { + safe fn arm_globalfn(); +} + +global_asm!( + r#" + .arm + .global arm_globalfn + .type arm_globalfn, %function + arm_globalfn: + nop + bx lr + .size arm_globalfn, . - arm_globalfn +"# +); + +#[unsafe(naked)] +#[instruction_set(arm::a32)] +extern "C" fn arm_nakedfn() { + naked_asm!("nop", "bx lr",); +} diff --git a/tests/run-make/thumb-interworking/rmake.rs b/tests/run-make/thumb-interworking/rmake.rs new file mode 100644 index 0000000000000..1aa39ed1ce159 --- /dev/null +++ b/tests/run-make/thumb-interworking/rmake.rs @@ -0,0 +1,52 @@ +//@ needs-llvm-components: arm +//@ needs-rust-lld +use run_make_support::{llvm_filecheck, llvm_objdump, path, rfs, run, rustc, source_root}; + +// Test a thumb target calling arm functions. Doing so requires switching from thumb mode to arm +// mode, calling the arm code, then switching back to thumb mode. Depending on the thumb version, +// this happens using a special calling instruction, or by calling a generated thunk that performs +// the mode switching. +// +// In particular this tests that naked functions behave like normal functions. Before LLVM 22, a +// bug in LLVM caused thumb mode to be used unconditonally when symbols were .hidden, miscompiling +// calls to arm functions. +// +// - https://github.com/llvm/llvm-project/pull/181156 +// - https://github.com/rust-lang/rust/issues/151946 + +fn main() { + // Thumb calling thumb and arm. + helper("thumbv5te", "thumbv5te-none-eabi"); + helper("thumbv4t", "thumbv4t-none-eabi"); + + // Arm calling thumb and arm. + helper("armv5te", "armv5te-none-eabi"); + helper("armv4t", "armv4t-none-eabi"); +} + +fn helper(prefix: &str, target: &str) { + rustc() + .input(source_root().join("tests/auxiliary/minicore.rs")) + .crate_name("minicore") + .crate_type("rlib") + .target(target) + .output("libminicore.rlib") + .run(); + let minicore = path("libminicore.rlib"); + + rustc() + .input("main.rs") + .panic("abort") + .link_arg("-Tlink.ld") + .arg("--extern") + .arg(format!("minicore={}", minicore.display())) + .target(target) + .output(prefix) + .run(); + + let dump = llvm_objdump().disassemble().demangle().input(path(prefix)).run(); + + eprintln!("{}", str::from_utf8(&dump.stdout()).unwrap()); + + llvm_filecheck().patterns("main.rs").check_prefix(prefix).stdin_buf(dump.stdout()).run(); +} diff --git a/tests/rustdoc-html/jump-to-def/non-local-method.rs b/tests/rustdoc-html/jump-to-def/non-local-method.rs index c601f3259c4da..e084899b2495e 100644 --- a/tests/rustdoc-html/jump-to-def/non-local-method.rs +++ b/tests/rustdoc-html/jump-to-def/non-local-method.rs @@ -4,8 +4,8 @@ //@ has 'src/foo/non-local-method.rs.html' -//@ has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html"]' 'std::sync::atomic::AtomicIsize' -use std::sync::atomic::AtomicIsize; +//@ has - '//a[@href="{{channel}}/alloc/boxed/struct.Box.html"]' 'std::boxed::Box' +use std::boxed::Box; //@ has - '//a[@href="{{channel}}/std/io/trait.Read.html"]' 'std::io::Read' use std::io::Read; //@ has - '//a[@href="{{channel}}/std/io/index.html"]' 'std::io' @@ -21,9 +21,9 @@ pub fn bar2(readable: T) { } pub fn bar() { - //@ has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html"]' 'AtomicIsize' - //@ has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html#method.new"]' 'new' - let _ = AtomicIsize::new(0); + //@ has - '//a[@href="{{channel}}/alloc/boxed/struct.Box.html"]' 'Box' + //@ has - '//a[@href="{{channel}}/alloc/boxed/struct.Box.html#method.new"]' 'new' + let _ = Box::new(0); //@ has - '//a[@href="#49"]' 'local_private' local_private(); } diff --git a/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs index fa43924ff4ebf..1b2e756c2ce70 100644 --- a/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs +++ b/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs @@ -1,26 +1,26 @@ -// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. +// Regression test to ensure that both `Thing` items are displayed but not the re-export. // https://github.com/rust-lang/rust/issues/105735 #![crate_name = "foo"] #![no_std] //@ has 'foo/index.html' -//@ has - '//dt/a[@class="type"]' 'AtomicU8' -//@ has - '//dt/a[@class="constant"]' 'AtomicU8' +//@ has - '//dt/a[@class="type"]' 'Thing' +//@ has - '//dt/a[@class="constant"]' 'Thing' // We also ensure we don't have another item displayed. //@ count - '//*[@id="main-content"]/*[@class="section-header"]' 2 //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases' //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod other { - pub type AtomicU8 = (); + pub type Thing = (); } mod thing { - pub use crate::other::AtomicU8; + pub use crate::other::Thing; #[allow(non_upper_case_globals)] - pub const AtomicU8: () = (); + pub const Thing: () = (); } -pub use crate::thing::AtomicU8; +pub use crate::thing::Thing; diff --git a/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs index d1b5c0b6749ad..499887b918ded 100644 --- a/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs +++ b/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs @@ -1,22 +1,22 @@ -// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. +// Regression test to ensure that both `Ordering` items are displayed but not the re-export. // https://github.com/rust-lang/rust/issues/105735 #![crate_name = "foo"] #![no_std] //@ has 'foo/index.html' -//@ has - '//dt/a[@class="struct"]' 'AtomicU8' -//@ has - '//dt/a[@class="constant"]' 'AtomicU8' +//@ has - '//dt/a[@class="enum"]' 'Ordering' +//@ has - '//dt/a[@class="constant"]' 'Ordering' // We also ensure we don't have another item displayed. //@ count - '//*[@id="main-content"]/*[@class="section-header"]' 2 -//@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +//@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Enums' //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod thing { - pub use core::sync::atomic::AtomicU8; + pub use core::cmp::Ordering; #[allow(non_upper_case_globals)] - pub const AtomicU8: () = (); + pub const Ordering: () = (); } -pub use crate::thing::AtomicU8; +pub use crate::thing::Ordering; diff --git a/tests/ui/borrowck/issue-47215-ice-from-drop-elab.stderr b/tests/ui/borrowck/issue-47215-ice-from-drop-elab.stderr index d6aeb410ec4de..d237d21d77de3 100644 --- a/tests/ui/borrowck/issue-47215-ice-from-drop-elab.stderr +++ b/tests/ui/borrowck/issue-47215-ice-from-drop-elab.stderr @@ -2,7 +2,7 @@ error[E0507]: cannot move out of static item `X` --> $DIR/issue-47215-ice-from-drop-elab.rs:17:21 | LL | let mut x = X; - | ^ move occurs because `X` has type `AtomicUsize`, which does not implement the `Copy` trait + | ^ move occurs because `X` has type `Atomic`, which does not implement the `Copy` trait | help: consider borrowing here | diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.rs b/tests/ui/consts/const_refs_to_static-ice-121413.rs index 27d5d8600b4b0..d0f89283ed049 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.rs +++ b/tests/ui/consts/const_refs_to_static-ice-121413.rs @@ -5,7 +5,7 @@ //@ compile-flags: -Zextra-const-ub-checks // ignore-tidy-linelength const REF_INTERIOR_MUT: &usize = { - //~^ HELP consider importing this struct + //~^ HELP consider importing this type alias static FOO: Sync = AtomicUsize::new(0); //~^ ERROR cannot find //~| WARN trait objects without an explicit `dyn` are deprecated diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr index 150b8cb079e72..2787109769324 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr +++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr @@ -4,7 +4,7 @@ error[E0433]: cannot find type `AtomicUsize` in this scope LL | static FOO: Sync = AtomicUsize::new(0); | ^^^^^^^^^^^ use of undeclared type `AtomicUsize` | -help: consider importing this struct +help: consider importing this type alias | LL + use std::sync::atomic::AtomicUsize; | diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index eb78b5335cba9..9546f34792ad4 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -8,7 +8,7 @@ use std::sync::atomic::Ordering; const MUTATE_INTERIOR_MUT: usize = { static FOO: AtomicUsize = AtomicUsize::new(0); - FOO.fetch_add(1, Ordering::Relaxed) //~ERROR calling non-const function `AtomicUsize::fetch_add` + FOO.fetch_add(1, Ordering::Relaxed) //~ERROR calling non-const function `Atomic::::fetch_add` }; const READ_INTERIOR_MUT: usize = { diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr index 5b8797c511627..bf7d6eecb7c3a 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -1,4 +1,4 @@ -error[E0080]: calling non-const function `AtomicUsize::fetch_add` +error[E0080]: calling non-const function `Atomic::::fetch_add` --> $DIR/const_refers_to_static.rs:11:5 | LL | FOO.fetch_add(1, Ordering::Relaxed) diff --git a/tests/ui/cycle-trait/pointee-sized-next-solver-ice.current.stderr b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.current.stderr new file mode 100644 index 0000000000000..39e815b9af4b5 --- /dev/null +++ b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.current.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i32: PointeeSized` is not satisfied + --> $DIR/pointee-sized-next-solver-ice.rs:19:21 + | +LL | require_trait::(); + | ^^^ the trait `PointeeSized` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/pointee-sized-next-solver-ice.rs:14:1 + | +LL | trait PointeeSized {} + | ^^^^^^^^^^^^^^^^^^ +note: required by a bound in `require_trait` + --> $DIR/pointee-sized-next-solver-ice.rs:16:21 + | +LL | fn require_trait() {} + | ^^^^^^^^^^^^ required by this bound in `require_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cycle-trait/pointee-sized-next-solver-ice.next.stderr b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.next.stderr new file mode 100644 index 0000000000000..39e815b9af4b5 --- /dev/null +++ b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.next.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i32: PointeeSized` is not satisfied + --> $DIR/pointee-sized-next-solver-ice.rs:19:21 + | +LL | require_trait::(); + | ^^^ the trait `PointeeSized` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/pointee-sized-next-solver-ice.rs:14:1 + | +LL | trait PointeeSized {} + | ^^^^^^^^^^^^^^^^^^ +note: required by a bound in `require_trait` + --> $DIR/pointee-sized-next-solver-ice.rs:16:21 + | +LL | fn require_trait() {} + | ^^^^^^^^^^^^ required by this bound in `require_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cycle-trait/pointee-sized-next-solver-ice.rs b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.rs new file mode 100644 index 0000000000000..20a11bf969184 --- /dev/null +++ b/tests/ui/cycle-trait/pointee-sized-next-solver-ice.rs @@ -0,0 +1,21 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +// Regression test for https://github.com/rust-lang/rust/issues/151957 +// +// When a user-defined trait shares the name `PointeeSized` with +// `core::marker::PointeeSized`, error reporting tries to check whether +// the type implements the lang-item `PointeeSized` trait via +// `predicate_must_hold_modulo_regions`. This creates a `PointeeSized` +// solver obligation which causes an ICE. We avoid this by skipping the +// `PointeeSized` lang item during the "similarly named trait" suggestion. + +trait PointeeSized {} + +fn require_trait() {} + +fn main() { + require_trait::(); + //~^ ERROR the trait bound `i32: PointeeSized` is not satisfied +} diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr index 908a196828999..dd6f561f5b799 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr @@ -4,7 +4,7 @@ warning: mutation of an interior mutable `const` item with call to `store` LL | let _a = A.store(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -22,7 +22,7 @@ warning: mutation of an interior mutable `const` item with call to `swap` LL | let _a = A.swap(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -39,7 +39,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_and_ LL | let _a = A.compare_and_swap(false, true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -56,7 +56,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch LL | let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -73,7 +73,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch LL | let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -90,7 +90,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_and` LL | let _a = A.fetch_and(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -107,7 +107,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_nand` LL | let _a = A.fetch_nand(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -124,7 +124,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_or` LL | let _a = A.fetch_or(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -141,7 +141,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_xor` LL | let _a = A.fetch_xor(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -158,7 +158,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_not` LL | let _a = A.fetch_not(Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -175,7 +175,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_update LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -192,7 +192,7 @@ warning: mutation of an interior mutable `const` item with call to `try_update` LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -209,7 +209,7 @@ warning: mutation of an interior mutable `const` item with call to `update` LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicBool` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -226,7 +226,7 @@ warning: mutation of an interior mutable `const` item with call to `store` LL | let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -243,7 +243,7 @@ warning: mutation of an interior mutable `const` item with call to `swap` LL | let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -260,7 +260,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_and_ LL | let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -275,7 +275,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch --> $DIR/const-item-interior-mutations-const-atomics.rs:64:14 | LL | let _a = A.compare_exchange( - | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ^ `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | ______________| | | LL | | @@ -299,7 +299,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch --> $DIR/const-item-interior-mutations-const-atomics.rs:72:14 | LL | let _a = A.compare_exchange_weak( - | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ^ `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | ______________| | | LL | | @@ -325,7 +325,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_update LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -342,7 +342,7 @@ warning: mutation of an interior mutable `const` item with call to `try_update` LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -359,7 +359,7 @@ warning: mutation of an interior mutable `const` item with call to `update` LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -376,7 +376,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_ptr_ad LL | let _a = A.fetch_ptr_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -393,7 +393,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_ptr_su LL | let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -410,7 +410,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_byte_a LL | let _a = A.fetch_byte_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -427,7 +427,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_byte_s LL | let _a = A.fetch_byte_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -444,7 +444,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_and` LL | let _a = A.fetch_and(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -461,7 +461,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_or` LL | let _a = A.fetch_or(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -478,7 +478,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_xor` LL | let _a = A.fetch_xor(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicPtr` + | `A` is a interior mutable `const` item of type `Atomic<*mut i32>` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -495,7 +495,7 @@ warning: mutation of an interior mutable `const` item with call to `store` LL | let _a = A.store(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -512,7 +512,7 @@ warning: mutation of an interior mutable `const` item with call to `swap` LL | let _a = A.swap(2, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -529,7 +529,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_and_ LL | let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -546,7 +546,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch LL | let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -563,7 +563,7 @@ warning: mutation of an interior mutable `const` item with call to `compare_exch LL | let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -580,7 +580,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_add` LL | let _a = A.fetch_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -597,7 +597,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_sub` LL | let _a = A.fetch_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -614,7 +614,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_add` LL | let _a = A.fetch_add(2, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -631,7 +631,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_nand` LL | let _a = A.fetch_nand(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -648,7 +648,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_or` LL | let _a = A.fetch_or(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -665,7 +665,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_xor` LL | let _a = A.fetch_xor(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -682,7 +682,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_update LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -699,7 +699,7 @@ warning: mutation of an interior mutable `const` item with call to `try_update` LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -716,7 +716,7 @@ warning: mutation of an interior mutable `const` item with call to `update` LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -733,7 +733,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_max` LL | let _a = A.fetch_max(20, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified @@ -750,7 +750,7 @@ warning: mutation of an interior mutable `const` item with call to `fetch_min` LL | let _a = A.fetch_min(5, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | `A` is a interior mutable `const` item of type `AtomicU32` + | `A` is a interior mutable `const` item of type `Atomic` | = note: each usage of a `const` item creates a new temporary = note: only the temporaries and never the original `const A` will be modified diff --git a/tests/ui/lint/unused/unused-result.rs b/tests/ui/lint/unused/unused-result.rs index e283eaa88dd13..bfc9d61bb9c88 100644 --- a/tests/ui/lint/unused/unused-result.rs +++ b/tests/ui/lint/unused/unused-result.rs @@ -3,12 +3,16 @@ //~^ NOTE: the lint level is defined here //~| NOTE: the lint level is defined here +use std::ops::ControlFlow; + #[must_use] enum MustUse { Test } #[must_use = "some message"] enum MustUseMsg { Test2 } +enum Nothing {} + fn foo() -> T { panic!() } fn bar() -> isize { return foo::(); } @@ -39,4 +43,15 @@ fn main() { let _ = foo::(); let _ = foo::(); let _ = foo::(); + + // "trivial" types + (); + ((), ()); + Ok::<(), Nothing>(()); + ControlFlow::::Continue(()); + ((), Ok::<(), Nothing>(()), ((((), ())), ((),))); + foo::(); + + ((), 1); //~ ERROR: unused result of type `((), i32)` + (1, ()); //~ ERROR: unused result of type `(i32, ())` } diff --git a/tests/ui/lint/unused/unused-result.stderr b/tests/ui/lint/unused/unused-result.stderr index f42995a65d13e..b584733ba1cb4 100644 --- a/tests/ui/lint/unused/unused-result.stderr +++ b/tests/ui/lint/unused/unused-result.stderr @@ -1,5 +1,5 @@ error: unused `MustUse` that must be used - --> $DIR/unused-result.rs:21:5 + --> $DIR/unused-result.rs:25:5 | LL | foo::(); | ^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | let _ = foo::(); | +++++++ error: unused `MustUseMsg` that must be used - --> $DIR/unused-result.rs:22:5 + --> $DIR/unused-result.rs:26:5 | LL | foo::(); | ^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | let _ = foo::(); | +++++++ error: unused result of type `isize` - --> $DIR/unused-result.rs:34:5 + --> $DIR/unused-result.rs:38:5 | LL | foo::(); | ^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | #![deny(unused_results, unused_must_use)] | ^^^^^^^^^^^^^^ error: unused `MustUse` that must be used - --> $DIR/unused-result.rs:35:5 + --> $DIR/unused-result.rs:39:5 | LL | foo::(); | ^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | let _ = foo::(); | +++++++ error: unused `MustUseMsg` that must be used - --> $DIR/unused-result.rs:36:5 + --> $DIR/unused-result.rs:40:5 | LL | foo::(); | ^^^^^^^^^^^^^^^^^^^ @@ -61,5 +61,17 @@ help: use `let _ = ...` to ignore the resulting value LL | let _ = foo::(); | +++++++ -error: aborting due to 5 previous errors +error: unused result of type `((), i32)` + --> $DIR/unused-result.rs:55:5 + | +LL | ((), 1); + | ^^^^^^^^ + +error: unused result of type `(i32, ())` + --> $DIR/unused-result.rs:56:5 + | +LL | (1, ()); + | ^^^^^^^^ + +error: aborting due to 7 previous errors diff --git a/tests/ui/resolve/112590-2.stderr b/tests/ui/resolve/112590-2.stderr index 8569dd0c3fa08..75e7961cb35f4 100644 --- a/tests/ui/resolve/112590-2.stderr +++ b/tests/ui/resolve/112590-2.stderr @@ -49,7 +49,7 @@ error[E0433]: cannot find `sync_error` in `std` LL | let _t = std::sync_error::atomic::AtomicBool::new(true); | ^^^^^^^^^^ could not find `sync_error` in `std` | -help: consider importing this struct +help: consider importing this type alias | LL + use std::sync::atomic::AtomicBool; | diff --git a/tests/ui/static/missing-type.stderr b/tests/ui/static/missing-type.stderr index 6489ceb700a2e..5aad521fb403e 100644 --- a/tests/ui/static/missing-type.stderr +++ b/tests/ui/static/missing-type.stderr @@ -2,7 +2,7 @@ error: missing type for `static` item --> $DIR/missing-type.rs:2:16 | LL | static S_COUNT: = std::sync::atomic::AtomicUsize::new(0); - | ^ help: provide a type for the static variable: `AtomicUsize` + | ^ help: provide a type for the static variable: `Atomic` error: aborting due to 1 previous error diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr index 93e189ffa0d3f..4b1cd8a5a1256 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr @@ -1,14 +1,20 @@ -error[E0599]: no function or associated item named `from_mut` found for struct `AtomicU64` in the current scope +error[E0599]: no function or associated item named `from_mut` found for struct `Atomic` in the current scope --> $DIR/atomic-from-mut-not-available.rs:24:36 | LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); - | ^^^^^^^^ function or associated item not found in `AtomicU64` + | ^^^^^^^^ function or associated item not found in `Atomic` | -note: if you're trying to build a new `AtomicU64`, consider using `AtomicU64::new` which returns `AtomicU64` +note: if you're trying to build a new `Atomic`, consider using `Atomic::::new` which returns `Atomic` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL ::: $SRC_DIR/core/src/sync/atomic.rs:LL:COL | = note: in this macro invocation + = note: the function or associated item was found for + - `Atomic<*mut T>` + - `Atomic` + - `Atomic` + - `Atomic` + and 6 more types = note: this error originates in the macro `atomic_int` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is an associated function `from` with a similar name | diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs index 7e9de3570eb91..519b6977dcb56 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.rs @@ -22,6 +22,6 @@ fn main() { core::sync::atomic::AtomicU64::from_mut(&mut 0u64); - //[alignment_mismatch]~^ ERROR no function or associated item named `from_mut` found for struct `AtomicU64` + //[alignment_mismatch]~^ ERROR no function or associated item named `from_mut` found for struct `Atomic` //[alignment_matches]~^^ ERROR use of unstable library feature `atomic_from_mut` } diff --git a/tests/ui/suggestions/into-convert.rs b/tests/ui/suggestions/into-convert.rs index 1c9a9e0aaf561..3fdb2587727a4 100644 --- a/tests/ui/suggestions/into-convert.rs +++ b/tests/ui/suggestions/into-convert.rs @@ -13,7 +13,7 @@ fn main() { let z: AtomicU32 = 1; //~^ ERROR mismatched types - //~| HELP call `Into::into` on this expression to convert `{integer}` into `AtomicU32` + //~| HELP call `Into::into` on this expression to convert `{integer}` into `Atomic` } struct A; diff --git a/tests/ui/suggestions/into-convert.stderr b/tests/ui/suggestions/into-convert.stderr index 704b280a985f4..8a754e7d2b3c0 100644 --- a/tests/ui/suggestions/into-convert.stderr +++ b/tests/ui/suggestions/into-convert.stderr @@ -30,11 +30,13 @@ error[E0308]: mismatched types --> $DIR/into-convert.rs:14:24 | LL | let z: AtomicU32 = 1; - | --------- ^ expected `AtomicU32`, found integer + | --------- ^ expected `Atomic`, found integer | | | expected due to this | -help: call `Into::into` on this expression to convert `{integer}` into `AtomicU32` + = note: expected struct `Atomic` + found type `{integer}` +help: call `Into::into` on this expression to convert `{integer}` into `Atomic` | LL | let z: AtomicU32 = 1.into(); | +++++++ diff --git a/tests/ui/sync/atomic-types-not-copyable.stderr b/tests/ui/sync/atomic-types-not-copyable.stderr index 05103f5d8f265..4d6918e63c744 100644 --- a/tests/ui/sync/atomic-types-not-copyable.stderr +++ b/tests/ui/sync/atomic-types-not-copyable.stderr @@ -2,7 +2,7 @@ error[E0507]: cannot move out of a shared reference --> $DIR/atomic-types-not-copyable.rs:11:13 | LL | let x = *&x; - | ^^^ move occurs because value has type `std::sync::atomic::AtomicBool`, which does not implement the `Copy` trait + | ^^^ move occurs because value has type `Atomic`, which does not implement the `Copy` trait | help: consider removing the dereference here | @@ -14,7 +14,7 @@ error[E0507]: cannot move out of a shared reference --> $DIR/atomic-types-not-copyable.rs:13:13 | LL | let x = *&x; - | ^^^ move occurs because value has type `std::sync::atomic::AtomicIsize`, which does not implement the `Copy` trait + | ^^^ move occurs because value has type `Atomic`, which does not implement the `Copy` trait | help: consider removing the dereference here | @@ -26,7 +26,7 @@ error[E0507]: cannot move out of a shared reference --> $DIR/atomic-types-not-copyable.rs:15:13 | LL | let x = *&x; - | ^^^ move occurs because value has type `std::sync::atomic::AtomicUsize`, which does not implement the `Copy` trait + | ^^^ move occurs because value has type `Atomic`, which does not implement the `Copy` trait | help: consider removing the dereference here | @@ -38,7 +38,7 @@ error[E0507]: cannot move out of a shared reference --> $DIR/atomic-types-not-copyable.rs:17:13 | LL | let x = *&x; - | ^^^ move occurs because value has type `std::sync::atomic::AtomicPtr`, which does not implement the `Copy` trait + | ^^^ move occurs because value has type `Atomic<*mut usize>`, which does not implement the `Copy` trait | help: consider removing the dereference here | diff --git a/triagebot.toml b/triagebot.toml index 7e4c9c1644ae1..b1675e00f0df7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1371,7 +1371,7 @@ cc = ["@ehuss"] [mentions."src/doc/rustc-dev-guide"] message = "The rustc-dev-guide subtree was changed. If this PR *only* touches the dev guide consider submitting a PR directly to [rust-lang/rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide/pulls) otherwise thank you for updating the dev guide with your changes." -cc = ["@BoxyUwU", "@jieyouxu", "@kobzol", "@tshepang"] +cc = ["@BoxyUwU", "@jieyouxu", "@tshepang"] [mentions."compiler/rustc_passes/src/check_attr.rs"] cc = ["@jdonszelmann", "@JonathanBrouwer"]