diff --git a/Cargo.lock b/Cargo.lock index b8dfdd7cae290..a3e77a97e04c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4392,7 +4392,6 @@ dependencies = [ "rustc_fs_util", "rustc_hir", "rustc_hir_pretty", - "rustc_incremental", "rustc_index", "rustc_macros", "rustc_middle", diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 112cf45ebbf2e..de1adf02a049d 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -15,9 +15,7 @@ use rustc_errors::{ }; use rustc_fs_util::link_or_copy; use rustc_hir::find_attr; -use rustc_incremental::{ - copy_cgu_workproduct_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess, -}; +use rustc_incremental::{copy_cgu_workproduct_to_incr_comp_cache_dir, in_incr_comp_dir_sess}; use rustc_macros::{Decodable, Encodable}; use rustc_metadata::fs::copy_to_stdout; use rustc_middle::bug; @@ -884,20 +882,24 @@ fn execute_copy_from_cache_work_item( let mut links_from_incr_cache = Vec::new(); let mut load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { - let source_file = in_incr_comp_dir(incr_comp_session_dir, saved_path); + let source_file_in_incr_comp_dir = incr_comp_session_dir.join(saved_path); debug!( "copying preexisting module `{}` from {:?} to {}", module.name, - source_file, + source_file_in_incr_comp_dir, output_path.display() ); - match link_or_copy(&source_file, &output_path) { + match link_or_copy(&source_file_in_incr_comp_dir, &output_path) { Ok(_) => { - links_from_incr_cache.push(source_file); + links_from_incr_cache.push(source_file_in_incr_comp_dir); Some(output_path) } Err(error) => { - dcx.emit_err(errors::CopyPathBuf { source_file, output_path, error }); + dcx.emit_err(errors::CopyPathBuf { + source_file: source_file_in_incr_comp_dir, + output_path, + error, + }); None } } diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 0f5d9c5389667..83646cb086d8d 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -10,8 +10,8 @@ mod diagnostics; mod persist; pub use persist::{ - copy_cgu_workproduct_to_incr_comp_cache_dir, finalize_session_directory, in_incr_comp_dir, - in_incr_comp_dir_sess, load_query_result_cache, save_work_product_index, setup_dep_graph, + copy_cgu_workproduct_to_incr_comp_cache_dir, finalize_session_directory, in_incr_comp_dir_sess, + load_query_result_cache, save_work_product_index, setup_dep_graph, }; use rustc_middle::util::Providers; diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 80134d5ff2202..562481e51188b 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -184,15 +184,7 @@ fn lock_file_path(session_dir: &Path) -> PathBuf { /// Returns the path for a given filename within the incremental compilation directory /// in the current session. pub fn in_incr_comp_dir_sess(sess: &Session, file_name: &str) -> PathBuf { - in_incr_comp_dir(&sess.incr_comp_session_dir(), file_name) -} - -/// Returns the path for a given filename within the incremental compilation directory, -/// not necessarily from the current session. -/// -/// To ensure the file is part of the current session, use [`in_incr_comp_dir_sess`]. -pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBuf { - incr_comp_session_dir.join(file_name) + sess.incr_comp_session_dir().join(file_name) } /// Allocates the private session directory. diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index c25c5f1ea47fb..7d486cc394b80 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -10,7 +10,7 @@ mod load; mod save; mod work_product; -pub use fs::{finalize_session_directory, in_incr_comp_dir, in_incr_comp_dir_sess}; +pub use fs::{finalize_session_directory, in_incr_comp_dir_sess}; pub use load::{load_query_result_cache, setup_dep_graph}; pub(crate) use save::save_dep_graph; pub use save::save_work_product_index; diff --git a/compiler/rustc_lint/src/c_void_returns.rs b/compiler/rustc_lint/src/c_void_returns.rs new file mode 100644 index 0000000000000..f4dd260dd5ae4 --- /dev/null +++ b/compiler/rustc_lint/src/c_void_returns.rs @@ -0,0 +1,89 @@ +use rustc_abi::ExternAbi; +use rustc_hir::def::Res; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{self as hir, LangItem}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; + +use crate::lints::{CVoidReturn, ExternCVoidReturn}; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `c_void_returns` lint detects the use of [`core::ffi::c_void`] as a return type. + /// + /// ### Example + /// + /// ```rust + /// use std::ffi::c_void; + /// + /// unsafe extern "C" { + /// fn foo() -> c_void; + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// `c_void` is designed for use through a [`pointer`], equivalent to C's `void*` type. It is a + /// mistake to use it directly as a return type, and calling `extern` functions declared as such + /// may result in undefined behavior. C functions that return `void` must be declared to return + /// [`()`] in Rust (omitting the return type implicitly returns `()`). + /// + /// [`core::ffi::c_void`]: https://doc.rust-lang.org/core/ffi/enum.c_void.html + /// [`pointer`]: https://doc.rust-lang.org/core/primitive.pointer.html + /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html + pub C_VOID_RETURNS, + Warn, + "detects use of `c_void` as a return type" +} + +declare_lint_pass!(CVoidReturns => [C_VOID_RETURNS]); + +impl<'tcx> LateLintPass<'tcx> for CVoidReturns { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + fn_kind: FnKind<'tcx>, + decl: &'tcx hir::FnDecl<'tcx>, + _: &'tcx hir::Body<'tcx>, + _: Span, + _: LocalDefId, + ) { + check_decl( + cx, + decl, + !matches!(fn_kind, FnKind::ItemFn(.., hir::FnHeader { abi: ExternAbi::Rust, .. })), + ); + } + + fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ForeignItem<'tcx>) { + if let hir::ForeignItemKind::Fn(sig, ..) = item.kind { + check_decl(cx, sig.decl, true); + } + } + + fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) { + if let hir::TyKind::FnPtr(fn_ptr_ty) = ty.kind { + check_decl(cx, fn_ptr_ty.decl, fn_ptr_ty.abi != ExternAbi::Rust); + } + } +} + +fn check_decl(cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, is_extern: bool) { + if let hir::FnRetTy::Return(output_ty) = decl.output + && let hir::TyKind::Path(qpath) = output_ty.kind + && let Res::Def(.., def_id) = cx.qpath_res(&qpath, output_ty.hir_id) + && cx.tcx.is_lang_item(def_id, LangItem::CVoid) + { + let suggestion = + cx.sess().source_map().span_extend_to_prev_char(decl.output.span(), ')', true); + + if is_extern { + cx.emit_span_lint(C_VOID_RETURNS, decl.output.span(), ExternCVoidReturn { suggestion }); + } else { + cx.emit_span_lint(C_VOID_RETURNS, decl.output.span(), CVoidReturn { suggestion }); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 74bee7d705e3a..0e96b9f118790 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -32,6 +32,7 @@ mod async_closures; mod async_fn_in_trait; mod autorefs; pub mod builtin; +mod c_void_returns; mod context; mod dangling; mod default_could_be_derived; @@ -86,6 +87,7 @@ use async_closures::AsyncClosureUsage; use async_fn_in_trait::AsyncFnInTrait; use autorefs::*; use builtin::*; +use c_void_returns::*; use dangling::*; use default_could_be_derived::DefaultCouldBeDerived; use deref_into_dyn_supertrait::*; @@ -269,6 +271,7 @@ late_lint_methods!( LifetimeSyntax: LifetimeSyntax, InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, ImplicitProvenanceCasts: ImplicitProvenanceCasts, + CVoidReturns: CVoidReturns, ] ] ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 83827c57aef00..eb82afab13186 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -614,6 +614,33 @@ pub(crate) enum BuiltinSpecialModuleNameUsed { Main, } +// c_void_return.rs +#[derive(Diagnostic)] +#[diag("`c_void` should not be used as a return type")] +#[help("returning `()` in Rust is equivalent to returning `void` in C")] +pub(crate) struct CVoidReturn { + #[suggestion( + "remove the return type to implicitly return `()`", + code = "", + applicability = "maybe-incorrect" + )] + pub suggestion: Span, +} + +// c_void_return.rs +#[derive(Diagnostic)] +#[diag("declarations returning `c_void` are not compatible with C functions returning `void`")] +#[help("returning `()` in Rust is equivalent to returning `void` in C")] +#[note("`c_void` is only used through raw pointers for compatibility with `void` pointers")] +pub(crate) struct ExternCVoidReturn { + #[suggestion( + "remove the return type to implicitly return `()`", + code = "", + applicability = "maybe-incorrect" + )] + pub suggestion: Span, +} + // deref_into_dyn_supertrait.rs #[derive(Diagnostic)] #[diag("this `Deref` implementation is covered by an implicit supertrait coercion")] diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 3a70ee130c27b..2fce131e08b6a 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -18,7 +18,6 @@ rustc_feature = { path = "../rustc_feature" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } -rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 0f63c8469953d..16a5a6c8877a5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2472,10 +2472,10 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { && tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { let saved_path = &work_product.saved_files["rmeta"]; - let incr_comp_session_dir = tcx.sess.incr_comp_session_dir_opt().unwrap(); - let source_file = rustc_incremental::in_incr_comp_dir(&incr_comp_session_dir, saved_path); - debug!("copying preexisting metadata from {source_file:?} to {path:?}"); - match rustc_fs_util::link_or_copy(&source_file, path) { + let incr_comp_session_dir = tcx.sess.incr_comp_session_dir(); + let source_file_in_incr_dir = &incr_comp_session_dir.join(saved_path); + debug!("copying preexisting metadata from {source_file_in_incr_dir:?} to {path:?}"); + match rustc_fs_util::link_or_copy(&source_file_in_incr_dir, path) { Ok(_) => {} Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }), }; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f00b6e079c76e..628b35e27da70 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1825,6 +1825,12 @@ supported_targets! { ("x86_64-unknown-linux-gnuasan", x86_64_unknown_linux_gnuasan), ("x86_64-unknown-linux-gnumsan", x86_64_unknown_linux_gnumsan), ("x86_64-unknown-linux-gnutsan", x86_64_unknown_linux_gnutsan), + + ("aarch64-oe-linux-gnu", aarch64_oe_linux_gnu), + ("armv7-oe-linux-gnueabihf", armv7_oe_linux_gnueabihf), + ("i686-oe-linux-gnu", i686_oe_linux_gnu), + ("riscv64-oe-linux-gnu", riscv64_oe_linux_gnu), + ("x86_64-oe-linux-gnu", x86_64_oe_linux_gnu), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/compiler/rustc_target/src/spec/targets/aarch64_oe_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_oe_linux_gnu.rs new file mode 100644 index 0000000000000..4486da9a471ac --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_oe_linux_gnu.rs @@ -0,0 +1,17 @@ +use crate::spec::{Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::aarch64_unknown_linux_gnu::target(); + + base.metadata = TargetMetadata { + description: Some("64-bit Linux (kernel 3.2+, glibc 2.17+) for yocto".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; + + base.llvm_target = "aarch64-oe-linux-gnu".into(); + base.options.linker = Some("aarch64-oe-linux-gcc".into()); + + base +} diff --git a/compiler/rustc_target/src/spec/targets/armv7_oe_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_oe_linux_gnueabihf.rs new file mode 100644 index 0000000000000..bf0cdb5cdc33f --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/armv7_oe_linux_gnueabihf.rs @@ -0,0 +1,17 @@ +use crate::spec::{Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::armv7_unknown_linux_gnueabihf::target(); + + base.metadata = TargetMetadata { + description: Some("Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) for yocto".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; + + base.llvm_target = "armv7-oe-linux-gnueabihf".into(); + base.options.linker = Some("arm-oe-linux-gnueabi-gcc".into()); + + base +} diff --git a/compiler/rustc_target/src/spec/targets/i686_oe_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_oe_linux_gnu.rs new file mode 100644 index 0000000000000..0e8165d25cee7 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/i686_oe_linux_gnu.rs @@ -0,0 +1,21 @@ +use crate::spec::{Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::i686_unknown_linux_gnu::target(); + + base.metadata = TargetMetadata { + description: Some("32-bit Linux (kernel 3.2, glibc 2.17+) for yocto".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; + + base.llvm_target = "i686-oe-linux-gnu".into(); + + base.options.linker = Some("i686-oe-linux-gcc".into()); + + base.options.cpu = "core2".into(); + base.options.features = "+sse3".into(); + + base +} diff --git a/compiler/rustc_target/src/spec/targets/riscv64_oe_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64_oe_linux_gnu.rs new file mode 100644 index 0000000000000..8d8d579444536 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/riscv64_oe_linux_gnu.rs @@ -0,0 +1,17 @@ +use crate::spec::{Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::riscv64gc_unknown_linux_gnu::target(); + + base.metadata = TargetMetadata { + description: Some("RISC-V Linux (kernel 4.20, glibc 2.29) for yocto".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; + + base.llvm_target = "riscv64-oe-linux-gnu".into(); + base.options.linker = Some("riscv64-oe-linux-gcc".into()); + + base +} diff --git a/compiler/rustc_target/src/spec/targets/x86_64_oe_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_oe_linux_gnu.rs new file mode 100644 index 0000000000000..5877d5092e103 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_oe_linux_gnu.rs @@ -0,0 +1,17 @@ +use crate::spec::{Target, TargetMetadata}; + +pub(crate) fn target() -> Target { + let mut base = super::x86_64_unknown_linux_gnu::target(); + + base.metadata = TargetMetadata { + description: Some("64-bit Linux (kernel 3.2+, glibc 2.17+) for yocto".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; + + base.llvm_target = "x86_64-oe-linux-gnu".into(); + base.options.linker = Some("x86_64-oe-linux-gcc".into()); + + base +} diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 3087a7d2004bc..40e0d8cacfff1 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1753,7 +1753,7 @@ impl Box { /// /// This method guarantees that for the purpose of the aliasing model, this method /// does not materialize a reference to the underlying memory, and thus the returned pointer - /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. + /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`]. /// Note that calling other methods that materialize references to the memory /// may still invalidate this pointer. /// See the example below for how this guarantee can be used. @@ -1776,6 +1776,8 @@ impl Box { /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr + /// [`as_non_null`]: Self::as_non_null + #[must_use] #[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] @@ -1797,7 +1799,7 @@ impl Box { /// /// This method guarantees that for the purpose of the aliasing model, this method /// does not materialize a reference to the underlying memory, and thus the returned pointer - /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. + /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`]. /// Note that calling other methods that materialize mutable references to the memory, /// as well as writing to this memory, may still invalidate this pointer. /// See the example below for how this guarantee can be used. @@ -1823,6 +1825,8 @@ impl Box { /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr + /// [`as_non_null`]: Self::as_non_null + #[must_use] #[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] @@ -1833,6 +1837,48 @@ impl Box { &raw const **b } + /// Returns a `NonNull` pointer to the `Box`'s contents. + /// + /// The caller must ensure that the `Box` outlives the pointer this + /// function returns, or else it will end up dangling. + /// + /// This method guarantees that for the purpose of the aliasing model, this method + /// does not materialize a reference to the underlying memory, and thus the returned pointer + /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`]. + /// Note that calling other methods that materialize references to the memory + /// may still invalidate this pointer. + /// See the example below for how this guarantee can be used. + /// + /// # Examples + /// + /// Due to the aliasing guarantee, the following code is legal: + /// + /// ```rust + /// #![feature(box_as_non_null)] + /// + /// unsafe { + /// let mut b = Box::new(0); + /// let ptr1 = Box::as_non_null(&mut b); + /// ptr1.write(1); + /// let ptr2 = Box::as_non_null(&mut b); + /// ptr2.write(2); + /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: + /// ptr1.write(3); + /// } + /// ``` + /// + /// [`as_mut_ptr`]: Self::as_mut_ptr + /// [`as_ptr`]: Self::as_ptr + /// [`as_non_null`]: Self::as_non_null + #[must_use] + #[unstable(feature = "box_as_non_null", issue = "157345")] + #[rustc_as_ptr] + #[inline] + pub fn as_non_null(b: &mut Self) -> NonNull { + // SAFETY: `Box` is guaranteed to be non-null. + unsafe { NonNull::new_unchecked(Self::as_mut_ptr(b)) } + } + /// Returns a reference to the underlying allocator. /// /// Note: this is an associated function, which means that you have diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index e8865823deb98..802d38e3994b3 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -608,7 +608,6 @@ impl AtomicBool { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bool = true; @@ -618,7 +617,7 @@ impl AtomicBool { /// ``` #[inline] #[cfg(target_has_atomic_primitive_alignment = "8")] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut(v: &mut bool) -> &mut Self { // SAFETY: the mutable reference guarantees unique ownership, and // alignment of both `bool` and `Self` is 1. @@ -633,7 +632,6 @@ impl AtomicBool { /// # Examples /// /// ```ignore-wasm - /// #![feature(atomic_from_mut)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [const { AtomicBool::new(false) }; 10]; @@ -653,7 +651,7 @@ impl AtomicBool { /// }); /// ``` #[inline] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut_slice(this: &mut [Self]) -> &mut [bool] { // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *(this as *mut [Self] as *mut [bool]) } @@ -664,7 +662,6 @@ impl AtomicBool { /// # Examples /// /// ```rust,ignore-wasm - /// #![feature(atomic_from_mut)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [false; 10]; @@ -678,7 +675,7 @@ impl AtomicBool { /// ``` #[inline] #[cfg(target_has_atomic_primitive_alignment = "8")] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut_slice(v: &mut [bool]) -> &mut [Self] { // SAFETY: the mutable reference guarantees unique ownership, and // alignment of both `bool` and `Self` is 1. @@ -1577,7 +1574,6 @@ impl AtomicPtr { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut)] /// use std::sync::atomic::{AtomicPtr, Ordering}; /// /// let mut data = 123; @@ -1589,7 +1585,7 @@ impl AtomicPtr { /// ``` #[inline] #[cfg(target_has_atomic_primitive_alignment = "ptr")] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut(v: &mut *mut T) -> &mut Self { let [] = [(); align_of::>() - align_of::<*mut ()>()]; // SAFETY: @@ -1607,7 +1603,6 @@ impl AtomicPtr { /// # Examples /// /// ```ignore-wasm - /// #![feature(atomic_from_mut)] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -1633,7 +1628,7 @@ impl AtomicPtr { /// }); /// ``` #[inline] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] { // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) } @@ -1646,7 +1641,6 @@ impl AtomicPtr { /// # Examples /// /// ```ignore-wasm - /// #![feature(atomic_from_mut)] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -1668,7 +1662,7 @@ impl AtomicPtr { /// ``` #[inline] #[cfg(target_has_atomic_primitive_alignment = "ptr")] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] { // SAFETY: // - the mutable reference guarantees unique ownership. @@ -2721,7 +2715,6 @@ macro_rules! atomic_int { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut)] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// /// let mut some_int = 123; @@ -2732,7 +2725,7 @@ macro_rules! atomic_int { /// #[inline] #[$cfg_align] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut(v: &mut $int_type) -> &mut Self { let [] = [(); align_of::() - align_of::<$int_type>()]; // SAFETY: @@ -2750,7 +2743,6 @@ macro_rules! atomic_int { /// # Examples /// /// ```ignore-wasm - /// #![feature(atomic_from_mut)] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")] @@ -2772,7 +2764,7 @@ macro_rules! atomic_int { /// }); /// ``` #[inline] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] { // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) } @@ -2791,7 +2783,6 @@ macro_rules! atomic_int { /// # Examples /// /// ```ignore-wasm - /// #![feature(atomic_from_mut)] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// /// let mut some_ints = [0; 10]; @@ -2807,7 +2798,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$cfg_align] - #[unstable(feature = "atomic_from_mut", issue = "76314")] + #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] { let [] = [(); align_of::() - align_of::<$int_type>()]; // SAFETY: diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 5a9c7264c006f..1db44c2c8b39c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1206,7 +1206,9 @@ impl Config { | Subcommand::Install => { assert_eq!( stage, 2, - "x.py should be run with `--stage 2` on CI, but was run with `--stage {stage}`", + "\ +x.py was run under CI with an implicit `--stage {stage}`. This is probably wrong and you want stage 2. +NOTE: Please add `--stage 2` to your command line, or if you're sure you want to run stage {stage} then add `--stage {stage}` explicitly" ); } Subcommand::Clean { .. } diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9118bf124fed3..3abeea4e41af3 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -104,6 +104,7 @@ - [mips\*-mti-none-elf](platform-support/mips-mti-none-elf.md) - [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) + - [\*-oe-linux-gnu](platform-support/oe-linux-gnu.md) - [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md) - [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md) - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index be64a6cfe3eb9..5cbdaf21de755 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -267,6 +267,7 @@ target | std | host | notes -------|:---:|:----:|------- [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon +[`aarch64-oe-linux-gnu`](platform-support/oe-linux-gnu.md) | ✓ | | ARM64 OpenEmbedded/Yocto Linux (GNU) [`aarch64-unknown-helenos`](platform-support/helenos.md) | ✓ | | ARM64 HelenOS [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos @@ -310,6 +311,7 @@ target | std | host | notes [`armv6-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv6 FreeBSD [`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain) +[`armv7-oe-linux-gnueabihf`](platform-support/oe-linux-gnu.md) | ✓ | | ARMv7 OpenEmbedded/Yocto Linux (GNU) [`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) [`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD @@ -337,6 +339,7 @@ target | std | host | notes [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] [`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] +[`i686-oe-linux-gnu`](platform-support/oe-linux-gnu.md) | ✓ | | 32-bit x86 OpenEmbedded/Yocto Linux (GNU) [`i686-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-helenos`](platform-support/helenos.md) | ✓ | | HelenOS IA-32 (see docs for pending issues) @@ -406,6 +409,7 @@ target | std | host | notes [`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF [`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX [`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android +[`riscv64-oe-linux-gnu`](platform-support/oe-linux-gnu.md) | ✓ | | RISC-V OpenEmbedded/Yocto Linux (GNU) [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | `riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia @@ -443,6 +447,7 @@ target | std | host | notes [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178 +[`x86_64-oe-linux-gnu`](platform-support/oe-linux-gnu.md) | ✓ | | x86 64-bit OpenEmbedded/Yocto Linux (GNU) [`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin | [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | diff --git a/src/doc/rustc/src/platform-support/oe-linux-gnu.md b/src/doc/rustc/src/platform-support/oe-linux-gnu.md new file mode 100644 index 0000000000000..353e909262fd0 --- /dev/null +++ b/src/doc/rustc/src/platform-support/oe-linux-gnu.md @@ -0,0 +1,41 @@ +# `*-oe-linux-gnu` + +**Tier: 3** + +Targets for OpenEmbedded/Yocto-based Linux systems. + +Target triplets available: + +* `x86_64-oe-linux-gnu` +* `aarch64-oe-linux-gnu` +* `i686-oe-linux-gnu` +* `armv7-oe-linux-gnueabihf` +* `riscv64-oe-linux-gnu` + +## Target maintainers + +[@DeepeshWR](https://github.com/DeepeshWR) + +## Requirements + +### Operating System + +These targets are intended for Linux systems built using the OpenEmbedded and Yocto Project build systems. + +### C Toolchain + +The targets use the architecture-specific OpenEmbedded GCC driver as the default linker and therefore require the corresponding OpenEmbedded cross-compilation toolchain to be available in the build environment. + +## Building + +These targets are intended for use with the OpenEmbedded/Yocto build system. They provide base target definitions from which downstream Yocto-generated targets may inherit. + +## Building Rust programs + +Rust does not currently ship precompiled artifacts for these targets. + +Downstream Yocto-generated targets may inherit from these base OpenEmbedded targets and customize metadata or vendor-specific configuration as needed. + +## Cross-compilation toolchains and C code + +The targets support linking with C code through the corresponding OpenEmbedded cross-compilation toolchains. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 08478a62b7d85..9469c806a26ad 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -142,7 +142,7 @@ pub(crate) fn try_inline( Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => return Some(Vec::new()), Res::Def(DefKind::Mod, did) => { record_extern_fqn(cx, did, ItemType::Module); - clean::ModuleItem(build_module(cx, did, visited)) + clean::ModuleItem(build_module(cx, did, name, visited)) } Res::Def(DefKind::Static { .. }, did) => { record_extern_fqn(cx, did, ItemType::Static); @@ -207,6 +207,7 @@ pub(crate) fn try_inline_glob( let mut items = build_module_items( cx, did, + cx.tcx.item_name(did), visited, inlined_names, Some(&reexports), @@ -665,16 +666,43 @@ pub(crate) fn build_impl( )); } -fn build_module(cx: &mut DocContext<'_>, did: DefId, visited: &mut DefIdSet) -> clean::Module { - let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None, None); +fn build_module( + cx: &mut DocContext<'_>, + did: DefId, + name: Symbol, + visited: &mut DefIdSet, +) -> clean::Module { + let items = build_module_items(cx, did, name, visited, &mut FxHashSet::default(), None, None); let span = clean::Span::new(cx.tcx.def_span(did)); clean::Module { items, span } } +// We are only interested into `Res::Def`. And in there, we only want "items" which get their own +// rustdoc page. So not `DefKind::Ctor` for example (which is returned by `tcx.module_children()`). +fn should_ignore_res(res: Res) -> bool { + !matches!( + res, + Res::Def(DefKind::Trait, _) + | Res::Def(DefKind::TraitAlias, _) + | Res::Def(DefKind::Fn, _) + | Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::TyAlias, _) + | Res::Def(DefKind::Enum, _) + | Res::Def(DefKind::ForeignTy, _) + | Res::Def(DefKind::Variant, _) + | Res::Def(DefKind::Mod, _) + | Res::Def(DefKind::Static { .. }, _) + | Res::Def(DefKind::Const { .. }, _) + | Res::Def(DefKind::Macro(_), _) + ) +} + fn build_module_items( cx: &mut DocContext<'_>, - did: DefId, + module_def_id: DefId, + module_name: Symbol, visited: &mut DefIdSet, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, allowed_def_ids: Option<&DefIdSet>, @@ -685,61 +713,107 @@ fn build_module_items( // If we're re-exporting a re-export it may actually re-export something in // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. - for item in cx.tcx.module_children(did).iter() { - if item.vis.is_public() { - let res = item.res.expect_non_local(); - if let Some(def_id) = res.opt_def_id() - && let Some(allowed_def_ids) = allowed_def_ids - && !allowed_def_ids.contains(&def_id) + for item in cx.tcx.module_children(module_def_id).iter() { + if !item.vis.is_public() { + continue; + } + let res = item.res.expect_non_local(); + if let Some(def_id) = res.opt_def_id() + && let Some(allowed_def_ids) = allowed_def_ids + && !allowed_def_ids.contains(&def_id) + { + continue; + } + if let Some(def_id) = res.mod_def_id() { + // If we're inlining a glob import, it's possible to have + // two distinct modules with the same name. We don't want to + // inline it, or mark any of its contents as visited. + if module_def_id == def_id + || inlined_names.contains(&(ItemType::Module, item.ident.name)) + || !visited.insert(def_id) { continue; } - if let Some(def_id) = res.mod_def_id() { - // If we're inlining a glob import, it's possible to have - // two distinct modules with the same name. We don't want to - // inline it, or mark any of its contents as visited. - if did == def_id - || inlined_names.contains(&(ItemType::Module, item.ident.name)) - || !visited.insert(def_id) - { - continue; - } - } - if let Res::PrimTy(p) = res { - // Primitive types can't be inlined so generate an import instead. - let prim_ty = clean::PrimitiveType::from(p); - items.push(clean::Item { - inner: Box::new(clean::ItemInner { - name: None, - // We can use the item's `DefId` directly since the only information ever - // used from it is `DefId.krate`. - item_id: ItemId::DefId(did), - attrs: Default::default(), - stability: None, - kind: clean::ImportItem(clean::Import::new_simple( - item.ident.name, - clean::ImportSource { - path: clean::Path { - res, - segments: thin_vec![clean::PathSegment { - name: prim_ty.as_sym(), - args: clean::GenericArgs::AngleBracketed { - args: Default::default(), - constraints: ThinVec::new(), - }, - }], - }, - did: None, + } + if let Res::PrimTy(p) = res { + // Primitive types can't be inlined so generate an import instead. + let prim_ty = clean::PrimitiveType::from(p); + items.push(clean::Item { + inner: Box::new(clean::ItemInner { + name: None, + // We can use the item's `DefId` directly since the only information ever + // used from it is `DefId.krate`. + item_id: ItemId::DefId(module_def_id), + attrs: Default::default(), + stability: None, + kind: clean::ImportItem(clean::Import::new_simple( + item.ident.name, + clean::ImportSource { + path: clean::Path { + res, + segments: thin_vec![clean::PathSegment { + name: prim_ty.as_sym(), + args: clean::GenericArgs::AngleBracketed { + args: Default::default(), + constraints: ThinVec::new(), + }, + }], }, - true, - )), - cfg: None, - inline_stmt_id: None, - }), - }); - } else if let Some(i) = try_inline(cx, res, item.ident.name, attrs, visited) { - items.extend(i) + did: None, + }, + true, + )), + cfg: None, + inline_stmt_id: None, + }), + }); + } else if let Some(def_id) = res.opt_def_id() + && let Some(reexport) = item.reexport_chain.first() + && let Some(reexport_def_id) = reexport.id() + && find_attr!( + load_attrs(cx.tcx, reexport_def_id), + Doc(d) + if d.inline.first().is_some_and(|(inline, _)| *inline == hir::attrs::DocInline::NoInline) + ) + { + if should_ignore_res(res) { + continue; } + // This item is reexported as `no_inline` so it shouldn't be inlined. + let item = Item::from_def_id_and_parts( + module_def_id, + None, + clean::ImportItem(clean::Import::new_simple( + item.ident.name, + clean::ImportSource { + path: clean::Path { + res, + segments: thin_vec![ + clean::PathSegment { + name: module_name, + args: clean::GenericArgs::AngleBracketed { + args: Default::default(), + constraints: ThinVec::new(), + }, + }, + clean::PathSegment { + name: cx.tcx.item_name(def_id), + args: clean::GenericArgs::AngleBracketed { + args: Default::default(), + constraints: ThinVec::new(), + }, + }, + ], + }, + did: None, + }, + true, + )), + cx.tcx, + ); + items.push(item); + } else if let Some(i) = try_inline(cx, res, item.ident.name, attrs, visited) { + items.extend(i) } } diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index bf4e842ceec3f..4c6d62917ab24 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -287,12 +287,14 @@ impl DocFolder for ImportStripper<'_> { clean::ImportItem(imp) if !self.document_hidden && self.import_should_be_hidden(&i, imp) => { + debug!("ImportStripper: stripping {:?}", i.name); None } // clean::ImportItem(_) if !self.document_hidden && i.is_doc_hidden() => None, clean::ExternCrateItem { .. } | clean::ImportItem(..) if i.visibility(self.tcx) != Some(Visibility::Public) => { + debug!("ImportStripper: stripping {:?}", i.name); None } _ => Some(self.fold_item_recur(i)), diff --git a/src/tools/miri/tests/pass/0weak_memory/extra_cpp.rs b/src/tools/miri/tests/pass/0weak_memory/extra_cpp.rs index 6791382f8e0f9..5f4e68b913335 100644 --- a/src/tools/miri/tests/pass/0weak_memory/extra_cpp.rs +++ b/src/tools/miri/tests/pass/0weak_memory/extra_cpp.rs @@ -3,8 +3,6 @@ // Tests operations not performable through C++'s atomic API // but doable in safe (at least sound) Rust. -#![feature(atomic_from_mut)] - use std::sync::atomic::Ordering::*; use std::sync::atomic::{AtomicU16, AtomicU32}; use std::thread::spawn; diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 3d7fd936baa88..7fe8b1a260612 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -28,6 +28,9 @@ //@ revisions: aarch64_nintendo_switch_freestanding //@ [aarch64_nintendo_switch_freestanding] compile-flags: --target aarch64-nintendo-switch-freestanding //@ [aarch64_nintendo_switch_freestanding] needs-llvm-components: aarch64 +//@ revisions: aarch64_oe_linux_gnu +//@ [aarch64_oe_linux_gnu] compile-flags: --target aarch64-oe-linux-gnu +//@ [aarch64_oe_linux_gnu] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_freebsd //@ [aarch64_unknown_freebsd] compile-flags: --target aarch64-unknown-freebsd //@ [aarch64_unknown_freebsd] needs-llvm-components: aarch64 @@ -166,6 +169,9 @@ //@ revisions: armv7_linux_androideabi //@ [armv7_linux_androideabi] compile-flags: --target armv7-linux-androideabi //@ [armv7_linux_androideabi] needs-llvm-components: arm +//@ revisions: armv7_oe_linux_gnueabihf +//@ [armv7_oe_linux_gnueabihf] compile-flags: --target armv7-oe-linux-gnueabihf +//@ [armv7_oe_linux_gnueabihf] needs-llvm-components: arm //@ revisions: armv7_rtems_eabihf //@ [armv7_rtems_eabihf] compile-flags: --target armv7-rtems-eabihf //@ [armv7_rtems_eabihf] needs-llvm-components: arm @@ -271,6 +277,9 @@ //@ revisions: i686_linux_android //@ [i686_linux_android] compile-flags: --target i686-linux-android //@ [i686_linux_android] needs-llvm-components: x86 +//@ revisions: i686_oe_linux_gnu +//@ [i686_oe_linux_gnu] compile-flags: --target i686-oe-linux-gnu +//@ [i686_oe_linux_gnu] needs-llvm-components: x86 //@ revisions: i686_unknown_freebsd //@ [i686_unknown_freebsd] compile-flags: --target i686-unknown-freebsd //@ [i686_unknown_freebsd] needs-llvm-components: x86 @@ -502,6 +511,9 @@ //@ revisions: riscv64_linux_android //@ [riscv64_linux_android] compile-flags: --target riscv64-linux-android //@ [riscv64_linux_android] needs-llvm-components: riscv +//@ revisions: riscv64_oe_linux_gnu +//@ [riscv64_oe_linux_gnu] compile-flags: --target riscv64-oe-linux-gnu +//@ [riscv64_oe_linux_gnu] needs-llvm-components: riscv //@ revisions: riscv64_wrs_vxworks //@ [riscv64_wrs_vxworks] compile-flags: --target riscv64-wrs-vxworks //@ [riscv64_wrs_vxworks] needs-llvm-components: riscv @@ -664,6 +676,9 @@ //@ revisions: x86_64_lynx_lynxos178 //@ [x86_64_lynx_lynxos178] compile-flags: --target x86_64-lynx-lynxos178 //@ [x86_64_lynx_lynxos178] needs-llvm-components: x86 +//@ revisions: x86_64_oe_linux_gnu +//@ [x86_64_oe_linux_gnu] compile-flags: --target x86_64-oe-linux-gnu +//@ [x86_64_oe_linux_gnu] needs-llvm-components: x86 //@ revisions: x86_64_pc_nto_qnx710 //@ [x86_64_pc_nto_qnx710] compile-flags: --target x86_64-pc-nto-qnx710 //@ [x86_64_pc_nto_qnx710] needs-llvm-components: x86 diff --git a/tests/rustdoc-html/reexport/auxiliary/inline-foreign-no_inline.rs b/tests/rustdoc-html/reexport/auxiliary/inline-foreign-no_inline.rs new file mode 100644 index 0000000000000..e27ad8d7f4e80 --- /dev/null +++ b/tests/rustdoc-html/reexport/auxiliary/inline-foreign-no_inline.rs @@ -0,0 +1,9 @@ +#[doc(no_inline)] +pub use crate::{ + future::{Future, FutureExt as _}, +}; + +mod future { + pub struct Future; + pub trait FutureExt {} +} diff --git a/tests/rustdoc-html/reexport/inline-foreign-no_inline.rs b/tests/rustdoc-html/reexport/inline-foreign-no_inline.rs new file mode 100644 index 0000000000000..329a36cc9d264 --- /dev/null +++ b/tests/rustdoc-html/reexport/inline-foreign-no_inline.rs @@ -0,0 +1,22 @@ +// This test ensures that an inlined foreign item with `#[doc(no_inline)]` is +// not inlined. +// This is a regression test for . + +//@ aux-build: inline-foreign-no_inline.rs + +#![crate_name = "foo"] + +extern crate inline_foreign_no_inline; + +// Since we cannot inline `inline_foreign_no_inline` because it has `no_inline`, there +// should have no other items than "Module". +//@ has 'foo/index.html' +//@ count - '//*[@id="main-content"]/h2' 1 +//@ has - '//*[@id="main-content"]/h2' 'Module' +//@ has - '//*[@id="main-content"]/dl[@class="item-table"]/dt' 'dep' + +//@ has 'foo/dep/index.html' +//@ has - '//*[@class="item-table reexports"]/dt' 'pub use dep::Future;' +//@ has - '//*[@class="item-table reexports"]/dt' 'pub use dep::FutureExt as _;' +#[doc(inline)] +pub use inline_foreign_no_inline as dep; diff --git a/tests/rustdoc-html/reexport/inline-no_inline.rs b/tests/rustdoc-html/reexport/inline-no_inline.rs new file mode 100644 index 0000000000000..af483181a487c --- /dev/null +++ b/tests/rustdoc-html/reexport/inline-no_inline.rs @@ -0,0 +1,21 @@ +// This test checks that inlining a `no_inline` is done correctly. + +#![crate_name = "foo"] + +//@ has 'foo/index.html' +// There should be `Re-exports` and `Structs` +//@ count - '//*[@id="main-content"]/h2' 2 +//@ has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Re-exports' +//@ has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Structs' + +//@ has - '//*[@id="main-content"]/dl[@class="item-table reexports"]/dt' 'pub use self::bar::A;' +//@ has - '//*[@id="main-content"]/dl[@class="item-table"]/dt' 'X' + +mod bar { + pub struct A; +} + +#[doc(no_inline)] +pub use self::bar::A; +#[doc(inline)] +pub use self::A as X; diff --git a/tests/ui/lint/c-void-returns.rs b/tests/ui/lint/c-void-returns.rs new file mode 100644 index 0000000000000..7531da3d72f41 --- /dev/null +++ b/tests/ui/lint/c-void-returns.rs @@ -0,0 +1,22 @@ +#![allow(unused)] +#![deny(c_void_returns)] + +use std::ffi::c_void; +use std::ptr; + +fn foo() -> c_void { //~ ERROR c_void + unreachable!() +} + +fn bar() -> *mut c_void { + ptr::null_mut() +} + +unsafe extern "C" { + fn baz() -> c_void; //~ ERROR c_void + fn quux() -> *const c_void; +} + +type Xyzzy = fn() -> c_void; //~ ERROR c_void + +fn main() {} diff --git a/tests/ui/lint/c-void-returns.stderr b/tests/ui/lint/c-void-returns.stderr new file mode 100644 index 0000000000000..7dc724955ecb4 --- /dev/null +++ b/tests/ui/lint/c-void-returns.stderr @@ -0,0 +1,38 @@ +error: `c_void` should not be used as a return type + --> $DIR/c-void-returns.rs:7:13 + | +LL | fn foo() -> c_void { + | ----^^^^^^ + | | + | help: remove the return type to implicitly return `()` + | + = help: returning `()` in Rust is equivalent to returning `void` in C +note: the lint level is defined here + --> $DIR/c-void-returns.rs:2:9 + | +LL | #![deny(c_void_returns)] + | ^^^^^^^^^^^^^^ + +error: declarations returning `c_void` are not compatible with C functions returning `void` + --> $DIR/c-void-returns.rs:16:17 + | +LL | fn baz() -> c_void; + | ----^^^^^^ + | | + | help: remove the return type to implicitly return `()` + | + = help: returning `()` in Rust is equivalent to returning `void` in C + = note: `c_void` is only used through raw pointers for compatibility with `void` pointers + +error: `c_void` should not be used as a return type + --> $DIR/c-void-returns.rs:20:22 + | +LL | type Xyzzy = fn() -> c_void; + | ----^^^^^^ + | | + | help: remove the return type to implicitly return `()` + | + = help: returning `()` in Rust is equivalent to returning `void` in C + +error: aborting due to 3 previous errors + diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_matches.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_matches.stderr deleted file mode 100644 index 109985c005286..0000000000000 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_matches.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: use of unstable library feature `atomic_from_mut` - --> $DIR/atomic-from-mut-not-available.rs:24:5 - | -LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76314 for more information - = help: add `#![feature(atomic_from_mut)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. 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 4df97a655d626..4d17a6d4b5e9e 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,5 +1,5 @@ error[E0599]: no associated function or constant named `from_mut` found for struct `Atomic` in the current scope - --> $DIR/atomic-from-mut-not-available.rs:24:36 + --> $DIR/atomic-from-mut-not-available.rs:25:36 | LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); | ^^^^^^^^ associated function or constant not found in `Atomic` 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 e8aad9cbeb9fa..0d5e09e6e2883 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 @@ -19,9 +19,9 @@ // ... but pass on 64-bit x86_64 linux. //@[alignment_matches] only-x86_64 //@[alignment_matches] only-linux +//@[alignment_matches] check-pass fn main() { core::sync::atomic::AtomicU64::from_mut(&mut 0u64); //[alignment_mismatch]~^ ERROR no associated function or constant named `from_mut` found for struct `Atomic` - //[alignment_matches]~^^ ERROR use of unstable library feature `atomic_from_mut` }