From 7643ea5b9c241019ecabb29b3d1eb30450dc2412 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 24 Jul 2024 15:14:41 -0400 Subject: [PATCH 001/102] create a new section on pointer to reference conversion also start deduplicating the docs that are getting moved to this section. --- library/core/src/ptr/mod.rs | 24 ++++++++++++++++++++ library/core/src/ptr/mut_ptr.rs | 40 ++++----------------------------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f2247e83ec5c5..683f1d57f2259 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -56,6 +56,30 @@ //! has size 0, i.e., even if memory is not actually touched. Consider using //! [`NonNull::dangling`] in such cases. //! +//! ## Pointer to reference conversion +//! When converting a pointer to a reference using `&*`, there are several +//! rules that must be followed: +//! * The pointer must be properly aligned. +//! +//! * It must be "dereferenceable" in the sense defined above +//! +//! * The pointer must point to an initialized instance of `T`. +//! +//! * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is +//! arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. +//! In particular, while this reference exists, the memory the pointer points to must +//! not get accessed (read or written) through any other pointer. +//! +//! If a pointer follows all of these rules, it is said to be +//! *convertable to a reference*. +//! +//! These apply even if the result is unused! +//! (The part about being initialized is not yet fully decided, but until +//! it is, the only safe approach is to ensure that they are indeed initialized.) +//! +//! An example of the implications of the above rules is that an expression such +//! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior. +//! //! ## Allocated object //! //! An *allocated object* is a subset of program memory which is addressable diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 904d6c62dcf1e..c88b356ec743c 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -247,24 +247,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -609,25 +592,10 @@ impl *mut T { /// /// # Safety /// - /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get accessed (read or written) through any other pointer. + /// When calling this method, you have to ensure that *either* + /// the pointer is null *or* + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety /// /// # Examples /// From 1073f97ed8ed11bad047fc0b647ed99b98afb7ca Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 24 Jul 2024 16:36:33 -0400 Subject: [PATCH 002/102] remove duplicate explanations of the ptr to ref conversion rules --- library/core/src/ptr/const_ptr.rs | 54 ++--------------------- library/core/src/ptr/mod.rs | 34 ++++++++++---- library/core/src/ptr/mut_ptr.rs | 73 ++++--------------------------- library/core/src/ptr/non_null.rs | 72 +++++------------------------- 4 files changed, 50 insertions(+), 183 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 3e7933e9eec86..8b9f7b57d0053 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -239,24 +239,7 @@ impl *const T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -302,24 +285,8 @@ impl *const T { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety + /// When calling this method, you have to ensure that + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -350,20 +317,7 @@ impl *const T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// - /// [the module documentation]: crate::ptr#safety + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 683f1d57f2259..591705a69fdee 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -57,21 +57,39 @@ //! [`NonNull::dangling`] in such cases. //! //! ## Pointer to reference conversion -//! When converting a pointer to a reference using `&*`, there are several -//! rules that must be followed: +//! When converting a pointer to a reference `&T` using `&*`, +//! there are several rules that must be followed: +//! //! * The pointer must be properly aligned. //! -//! * It must be "dereferenceable" in the sense defined above +// some microprocessors may use address 0 for an interrupt vector. +// users of these microprocessors must always read/write address 0 through +// a raw pointer, not a reference. +//! * It must be non-null. +//! +//! * It must be "dereferenceable" in the sense defined above. //! -//! * The pointer must point to an initialized instance of `T`. +//! * The pointer must point to a valid instance of `T`. +//! This means that the created reference can only refer to +//! uninitialized memory through careful use of `MaybeUninit`. //! -//! * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is -//! arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. -//! In particular, while this reference exists, the memory the pointer points to must -//! not get accessed (read or written) through any other pointer. +//! * You must enforce Rust's aliasing rules, since the lifetime of the +//! created reference is arbitrarily chosen, +//! and does not necessarily reflect the actual lifetime of the data. +//! In particular, while this reference exists, +//! the memory the pointer points to must +//! not get accessed (read or written) through any raw pointer, +//! except for data inside an `UnsafeCell` +// ^ previous documentation was somewhat unclear on if modifications through +// an UnsafeCell are safe even if they would seemingly violate the exclusivity +// of a mut ref. //! //! If a pointer follows all of these rules, it is said to be //! *convertable to a reference*. +// ^ we use this term instead of saying that the produced reference must +// be valid, as the validity of a reference is easily confused for the +// validity of the thing it refers to, and while the two concepts are +// closly related, they are not identical. //! //! These apply even if the result is unused! //! (The part about being initialized is not yet fully decided, but until diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c88b356ec743c..fb393ffadd5cd 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -296,24 +296,7 @@ impl *mut T { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety + /// When calling this method, you have to ensure that the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -347,20 +330,9 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// - /// [the module documentation]: crate::ptr#safety + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// Note that because the created reference is to `MaybeUninit`, the + /// source pointer can point to uninitialized memory. /// /// # Examples /// @@ -594,7 +566,7 @@ impl *mut T { /// /// When calling this method, you have to ensure that *either* /// the pointer is null *or* - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// /// # Examples @@ -643,24 +615,8 @@ impl *mut T { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) - /// - /// [the module documentation]: crate::ptr#safety + /// When calling this method, you have to ensure that + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -695,20 +651,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get accessed (read or written) through any other pointer. - /// - /// This applies even if the result of this method is unused! - /// - /// [the module documentation]: crate::ptr#safety + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 796c85d0cacc7..1e1cf780c28f0 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -128,20 +128,10 @@ impl NonNull { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// - /// [the module documentation]: crate::ptr#safety + /// When calling this method, you have to ensure that + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// Note that because the created reference is to `MaybeUninit`, the + /// source pointer can point to uninitialized memory. #[inline] #[must_use] #[unstable(feature = "ptr_as_uninit", issue = "75402")] @@ -162,20 +152,10 @@ impl NonNull { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get accessed (read or written) through any other pointer. - /// - /// This applies even if the result of this method is unused! - /// - /// [the module documentation]: crate::ptr#safety + /// When calling this method, you have to ensure that + /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// Note that because the created reference is to `MaybeUninit`, the + /// source pointer can point to uninitialized memory. #[inline] #[must_use] #[unstable(feature = "ptr_as_uninit", issue = "75402")] @@ -361,22 +341,8 @@ impl NonNull { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) + /// When calling this method, you have to ensure that + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -412,22 +378,8 @@ impl NonNull { /// /// # Safety /// - /// When calling this method, you have to ensure that all of the following is true: - /// - /// * The pointer must be properly aligned. - /// - /// * It must be "dereferenceable" in the sense defined in [the module documentation]. - /// - /// * The pointer must point to an initialized instance of `T`. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get accessed (read or written) through any other pointer. - /// - /// This applies even if the result of this method is unused! - /// (The part about being initialized is not yet fully decided, but until - /// it is, the only safe approach is to ensure that they are indeed initialized.) + /// When calling this method, you have to ensure that + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// # Examples /// /// ``` From 3877a7bcf3176740b49c94a137b233e88ce0a401 Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 25 Jul 2024 11:53:07 -0400 Subject: [PATCH 003/102] clarify interactions with MaybeUninit and UnsafeCell --- library/core/src/ptr/mod.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 591705a69fdee..b2fb365d22745 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -69,9 +69,12 @@ //! //! * It must be "dereferenceable" in the sense defined above. //! -//! * The pointer must point to a valid instance of `T`. +//! * The pointer must point to a valid value of type `T`. //! This means that the created reference can only refer to -//! uninitialized memory through careful use of `MaybeUninit`. +//! uninitialized memory through careful use of `MaybeUninit`, +//! or if the uninitialized memory is entirly contained within +//! padding bytes, since +//! [padding has the same validity invariant as `MaybeUninit`][ucg-pad]. //! //! * You must enforce Rust's aliasing rules, since the lifetime of the //! created reference is arbitrarily chosen, @@ -79,10 +82,9 @@ //! In particular, while this reference exists, //! the memory the pointer points to must //! not get accessed (read or written) through any raw pointer, -//! except for data inside an `UnsafeCell` -// ^ previous documentation was somewhat unclear on if modifications through -// an UnsafeCell are safe even if they would seemingly violate the exclusivity -// of a mut ref. +//! except for data inside an `UnsafeCell`. +//! Note that aliased writes are always UB for mutable references, +//! even if they only modify `UnsafeCell` data. //! //! If a pointer follows all of these rules, it is said to be //! *convertable to a reference*. @@ -98,6 +100,8 @@ //! An example of the implications of the above rules is that an expression such //! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior. //! +//! [ucgpad]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#padding +//! //! ## Allocated object //! //! An *allocated object* is a subset of program memory which is addressable From 0b87af9d4f7c6faa9e89496609f016dc3e3977e1 Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Sat, 27 Apr 2024 23:14:36 +0200 Subject: [PATCH 004/102] Add `-Z embed-source=yes` to embed source code in DWARF debug info --- .../src/debuginfo/metadata.rs | 9 +++++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 ++ compiler/rustc_interface/src/tests.rs | 1 + .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 9 +++++-- compiler/rustc_session/messages.ftl | 6 +++++ compiler/rustc_session/src/errors.rs | 14 +++++++++++ compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 25 +++++++++++++++++-- .../src/compiler-flags/embed-source.md | 12 +++++++++ 9 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/embed-source.md diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index ad63858861261..701ea62b21a7d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -629,6 +629,9 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> }; let hash_value = hex_encode(source_file.src_hash.hash_bytes()); + let source = + cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref()); + unsafe { llvm::LLVMRustDIBuilderCreateFile( DIB(cx), @@ -639,6 +642,8 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> hash_kind, hash_value.as_ptr().cast(), hash_value.len(), + source.map_or(ptr::null(), |x| x.as_ptr().cast()), + source.map_or(0, |x| x.len()), ) } } @@ -659,6 +664,8 @@ pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { llvm::ChecksumKind::None, hash_value.as_ptr().cast(), hash_value.len(), + ptr::null(), + 0, ) }) } @@ -943,6 +950,8 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( llvm::ChecksumKind::None, ptr::null(), 0, + ptr::null(), + 0, ); let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index c8e0e075eeabc..faa675b66c8a1 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1853,6 +1853,8 @@ extern "C" { CSKind: ChecksumKind, Checksum: *const c_char, ChecksumLen: size_t, + Source: *const c_char, + SourceLen: size_t, ) -> &'a DIFile; pub fn LLVMRustDIBuilderCreateSubroutineType<'a>( diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ce3b2f77f210a..c4704e38ce6fa 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -773,6 +773,7 @@ fn test_unstable_options_tracking_hash() { tracked!(direct_access_external_data, Some(true)); tracked!(dual_proc_macros, true); tracked!(dwarf_version, Some(5)); + tracked!(embed_source, true); tracked!(emit_thin_lto, false); tracked!(export_executable_symbols, true); tracked!(fewer_names, Some(true)); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 4cdd8af1008c0..6e700c31e6763 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -901,14 +901,19 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind, - const char *Checksum, size_t ChecksumLen) { + const char *Checksum, size_t ChecksumLen, + const char *Source, size_t SourceLen) { std::optional llvmCSKind = fromRust(CSKind); std::optional> CSInfo{}; if (llvmCSKind) CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen}); + std::optional oSource{}; + if (Source) + oSource = StringRef(Source, SourceLen); return wrap(Builder->createFile(StringRef(Filename, FilenameLen), - StringRef(Directory, DirectoryLen), CSInfo)); + StringRef(Directory, DirectoryLen), CSInfo, + oSource)); } extern "C" LLVMMetadataRef diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index b84280a3ccf3f..afd5360c81194 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -14,6 +14,12 @@ session_crate_name_empty = crate name must not be empty session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen +session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version} + +session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled + +session_embed_source_requires_llvm_backend = `-Zembed-source=y` is only supported on the LLVM codegen backend + session_expr_parentheses_needed = parentheses are required to parse this as an expression session_failed_to_create_profiler = failed to create profiler: {$err} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 5cc54a5855bbe..f708109b87a0c 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -165,6 +165,20 @@ pub(crate) struct UnsupportedDwarfVersion { pub(crate) dwarf_version: u32, } +#[derive(Diagnostic)] +#[diag(session_embed_source_insufficient_dwarf_version)] +pub(crate) struct EmbedSourceInsufficientDwarfVersion { + pub(crate) dwarf_version: u32, +} + +#[derive(Diagnostic)] +#[diag(session_embed_source_requires_debug_info)] +pub(crate) struct EmbedSourceRequiresDebugInfo; + +#[derive(Diagnostic)] +#[diag(session_embed_source_requires_llvm_backend)] +pub(crate) struct EmbedSourceRequiresLLVMBackend; + #[derive(Diagnostic)] #[diag(session_target_stack_protector_not_supported)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index bf54aae1cfeb0..13aac6669fe4f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1708,6 +1708,8 @@ options! { them only if an error has not been emitted"), ehcont_guard: bool = (false, parse_bool, [TRACKED], "generate Windows EHCont Guard tables"), + embed_source: bool = (false, parse_bool, [TRACKED], + "embed source text in DWARF debug sections (default: no)"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), emit_thin_lto: bool = (true, parse_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index be67baf57f6dc..634f3684b51aa 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -37,8 +37,9 @@ use rustc_target::spec::{ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CoverageLevel, CrateType, ErrorOutputType, FunctionReturn, Input, InstrumentCoverage, - OptLevel, OutFileName, OutputType, RemapPathScopeComponents, SwitchWithOptPath, + self, CoverageLevel, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, Input, + InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents, + SwitchWithOptPath, }; use crate::parse::{add_feature_diagnostics, ParseSess}; use crate::search_paths::{PathKind, SearchPath}; @@ -1300,6 +1301,26 @@ fn validate_commandline_args_with_session_available(sess: &Session) { .emit_err(errors::SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() }); } + if sess.opts.unstable_opts.embed_source { + let dwarf_version = + sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); + + let uses_llvm_backend = + matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm")); + + if dwarf_version < 5 { + sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version }); + } + + if sess.opts.debuginfo == DebugInfo::None { + sess.dcx().emit_warn(errors::EmbedSourceRequiresDebugInfo); + } + + if !uses_llvm_backend { + sess.dcx().emit_warn(errors::EmbedSourceRequiresLLVMBackend); + } + } + if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray { sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() }); } diff --git a/src/doc/unstable-book/src/compiler-flags/embed-source.md b/src/doc/unstable-book/src/compiler-flags/embed-source.md new file mode 100644 index 0000000000000..01a11e3779712 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/embed-source.md @@ -0,0 +1,12 @@ +# `embed-source` + +This flag controls whether the compiler embeds the program source code text into +the object debug information section. It takes one of the following values: + +* `y`, `yes`, `on` or `true`: put source code in debug info. +* `n`, `no`, `off`, `false` or no value: omit source code from debug info (the default). + +This flag is ignored in configurations that don't emit DWARF debug information +and is ignored on non-LLVM backends. `-Z embed-source` requires DWARFv5. Use +`-Z dwarf-version=5` to control the compiler's DWARF target version and `-g` to +enable debug info generation. From 608901b9c07d7d2f3e2803378c4f0cc07c61bc36 Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Tue, 16 Jul 2024 20:50:28 +0200 Subject: [PATCH 005/102] Add run-make test for -Zembed-source=yes --- tests/run-make/embed-source-dwarf/main.rs | 2 + tests/run-make/embed-source-dwarf/rmake.rs | 70 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/run-make/embed-source-dwarf/main.rs create mode 100644 tests/run-make/embed-source-dwarf/rmake.rs diff --git a/tests/run-make/embed-source-dwarf/main.rs b/tests/run-make/embed-source-dwarf/main.rs new file mode 100644 index 0000000000000..c80af84f41415 --- /dev/null +++ b/tests/run-make/embed-source-dwarf/main.rs @@ -0,0 +1,2 @@ +// hello +fn main() {} diff --git a/tests/run-make/embed-source-dwarf/rmake.rs b/tests/run-make/embed-source-dwarf/rmake.rs new file mode 100644 index 0000000000000..06d550121b0de --- /dev/null +++ b/tests/run-make/embed-source-dwarf/rmake.rs @@ -0,0 +1,70 @@ +//@ ignore-windows +//@ ignore-apple + +// LLVM 17's embed-source implementation requires that source code is attached +// for all files in the output DWARF debug info. This restriction was lifted in +// LLVM 18 (87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d). +//@ min-llvm-version: 18 + +// This test should be replaced with one in tests/debuginfo once we can easily +// tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB +// like setting an invalid source map path don't appear to work, maybe this'll +// become easier once GDB supports DWARFv6? + +use std::collections::HashMap; +use std::path::PathBuf; +use std::rc::Rc; + +use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; +use object::{Object, ObjectSection}; +use run_make_support::{gimli, object, rfs, rustc}; + +fn main() { + let output = PathBuf::from("embed-source-main"); + rustc() + .input("main.rs") + .output(&output) + .arg("-g") + .arg("-Zembed-source=yes") + .arg("-Zdwarf-version=5") + .run(); + let output = rfs::read(output); + let obj = object::File::parse(output.as_slice()).unwrap(); + let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; + let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { + let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap()); + Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian)) + }) + .unwrap(); + + let mut sources = HashMap::new(); + + let mut iter = dwarf.units(); + while let Some(header) = iter.next().unwrap() { + let unit = dwarf.unit(header).unwrap(); + let unit = unit.unit_ref(&dwarf); + + if let Some(program) = &unit.line_program { + let header = program.header(); + for file in header.file_names() { + if let Some(source) = file.source() { + let path = unit + .attr_string(file.path_name()) + .unwrap() + .to_string_lossy() + .unwrap() + .to_string(); + let source = + unit.attr_string(source).unwrap().to_string_lossy().unwrap().to_string(); + if !source.is_empty() { + sources.insert(path, source); + } + } + } + } + } + + dbg!(&sources); + assert_eq!(sources.len(), 1); + assert_eq!(sources.get("main.rs").unwrap(), "// hello\nfn main() {}\n"); +} From 6899f5a8e12986ee16e028f1597963d0de668aca Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Tue, 6 Aug 2024 20:31:12 +0200 Subject: [PATCH 006/102] -Zembed-source: Don't try to warn about incompatible codegen backends --- compiler/rustc_session/messages.ftl | 2 -- compiler/rustc_session/src/errors.rs | 4 ---- compiler/rustc_session/src/session.rs | 7 ------- 3 files changed, 13 deletions(-) diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index afd5360c81194..01c371ee49884 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -18,8 +18,6 @@ session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled -session_embed_source_requires_llvm_backend = `-Zembed-source=y` is only supported on the LLVM codegen backend - session_expr_parentheses_needed = parentheses are required to parse this as an expression session_failed_to_create_profiler = failed to create profiler: {$err} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index f708109b87a0c..15bbd4ff7bf4b 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -175,10 +175,6 @@ pub(crate) struct EmbedSourceInsufficientDwarfVersion { #[diag(session_embed_source_requires_debug_info)] pub(crate) struct EmbedSourceRequiresDebugInfo; -#[derive(Diagnostic)] -#[diag(session_embed_source_requires_llvm_backend)] -pub(crate) struct EmbedSourceRequiresLLVMBackend; - #[derive(Diagnostic)] #[diag(session_target_stack_protector_not_supported)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 634f3684b51aa..e2ef144e732a4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1305,9 +1305,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { let dwarf_version = sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); - let uses_llvm_backend = - matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm")); - if dwarf_version < 5 { sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version }); } @@ -1315,10 +1312,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { if sess.opts.debuginfo == DebugInfo::None { sess.dcx().emit_warn(errors::EmbedSourceRequiresDebugInfo); } - - if !uses_llvm_backend { - sess.dcx().emit_warn(errors::EmbedSourceRequiresLLVMBackend); - } } if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray { From 8b18c6bdd3d61dda5fe8c4ed378286abec2a9bc4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Aug 2024 21:54:44 +0200 Subject: [PATCH 007/102] miri weak memory emulation: initialize store buffer only on atomic writes; pre-fill with previous value --- .../rustc_const_eval/src/interpret/memory.rs | 2 +- src/tools/miri/src/concurrency/data_race.rs | 19 +- src/tools/miri/src/concurrency/weak_memory.rs | 164 ++++++++---------- .../tests/fail/weak_memory/weak_uninit.rs | 43 +++++ .../tests/fail/weak_memory/weak_uninit.stderr | 15 ++ src/tools/miri/tests/pass/weak_memory/weak.rs | 19 +- 6 files changed, 153 insertions(+), 109 deletions(-) create mode 100644 src/tools/miri/tests/fail/weak_memory/weak_uninit.rs create mode 100644 src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 2e5d0ae773654..b0a583f136fd7 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1011,7 +1011,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// /// We do this so Miri's allocation access tracking does not show the validation /// reads as spurious accesses. - pub(super) fn run_for_validation(&self, f: impl FnOnce() -> R) -> R { + pub fn run_for_validation(&self, f: impl FnOnce() -> R) -> R { // This deliberately uses `==` on `bool` to follow the pattern // `assert!(val.replace(new) == old)`. assert!( diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 9df0d95f1f275..6fd207c92b937 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -617,9 +617,10 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { // the *value* (including the associated provenance if this is an AtomicPtr) at this location. // Only metadata on the location itself is used. let scalar = this.allow_data_races_ref(move |this| this.read_scalar(place))?; - this.buffered_atomic_read(place, atomic, scalar, || { + let buffered_scalar = this.buffered_atomic_read(place, atomic, scalar, || { this.validate_atomic_load(place, atomic) - }) + })?; + Ok(buffered_scalar.ok_or_else(|| err_ub!(InvalidUninitBytes(None)))?) } /// Perform an atomic write operation at the memory location. @@ -632,14 +633,14 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); this.atomic_access_check(dest, AtomicAccessType::Store)?; + // Read the previous value so we can put it in the store buffer later. + // The program didn't actually do a read, so suppress the memory access hooks. + // This is also a very special exception where we just ignore an error -- if this read + // was UB e.g. because the memory is uninitialized, we don't want to know! + let old_val = this.run_for_validation(|| this.read_scalar(dest)).ok(); this.allow_data_races_mut(move |this| this.write_scalar(val, dest))?; this.validate_atomic_store(dest, atomic)?; - // FIXME: it's not possible to get the value before write_scalar. A read_scalar will cause - // side effects from a read the program did not perform. So we have to initialise - // the store buffer with the value currently being written - // ONCE this is fixed please remove the hack in buffered_atomic_write() in weak_memory.rs - // https://github.com/rust-lang/miri/issues/2164 - this.buffered_atomic_write(val, dest, atomic, val) + this.buffered_atomic_write(val, dest, atomic, old_val) } /// Perform an atomic RMW operation on a memory location. @@ -768,7 +769,7 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { // in the modification order. // Since `old` is only a value and not the store element, we need to separately // find it in our store buffer and perform load_impl on it. - this.perform_read_on_buffered_latest(place, fail, old.to_scalar())?; + this.perform_read_on_buffered_latest(place, fail)?; } // Return the old value. diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 6f4171584a8f7..0605b744e6afd 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -39,11 +39,10 @@ //! to attach store buffers to atomic objects. However, Rust follows LLVM in that it only has //! 'atomic accesses'. Therefore Miri cannot know when and where atomic 'objects' are being //! created or destroyed, to manage its store buffers. Instead, we hence lazily create an -//! atomic object on the first atomic access to a given region, and we destroy that object -//! on the next non-atomic or imperfectly overlapping atomic access to that region. +//! atomic object on the first atomic write to a given region, and we destroy that object +//! on the next non-atomic or imperfectly overlapping atomic write to that region. //! These lazy (de)allocations happen in memory_accessed() on non-atomic accesses, and -//! get_or_create_store_buffer() on atomic accesses. This mostly works well, but it does -//! lead to some issues (). +//! get_or_create_store_buffer_mut() on atomic writes. //! //! One consequence of this difference is that safe/sound Rust allows for more operations on atomic locations //! than the C++20 atomic API was intended to allow, such as non-atomically accessing @@ -144,11 +143,9 @@ struct StoreElement { /// The timestamp of the storing thread when it performed the store timestamp: VTimestamp, - /// The value of this store - // FIXME: this means the store must be fully initialized; - // we will have to change this if we want to support atomics on - // (partially) uninitialized data. - val: Scalar, + /// The value of this store. `None` means uninitialized. + // FIXME: Currently, we cannot represent partial initialization. + val: Option, /// Metadata about loads from this store element, /// behind a RefCell to keep load op take &self @@ -170,7 +167,7 @@ impl StoreBufferAlloc { /// When a non-atomic access happens on a location that has been atomically accessed /// before without data race, we can determine that the non-atomic access fully happens - /// after all the prior atomic accesses so the location no longer needs to exhibit + /// after all the prior atomic writes so the location no longer needs to exhibit /// any weak memory behaviours until further atomic accesses. pub fn memory_accessed(&self, range: AllocRange, global: &DataRaceState) { if !global.ongoing_action_data_race_free() { @@ -192,37 +189,29 @@ impl StoreBufferAlloc { } } - /// Gets a store buffer associated with an atomic object in this allocation, - /// or creates one with the specified initial value if no atomic object exists yet. - fn get_or_create_store_buffer<'tcx>( + /// Gets a store buffer associated with an atomic object in this allocation. + /// Returns `None` if there is no store buffer. + fn get_store_buffer<'tcx>( &self, range: AllocRange, - init: Scalar, - ) -> InterpResult<'tcx, Ref<'_, StoreBuffer>> { + ) -> InterpResult<'tcx, Option>> { let access_type = self.store_buffers.borrow().access_type(range); let pos = match access_type { AccessType::PerfectlyOverlapping(pos) => pos, - AccessType::Empty(pos) => { - let mut buffers = self.store_buffers.borrow_mut(); - buffers.insert_at_pos(pos, range, StoreBuffer::new(init)); - pos - } - AccessType::ImperfectlyOverlapping(pos_range) => { - // Once we reach here we would've already checked that this access is not racy. - let mut buffers = self.store_buffers.borrow_mut(); - buffers.remove_pos_range(pos_range.clone()); - buffers.insert_at_pos(pos_range.start, range, StoreBuffer::new(init)); - pos_range.start - } + // If there is nothing here yet, that means there wasn't an atomic write yet so + // we can't return anything outdated. + _ => return Ok(None), }; - Ok(Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos])) + let store_buffer = Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos]); + Ok(Some(store_buffer)) } - /// Gets a mutable store buffer associated with an atomic object in this allocation + /// Gets a mutable store buffer associated with an atomic object in this allocation, + /// or creates one with the specified initial value if no atomic object exists yet. fn get_or_create_store_buffer_mut<'tcx>( &mut self, range: AllocRange, - init: Scalar, + init: Option, ) -> InterpResult<'tcx, &mut StoreBuffer> { let buffers = self.store_buffers.get_mut(); let access_type = buffers.access_type(range); @@ -244,10 +233,8 @@ impl StoreBufferAlloc { } impl<'tcx> StoreBuffer { - fn new(init: Scalar) -> Self { + fn new(init: Option) -> Self { let mut buffer = VecDeque::new(); - buffer.reserve(STORE_BUFFER_LIMIT); - let mut ret = Self { buffer }; let store_elem = StoreElement { // The thread index and timestamp of the initialisation write // are never meaningfully used, so it's fine to leave them as 0 @@ -257,11 +244,11 @@ impl<'tcx> StoreBuffer { is_seqcst: false, load_info: RefCell::new(LoadInfo::default()), }; - ret.buffer.push_back(store_elem); - ret + buffer.push_back(store_elem); + Self { buffer } } - /// Reads from the last store in modification order + /// Reads from the last store in modification order, if any. fn read_from_last_store( &self, global: &DataRaceState, @@ -282,7 +269,7 @@ impl<'tcx> StoreBuffer { is_seqcst: bool, rng: &mut (impl rand::Rng + ?Sized), validate: impl FnOnce() -> InterpResult<'tcx>, - ) -> InterpResult<'tcx, (Scalar, LoadRecency)> { + ) -> InterpResult<'tcx, (Option, LoadRecency)> { // Having a live borrow to store_buffer while calling validate_atomic_load is fine // because the race detector doesn't touch store_buffer @@ -419,15 +406,15 @@ impl<'tcx> StoreBuffer { // In the language provided in the paper, an atomic store takes the value from a // non-atomic memory location. // But we already have the immediate value here so we don't need to do the memory - // access - val, + // access. + val: Some(val), is_seqcst, load_info: RefCell::new(LoadInfo::default()), }; - self.buffer.push_back(store_elem); - if self.buffer.len() > STORE_BUFFER_LIMIT { + if self.buffer.len() >= STORE_BUFFER_LIMIT { self.buffer.pop_front(); } + self.buffer.push_back(store_elem); if is_seqcst { // Every store that happens before this needs to be marked as SC // so that in a later SC load, only the last SC store (i.e. this one) or stores that @@ -450,7 +437,12 @@ impl StoreElement { /// buffer regardless of subsequent loads by the same thread; if the earliest load of another /// thread doesn't happen before the current one, then no subsequent load by the other thread /// can happen before the current one. - fn load_impl(&self, index: VectorIdx, clocks: &ThreadClockSet, is_seqcst: bool) -> Scalar { + fn load_impl( + &self, + index: VectorIdx, + clocks: &ThreadClockSet, + is_seqcst: bool, + ) -> Option { let mut load_info = self.load_info.borrow_mut(); load_info.sc_loaded |= is_seqcst; let _ = load_info.timestamps.try_insert(index, clocks.clock[index]); @@ -479,7 +471,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { global.sc_write(threads); } let range = alloc_range(base_offset, place.layout.size); - let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, init)?; + let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, Some(init))?; buffer.read_from_last_store(global, threads, atomic == AtomicRwOrd::SeqCst); buffer.buffered_write(new_val, global, threads, atomic == AtomicRwOrd::SeqCst)?; } @@ -492,47 +484,55 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { atomic: AtomicReadOrd, latest_in_mo: Scalar, validate: impl FnOnce() -> InterpResult<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + ) -> InterpResult<'tcx, Option> { let this = self.eval_context_ref(); - if let Some(global) = &this.machine.data_race { - let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?; - if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() { - if atomic == AtomicReadOrd::SeqCst { - global.sc_read(&this.machine.threads); - } - let mut rng = this.machine.rng.borrow_mut(); - let buffer = alloc_buffers.get_or_create_store_buffer( - alloc_range(base_offset, place.layout.size), - latest_in_mo, - )?; - let (loaded, recency) = buffer.buffered_read( - global, - &this.machine.threads, - atomic == AtomicReadOrd::SeqCst, - &mut *rng, - validate, - )?; - if global.track_outdated_loads && recency == LoadRecency::Outdated { - this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad { - ptr: place.ptr(), - }); + 'fallback: { + if let Some(global) = &this.machine.data_race { + let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?; + if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() { + if atomic == AtomicReadOrd::SeqCst { + global.sc_read(&this.machine.threads); + } + let mut rng = this.machine.rng.borrow_mut(); + let Some(buffer) = alloc_buffers + .get_store_buffer(alloc_range(base_offset, place.layout.size))? + else { + // No old writes available, fall back to base case. + break 'fallback; + }; + let (loaded, recency) = buffer.buffered_read( + global, + &this.machine.threads, + atomic == AtomicReadOrd::SeqCst, + &mut *rng, + validate, + )?; + if global.track_outdated_loads && recency == LoadRecency::Outdated { + this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad { + ptr: place.ptr(), + }); + } + + return Ok(loaded); } - - return Ok(loaded); } } // Race detector or weak memory disabled, simply read the latest value validate()?; - Ok(latest_in_mo) + Ok(Some(latest_in_mo)) } + /// Add the given write to the store buffer. (Does not change machine memory.) + /// + /// `init` says with which value to initialize the store buffer in case there wasn't a store + /// buffer for this memory range before. fn buffered_atomic_write( &mut self, val: Scalar, dest: &MPlaceTy<'tcx>, atomic: AtomicWriteOrd, - init: Scalar, + init: Option, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr(), 0)?; @@ -545,23 +545,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { global.sc_write(threads); } - // UGLY HACK: in write_scalar_atomic() we don't know the value before our write, - // so init == val always. If the buffer is fresh then we would've duplicated an entry, - // so we need to remove it. - // See https://github.com/rust-lang/miri/issues/2164 - let was_empty = matches!( - alloc_buffers - .store_buffers - .borrow() - .access_type(alloc_range(base_offset, dest.layout.size)), - AccessType::Empty(_) - ); let buffer = alloc_buffers .get_or_create_store_buffer_mut(alloc_range(base_offset, dest.layout.size), init)?; - if was_empty { - buffer.buffer.pop_front(); - } - buffer.buffered_write(val, global, threads, atomic == AtomicWriteOrd::SeqCst)?; } @@ -576,7 +561,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &self, place: &MPlaceTy<'tcx>, atomic: AtomicReadOrd, - init: Scalar, ) -> InterpResult<'tcx> { let this = self.eval_context_ref(); @@ -587,8 +571,12 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let size = place.layout.size; let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?; if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() { - let buffer = alloc_buffers - .get_or_create_store_buffer(alloc_range(base_offset, size), init)?; + let Some(buffer) = + alloc_buffers.get_store_buffer(alloc_range(base_offset, size))? + else { + // No store buffer, nothing to do. + return Ok(()); + }; buffer.read_from_last_store( global, &this.machine.threads, diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs new file mode 100644 index 0000000000000..54bea6c6908e3 --- /dev/null +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs @@ -0,0 +1,43 @@ +//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0 + +// Tests showing weak memory behaviours are exhibited. All tests +// return true when the desired behaviour is seen. +// This is scheduler and pseudo-RNG dependent, so each test is +// run multiple times until one try returns true. +// Spurious failure is possible, if you are really unlucky with +// the RNG and always read the latest value from the store buffer. +#![feature(new_uninit)] + +use std::sync::atomic::*; +use std::thread::spawn; + +#[allow(dead_code)] +#[derive(Copy, Clone)] +struct EvilSend(pub T); + +unsafe impl Send for EvilSend {} +unsafe impl Sync for EvilSend {} + +// We can't create static items because we need to run each test multiple times. +fn static_uninit_atomic() -> &'static AtomicUsize { + unsafe { Box::leak(Box::new_uninit()).assume_init_ref() } +} + +fn relaxed() { + let x = static_uninit_atomic(); + let j1 = spawn(move || { + x.store(1, Ordering::Relaxed); + }); + + let j2 = spawn(move || x.load(Ordering::Relaxed)); //~ERROR: using uninitialized data + + j1.join().unwrap(); + j2.join().unwrap(); +} + +pub fn main() { + // If we try often enough, we should hit UB. + for _ in 0..100 { + relaxed(); + } +} diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr new file mode 100644 index 0000000000000..9aa5bc2fa76df --- /dev/null +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/weak_uninit.rs:LL:CC + | +LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/weak_uninit.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs index dac63eeeb0b24..1b5c98cd51826 100644 --- a/src/tools/miri/tests/pass/weak_memory/weak.rs +++ b/src/tools/miri/tests/pass/weak_memory/weak.rs @@ -18,11 +18,9 @@ struct EvilSend(pub T); unsafe impl Send for EvilSend {} unsafe impl Sync for EvilSend {} -// We can't create static items because we need to run each test -// multiple times +// We can't create static items because we need to run each test multiple times. fn static_atomic(val: usize) -> &'static AtomicUsize { - let ret = Box::leak(Box::new(AtomicUsize::new(val))); - ret + Box::leak(Box::new(AtomicUsize::new(val))) } // Spins until it reads the given value @@ -33,7 +31,7 @@ fn reads_value(loc: &AtomicUsize, val: usize) -> usize { val } -fn relaxed() -> bool { +fn relaxed(initial_read: bool) -> bool { let x = static_atomic(0); let j1 = spawn(move || { x.store(1, Relaxed); @@ -47,7 +45,9 @@ fn relaxed() -> bool { j1.join().unwrap(); let r2 = j2.join().unwrap(); - r2 == 1 + // There are three possible values here: 0 (from the initial read), 1 (from the first relaxed + // read), and 2 (the last read). The last case is boring and we cover the other two. + r2 == if initial_read { 0 } else { 1 } } // https://www.doc.ic.ac.uk/~afd/homepages/papers/pdfs/2017/POPL.pdf Figure 8 @@ -74,7 +74,6 @@ fn seq_cst() -> bool { fn initialization_write(add_fence: bool) -> bool { let x = static_atomic(11); - assert_eq!(x.load(Relaxed), 11); // work around https://github.com/rust-lang/miri/issues/2164 let wait = static_atomic(0); @@ -112,11 +111,8 @@ fn faa_replaced_by_load() -> bool { } let x = static_atomic(0); - assert_eq!(x.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164 let y = static_atomic(0); - assert_eq!(y.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164 let z = static_atomic(0); - assert_eq!(z.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164 // Since each thread is so short, we need to make sure that they truely run at the same time // Otherwise t1 will finish before t2 even starts @@ -146,7 +142,8 @@ fn assert_once(f: fn() -> bool) { } pub fn main() { - assert_once(relaxed); + assert_once(|| relaxed(false)); + assert_once(|| relaxed(true)); assert_once(seq_cst); assert_once(|| initialization_write(false)); assert_once(|| initialization_write(true)); From 194baa820d36926cfa9128211bbd61866d49d501 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2024 12:25:37 +0200 Subject: [PATCH 008/102] simd_shuffle intrinsic: allow argument to be passed as vector (not just as array) --- .../src/intrinsics/simd.rs | 10 +++++++ .../rustc_codegen_gcc/src/intrinsic/simd.rs | 19 ++++++++----- compiler/rustc_codegen_llvm/src/intrinsic.rs | 19 ++++++++----- library/core/src/intrinsics/simd.rs | 2 +- tests/ui/simd/shuffle.rs | 27 +++++++++++++++++-- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index ca910dccb0d06..604a88393fd95 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -191,6 +191,14 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }) .try_into() .unwrap(), + _ if idx_ty.is_simd() + && matches!( + idx_ty.simd_size_and_type(fx.tcx).1.kind(), + ty::Uint(ty::UintTy::U32) + ) => + { + idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap() + } _ => { fx.tcx.dcx().span_err( span, @@ -213,6 +221,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; + // FIXME: this is a terrible abstraction-breaking hack. + // Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead. let indexes = { use rustc_middle::mir::interpret::*; let idx_const = match &idx.node { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 8da1df3be1534..96a833ccaf2b6 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -353,19 +353,24 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } if name == sym::simd_shuffle { - // Make sure this is actually an array, since typeck only checks the length-suffixed + // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed // version of this intrinsic. - let n: u64 = match *args[2].layout.ty.kind() { + let idx_ty = args[2].layout.ty; + let n: u64 = match idx_ty.kind() { ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => { len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else( || span_bug!(span, "could not evaluate shuffle index array length"), ) } - _ => return_error!(InvalidMonomorphization::SimdShuffle { - span, - name, - ty: args[2].layout.ty - }), + _ if idx_ty.is_simd() + && matches!( + idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), + ty::Uint(ty::UintTy::U32) + ) => + { + idx_ty.simd_size_and_type(bx.cx.tcx).0 + } + _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }), }; require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index f5558723d11bf..5d32ef0d9d65f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1279,19 +1279,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_shuffle { - // Make sure this is actually an array, since typeck only checks the length-suffixed + // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed // version of this intrinsic. - let n: u64 = match args[2].layout.ty.kind() { + let idx_ty = args[2].layout.ty; + let n: u64 = match idx_ty.kind() { ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else( || span_bug!(span, "could not evaluate shuffle index array length"), ) } - _ => return_error!(InvalidMonomorphization::SimdShuffle { - span, - name, - ty: args[2].layout.ty - }), + _ if idx_ty.is_simd() + && matches!( + idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), + ty::Uint(ty::UintTy::U32) + ) => + { + idx_ty.simd_size_and_type(bx.cx.tcx).0 + } + _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }), }; let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn); diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 221724d7b4ae9..5982819809937 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -232,7 +232,7 @@ extern "rust-intrinsic" { /// /// `T` must be a vector. /// - /// `U` must be a **const** array of `i32`s. This means it must either refer to a named + /// `U` must be a **const** array or vector of `u32`s. This means it must either refer to a named /// const or be given as an inline const expression (`const { ... }`). /// /// `V` must be a vector with the same element type as `T` and the same length as `U`. diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs index 09926d95557cd..dc0d688284e3c 100644 --- a/tests/ui/simd/shuffle.rs +++ b/tests/ui/simd/shuffle.rs @@ -6,15 +6,20 @@ #![allow(incomplete_features)] #![feature(adt_const_params)] +use std::marker::ConstParamTy; + extern "rust-intrinsic" { fn simd_shuffle(a: T, b: T, i: I) -> U; } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, ConstParamTy, PartialEq, Eq)] #[repr(simd)] struct Simd([T; N]); -pub unsafe fn __shuffle_vector16(x: T, y: T) -> U { +unsafe fn __shuffle_vector16(x: T, y: T) -> U { + simd_shuffle(x, y, IDX) +} +unsafe fn __shuffle_vector16_v2, T, U>(x: T, y: T) -> U { simd_shuffle(x, y, IDX) } @@ -30,6 +35,17 @@ fn main() { let y: Simd = simd_shuffle(a, b, I2); assert_eq!(y.0, [1, 5]); } + // Test that we can also use a SIMD vector instead of a normal array for the shuffle. + const I1_SIMD: Simd = Simd([0, 2, 4, 6]); + const I2_SIMD: Simd = Simd([1, 5]); + unsafe { + let x: Simd = simd_shuffle(a, b, I1_SIMD); + assert_eq!(x.0, [0, 2, 4, 6]); + + let y: Simd = simd_shuffle(a, b, I2_SIMD); + assert_eq!(y.0, [1, 5]); + } + // Test that an indirection (via an unnamed constant) // through a const generic parameter also works. // See https://github.com/rust-lang/rust/issues/113500 for details. @@ -42,4 +58,11 @@ fn main() { Simd, >(a, b); } + unsafe { + __shuffle_vector16_v2::< + { Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }, + Simd, + Simd, + >(a, b); + } } From daedbd4d7abb9132638cb420acc549d198c46c48 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2024 17:08:50 +0200 Subject: [PATCH 009/102] make the GCC backend compatible with vector shuffle indices --- compiler/rustc_codegen_gcc/src/builder.rs | 44 +++++++++++++++-------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 47b378cc1cd82..6ba678e2e7c65 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1923,15 +1923,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { v2: RValue<'gcc>, mask: RValue<'gcc>, ) -> RValue<'gcc> { - let struct_type = mask.get_type().is_struct().expect("mask should be of struct type"); - // TODO(antoyo): use a recursive unqualified() here. let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type"); let element_type = vector_type.get_element_type(); let vec_num_units = vector_type.get_num_units(); - let mask_num_units = struct_type.get_field_count(); - let mut vector_elements = vec![]; let mask_element_type = if element_type.is_integral() { element_type } else { @@ -1942,19 +1938,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { #[cfg(not(feature = "master"))] self.int_type }; - for i in 0..mask_num_units { - let field = struct_type.get_field(i as i32); - vector_elements.push(self.context.new_cast( - self.location, - mask.access_field(self.location, field).to_rvalue(), - mask_element_type, - )); - } + + let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() { + let mask_num_units = vector_type.get_num_units(); + let mut mask_elements = vec![]; + for i in 0..mask_num_units { + let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _); + mask_elements.push(self.context.new_cast( + self.location, + self.extract_element(mask, index).to_rvalue(), + mask_element_type, + )); + } + mask_elements + } else { + let struct_type = mask.get_type().is_struct().expect("mask should be of struct type"); + let mask_num_units = struct_type.get_field_count(); + let mut mask_elements = vec![]; + for i in 0..mask_num_units { + let field = struct_type.get_field(i as i32); + mask_elements.push(self.context.new_cast( + self.location, + mask.access_field(self.location, field).to_rvalue(), + mask_element_type, + )); + } + mask_elements + }; + let mask_num_units = mask_elements.len(); // NOTE: the mask needs to be the same length as the input vectors, so add the missing // elements in the mask if needed. for _ in mask_num_units..vec_num_units { - vector_elements.push(self.context.new_rvalue_zero(mask_element_type)); + mask_elements.push(self.context.new_rvalue_zero(mask_element_type)); } let result_type = self.context.new_vector_type(element_type, mask_num_units as u64); @@ -1998,7 +2014,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units); let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64); - let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements); + let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &mask_elements); let result = self.context.new_rvalue_vector_perm(self.location, v1, v2, mask); if vec_num_units != mask_num_units { From 194489473d6edf6d421d657b5716996f02230928 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 10:27:44 +1000 Subject: [PATCH 010/102] Add `warn(unreachable_pub)` to several crates. It requires no additonal changes to these crates, but will prevent unnecessary `pub`s in the future. --- compiler/rustc_abi/src/lib.rs | 1 + compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast_ir/src/lib.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 3dc548c4554a3..ea634d7485ef7 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -3,6 +3,7 @@ #![cfg_attr(feature = "nightly", doc(rust_logo))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::fmt; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 27e9f3d137ffd..7730d0b4b78df 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -19,6 +19,7 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod util { diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 1d0c76f6ceae8..eeed5d3615139 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -2,6 +2,7 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[cfg(feature = "nightly")] From f839309c74d08a2cc8fb0a6db5089bb6f70f669b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 10:40:10 +1000 Subject: [PATCH 011/102] Add `warn(unreachable_pub)` to `rustc_arena`. --- compiler/rustc_arena/src/lib.rs | 1 + compiler/rustc_arena/src/tests.rs | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index f5f01348e4612..8493354014734 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -25,6 +25,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(strict_provenance)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::alloc::Layout; diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs index 9eaa292e9893c..bfde8abd5893a 100644 --- a/compiler/rustc_arena/src/tests.rs +++ b/compiler/rustc_arena/src/tests.rs @@ -32,7 +32,7 @@ impl TypedArena { } #[test] -pub fn test_unused() { +fn test_unused() { let arena: TypedArena = TypedArena::default(); assert!(arena.chunks.borrow().is_empty()); } @@ -75,7 +75,7 @@ fn test_arena_alloc_nested() { } #[test] -pub fn test_copy() { +fn test_copy() { let arena = TypedArena::default(); #[cfg(not(miri))] const N: usize = 100000; @@ -87,13 +87,13 @@ pub fn test_copy() { } #[bench] -pub fn bench_copy(b: &mut Bencher) { +fn bench_copy(b: &mut Bencher) { let arena = TypedArena::default(); b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 })) } #[bench] -pub fn bench_copy_nonarena(b: &mut Bencher) { +fn bench_copy_nonarena(b: &mut Bencher) { b.iter(|| { let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 }); }) @@ -106,7 +106,7 @@ struct Noncopy { } #[test] -pub fn test_noncopy() { +fn test_noncopy() { let arena = TypedArena::default(); #[cfg(not(miri))] const N: usize = 100000; @@ -118,7 +118,7 @@ pub fn test_noncopy() { } #[test] -pub fn test_typed_arena_zero_sized() { +fn test_typed_arena_zero_sized() { let arena = TypedArena::default(); #[cfg(not(miri))] const N: usize = 100000; @@ -130,7 +130,7 @@ pub fn test_typed_arena_zero_sized() { } #[test] -pub fn test_typed_arena_clear() { +fn test_typed_arena_clear() { let mut arena = TypedArena::default(); for _ in 0..10 { arena.clear(); @@ -145,7 +145,7 @@ pub fn test_typed_arena_clear() { } #[bench] -pub fn bench_typed_arena_clear(b: &mut Bencher) { +fn bench_typed_arena_clear(b: &mut Bencher) { let mut arena = TypedArena::default(); b.iter(|| { arena.alloc(Point { x: 1, y: 2, z: 3 }); @@ -154,7 +154,7 @@ pub fn bench_typed_arena_clear(b: &mut Bencher) { } #[bench] -pub fn bench_typed_arena_clear_100(b: &mut Bencher) { +fn bench_typed_arena_clear_100(b: &mut Bencher) { let mut arena = TypedArena::default(); b.iter(|| { for _ in 0..100 { @@ -230,7 +230,7 @@ fn test_typed_arena_drop_small_count() { } #[bench] -pub fn bench_noncopy(b: &mut Bencher) { +fn bench_noncopy(b: &mut Bencher) { let arena = TypedArena::default(); b.iter(|| { arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] }) @@ -238,7 +238,7 @@ pub fn bench_noncopy(b: &mut Bencher) { } #[bench] -pub fn bench_noncopy_nonarena(b: &mut Bencher) { +fn bench_noncopy_nonarena(b: &mut Bencher) { b.iter(|| { let _: Box<_> = Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] }); From ea014b4d75d63c2c9d19a67abae5309790186525 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 10:46:06 +1000 Subject: [PATCH 012/102] Add `warn(unreachable_pub)` to `rustc_ast_lowering`. --- compiler/rustc_ast_lowering/src/errors.rs | 80 +++++++++++------------ compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 1 + 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 7a6c9d8d0d375..18019b3da9206 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(ast_lowering_generic_type_with_parentheses, code = E0214)] -pub struct GenericTypeWithParentheses { +pub(crate) struct GenericTypeWithParentheses { #[primary_span] #[label] pub span: Span, @@ -16,7 +16,7 @@ pub struct GenericTypeWithParentheses { #[derive(Subdiagnostic)] #[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")] -pub struct UseAngleBrackets { +pub(crate) struct UseAngleBrackets { #[suggestion_part(code = "<")] pub open_param: Span, #[suggestion_part(code = ">")] @@ -26,7 +26,7 @@ pub struct UseAngleBrackets { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_abi, code = E0703)] #[note] -pub struct InvalidAbi { +pub(crate) struct InvalidAbi { #[primary_span] #[label] pub span: Span, @@ -38,7 +38,7 @@ pub struct InvalidAbi { pub suggestion: Option, } -pub struct InvalidAbiReason(pub &'static str); +pub(crate) struct InvalidAbiReason(pub &'static str); impl Subdiagnostic for InvalidAbiReason { fn add_to_diag_with>( @@ -57,7 +57,7 @@ impl Subdiagnostic for InvalidAbiReason { code = "{suggestion}", applicability = "maybe-incorrect" )] -pub struct InvalidAbiSuggestion { +pub(crate) struct InvalidAbiSuggestion { #[primary_span] pub span: Span, pub suggestion: String, @@ -65,7 +65,7 @@ pub struct InvalidAbiSuggestion { #[derive(Diagnostic)] #[diag(ast_lowering_assoc_ty_parentheses)] -pub struct AssocTyParentheses { +pub(crate) struct AssocTyParentheses { #[primary_span] pub span: Span, #[subdiagnostic] @@ -73,7 +73,7 @@ pub struct AssocTyParentheses { } #[derive(Subdiagnostic)] -pub enum AssocTyParenthesesSub { +pub(crate) enum AssocTyParenthesesSub { #[multipart_suggestion(ast_lowering_remove_parentheses)] Empty { #[suggestion_part(code = "")] @@ -91,7 +91,7 @@ pub enum AssocTyParenthesesSub { #[derive(Diagnostic)] #[diag(ast_lowering_misplaced_impl_trait, code = E0562)] #[note] -pub struct MisplacedImplTrait<'a> { +pub(crate) struct MisplacedImplTrait<'a> { #[primary_span] pub span: Span, pub position: DiagArgFromDisplay<'a>, @@ -99,7 +99,7 @@ pub struct MisplacedImplTrait<'a> { #[derive(Diagnostic)] #[diag(ast_lowering_assoc_ty_binding_in_dyn)] -pub struct MisplacedAssocTyBinding { +pub(crate) struct MisplacedAssocTyBinding { #[primary_span] pub span: Span, #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")] @@ -108,7 +108,7 @@ pub struct MisplacedAssocTyBinding { #[derive(Diagnostic)] #[diag(ast_lowering_underscore_expr_lhs_assign)] -pub struct UnderscoreExprLhsAssign { +pub(crate) struct UnderscoreExprLhsAssign { #[primary_span] #[label] pub span: Span, @@ -116,7 +116,7 @@ pub struct UnderscoreExprLhsAssign { #[derive(Diagnostic)] #[diag(ast_lowering_base_expression_double_dot, code = E0797)] -pub struct BaseExpressionDoubleDot { +pub(crate) struct BaseExpressionDoubleDot { #[primary_span] #[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")] pub span: Span, @@ -124,7 +124,7 @@ pub struct BaseExpressionDoubleDot { #[derive(Diagnostic)] #[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)] -pub struct AwaitOnlyInAsyncFnAndBlocks { +pub(crate) struct AwaitOnlyInAsyncFnAndBlocks { #[primary_span] #[label] pub await_kw_span: Span, @@ -134,21 +134,21 @@ pub struct AwaitOnlyInAsyncFnAndBlocks { #[derive(Diagnostic)] #[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)] -pub struct CoroutineTooManyParameters { +pub(crate) struct CoroutineTooManyParameters { #[primary_span] pub fn_decl_span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_closure_cannot_be_static, code = E0697)] -pub struct ClosureCannotBeStatic { +pub(crate) struct ClosureCannotBeStatic { #[primary_span] pub fn_decl_span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_functional_record_update_destructuring_assignment)] -pub struct FunctionalRecordUpdateDestructuringAssignment { +pub(crate) struct FunctionalRecordUpdateDestructuringAssignment { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub span: Span, @@ -156,28 +156,28 @@ pub struct FunctionalRecordUpdateDestructuringAssignment { #[derive(Diagnostic)] #[diag(ast_lowering_async_coroutines_not_supported, code = E0727)] -pub struct AsyncCoroutinesNotSupported { +pub(crate) struct AsyncCoroutinesNotSupported { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)] -pub struct InlineAsmUnsupportedTarget { +pub(crate) struct InlineAsmUnsupportedTarget { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_att_syntax_only_x86)] -pub struct AttSyntaxOnlyX86 { +pub(crate) struct AttSyntaxOnlyX86 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_abi_specified_multiple_times)] -pub struct AbiSpecifiedMultipleTimes { +pub(crate) struct AbiSpecifiedMultipleTimes { #[primary_span] pub abi_span: Span, pub prev_name: Symbol, @@ -189,7 +189,7 @@ pub struct AbiSpecifiedMultipleTimes { #[derive(Diagnostic)] #[diag(ast_lowering_clobber_abi_not_supported)] -pub struct ClobberAbiNotSupported { +pub(crate) struct ClobberAbiNotSupported { #[primary_span] pub abi_span: Span, } @@ -197,7 +197,7 @@ pub struct ClobberAbiNotSupported { #[derive(Diagnostic)] #[note] #[diag(ast_lowering_invalid_abi_clobber_abi)] -pub struct InvalidAbiClobberAbi { +pub(crate) struct InvalidAbiClobberAbi { #[primary_span] pub abi_span: Span, pub supported_abis: String, @@ -205,7 +205,7 @@ pub struct InvalidAbiClobberAbi { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_register)] -pub struct InvalidRegister<'a> { +pub(crate) struct InvalidRegister<'a> { #[primary_span] pub op_span: Span, pub reg: Symbol, @@ -214,7 +214,7 @@ pub struct InvalidRegister<'a> { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_register_class)] -pub struct InvalidRegisterClass<'a> { +pub(crate) struct InvalidRegisterClass<'a> { #[primary_span] pub op_span: Span, pub reg_class: Symbol, @@ -223,7 +223,7 @@ pub struct InvalidRegisterClass<'a> { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_asm_template_modifier_reg_class)] -pub struct InvalidAsmTemplateModifierRegClass { +pub(crate) struct InvalidAsmTemplateModifierRegClass { #[primary_span] #[label(ast_lowering_template_modifier)] pub placeholder_span: Span, @@ -234,7 +234,7 @@ pub struct InvalidAsmTemplateModifierRegClass { } #[derive(Subdiagnostic)] -pub enum InvalidAsmTemplateModifierRegClassSub { +pub(crate) enum InvalidAsmTemplateModifierRegClassSub { #[note(ast_lowering_support_modifiers)] SupportModifier { class_name: Symbol, modifiers: String }, #[note(ast_lowering_does_not_support_modifiers)] @@ -243,7 +243,7 @@ pub enum InvalidAsmTemplateModifierRegClassSub { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_asm_template_modifier_const)] -pub struct InvalidAsmTemplateModifierConst { +pub(crate) struct InvalidAsmTemplateModifierConst { #[primary_span] #[label(ast_lowering_template_modifier)] pub placeholder_span: Span, @@ -253,7 +253,7 @@ pub struct InvalidAsmTemplateModifierConst { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_asm_template_modifier_sym)] -pub struct InvalidAsmTemplateModifierSym { +pub(crate) struct InvalidAsmTemplateModifierSym { #[primary_span] #[label(ast_lowering_template_modifier)] pub placeholder_span: Span, @@ -263,7 +263,7 @@ pub struct InvalidAsmTemplateModifierSym { #[derive(Diagnostic)] #[diag(ast_lowering_invalid_asm_template_modifier_label)] -pub struct InvalidAsmTemplateModifierLabel { +pub(crate) struct InvalidAsmTemplateModifierLabel { #[primary_span] #[label(ast_lowering_template_modifier)] pub placeholder_span: Span, @@ -273,7 +273,7 @@ pub struct InvalidAsmTemplateModifierLabel { #[derive(Diagnostic)] #[diag(ast_lowering_register_class_only_clobber)] -pub struct RegisterClassOnlyClobber { +pub(crate) struct RegisterClassOnlyClobber { #[primary_span] pub op_span: Span, pub reg_class_name: Symbol, @@ -281,7 +281,7 @@ pub struct RegisterClassOnlyClobber { #[derive(Diagnostic)] #[diag(ast_lowering_register_conflict)] -pub struct RegisterConflict<'a> { +pub(crate) struct RegisterConflict<'a> { #[primary_span] #[label(ast_lowering_register1)] pub op_span1: Span, @@ -296,7 +296,7 @@ pub struct RegisterConflict<'a> { #[derive(Diagnostic)] #[help] #[diag(ast_lowering_sub_tuple_binding)] -pub struct SubTupleBinding<'a> { +pub(crate) struct SubTupleBinding<'a> { #[primary_span] #[label] #[suggestion( @@ -313,7 +313,7 @@ pub struct SubTupleBinding<'a> { #[derive(Diagnostic)] #[diag(ast_lowering_extra_double_dot)] -pub struct ExtraDoubleDot<'a> { +pub(crate) struct ExtraDoubleDot<'a> { #[primary_span] #[label] pub span: Span, @@ -325,21 +325,21 @@ pub struct ExtraDoubleDot<'a> { #[derive(Diagnostic)] #[note] #[diag(ast_lowering_misplaced_double_dot)] -pub struct MisplacedDoubleDot { +pub(crate) struct MisplacedDoubleDot { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_misplaced_relax_trait_bound)] -pub struct MisplacedRelaxTraitBound { +pub(crate) struct MisplacedRelaxTraitBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_lowering_match_arm_with_no_body)] -pub struct MatchArmWithNoBody { +pub(crate) struct MatchArmWithNoBody { #[primary_span] pub span: Span, #[suggestion(code = " => todo!(),", applicability = "has-placeholders")] @@ -348,7 +348,7 @@ pub struct MatchArmWithNoBody { #[derive(Diagnostic)] #[diag(ast_lowering_never_pattern_with_body)] -pub struct NeverPatternWithBody { +pub(crate) struct NeverPatternWithBody { #[primary_span] #[label] #[suggestion(code = "", applicability = "maybe-incorrect")] @@ -357,7 +357,7 @@ pub struct NeverPatternWithBody { #[derive(Diagnostic)] #[diag(ast_lowering_never_pattern_with_guard)] -pub struct NeverPatternWithGuard { +pub(crate) struct NeverPatternWithGuard { #[primary_span] #[suggestion(code = "", applicability = "maybe-incorrect")] pub span: Span, @@ -365,7 +365,7 @@ pub struct NeverPatternWithGuard { #[derive(Diagnostic)] #[diag(ast_lowering_arbitrary_expression_in_pattern)] -pub struct ArbitraryExpressionInPattern { +pub(crate) struct ArbitraryExpressionInPattern { #[primary_span] pub span: Span, #[note(ast_lowering_pattern_from_macro_note)] @@ -374,13 +374,13 @@ pub struct ArbitraryExpressionInPattern { #[derive(Diagnostic)] #[diag(ast_lowering_inclusive_range_with_no_end)] -pub struct InclusiveRangeWithNoEnd { +pub(crate) struct InclusiveRangeWithNoEnd { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -pub enum BadReturnTypeNotation { +pub(crate) enum BadReturnTypeNotation { #[diag(ast_lowering_bad_return_type_notation_inputs)] Inputs { #[primary_span] diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7af3945d3f99d..46ea7e6acb724 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1182,7 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// into the body. This is to make sure that the future actually owns the /// arguments that are passed to the function, and to ensure things like /// drop order are stable. - pub fn lower_coroutine_body_with_moved_arguments( + pub(crate) fn lower_coroutine_body_with_moved_arguments( &mut self, decl: &FnDecl, lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 81d17a9dec205..43b56d7a91b12 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -37,6 +37,7 @@ #![feature(box_patterns)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::collections::hash_map::Entry; From a6b2880d5a3f8faec20b96014792b21ae2c5bfbb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 21:19:05 +1000 Subject: [PATCH 013/102] Add `warn(unreachable_pub)` to `rustc_ast_passes`. --- compiler/rustc_ast_passes/src/errors.rs | 164 ++++++++++++------------ compiler/rustc_ast_passes/src/lib.rs | 1 + 2 files changed, 83 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 9e40368083729..d2c127a7bbb0d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -11,7 +11,7 @@ use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(ast_passes_visibility_not_permitted, code = E0449)] -pub struct VisibilityNotPermitted { +pub(crate) struct VisibilityNotPermitted { #[primary_span] pub span: Span, #[subdiagnostic] @@ -25,7 +25,7 @@ pub struct VisibilityNotPermitted { } #[derive(Subdiagnostic)] -pub enum VisibilityNotPermittedNote { +pub(crate) enum VisibilityNotPermittedNote { #[note(ast_passes_enum_variant)] EnumVariant, #[note(ast_passes_trait_impl)] @@ -38,7 +38,7 @@ pub enum VisibilityNotPermittedNote { #[derive(Diagnostic)] #[diag(ast_passes_trait_fn_const, code = E0379)] -pub struct TraitFnConst { +pub(crate) struct TraitFnConst { #[primary_span] #[label] pub span: Span, @@ -64,21 +64,21 @@ pub struct TraitFnConst { #[derive(Diagnostic)] #[diag(ast_passes_forbidden_bound)] -pub struct ForbiddenBound { +pub(crate) struct ForbiddenBound { #[primary_span] pub spans: Vec, } #[derive(Diagnostic)] #[diag(ast_passes_forbidden_const_param)] -pub struct ForbiddenConstParam { +pub(crate) struct ForbiddenConstParam { #[primary_span] pub const_param_spans: Vec, } #[derive(Diagnostic)] #[diag(ast_passes_fn_param_too_many)] -pub struct FnParamTooMany { +pub(crate) struct FnParamTooMany { #[primary_span] pub span: Span, pub max_num_args: usize, @@ -86,14 +86,14 @@ pub struct FnParamTooMany { #[derive(Diagnostic)] #[diag(ast_passes_fn_param_c_var_args_not_last)] -pub struct FnParamCVarArgsNotLast { +pub(crate) struct FnParamCVarArgsNotLast { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_fn_param_doc_comment)] -pub struct FnParamDocComment { +pub(crate) struct FnParamDocComment { #[primary_span] #[label] pub span: Span, @@ -101,7 +101,7 @@ pub struct FnParamDocComment { #[derive(Diagnostic)] #[diag(ast_passes_fn_param_forbidden_attr)] -pub struct FnParamForbiddenAttr { +pub(crate) struct FnParamForbiddenAttr { #[primary_span] pub span: Span, } @@ -109,7 +109,7 @@ pub struct FnParamForbiddenAttr { #[derive(Diagnostic)] #[diag(ast_passes_fn_param_forbidden_self)] #[note] -pub struct FnParamForbiddenSelf { +pub(crate) struct FnParamForbiddenSelf { #[primary_span] #[label] pub span: Span, @@ -117,7 +117,7 @@ pub struct FnParamForbiddenSelf { #[derive(Diagnostic)] #[diag(ast_passes_forbidden_default)] -pub struct ForbiddenDefault { +pub(crate) struct ForbiddenDefault { #[primary_span] pub span: Span, #[label] @@ -126,7 +126,7 @@ pub struct ForbiddenDefault { #[derive(Diagnostic)] #[diag(ast_passes_assoc_const_without_body)] -pub struct AssocConstWithoutBody { +pub(crate) struct AssocConstWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " = ;", applicability = "has-placeholders")] @@ -135,7 +135,7 @@ pub struct AssocConstWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_assoc_fn_without_body)] -pub struct AssocFnWithoutBody { +pub(crate) struct AssocFnWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " {{ }}", applicability = "has-placeholders")] @@ -144,7 +144,7 @@ pub struct AssocFnWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_assoc_type_without_body)] -pub struct AssocTypeWithoutBody { +pub(crate) struct AssocTypeWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " = ;", applicability = "has-placeholders")] @@ -153,7 +153,7 @@ pub struct AssocTypeWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_const_without_body)] -pub struct ConstWithoutBody { +pub(crate) struct ConstWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " = ;", applicability = "has-placeholders")] @@ -162,7 +162,7 @@ pub struct ConstWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_static_without_body)] -pub struct StaticWithoutBody { +pub(crate) struct StaticWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " = ;", applicability = "has-placeholders")] @@ -171,7 +171,7 @@ pub struct StaticWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_ty_alias_without_body)] -pub struct TyAliasWithoutBody { +pub(crate) struct TyAliasWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " = ;", applicability = "has-placeholders")] @@ -180,7 +180,7 @@ pub struct TyAliasWithoutBody { #[derive(Diagnostic)] #[diag(ast_passes_fn_without_body)] -pub struct FnWithoutBody { +pub(crate) struct FnWithoutBody { #[primary_span] pub span: Span, #[suggestion(code = " {{ }}", applicability = "has-placeholders")] @@ -190,7 +190,7 @@ pub struct FnWithoutBody { } #[derive(Subdiagnostic)] -pub enum ExternBlockSuggestion { +pub(crate) enum ExternBlockSuggestion { #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")] Implicit { #[suggestion_part(code = "extern {{")] @@ -210,7 +210,7 @@ pub enum ExternBlockSuggestion { #[derive(Diagnostic)] #[diag(ast_passes_extern_invalid_safety)] -pub struct InvalidSafetyOnExtern { +pub(crate) struct InvalidSafetyOnExtern { #[primary_span] pub item_span: Span, #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] @@ -219,28 +219,28 @@ pub struct InvalidSafetyOnExtern { #[derive(Diagnostic)] #[diag(ast_passes_item_invalid_safety)] -pub struct InvalidSafetyOnItem { +pub(crate) struct InvalidSafetyOnItem { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_bare_fn_invalid_safety)] -pub struct InvalidSafetyOnBareFn { +pub(crate) struct InvalidSafetyOnBareFn { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_unsafe_static)] -pub struct UnsafeStatic { +pub(crate) struct UnsafeStatic { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_bound_in_context)] -pub struct BoundInContext<'a> { +pub(crate) struct BoundInContext<'a> { #[primary_span] pub span: Span, pub ctx: &'a str, @@ -249,7 +249,7 @@ pub struct BoundInContext<'a> { #[derive(Diagnostic)] #[diag(ast_passes_extern_types_cannot)] #[note(ast_passes_extern_keyword_link)] -pub struct ExternTypesCannotHave<'a> { +pub(crate) struct ExternTypesCannotHave<'a> { #[primary_span] #[suggestion(code = "", applicability = "maybe-incorrect")] pub span: Span, @@ -262,7 +262,7 @@ pub struct ExternTypesCannotHave<'a> { #[derive(Diagnostic)] #[diag(ast_passes_body_in_extern)] #[note(ast_passes_extern_keyword_link)] -pub struct BodyInExtern<'a> { +pub(crate) struct BodyInExtern<'a> { #[primary_span] #[label(ast_passes_cannot_have)] pub span: Span, @@ -277,7 +277,7 @@ pub struct BodyInExtern<'a> { #[diag(ast_passes_fn_body_extern)] #[help] #[note(ast_passes_extern_keyword_link)] -pub struct FnBodyInExtern { +pub(crate) struct FnBodyInExtern { #[primary_span] #[label(ast_passes_cannot_have)] pub span: Span, @@ -289,7 +289,7 @@ pub struct FnBodyInExtern { #[derive(Diagnostic)] #[diag(ast_passes_extern_fn_qualifiers)] -pub struct FnQualifierInExtern { +pub(crate) struct FnQualifierInExtern { #[primary_span] #[suggestion(code = "", applicability = "maybe-incorrect")] pub span: Span, @@ -300,7 +300,7 @@ pub struct FnQualifierInExtern { #[derive(Diagnostic)] #[diag(ast_passes_extern_item_ascii)] #[note] -pub struct ExternItemAscii { +pub(crate) struct ExternItemAscii { #[primary_span] pub span: Span, #[label] @@ -309,14 +309,14 @@ pub struct ExternItemAscii { #[derive(Diagnostic)] #[diag(ast_passes_bad_c_variadic)] -pub struct BadCVariadic { +pub(crate) struct BadCVariadic { #[primary_span] pub span: Vec, } #[derive(Diagnostic)] #[diag(ast_passes_item_underscore)] -pub struct ItemUnderscore<'a> { +pub(crate) struct ItemUnderscore<'a> { #[primary_span] #[label] pub span: Span, @@ -325,7 +325,7 @@ pub struct ItemUnderscore<'a> { #[derive(Diagnostic)] #[diag(ast_passes_nomangle_ascii, code = E0754)] -pub struct NoMangleAscii { +pub(crate) struct NoMangleAscii { #[primary_span] pub span: Span, } @@ -333,7 +333,7 @@ pub struct NoMangleAscii { #[derive(Diagnostic)] #[diag(ast_passes_module_nonascii, code = E0754)] #[help] -pub struct ModuleNonAscii { +pub(crate) struct ModuleNonAscii { #[primary_span] pub span: Span, pub name: Symbol, @@ -341,7 +341,7 @@ pub struct ModuleNonAscii { #[derive(Diagnostic)] #[diag(ast_passes_auto_generic, code = E0567)] -pub struct AutoTraitGeneric { +pub(crate) struct AutoTraitGeneric { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub span: Span, @@ -351,7 +351,7 @@ pub struct AutoTraitGeneric { #[derive(Diagnostic)] #[diag(ast_passes_auto_super_lifetime, code = E0568)] -pub struct AutoTraitBounds { +pub(crate) struct AutoTraitBounds { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub span: Span, @@ -361,7 +361,7 @@ pub struct AutoTraitBounds { #[derive(Diagnostic)] #[diag(ast_passes_auto_items, code = E0380)] -pub struct AutoTraitItems { +pub(crate) struct AutoTraitItems { #[primary_span] pub spans: Vec, #[suggestion(code = "", applicability = "machine-applicable")] @@ -372,7 +372,7 @@ pub struct AutoTraitItems { #[derive(Diagnostic)] #[diag(ast_passes_generic_before_constraints)] -pub struct ArgsBeforeConstraint { +pub(crate) struct ArgsBeforeConstraint { #[primary_span] pub arg_spans: Vec, #[label(ast_passes_constraints)] @@ -390,7 +390,7 @@ pub struct ArgsBeforeConstraint { pub arg_spans2: EmptyLabelManySpans, } -pub struct EmptyLabelManySpans(pub Vec); +pub(crate) struct EmptyLabelManySpans(pub Vec); // The derive for `Vec` does multiple calls to `span_label`, adding commas between each impl Subdiagnostic for EmptyLabelManySpans { @@ -405,28 +405,28 @@ impl Subdiagnostic for EmptyLabelManySpans { #[derive(Diagnostic)] #[diag(ast_passes_pattern_in_fn_pointer, code = E0561)] -pub struct PatternFnPointer { +pub(crate) struct PatternFnPointer { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_trait_object_single_bound, code = E0226)] -pub struct TraitObjectBound { +pub(crate) struct TraitObjectBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_impl_trait_path, code = E0667)] -pub struct ImplTraitPath { +pub(crate) struct ImplTraitPath { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_nested_impl_trait, code = E0666)] -pub struct NestedImplTrait { +pub(crate) struct NestedImplTrait { #[primary_span] pub span: Span, #[label(ast_passes_outer)] @@ -437,14 +437,14 @@ pub struct NestedImplTrait { #[derive(Diagnostic)] #[diag(ast_passes_at_least_one_trait)] -pub struct AtLeastOneTrait { +pub(crate) struct AtLeastOneTrait { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_out_of_order_params)] -pub struct OutOfOrderParams<'a> { +pub(crate) struct OutOfOrderParams<'a> { #[primary_span] pub spans: Vec, #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")] @@ -457,14 +457,14 @@ pub struct OutOfOrderParams<'a> { #[derive(Diagnostic)] #[diag(ast_passes_obsolete_auto)] #[help] -pub struct ObsoleteAuto { +pub(crate) struct ObsoleteAuto { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_unsafe_negative_impl, code = E0198)] -pub struct UnsafeNegativeImpl { +pub(crate) struct UnsafeNegativeImpl { #[primary_span] pub span: Span, #[label(ast_passes_negative)] @@ -475,7 +475,7 @@ pub struct UnsafeNegativeImpl { #[derive(Diagnostic)] #[diag(ast_passes_inherent_cannot_be)] -pub struct InherentImplCannot<'a> { +pub(crate) struct InherentImplCannot<'a> { #[primary_span] pub span: Span, #[label(ast_passes_because)] @@ -489,7 +489,7 @@ pub struct InherentImplCannot<'a> { #[derive(Diagnostic)] #[diag(ast_passes_inherent_cannot_be, code = E0197)] -pub struct InherentImplCannotUnsafe<'a> { +pub(crate) struct InherentImplCannotUnsafe<'a> { #[primary_span] pub span: Span, #[label(ast_passes_because)] @@ -501,7 +501,7 @@ pub struct InherentImplCannotUnsafe<'a> { #[derive(Diagnostic)] #[diag(ast_passes_unsafe_item)] -pub struct UnsafeItem { +pub(crate) struct UnsafeItem { #[primary_span] pub span: Span, pub kind: &'static str, @@ -509,14 +509,14 @@ pub struct UnsafeItem { #[derive(Diagnostic)] #[diag(ast_passes_missing_unsafe_on_extern)] -pub struct MissingUnsafeOnExtern { +pub(crate) struct MissingUnsafeOnExtern { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_fieldless_union)] -pub struct FieldlessUnion { +pub(crate) struct FieldlessUnion { #[primary_span] pub span: Span, } @@ -524,7 +524,7 @@ pub struct FieldlessUnion { #[derive(Diagnostic)] #[diag(ast_passes_where_clause_after_type_alias)] #[note] -pub struct WhereClauseAfterTypeAlias { +pub(crate) struct WhereClauseAfterTypeAlias { #[primary_span] pub span: Span, #[help] @@ -534,7 +534,7 @@ pub struct WhereClauseAfterTypeAlias { #[derive(Diagnostic)] #[diag(ast_passes_where_clause_before_type_alias)] #[note] -pub struct WhereClauseBeforeTypeAlias { +pub(crate) struct WhereClauseBeforeTypeAlias { #[primary_span] pub span: Span, #[subdiagnostic] @@ -543,7 +543,7 @@ pub struct WhereClauseBeforeTypeAlias { #[derive(Subdiagnostic)] -pub enum WhereClauseBeforeTypeAliasSugg { +pub(crate) enum WhereClauseBeforeTypeAliasSugg { #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")] Remove { #[primary_span] @@ -565,14 +565,14 @@ pub enum WhereClauseBeforeTypeAliasSugg { #[derive(Diagnostic)] #[diag(ast_passes_generic_default_trailing)] -pub struct GenericDefaultTrailing { +pub(crate) struct GenericDefaultTrailing { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_nested_lifetimes, code = E0316)] -pub struct NestedLifetimes { +pub(crate) struct NestedLifetimes { #[primary_span] pub span: Span, } @@ -580,7 +580,7 @@ pub struct NestedLifetimes { #[derive(Diagnostic)] #[diag(ast_passes_optional_trait_supertrait)] #[note] -pub struct OptionalTraitSupertrait { +pub(crate) struct OptionalTraitSupertrait { #[primary_span] pub span: Span, pub path_str: String, @@ -588,14 +588,14 @@ pub struct OptionalTraitSupertrait { #[derive(Diagnostic)] #[diag(ast_passes_optional_trait_object)] -pub struct OptionalTraitObject { +pub(crate) struct OptionalTraitObject { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_const_bound_trait_object)] -pub struct ConstBoundTraitObject { +pub(crate) struct ConstBoundTraitObject { #[primary_span] pub span: Span, } @@ -604,7 +604,7 @@ pub struct ConstBoundTraitObject { // FIXME(effects): Provide structured suggestions (e.g., add `const` / `#[const_trait]` here). #[derive(Diagnostic)] #[diag(ast_passes_tilde_const_disallowed)] -pub struct TildeConstDisallowed { +pub(crate) struct TildeConstDisallowed { #[primary_span] pub span: Span, #[subdiagnostic] @@ -612,7 +612,7 @@ pub struct TildeConstDisallowed { } #[derive(Subdiagnostic, Copy, Clone)] -pub enum TildeConstReason { +pub(crate) enum TildeConstReason { #[note(ast_passes_closure)] Closure, #[note(ast_passes_function)] @@ -658,7 +658,7 @@ pub enum TildeConstReason { #[derive(Diagnostic)] #[diag(ast_passes_const_and_async)] -pub struct ConstAndAsync { +pub(crate) struct ConstAndAsync { #[primary_span] pub spans: Vec, #[label(ast_passes_const)] @@ -671,7 +671,7 @@ pub struct ConstAndAsync { #[derive(Diagnostic)] #[diag(ast_passes_const_and_c_variadic)] -pub struct ConstAndCVariadic { +pub(crate) struct ConstAndCVariadic { #[primary_span] pub spans: Vec, #[label(ast_passes_const)] @@ -683,7 +683,7 @@ pub struct ConstAndCVariadic { #[derive(Diagnostic)] #[diag(ast_passes_pattern_in_foreign, code = E0130)] // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) -pub struct PatternInForeign { +pub(crate) struct PatternInForeign { #[primary_span] #[label] pub span: Span, @@ -692,7 +692,7 @@ pub struct PatternInForeign { #[derive(Diagnostic)] #[diag(ast_passes_pattern_in_bodiless, code = E0642)] // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) -pub struct PatternInBodiless { +pub(crate) struct PatternInBodiless { #[primary_span] #[label] pub span: Span, @@ -701,7 +701,7 @@ pub struct PatternInBodiless { #[derive(Diagnostic)] #[diag(ast_passes_equality_in_where)] #[note] -pub struct EqualityInWhere { +pub(crate) struct EqualityInWhere { #[primary_span] #[label] pub span: Span, @@ -718,7 +718,7 @@ pub struct EqualityInWhere { style = "verbose", applicability = "maybe-incorrect" )] -pub struct AssociatedSuggestion { +pub(crate) struct AssociatedSuggestion { #[primary_span] pub span: Span, pub ident: Ident, @@ -728,7 +728,7 @@ pub struct AssociatedSuggestion { #[derive(Subdiagnostic)] #[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")] -pub struct AssociatedSuggestion2 { +pub(crate) struct AssociatedSuggestion2 { #[suggestion_part(code = "{args}")] pub span: Span, pub args: String, @@ -740,14 +740,14 @@ pub struct AssociatedSuggestion2 { #[derive(Diagnostic)] #[diag(ast_passes_stability_outside_std, code = E0734)] -pub struct StabilityOutsideStd { +pub(crate) struct StabilityOutsideStd { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_feature_on_non_nightly, code = E0554)] -pub struct FeatureOnNonNightly { +pub(crate) struct FeatureOnNonNightly { #[primary_span] pub span: Span, pub channel: &'static str, @@ -757,7 +757,7 @@ pub struct FeatureOnNonNightly { pub sugg: Option, } -pub struct StableFeature { +pub(crate) struct StableFeature { pub name: Symbol, pub since: Symbol, } @@ -777,7 +777,7 @@ impl Subdiagnostic for StableFeature { #[derive(Diagnostic)] #[diag(ast_passes_incompatible_features)] #[help] -pub struct IncompatibleFeatures { +pub(crate) struct IncompatibleFeatures { #[primary_span] pub spans: Vec, pub f1: Symbol, @@ -786,7 +786,7 @@ pub struct IncompatibleFeatures { #[derive(Diagnostic)] #[diag(ast_passes_show_span)] -pub struct ShowSpan { +pub(crate) struct ShowSpan { #[primary_span] pub span: Span, pub msg: &'static str, @@ -794,28 +794,28 @@ pub struct ShowSpan { #[derive(Diagnostic)] #[diag(ast_passes_negative_bound_not_supported)] -pub struct NegativeBoundUnsupported { +pub(crate) struct NegativeBoundUnsupported { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_constraint_on_negative_bound)] -pub struct ConstraintOnNegativeBound { +pub(crate) struct ConstraintOnNegativeBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_negative_bound_with_parenthetical_notation)] -pub struct NegativeBoundWithParentheticalNotation { +pub(crate) struct NegativeBoundWithParentheticalNotation { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(ast_passes_invalid_unnamed_field_ty)] -pub struct InvalidUnnamedFieldTy { +pub(crate) struct InvalidUnnamedFieldTy { #[primary_span] pub span: Span, #[label] @@ -824,7 +824,7 @@ pub struct InvalidUnnamedFieldTy { #[derive(Diagnostic)] #[diag(ast_passes_invalid_unnamed_field)] -pub struct InvalidUnnamedField { +pub(crate) struct InvalidUnnamedField { #[primary_span] pub span: Span, #[label] @@ -833,7 +833,7 @@ pub struct InvalidUnnamedField { #[derive(Diagnostic)] #[diag(ast_passes_anon_struct_or_union_not_allowed)] -pub struct AnonStructOrUnionNotAllowed { +pub(crate) struct AnonStructOrUnionNotAllowed { #[primary_span] #[label] pub span: Span, @@ -842,7 +842,7 @@ pub struct AnonStructOrUnionNotAllowed { #[derive(Diagnostic)] #[diag(ast_passes_match_arm_with_no_body)] -pub struct MatchArmWithNoBody { +pub(crate) struct MatchArmWithNoBody { #[primary_span] pub span: Span, #[suggestion(code = " => todo!(),", applicability = "has-placeholders")] @@ -851,7 +851,7 @@ pub struct MatchArmWithNoBody { #[derive(Diagnostic)] #[diag(ast_passes_precise_capturing_not_allowed_here)] -pub struct PreciseCapturingNotAllowedHere { +pub(crate) struct PreciseCapturingNotAllowedHere { #[primary_span] pub span: Span, pub loc: &'static str, @@ -859,7 +859,7 @@ pub struct PreciseCapturingNotAllowedHere { #[derive(Diagnostic)] #[diag(ast_passes_precise_capturing_duplicated)] -pub struct DuplicatePreciseCapturing { +pub(crate) struct DuplicatePreciseCapturing { #[primary_span] pub bound1: Span, #[label] diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 1f4bcd59afa01..88c6bde3106d5 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -12,6 +12,7 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod ast_validation; From f2fc87db44413bc4706980481c057e30cac2efd9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 21:27:29 +1000 Subject: [PATCH 014/102] Add `warn(unreachable_pub)` to `rustc_ast_pretty`. --- compiler/rustc_ast_pretty/src/lib.rs | 1 + .../rustc_ast_pretty/src/pp/convenience.rs | 2 +- compiler/rustc_ast_pretty/src/pp/ring.rs | 22 +++++++++---------- .../src/pprust/state/fixup.rs | 14 ++++++------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 84d9ce278a21a..602ab69ee5b5d 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,6 +3,7 @@ #![doc(rust_logo)] #![feature(box_patterns)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod helpers; diff --git a/compiler/rustc_ast_pretty/src/pp/convenience.rs b/compiler/rustc_ast_pretty/src/pp/convenience.rs index 6d46c26311be3..7559b181f7d41 100644 --- a/compiler/rustc_ast_pretty/src/pp/convenience.rs +++ b/compiler/rustc_ast_pretty/src/pp/convenience.rs @@ -89,7 +89,7 @@ impl Printer { } impl Token { - pub fn is_hardbreak_tok(&self) -> bool { + pub(crate) fn is_hardbreak_tok(&self) -> bool { *self == Printer::hardbreak_tok_offset(0) } } diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs index 8187394fe30e0..003c0a999b50a 100644 --- a/compiler/rustc_ast_pretty/src/pp/ring.rs +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -11,54 +11,54 @@ use std::ops::{Index, IndexMut}; /// Holding a RingBuffer whose view is elements left..right gives the ability to /// use Index and IndexMut to access elements i in the infinitely long queue for /// which left <= i < right. -pub struct RingBuffer { +pub(super) struct RingBuffer { data: VecDeque, // Abstract index of data[0] in the infinitely sized queue. offset: usize, } impl RingBuffer { - pub fn new() -> Self { + pub(super) fn new() -> Self { RingBuffer { data: VecDeque::new(), offset: 0 } } - pub fn is_empty(&self) -> bool { + pub(super) fn is_empty(&self) -> bool { self.data.is_empty() } - pub fn push(&mut self, value: T) -> usize { + pub(super) fn push(&mut self, value: T) -> usize { let index = self.offset + self.data.len(); self.data.push_back(value); index } - pub fn clear(&mut self) { + pub(super) fn clear(&mut self) { self.data.clear(); } - pub fn index_of_first(&self) -> usize { + pub(super) fn index_of_first(&self) -> usize { self.offset } - pub fn first(&self) -> Option<&T> { + pub(super) fn first(&self) -> Option<&T> { self.data.front() } - pub fn first_mut(&mut self) -> Option<&mut T> { + pub(super) fn first_mut(&mut self) -> Option<&mut T> { self.data.front_mut() } - pub fn pop_first(&mut self) -> Option { + pub(super) fn pop_first(&mut self) -> Option { let first = self.data.pop_front()?; self.offset += 1; Some(first) } - pub fn last(&self) -> Option<&T> { + pub(super) fn last(&self) -> Option<&T> { self.data.back() } - pub fn last_mut(&mut self) -> Option<&mut T> { + pub(super) fn last_mut(&mut self) -> Option<&mut T> { self.data.back_mut() } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index 86d4796e9ce3b..c9baca72485ef 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -110,13 +110,13 @@ impl Default for FixupContext { impl FixupContext { /// Create the initial fixup for printing an expression in statement /// position. - pub fn new_stmt() -> Self { + pub(crate) fn new_stmt() -> Self { FixupContext { stmt: true, ..FixupContext::default() } } /// Create the initial fixup for printing an expression as the right-hand /// side of a match arm. - pub fn new_match_arm() -> Self { + pub(crate) fn new_match_arm() -> Self { FixupContext { match_arm: true, ..FixupContext::default() } } @@ -124,7 +124,7 @@ impl FixupContext { /// of an `if` or `while`. There are a few other positions which are /// grammatically equivalent and also use this, such as the iterator /// expression in `for` and the scrutinee in `match`. - pub fn new_cond() -> Self { + pub(crate) fn new_cond() -> Self { FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() } } @@ -139,7 +139,7 @@ impl FixupContext { /// /// Not every expression has a leftmost subexpression. For example neither /// `-$a` nor `[$a]` have one. - pub fn leftmost_subexpression(self) -> Self { + pub(crate) fn leftmost_subexpression(self) -> Self { FixupContext { stmt: false, leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt, @@ -158,7 +158,7 @@ impl FixupContext { /// current expression, and is not surrounded by a paren/bracket/brace. For /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or /// `$a.f($b)`. - pub fn subsequent_subexpression(self) -> Self { + pub(crate) fn subsequent_subexpression(self) -> Self { FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, @@ -173,7 +173,7 @@ impl FixupContext { /// /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. - pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { + pub(crate) fn would_cause_statement_boundary(self, expr: &Expr) -> bool { (self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr)) || (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr)) } @@ -189,7 +189,7 @@ impl FixupContext { /// /// - `true && false`, because otherwise this would be misinterpreted as a /// "let chain". - pub fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool { + pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool { self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr) || parser::needs_par_as_let_scrutinee(expr.precedence().order()) } From 6614165eac9532a843f691fe1b7e3c37fa637ebf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 21:31:11 +1000 Subject: [PATCH 015/102] Add `warn(unreachable_pub)` to `rustc_attr`. --- compiler/rustc_attr/src/lib.rs | 1 + compiler/rustc_attr/src/session_diagnostics.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 1ecfc42ec1df4..0dad637238982 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -9,6 +9,7 @@ #![doc(rust_logo)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod builtin; diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 92a3a385a7441..a1a10d2d36422 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -127,7 +127,7 @@ pub(crate) enum InvalidIssueStringCause { } impl InvalidIssueStringCause { - pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option { + pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option { match kind { IntErrorKind::Empty => Some(Self::Empty { span }), IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }), @@ -303,7 +303,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { } impl<'a> IncorrectReprFormatGenericCause<'a> { - pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { + pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { match kind { ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { Some(Self::Int { span, name, int: int.get() }) From cb3f43569933111c99222e1d8d87d529117f0bd6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 21:35:12 +1000 Subject: [PATCH 016/102] Don't add `warn(unreachable_pub)` to `rustc_baked_icu`. But explain why. --- compiler/rustc_baked_icu_data/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index e964a709757cf..f86a9db61c600 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -25,6 +25,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] +// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code // tidy-alphabetical-end mod data { From 0685c978434b21c18ae2575cbbd72b6234b7701e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 21:53:49 +1000 Subject: [PATCH 017/102] Add `warn(unreachable_pub)` to `rustc_borrowck`. --- .../rustc_borrowck/src/borrowck_errors.rs | 2 +- compiler/rustc_borrowck/src/dataflow.rs | 4 +- compiler/rustc_borrowck/src/def_use.rs | 4 +- .../src/diagnostics/conflict_errors.rs | 8 ++-- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/diagnostics/outlives_suggestion.rs | 2 +- .../src/diagnostics/region_errors.rs | 14 ++++--- compiler/rustc_borrowck/src/lib.rs | 26 +++++++----- compiler/rustc_borrowck/src/prefixes.rs | 2 +- .../rustc_borrowck/src/region_infer/mod.rs | 12 +++--- .../src/region_infer/opaque_types.rs | 8 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- .../src/type_check/relate_tys.rs | 4 +- .../rustc_borrowck/src/universal_regions.rs | 42 +++++++++---------- .../rustc_borrowck/src/util/collect_writes.rs | 2 +- compiler/rustc_borrowck/src/util/mod.rs | 2 +- 18 files changed, 74 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 76e39fe94af43..86f46b55bfb44 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'infcx> { + pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> { self.infcx.dcx() } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 77794a8525f8d..2795bc7162fc8 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -14,7 +14,7 @@ use rustc_mir_dataflow::{Analysis, AnalysisDomain, GenKill, Results, ResultsVisi use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; /// The results of the dataflow analyses used by the borrow checker. -pub struct BorrowckResults<'a, 'mir, 'tcx> { +pub(crate) struct BorrowckResults<'a, 'mir, 'tcx> { pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>, pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>, @@ -22,7 +22,7 @@ pub struct BorrowckResults<'a, 'mir, 'tcx> { /// The transient state of the dataflow analyses used by the borrow checker. #[derive(Debug)] -pub struct BorrowckFlowState<'a, 'mir, 'tcx> { +pub(crate) struct BorrowckFlowState<'a, 'mir, 'tcx> { pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 1f0b0981c8f29..7eb9e689afe82 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -4,13 +4,13 @@ use rustc_middle::mir::visit::{ }; #[derive(Eq, PartialEq, Clone)] -pub enum DefUse { +pub(crate) enum DefUse { Def, Use, Drop, } -pub fn categorize(context: PlaceContext) -> Option { +pub(crate) fn categorize(context: PlaceContext) -> Option { match context { /////////////////////////////////////////////////////////////////////////// // DEFS diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2b46e5597f778..cd35427b914c2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -645,7 +645,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { } } - pub fn suggest_reborrow( + pub(crate) fn suggest_reborrow( &self, err: &mut Diag<'infcx>, span: Span, @@ -1891,10 +1891,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { struct FindUselessClone<'tcx> { tcx: TyCtxt<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, - pub clones: Vec<&'tcx hir::Expr<'tcx>>, + clones: Vec<&'tcx hir::Expr<'tcx>>, } impl<'tcx> FindUselessClone<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] } } } @@ -1916,7 +1916,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { let body = hir.body(body_id).value; expr_finder.visit_expr(body); - pub struct Holds<'tcx> { + struct Holds<'tcx> { ty: Ty<'tcx>, } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a2e5c7b85145a..33f91d7ad3043 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -58,11 +58,11 @@ pub(crate) use region_name::{RegionName, RegionNameSource}; pub(crate) use rustc_middle::util::CallKind; pub(super) struct DescribePlaceOpt { - pub including_downcast: bool, + including_downcast: bool, /// Enable/Disable tuple fields. /// For example `x` tuple. if it's `true` `x.0`. Otherwise `x` - pub including_tuple_field: bool, + including_tuple_field: bool, } pub(super) struct IncludingTupleField(pub(super) bool); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 792f1548e081e..42b1ffd58ad3e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -16,7 +16,7 @@ use crate::prefixes::PrefixSet; use crate::MirBorrowckCtxt; #[derive(Debug)] -pub enum IllegalMoveOriginKind<'tcx> { +pub(crate) enum IllegalMoveOriginKind<'tcx> { /// Illegal move due to attempt to move from behind a reference. BorrowedContent { /// The place the reference refers to: if erroneous code was trying to diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 0303b80cace45..7b791928689c9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1374,7 +1374,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder { } } -pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option) -> bool { +fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option) -> bool { debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind()); match *local_decl.local_info() { diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index de0df3474299a..a59b7b3cde914 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -31,7 +31,7 @@ enum SuggestedConstraint { /// /// Adds a help note suggesting adding a where clause with the needed constraints. #[derive(Default)] -pub struct OutlivesSuggestionBuilder { +pub(crate) struct OutlivesSuggestionBuilder { /// The list of outlives constraints that need to be added. Specifically, we map each free /// region to all other regions that it must outlive. I will use the shorthand `fr: /// outlived_frs`. Not all of these regions will already have names necessarily. Some could be diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 451e8bcb16da4..ab48a09cfa4ce 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -72,22 +72,24 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>); impl<'tcx> RegionErrors<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>) -> Self { + pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self { Self(vec![], tcx) } #[track_caller] - pub fn push(&mut self, val: impl Into>) { + pub(crate) fn push(&mut self, val: impl Into>) { let val = val.into(); let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}")); self.0.push((val, guar)); } - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.0.is_empty() } - pub fn into_iter(self) -> impl Iterator, ErrorGuaranteed)> { + pub(crate) fn into_iter( + self, + ) -> impl Iterator, ErrorGuaranteed)> { self.0.into_iter() } - pub fn has_errors(&self) -> Option { + pub(crate) fn has_errors(&self) -> Option { self.0.get(0).map(|x| x.1) } } @@ -141,7 +143,7 @@ pub(crate) enum RegionErrorKind<'tcx> { /// Information about the various region constraints involved in a borrow checker error. #[derive(Clone, Debug)] -pub struct ErrorConstraintInfo<'tcx> { +pub(crate) struct ErrorConstraintInfo<'tcx> { // fr: outlived_fr pub(super) fr: RegionVid, pub(super) fr_is_local: bool, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 30dd45d847c9b..5d54204bf800a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -12,6 +12,7 @@ #![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] @@ -2444,7 +2445,7 @@ mod diags { } } - pub struct BorrowckDiags<'infcx, 'tcx> { + pub(crate) struct BorrowckDiags<'infcx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -2468,7 +2469,7 @@ mod diags { } impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { - pub fn new() -> Self { + pub(crate) fn new() -> Self { BorrowckDiags { buffered_move_errors: BTreeMap::new(), buffered_mut_errors: Default::default(), @@ -2476,25 +2477,25 @@ mod diags { } } - pub fn buffer_error(&mut self, diag: Diag<'infcx>) { + pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } } impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { - pub fn buffer_error(&mut self, diag: Diag<'infcx>) { + pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { self.diags.buffer_error(diag); } - pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.diags.buffer_non_error(diag); } - pub fn buffer_move_error( + pub(crate) fn buffer_move_error( &mut self, move_out_indices: Vec, place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), @@ -2510,16 +2511,19 @@ mod diags { } } - pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { + pub(crate) fn get_buffered_mut_error( + &mut self, + span: Span, + ) -> Option<(Diag<'infcx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags.buffered_mut_errors.swap_remove(&span) } - pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { + pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { self.diags.buffered_mut_errors.insert(span, (diag, count)); } - pub fn emit_errors(&mut self) -> Option { + pub(crate) fn emit_errors(&mut self) -> Option { let mut res = None; // Buffer any move errors that we collected and de-duplicated. @@ -2553,7 +2557,7 @@ mod diags { self.diags.buffered_diags.is_empty() } - pub fn has_move_error( + pub(crate) fn has_move_error( &self, move_out_indices: &[MoveOutIndex], ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index d3bfd1c418fe4..39d831378cde6 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::{PlaceRef, ProjectionElem}; use super::MirBorrowckCtxt; -pub trait IsPrefixOf<'tcx> { +pub(crate) trait IsPrefixOf<'tcx> { fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool; } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index c8dc012de4a29..6cbdd890b5e8b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -42,9 +42,9 @@ mod graphviz; mod opaque_types; mod reverse_sccs; -pub mod values; +pub(crate) mod values; -pub type ConstraintSccs = Sccs; +pub(crate) type ConstraintSccs = Sccs; /// An annotation for region graph SCCs that tracks /// the values of its elements. @@ -226,7 +226,7 @@ pub(crate) struct AppliedMemberConstraint { } #[derive(Debug)] -pub struct RegionDefinition<'tcx> { +pub(crate) struct RegionDefinition<'tcx> { /// What kind of variable is this -- a free region? existential /// variable? etc. (See the `NllRegionVariableOrigin` for more /// info.) @@ -288,7 +288,7 @@ pub(crate) enum Cause { /// `InferCtxt::process_registered_region_obligations` and /// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`. #[derive(Clone, Debug)] -pub struct TypeTest<'tcx> { +pub(crate) struct TypeTest<'tcx> { /// The type `T` that must outlive the region. pub generic_kind: GenericKind<'tcx>, @@ -320,7 +320,7 @@ enum Trace<'tcx> { } #[derive(Clone, PartialEq, Eq, Debug)] -pub enum ExtraConstraintInfo { +pub(crate) enum ExtraConstraintInfo { PlaceholderFromPredicate(Span), } @@ -2259,7 +2259,7 @@ impl<'tcx> RegionDefinition<'tcx> { } #[derive(Clone, Debug)] -pub struct BlameConstraint<'tcx> { +pub(crate) struct BlameConstraint<'tcx> { pub category: ConstraintCategory<'tcx>, pub from_closure: bool, pub cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 1073ea4069483..cd66acd0a8f21 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -473,20 +473,20 @@ struct LazyOpaqueTyEnv<'tcx> { } impl<'tcx> LazyOpaqueTyEnv<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() } } - pub fn param_equal_static(&self, param_index: usize) -> bool { + fn param_equal_static(&self, param_index: usize) -> bool { self.get_canonical_args()[param_index].expect_region().is_static() } - pub fn params_equal(&self, param1: usize, param2: usize) -> bool { + fn params_equal(&self, param1: usize, param2: usize) -> bool { let canonical_args = self.get_canonical_args(); canonical_args[param1] == canonical_args[param2] } - pub fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { + fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { self.get_canonical_args()[param_index].error_reported() } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a2669da1b04e8..bbcc2bbdc1086 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -86,7 +86,7 @@ macro_rules! span_mirbug_and_err { mod canonical; mod constraint_conversion; -pub mod free_region_relations; +pub(crate) mod free_region_relations; mod input_output; pub(crate) mod liveness; mod relate_tys; diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 8da4d80badfec..35d8e2573fe17 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -57,7 +57,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } -pub struct NllTypeRelating<'me, 'bccx, 'tcx> { +struct NllTypeRelating<'me, 'bccx, 'tcx> { type_checker: &'me mut TypeChecker<'bccx, 'tcx>, /// Where (and why) is this relation taking place? @@ -82,7 +82,7 @@ pub struct NllTypeRelating<'me, 'bccx, 'tcx> { } impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { - pub fn new( + fn new( type_checker: &'me mut TypeChecker<'bccx, 'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 1ad80cb122ab6..2e41c91877431 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -39,7 +39,7 @@ use crate::renumber::RegionCtxt; use crate::BorrowckInferCtxt; #[derive(Debug)] -pub struct UniversalRegions<'tcx> { +pub(crate) struct UniversalRegions<'tcx> { indices: UniversalRegionIndices<'tcx>, /// The vid assigned to `'static` @@ -95,7 +95,7 @@ pub struct UniversalRegions<'tcx> { /// regions appear free in the defining type and late-bound regions /// appear bound in the signature. #[derive(Copy, Clone, Debug)] -pub enum DefiningTy<'tcx> { +pub(crate) enum DefiningTy<'tcx> { /// The MIR is a closure. The signature is found via /// `ClosureArgs::closure_sig_ty`. Closure(DefId, GenericArgsRef<'tcx>), @@ -131,7 +131,7 @@ impl<'tcx> DefiningTy<'tcx> { /// not a closure or coroutine, there are no upvars, and hence it /// will be an empty list. The order of types in this list will /// match up with the upvar order in the HIR, typesystem, and MIR. - pub fn upvar_tys(self) -> &'tcx ty::List> { + pub(crate) fn upvar_tys(self) -> &'tcx ty::List> { match self { DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(), DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(), @@ -145,7 +145,7 @@ impl<'tcx> DefiningTy<'tcx> { /// Number of implicit inputs -- notably the "environment" /// parameter for closures -- that appear in MIR but not in the /// user's code. - pub fn implicit_inputs(self) -> usize { + pub(crate) fn implicit_inputs(self) -> usize { match self { DefiningTy::Closure(..) | DefiningTy::CoroutineClosure(..) @@ -154,15 +154,15 @@ impl<'tcx> DefiningTy<'tcx> { } } - pub fn is_fn_def(&self) -> bool { + pub(crate) fn is_fn_def(&self) -> bool { matches!(*self, DefiningTy::FnDef(..)) } - pub fn is_const(&self) -> bool { + pub(crate) fn is_const(&self) -> bool { matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..)) } - pub fn def_id(&self) -> DefId { + pub(crate) fn def_id(&self) -> DefId { match *self { DefiningTy::Closure(def_id, ..) | DefiningTy::CoroutineClosure(def_id, ..) @@ -196,7 +196,7 @@ struct UniversalRegionIndices<'tcx> { } #[derive(Debug, PartialEq)] -pub enum RegionClassification { +pub(crate) enum RegionClassification { /// A **global** region is one that can be named from /// anywhere. There is only one, `'static`. Global, @@ -246,7 +246,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// MIR -- that is, all the regions that appear in the function's /// signature. This will also compute the relationships that are /// known between those regions. - pub fn new( + pub(crate) fn new( infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, @@ -263,7 +263,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// if the `ClosureRegionRequirements` contains something like /// `'1: '2`, then the caller would impose the constraint that /// `V[1]: V[2]`. - pub fn closure_mapping( + pub(crate) fn closure_mapping( tcx: TyCtxt<'tcx>, closure_args: GenericArgsRef<'tcx>, expected_num_vars: usize, @@ -289,13 +289,13 @@ impl<'tcx> UniversalRegions<'tcx> { } /// Returns `true` if `r` is a member of this set of universal regions. - pub fn is_universal_region(&self, r: RegionVid) -> bool { + pub(crate) fn is_universal_region(&self, r: RegionVid) -> bool { (FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index()) } /// Classifies `r` as a universal region, returning `None` if this /// is not a member of this set of universal regions. - pub fn region_classification(&self, r: RegionVid) -> Option { + pub(crate) fn region_classification(&self, r: RegionVid) -> Option { let index = r.index(); if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) { Some(RegionClassification::Global) @@ -310,17 +310,17 @@ impl<'tcx> UniversalRegions<'tcx> { /// Returns an iterator over all the RegionVids corresponding to /// universally quantified free regions. - pub fn universal_regions(&self) -> impl Iterator { + pub(crate) fn universal_regions(&self) -> impl Iterator { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } /// Returns `true` if `r` is classified as a local region. - pub fn is_local_free_region(&self, r: RegionVid) -> bool { + pub(crate) fn is_local_free_region(&self, r: RegionVid) -> bool { self.region_classification(r) == Some(RegionClassification::Local) } /// Returns the number of universal regions created in any category. - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.num_universals } @@ -329,19 +329,19 @@ impl<'tcx> UniversalRegions<'tcx> { /// closure type (versus those bound in the closure /// signature). They are therefore the regions between which the /// closure may impose constraints that its creator must verify. - pub fn num_global_and_external_regions(&self) -> usize { + pub(crate) fn num_global_and_external_regions(&self) -> usize { self.first_local_index } /// Gets an iterator over all the early-bound regions that have names. - pub fn named_universal_regions<'s>( + pub(crate) fn named_universal_regions<'s>( &'s self, ) -> impl Iterator, ty::RegionVid)> + 's { self.indices.indices.iter().map(|(&r, &v)| (r, v)) } /// See `UniversalRegionIndices::to_region_vid`. - pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { + pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { self.indices.to_region_vid(r) } @@ -416,7 +416,7 @@ impl<'tcx> UniversalRegions<'tcx> { } } - pub fn tainted_by_errors(&self) -> Option { + pub(crate) fn tainted_by_errors(&self) -> Option { self.indices.tainted_by_errors.get() } } @@ -880,7 +880,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// reference those regions from the `ParamEnv`. It is also used /// during initialization. Relies on the `indices` map having been /// fully initialized. - pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { + fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.as_var() } else if let ty::ReError(guar) = *r { @@ -899,7 +899,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// Replaces all free regions in `value` with region vids, as /// returned by `to_region_vid`. - pub fn fold_to_region_vids(&self, tcx: TyCtxt<'tcx>, value: T) -> T + fn fold_to_region_vids(&self, tcx: TyCtxt<'tcx>, value: T) -> T where T: TypeFoldable>, { diff --git a/compiler/rustc_borrowck/src/util/collect_writes.rs b/compiler/rustc_borrowck/src/util/collect_writes.rs index 93c7810b54517..55f1073176aef 100644 --- a/compiler/rustc_borrowck/src/util/collect_writes.rs +++ b/compiler/rustc_borrowck/src/util/collect_writes.rs @@ -1,7 +1,7 @@ use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{Body, Local, Location}; -pub trait FindAssignments { +pub(crate) trait FindAssignments { // Finds all statements that assign directly to local (i.e., X = ...) // and returns their locations. fn find_assignments(&self, local: Local) -> Vec; diff --git a/compiler/rustc_borrowck/src/util/mod.rs b/compiler/rustc_borrowck/src/util/mod.rs index 7377d4de7274f..5f2960b768b29 100644 --- a/compiler/rustc_borrowck/src/util/mod.rs +++ b/compiler/rustc_borrowck/src/util/mod.rs @@ -1,3 +1,3 @@ mod collect_writes; -pub use collect_writes::FindAssignments; +pub(crate) use collect_writes::FindAssignments; From 0544d3a952056da8d4c69130cc52ca52e8f78bf3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 22:08:04 +1000 Subject: [PATCH 018/102] Add `warn(unreachable_pub)` to `rustc_builtin_macros`. --- .../src/deriving/generic/mod.rs | 10 +-- .../src/deriving/generic/ty.rs | 18 ++--- .../src/deriving/smart_ptr.rs | 2 +- compiler/rustc_builtin_macros/src/errors.rs | 2 +- .../src/format_foreign.rs | 68 +++++++++---------- compiler/rustc_builtin_macros/src/lib.rs | 1 + 6 files changed, 51 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index c90a916488606..289e92a69b2c0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -351,15 +351,15 @@ struct TypeParameter { pub(crate) struct BlockOrExpr(ThinVec, Option>); impl BlockOrExpr { - pub fn new_stmts(stmts: ThinVec) -> BlockOrExpr { + pub(crate) fn new_stmts(stmts: ThinVec) -> BlockOrExpr { BlockOrExpr(stmts, None) } - pub fn new_expr(expr: P) -> BlockOrExpr { + pub(crate) fn new_expr(expr: P) -> BlockOrExpr { BlockOrExpr(ThinVec::new(), Some(expr)) } - pub fn new_mixed(stmts: ThinVec, expr: Option>) -> BlockOrExpr { + pub(crate) fn new_mixed(stmts: ThinVec, expr: Option>) -> BlockOrExpr { BlockOrExpr(stmts, expr) } @@ -461,7 +461,7 @@ fn find_type_parameters( } impl<'a> TraitDef<'a> { - pub fn expand( + pub(crate) fn expand( self, cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, @@ -471,7 +471,7 @@ impl<'a> TraitDef<'a> { self.expand_ext(cx, mitem, item, push, false); } - pub fn expand_ext( + pub(crate) fn expand_ext( self, cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 747da2ee43bdf..42855e255a806 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -27,17 +27,17 @@ pub(crate) enum PathKind { } impl Path { - pub fn new(path: Vec) -> Path { + pub(crate) fn new(path: Vec) -> Path { Path::new_(path, Vec::new(), PathKind::Std) } - pub fn new_local(path: Symbol) -> Path { + pub(crate) fn new_local(path: Symbol) -> Path { Path::new_(vec![path], Vec::new(), PathKind::Local) } - pub fn new_(path: Vec, params: Vec>, kind: PathKind) -> Path { + pub(crate) fn new_(path: Vec, params: Vec>, kind: PathKind) -> Path { Path { path, params, kind } } - pub fn to_ty( + pub(crate) fn to_ty( &self, cx: &ExtCtxt<'_>, span: Span, @@ -46,7 +46,7 @@ impl Path { ) -> P { cx.ty_path(self.to_path(cx, span, self_ty, self_generics)) } - pub fn to_path( + pub(crate) fn to_path( &self, cx: &ExtCtxt<'_>, span: Span, @@ -87,7 +87,7 @@ pub(crate) fn self_ref() -> Ty { } impl Ty { - pub fn to_ty( + pub(crate) fn to_ty( &self, cx: &ExtCtxt<'_>, span: Span, @@ -108,7 +108,7 @@ impl Ty { } } - pub fn to_path( + pub(crate) fn to_path( &self, cx: &ExtCtxt<'_>, span: Span, @@ -167,10 +167,10 @@ pub(crate) struct Bounds { } impl Bounds { - pub fn empty() -> Bounds { + pub(crate) fn empty() -> Bounds { Bounds { bounds: Vec::new() } } - pub fn to_generics( + pub(crate) fn to_generics( &self, cx: &ExtCtxt<'_>, span: Span, diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index 7eb1f17a59ce3..c88c5bd35a526 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -18,7 +18,7 @@ macro_rules! path { ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] } } -pub fn expand_deriving_smart_ptr( +pub(crate) fn expand_deriving_smart_ptr( cx: &ExtCtxt<'_>, span: Span, _mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 6ca43441e0582..4fffffb91c8b4 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -930,7 +930,7 @@ pub(crate) struct ExpectedItem<'a> { #[derive(Diagnostic)] #[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)] -pub struct NakedFunctionTestingAttribute { +pub(crate) struct NakedFunctionTestingAttribute { #[primary_span] #[label(builtin_macros_naked_attribute)] pub naked_span: Span, diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index b52f606f342e2..866ec72f11646 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -5,7 +5,7 @@ pub(crate) mod printf { /// Represents a single `printf`-style substitution. #[derive(Clone, PartialEq, Debug)] - pub enum Substitution<'a> { + pub(crate) enum Substitution<'a> { /// A formatted output substitution with its internal byte offset. Format(Format<'a>), /// A literal `%%` escape, with its start and end indices. @@ -13,21 +13,21 @@ pub(crate) mod printf { } impl<'a> Substitution<'a> { - pub fn as_str(&self) -> &str { + pub(crate) fn as_str(&self) -> &str { match self { Substitution::Format(fmt) => fmt.span, Substitution::Escape(_) => "%%", } } - pub fn position(&self) -> InnerSpan { + pub(crate) fn position(&self) -> InnerSpan { match self { Substitution::Format(fmt) => fmt.position, &Substitution::Escape((start, end)) => InnerSpan::new(start, end), } } - pub fn set_position(&mut self, start: usize, end: usize) { + pub(crate) fn set_position(&mut self, start: usize, end: usize) { match self { Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end), Substitution::Escape(pos) => *pos = (start, end), @@ -38,7 +38,7 @@ pub(crate) mod printf { /// /// This ignores cases where the substitution does not have an exact equivalent, or where /// the substitution would be unnecessary. - pub fn translate(&self) -> Result> { + pub(crate) fn translate(&self) -> Result> { match self { Substitution::Format(fmt) => fmt.translate(), Substitution::Escape(_) => Err(None), @@ -48,23 +48,23 @@ pub(crate) mod printf { #[derive(Clone, PartialEq, Debug)] /// A single `printf`-style formatting directive. - pub struct Format<'a> { + pub(crate) struct Format<'a> { /// The entire original formatting directive. - pub span: &'a str, + span: &'a str, /// The (1-based) parameter to be converted. - pub parameter: Option, + parameter: Option, /// Formatting flags. - pub flags: &'a str, + flags: &'a str, /// Minimum width of the output. - pub width: Option, + width: Option, /// Precision of the conversion. - pub precision: Option, + precision: Option, /// Length modifier for the conversion. - pub length: Option<&'a str>, + length: Option<&'a str>, /// Type of parameter being converted. - pub type_: &'a str, + type_: &'a str, /// Byte offset for the start and end of this formatting directive. - pub position: InnerSpan, + position: InnerSpan, } impl Format<'_> { @@ -72,7 +72,7 @@ pub(crate) mod printf { /// /// Returns `Err` in cases where the `printf` directive does not have an exact Rust /// equivalent, rather than guessing. - pub fn translate(&self) -> Result> { + pub(crate) fn translate(&self) -> Result> { use std::fmt::Write; let (c_alt, c_zero, c_left, c_plus) = { @@ -249,7 +249,7 @@ pub(crate) mod printf { /// A general number used in a `printf` formatting directive. #[derive(Copy, Clone, PartialEq, Debug)] - pub enum Num { + enum Num { // The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU // libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it // is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or @@ -288,12 +288,12 @@ pub(crate) mod printf { } /// Returns an iterator over all substitutions in a given string. - pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> { + pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> { Substitutions { s, pos: start_pos } } /// Iterator over substitutions in a string. - pub struct Substitutions<'a> { + pub(crate) struct Substitutions<'a> { s: &'a str, pos: usize, } @@ -327,7 +327,7 @@ pub(crate) mod printf { } /// Parse the next substitution from the input string. - pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { + fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { use self::State::*; let at = { @@ -615,20 +615,20 @@ pub(crate) mod printf { mod tests; } -pub mod shell { +pub(crate) mod shell { use rustc_span::InnerSpan; use super::strcursor::StrCursor as Cur; #[derive(Clone, PartialEq, Debug)] - pub enum Substitution<'a> { + pub(crate) enum Substitution<'a> { Ordinal(u8, (usize, usize)), Name(&'a str, (usize, usize)), Escape((usize, usize)), } impl Substitution<'_> { - pub fn as_str(&self) -> String { + pub(crate) fn as_str(&self) -> String { match self { Substitution::Ordinal(n, _) => format!("${n}"), Substitution::Name(n, _) => format!("${n}"), @@ -636,17 +636,17 @@ pub mod shell { } } - pub fn position(&self) -> InnerSpan { + pub(crate) fn position(&self) -> InnerSpan { let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self; InnerSpan::new(pos.0, pos.1) } - pub fn set_position(&mut self, start: usize, end: usize) { + fn set_position(&mut self, start: usize, end: usize) { let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self; *pos = (start, end); } - pub fn translate(&self) -> Result> { + pub(crate) fn translate(&self) -> Result> { match self { Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)), Substitution::Name(n, _) => Ok(format!("{{{}}}", n)), @@ -656,12 +656,12 @@ pub mod shell { } /// Returns an iterator over all substitutions in a given string. - pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> { + pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> { Substitutions { s, pos: start_pos } } /// Iterator over substitutions in a string. - pub struct Substitutions<'a> { + pub(crate) struct Substitutions<'a> { s: &'a str, pos: usize, } @@ -683,7 +683,7 @@ pub mod shell { } /// Parse the next substitution from the input string. - pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { + fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> { let at = { let start = s.find('$')?; match s[start + 1..].chars().next()? { @@ -743,24 +743,24 @@ pub mod shell { } mod strcursor { - pub struct StrCursor<'a> { + pub(crate) struct StrCursor<'a> { s: &'a str, pub at: usize, } impl<'a> StrCursor<'a> { - pub fn new_at(s: &'a str, at: usize) -> StrCursor<'a> { + pub(crate) fn new_at(s: &'a str, at: usize) -> StrCursor<'a> { StrCursor { s, at } } - pub fn at_next_cp(mut self) -> Option> { + pub(crate) fn at_next_cp(mut self) -> Option> { match self.try_seek_right_cp() { true => Some(self), false => None, } } - pub fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> { + pub(crate) fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> { let cp = self.cp_after()?; self.seek_right(cp.len_utf8()); Some((cp, self)) @@ -770,11 +770,11 @@ mod strcursor { &self.s[0..self.at] } - pub fn slice_after(&self) -> &'a str { + pub(crate) fn slice_after(&self) -> &'a str { &self.s[self.at..] } - pub fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> { + pub(crate) fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> { if !str_eq_literal(self.s, until.s) { None } else { diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index a9ba7334d930e..30e1c8d262216 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -16,6 +16,7 @@ #![feature(proc_macro_quote)] #![feature(rustdoc_internals)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro; From 61627438ebb72977c8480a2d8b573137cfecefb1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 22:26:42 +1000 Subject: [PATCH 019/102] Add `warn(unreachable_pub)` to `rustc_codegen_llvm`. --- compiler/rustc_codegen_llvm/src/abi.rs | 14 ++--- compiler/rustc_codegen_llvm/src/attributes.rs | 20 +++---- .../rustc_codegen_llvm/src/back/archive.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 10 ++-- .../rustc_codegen_llvm/src/back/profiling.rs | 8 +-- compiler/rustc_codegen_llvm/src/back/write.rs | 20 +++---- compiler/rustc_codegen_llvm/src/base.rs | 15 +++-- compiler/rustc_codegen_llvm/src/builder.rs | 58 +++++++++++-------- compiler/rustc_codegen_llvm/src/callee.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 22 +++---- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 10 ++-- .../src/coverageinfo/ffi.rs | 18 +++--- .../src/coverageinfo/map_data.rs | 8 +-- .../src/coverageinfo/mapgen.rs | 2 +- .../src/coverageinfo/mod.rs | 8 +-- .../src/debuginfo/create_scope_map.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/gdb.rs | 8 ++- .../src/debuginfo/metadata.rs | 22 ++++--- .../src/debuginfo/metadata/enums/mod.rs | 2 +- .../src/debuginfo/metadata/type_map.rs | 24 ++++---- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 26 ++++----- .../src/debuginfo/namespace.rs | 4 +- .../rustc_codegen_llvm/src/debuginfo/utils.rs | 10 ++-- compiler/rustc_codegen_llvm/src/declare.rs | 16 ++--- compiler/rustc_codegen_llvm/src/errors.rs | 4 +- compiler/rustc_codegen_llvm/src/lib.rs | 9 +-- compiler/rustc_codegen_llvm/src/llvm_util.rs | 32 +++++----- compiler/rustc_codegen_llvm/src/type_.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 8 +-- compiler/rustc_codegen_llvm/src/value.rs | 2 +- 31 files changed, 206 insertions(+), 184 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 5ff580e295a60..dea574a53cd7b 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -6,13 +6,13 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::MemFlags; use rustc_middle::ty::layout::LayoutOf; -pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; +pub(crate) use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc_middle::ty::Ty; use rustc_middle::{bug, ty}; use rustc_session::config; -pub use rustc_target::abi::call::*; +pub(crate) use rustc_target::abi::call::*; use rustc_target::abi::{self, HasDataLayout, Int, Size}; -pub use rustc_target::spec::abi::Abi; +pub(crate) use rustc_target::spec::abi::Abi; use rustc_target::spec::SanitizerSet; use smallvec::SmallVec; @@ -25,7 +25,7 @@ use crate::type_of::LayoutLlvmExt; use crate::value::Value; use crate::{attributes, llvm_util}; -pub trait ArgAttributesExt { +trait ArgAttributesExt { fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value); fn apply_attrs_to_callsite( &self, @@ -111,7 +111,7 @@ impl ArgAttributesExt for ArgAttributes { } } -pub trait LlvmType { +pub(crate) trait LlvmType { fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type; } @@ -171,7 +171,7 @@ impl LlvmType for CastTarget { } } -pub trait ArgAbiExt<'ll, 'tcx> { +trait ArgAbiExt<'ll, 'tcx> { fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn store( &self, @@ -307,7 +307,7 @@ impl<'ll, 'tcx> ArgAbiMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } -pub trait FnAbiLlvmExt<'ll, 'tcx> { +pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> { fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index fde95104093e5..317e970d70485 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,6 +1,6 @@ //! Set and unset common attributes on LLVM values. -pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; @@ -17,13 +17,13 @@ use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace use crate::value::Value; use crate::{attributes, llvm_util}; -pub fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { +pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { if !attrs.is_empty() { llvm::AddFunctionAttributes(llfn, idx, attrs); } } -pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) { +pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) { if !attrs.is_empty() { llvm::AddCallSiteAttributes(callsite, idx, attrs); } @@ -80,7 +80,7 @@ fn patchable_function_entry_attrs<'ll>( /// Get LLVM sanitize attributes. #[inline] -pub fn sanitize_attrs<'ll>( +pub(crate) fn sanitize_attrs<'ll>( cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, ) -> SmallVec<[&'ll Attribute; 4]> { @@ -120,7 +120,7 @@ pub fn sanitize_attrs<'ll>( /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] -pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option) -> &Attribute { +pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option) -> &Attribute { // NOTE: We should determine if we even need async unwind tables, as they // take have more overhead and if we can use sync unwind tables we // probably should. @@ -128,7 +128,7 @@ pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option) -> &Att llvm::CreateUWTableAttr(llcx, async_unwind) } -pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { let mut fp = cx.sess().target.frame_pointer; let opts = &cx.sess().opts; // "mcount" function relies on stack pointer. @@ -280,19 +280,19 @@ fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None } } -pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { +pub(crate) fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { let target_cpu = llvm_util::target_cpu(cx.tcx.sess); llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) } -pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { llvm_util::tune_cpu(cx.tcx.sess) .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu)) } /// Get the `NonLazyBind` LLVM attribute, /// if the codegen options allow skipping the PLT. -pub fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { // Don't generate calls through PLT if it's not necessary if !cx.sess().needs_plt() { Some(AttributeKind::NonLazyBind.create_attr(cx.llcx)) @@ -327,7 +327,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute { /// Helper for `FnAbi::apply_attrs_llfn`: /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. -pub fn llfn_attrs_from_instance<'ll, 'tcx>( +pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>, diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index a2ab19ac800b7..8bc989538c3f8 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -102,7 +102,7 @@ impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> { } } -pub struct LlvmArchiveBuilderBuilder; +pub(crate) struct LlvmArchiveBuilderBuilder; impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box { diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index f68155f523a6e..d06b240671251 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -33,9 +33,9 @@ use crate::{LlvmCodegenBackend, ModuleLlvm}; /// We keep track of the computed LTO cache keys from the previous /// session to determine which CGUs we can reuse. -pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; +const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; -pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { +fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { CrateType::Executable | CrateType::Dylib @@ -710,7 +710,7 @@ impl Drop for ThinBuffer { } } -pub unsafe fn optimize_thin_module( +pub(crate) unsafe fn optimize_thin_module( thin_module: ThinModule, cgcx: &CodegenContext, ) -> Result, FatalError> { @@ -806,7 +806,7 @@ pub unsafe fn optimize_thin_module( /// Maps LLVM module identifiers to their corresponding LLVM LTO cache keys #[derive(Debug, Default)] -pub struct ThinLTOKeysMap { +struct ThinLTOKeysMap { // key = llvm name of importing module, value = LLVM cache key keys: BTreeMap, } @@ -863,7 +863,7 @@ fn module_name_to_str(c_str: &CStr) -> &str { }) } -pub fn parse_module<'a>( +pub(crate) fn parse_module<'a>( cx: &'a llvm::Context, name: &CStr, data: &[u8], diff --git a/compiler/rustc_codegen_llvm/src/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs index 26fb4a96f846b..79794775b7b66 100644 --- a/compiler/rustc_codegen_llvm/src/back/profiling.rs +++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs @@ -21,14 +21,14 @@ fn llvm_args_to_string_id(profiler: &SelfProfiler, pass_name: &str, ir_name: &st EventId::from_label(profiler.alloc_string(components.as_slice())) } -pub struct LlvmSelfProfiler<'a> { +pub(crate) struct LlvmSelfProfiler<'a> { profiler: Arc, stack: Vec>, llvm_pass_event_kind: StringId, } impl<'a> LlvmSelfProfiler<'a> { - pub fn new(profiler: Arc) -> Self { + pub(crate) fn new(profiler: Arc) -> Self { let llvm_pass_event_kind = profiler.alloc_string("LLVM Pass"); Self { profiler, stack: Vec::default(), llvm_pass_event_kind } } @@ -43,7 +43,7 @@ impl<'a> LlvmSelfProfiler<'a> { } } -pub unsafe extern "C" fn selfprofile_before_pass_callback( +pub(crate) unsafe extern "C" fn selfprofile_before_pass_callback( llvm_self_profiler: *mut c_void, pass_name: *const c_char, ir_name: *const c_char, @@ -56,7 +56,7 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback( } } -pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) { +pub(crate) unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) { let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) }; llvm_self_profiler.after_pass_callback(); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a1f2433ab6f3b..853321ef1c7d7 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -43,14 +43,14 @@ use crate::llvm::{self, DiagnosticInfo, PassManager}; use crate::type_::Type; use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm}; -pub fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError { +pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError { match llvm::last_error() { Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)), None => dcx.emit_almost_fatal(err), } } -pub fn write_output_file<'ll>( +fn write_output_file<'ll>( dcx: DiagCtxtHandle<'_>, target: &'ll llvm::TargetMachine, pm: &llvm::PassManager<'ll>, @@ -95,7 +95,7 @@ pub fn write_output_file<'ll>( } } -pub fn create_informational_target_machine( +pub(crate) fn create_informational_target_machine( sess: &Session, only_base_features: bool, ) -> OwnedTargetMachine { @@ -107,7 +107,7 @@ pub fn create_informational_target_machine( .unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise()) } -pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine { +pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine { let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() { tcx.output_filenames(()).split_dwarf_path( tcx.sess.split_debuginfo(), @@ -130,9 +130,7 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMach .unwrap_or_else(|err| llvm_err(tcx.dcx(), err).raise()) } -pub fn to_llvm_opt_settings( - cfg: config::OptLevel, -) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) { +fn to_llvm_opt_settings(cfg: config::OptLevel) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) { use self::config::OptLevel::*; match cfg { No => (llvm::CodeGenOptLevel::None, llvm::CodeGenOptSizeNone), @@ -179,7 +177,7 @@ pub(crate) fn to_llvm_code_model(code_model: Option) -> llvm::CodeMod } } -pub fn target_machine_factory( +pub(crate) fn target_machine_factory( sess: &Session, optlvl: config::OptLevel, target_features: &[String], @@ -320,7 +318,7 @@ pub(crate) fn save_temp_bitcode( } /// In what context is a dignostic handler being attached to a codegen unit? -pub enum CodegenDiagnosticsStage { +pub(crate) enum CodegenDiagnosticsStage { /// Prelink optimization stage. Opt, /// LTO/ThinLTO postlink optimization stage. @@ -329,14 +327,14 @@ pub enum CodegenDiagnosticsStage { Codegen, } -pub struct DiagnosticHandlers<'a> { +pub(crate) struct DiagnosticHandlers<'a> { data: *mut (&'a CodegenContext, DiagCtxtHandle<'a>), llcx: &'a llvm::Context, old_handler: Option<&'a llvm::DiagnosticHandler>, } impl<'a> DiagnosticHandlers<'a> { - pub fn new( + pub(crate) fn new( cgcx: &'a CodegenContext, dcx: DiagCtxtHandle<'a>, llcx: &'a llvm::Context, diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index e8236b45c8966..0ba8d82406a82 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -32,7 +32,7 @@ use crate::context::CodegenCx; use crate::value::Value; use crate::{attributes, llvm}; -pub struct ValueIter<'ll> { +pub(crate) struct ValueIter<'ll> { cur: Option<&'ll Value>, step: unsafe extern "C" fn(&'ll Value) -> Option<&'ll Value>, } @@ -49,11 +49,14 @@ impl<'ll> Iterator for ValueIter<'ll> { } } -pub fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> { +pub(crate) fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> { unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } } } -pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen, u64) { +pub(crate) fn compile_codegen_unit( + tcx: TyCtxt<'_>, + cgu_name: Symbol, +) -> (ModuleCodegen, u64) { let start_time = Instant::now(); let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx); @@ -140,7 +143,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen (module, cost) } -pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) { +pub(crate) fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) { let Some(sect) = attrs.link_section else { return }; unsafe { let buf = SmallCStr::new(sect.as_str()); @@ -148,7 +151,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) { } } -pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { +pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { match linkage { Linkage::External => llvm::Linkage::ExternalLinkage, Linkage::AvailableExternally => llvm::Linkage::AvailableExternallyLinkage, @@ -164,7 +167,7 @@ pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { } } -pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { +pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { match linkage { Visibility::Default => llvm::Visibility::Default, Visibility::Hidden => llvm::Visibility::Hidden, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index cc081f29e128e..40783825cae57 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -36,7 +36,7 @@ use crate::{attributes, llvm_util}; // All Builders must have an llfn associated with them #[must_use] -pub struct Builder<'a, 'll, 'tcx> { +pub(crate) struct Builder<'a, 'll, 'tcx> { pub llbuilder: &'ll mut llvm::Builder<'ll>, pub cx: &'a CodegenCx<'ll, 'tcx>, } @@ -1343,7 +1343,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { Builder { llbuilder, cx } } - pub fn llfn(&self) -> &'ll Value { + pub(crate) fn llfn(&self) -> &'ll Value { unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) } } @@ -1375,7 +1375,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } } - pub fn set_unpredictable(&mut self, inst: &'ll Value) { + pub(crate) fn set_unpredictable(&mut self, inst: &'ll Value) { unsafe { llvm::LLVMSetMetadata( inst, @@ -1385,15 +1385,15 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } } - pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } } - pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) } } - pub fn insert_element( + pub(crate) fn insert_element( &mut self, vec: &'ll Value, elt: &'ll Value, @@ -1402,7 +1402,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) } } - pub fn shuffle_vector( + pub(crate) fn shuffle_vector( &mut self, v1: &'ll Value, v2: &'ll Value, @@ -1411,65 +1411,77 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) } } - pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) } } - pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) } } - pub fn vector_reduce_fadd_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fadd_reassoc( + &mut self, + acc: &'ll Value, + src: &'ll Value, + ) -> &'ll Value { unsafe { let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); llvm::LLVMRustSetAllowReassoc(instr); instr } } - pub fn vector_reduce_fmul_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fmul_reassoc( + &mut self, + acc: &'ll Value, + src: &'ll Value, + ) -> &'ll Value { unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); llvm::LLVMRustSetAllowReassoc(instr); instr } } - pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) } } - pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) } } - pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) } } - pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) } } - pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } } - pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) } } - pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { + pub(crate) fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) } } - pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { + pub(crate) fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) } } - pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { + pub(crate) fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) } } - pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) { + pub(crate) fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) { unsafe { llvm::LLVMAddClause(landing_pad, clause); } } - pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { + pub(crate) fn catch_ret( + &mut self, + funclet: &Funclet<'ll>, + unwind: &'ll BasicBlock, + ) -> &'ll Value { let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } @@ -1515,7 +1527,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { Cow::Owned(casted_args) } - pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { + pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 663c5be46e5e4..949fd1bc124f5 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -20,7 +20,7 @@ use crate::value::Value; /// /// - `cx`: the crate context /// - `instance`: the instance to be instantiated -pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value { +pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value { let tcx = cx.tcx(); debug!("get_fn(instance={:?})", instance); diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index a399790018439..ef6560ecbe59e 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -13,7 +13,7 @@ use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer}; use tracing::debug; use crate::consts::const_alloc_to_llvm; -pub use crate::context::CodegenCx; +pub(crate) use crate::context::CodegenCx; use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True}; use crate::type_::Type; use crate::value::Value; @@ -58,21 +58,21 @@ use crate::value::Value; /// When inside of a landing pad, each function call in LLVM IR needs to be /// annotated with which landing pad it's a part of. This is accomplished via /// the `OperandBundleDef` value created for MSVC landing pads. -pub struct Funclet<'ll> { +pub(crate) struct Funclet<'ll> { cleanuppad: &'ll Value, operand: OperandBundleDef<'ll>, } impl<'ll> Funclet<'ll> { - pub fn new(cleanuppad: &'ll Value) -> Self { + pub(crate) fn new(cleanuppad: &'ll Value) -> Self { Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]) } } - pub fn cleanuppad(&self) -> &'ll Value { + pub(crate) fn cleanuppad(&self) -> &'ll Value { self.cleanuppad } - pub fn bundle(&self) -> &OperandBundleDef<'ll> { + pub(crate) fn bundle(&self) -> &OperandBundleDef<'ll> { &self.operand } } @@ -92,16 +92,16 @@ impl<'ll> BackendTypes for CodegenCx<'ll, '_> { } impl<'ll> CodegenCx<'ll, '_> { - pub fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { + pub(crate) fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { let len = u64::try_from(elts.len()).expect("LLVMConstArray2 elements len overflow"); unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) } } - pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value { + pub(crate) fn const_bytes(&self, bytes: &[u8]) -> &'ll Value { bytes_in_context(self.llcx, bytes) } - pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { + pub(crate) fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { unsafe { let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow"); let r = llvm::LLVMGetAggregateElement(v, idx).unwrap(); @@ -339,18 +339,18 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } /// Get the [LLVM type][Type] of a [`Value`]. -pub fn val_ty(v: &Value) -> &Type { +pub(crate) fn val_ty(v: &Value) -> &Type { unsafe { llvm::LLVMTypeOf(v) } } -pub fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { +pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { unsafe { let ptr = bytes.as_ptr() as *const c_char; llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), True) } } -pub fn struct_in_context<'ll>( +fn struct_in_context<'ll>( llcx: &'ll llvm::Context, elts: &[&'ll Value], packed: bool, diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 75b298f14ca1e..18fadca8d33f0 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -29,7 +29,7 @@ use crate::type_of::LayoutLlvmExt; use crate::value::Value; use crate::{base, debuginfo}; -pub fn const_alloc_to_llvm<'ll>( +pub(crate) fn const_alloc_to_llvm<'ll>( cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>, is_static: bool, diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index dd3f39eceadb6..7b12ff2fd8868 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -39,7 +39,7 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util}; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM /// `llvm::Context` so that several compilation units may be optimized in parallel. /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. -pub struct CodegenCx<'ll, 'tcx> { +pub(crate) struct CodegenCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, pub use_dll_storage_attrs: bool, pub tls_model: llvm::ThreadLocalMode, @@ -110,7 +110,7 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { } } -pub unsafe fn create_module<'ll>( +pub(crate) unsafe fn create_module<'ll>( tcx: TyCtxt<'_>, llcx: &'ll llvm::Context, mod_name: &str, @@ -531,7 +531,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } #[inline] - pub fn coverage_context(&self) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> { + pub(crate) fn coverage_context( + &self, + ) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> { self.coverage_cx.as_ref() } @@ -1064,7 +1066,7 @@ impl<'ll> CodegenCx<'ll, '_> { impl CodegenCx<'_, '_> { /// Generates a new symbol name with the given prefix. This symbol name must /// only be used for definitions with `internal` or `private` linkage. - pub fn generate_local_symbol_name(&self, prefix: &str) -> String { + pub(crate) fn generate_local_symbol_name(&self, prefix: &str) -> String { let idx = self.local_gen_sym_counter.get(); self.local_gen_sym_counter.set(idx + 1); // Include a '.' character, so there can be no accidental conflicts with diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index 584d033d6bdd1..cabdd310d1fc8 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -80,7 +80,7 @@ pub struct CounterExpression { /// Must match the layout of `LLVMRustCounterMappingRegionKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] -pub enum RegionKind { +enum RegionKind { /// A CodeRegion associates some code with a counter CodeRegion = 0, @@ -110,13 +110,13 @@ pub enum RegionKind { MCDCBranchRegion = 6, } -pub mod mcdc { +mod mcdc { use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo}; /// Must match the layout of `LLVMRustMCDCDecisionParameters`. #[repr(C)] #[derive(Clone, Copy, Debug, Default)] - pub struct DecisionParameters { + pub(crate) struct DecisionParameters { bitmap_idx: u32, num_conditions: u16, } @@ -127,14 +127,14 @@ pub mod mcdc { /// Must match the layout of `LLVMRustMCDCBranchParameters`. #[repr(C)] #[derive(Clone, Copy, Debug, Default)] - pub struct BranchParameters { + pub(crate) struct BranchParameters { condition_id: LLVMConditionId, condition_ids: [LLVMConditionId; 2], } #[repr(C)] #[derive(Clone, Copy, Debug)] - pub enum ParameterTag { + enum ParameterTag { None = 0, Decision = 1, Branch = 2, @@ -142,24 +142,24 @@ pub mod mcdc { /// Same layout with `LLVMRustMCDCParameters` #[repr(C)] #[derive(Clone, Copy, Debug)] - pub struct Parameters { + pub(crate) struct Parameters { tag: ParameterTag, decision_params: DecisionParameters, branch_params: BranchParameters, } impl Parameters { - pub fn none() -> Self { + pub(crate) fn none() -> Self { Self { tag: ParameterTag::None, decision_params: Default::default(), branch_params: Default::default(), } } - pub fn decision(decision_params: DecisionParameters) -> Self { + pub(crate) fn decision(decision_params: DecisionParameters) -> Self { Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() } } - pub fn branch(branch_params: BranchParameters) -> Self { + pub(crate) fn branch(branch_params: BranchParameters) -> Self { Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params } } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs index 9433385c23a5b..44eafab6060b3 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs @@ -14,7 +14,7 @@ use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind}; /// Holds all of the coverage mapping data associated with a function instance, /// collected during traversal of `Coverage` statements in the function's MIR. #[derive(Debug)] -pub struct FunctionCoverageCollector<'tcx> { +pub(crate) struct FunctionCoverageCollector<'tcx> { /// Coverage info that was attached to this function by the instrumentor. function_coverage_info: &'tcx FunctionCoverageInfo, is_used: bool, @@ -32,7 +32,7 @@ pub struct FunctionCoverageCollector<'tcx> { impl<'tcx> FunctionCoverageCollector<'tcx> { /// Creates a new set of coverage data for a used (called) function. - pub fn new( + pub(crate) fn new( instance: Instance<'tcx>, function_coverage_info: &'tcx FunctionCoverageInfo, ) -> Self { @@ -40,7 +40,7 @@ impl<'tcx> FunctionCoverageCollector<'tcx> { } /// Creates a new set of coverage data for an unused (never called) function. - pub fn unused( + pub(crate) fn unused( instance: Instance<'tcx>, function_coverage_info: &'tcx FunctionCoverageInfo, ) -> Self { @@ -195,7 +195,7 @@ impl<'tcx> FunctionCoverage<'tcx> { /// Return the source hash, generated from the HIR node structure, and used to indicate whether /// or not the source code structure changed between different compilations. - pub fn source_hash(&self) -> u64 { + pub(crate) fn source_hash(&self) -> u64 { if self.is_used { self.function_coverage_info.function_source_hash } else { 0 } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index f8929a26011ab..069b62af5e748 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -27,7 +27,7 @@ use crate::{coverageinfo, llvm}; /// implementing this Rust version, and though the format documentation is very explicit and /// detailed, some undocumented details in Clang's implementation (that may or may not be important) /// were also replicated for Rust's Coverage Map. -pub fn finalize(cx: &CodegenCx<'_, '_>) { +pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { let tcx = cx.tcx; // Ensure that LLVM is using a version of the coverage mapping format that diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 20a713b856419..69babc7c9cf3e 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -22,10 +22,10 @@ use crate::llvm; pub(crate) mod ffi; pub(crate) mod map_data; -pub mod mapgen; +mod mapgen; /// A context object for maintaining all state needed by the coverageinfo module. -pub struct CrateCoverageContext<'ll, 'tcx> { +pub(crate) struct CrateCoverageContext<'ll, 'tcx> { /// Coverage data for each instrumented function identified by DefId. pub(crate) function_coverage_map: RefCell, FunctionCoverageCollector<'tcx>>>, @@ -34,7 +34,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> { } impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { function_coverage_map: Default::default(), pgo_func_name_var_map: Default::default(), @@ -42,7 +42,7 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> { } } - pub fn take_function_coverage_map( + fn take_function_coverage_map( &self, ) -> FxIndexMap, FunctionCoverageCollector<'tcx>> { self.function_coverage_map.replace(FxIndexMap::default()) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index efe616838bfe4..19100ed3f3312 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -15,7 +15,7 @@ use crate::llvm::debuginfo::{DILocation, DIScope}; /// Produces DIScope DIEs for each MIR Scope which has variables defined in it. // FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`. -pub fn compute_mir_scopes<'ll, 'tcx>( +pub(crate) fn compute_mir_scopes<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, mir: &Body<'tcx>, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 5a08f2f00e5be..42b03fd053796 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -16,7 +16,7 @@ use crate::value::Value; /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. -pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) { +pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) { if needs_gdb_debug_scripts_section(bx) { let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx); // Load just the first byte as that's all that's necessary to force @@ -30,7 +30,9 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, /// Allocates the global variable responsible for the .debug_gdb_scripts binary /// section. -pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Value { +pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( + cx: &CodegenCx<'ll, '_>, +) -> &'ll Value { let c_section_var_name = c"__rustc_debug_gdb_scripts_section__"; let section_var_name = c_section_var_name.to_str().unwrap(); @@ -83,7 +85,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' }) } -pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { +pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 87bea22d8ddaf..26999d8103536 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -85,7 +85,7 @@ const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = | // SmallVec is used quite a bit in this module, so create a shorthand. // The actual number of elements is not so important. -pub type SmallVec = smallvec::SmallVec<[T; 16]>; +type SmallVec = smallvec::SmallVec<[T; 16]>; mod enums; mod type_map; @@ -425,7 +425,7 @@ fn build_slice_type_di_node<'ll, 'tcx>( /// /// This function will look up the debuginfo node in the TypeMap. If it can't find it, it /// will create the node by dispatching to the corresponding `build_*_di_node()` function. -pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { +pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t); if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id) @@ -531,7 +531,7 @@ fn hex_encode(data: &[u8]) -> String { hex_string } -pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile { +pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile { let cache_key = Some((source_file.stable_id, source_file.src_hash)); return debug_context(cx) .created_files @@ -644,7 +644,7 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> } } -pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { +fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe { let file_name = ""; let directory = ""; @@ -859,7 +859,7 @@ fn build_param_type_di_node<'ll, 'tcx>( } } -pub fn build_compile_unit_di_node<'ll, 'tcx>( +pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( tcx: TyCtxt<'tcx>, codegen_unit_name: &str, debug_context: &CodegenUnitDebugContext<'ll, 'tcx>, @@ -1319,7 +1319,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( /// Creates debug information for the given global variable. /// /// Adds the created debuginfo nodes directly to the crate's IR. -pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, global: &'ll Value) { +pub(crate) fn build_global_var_di_node<'ll>( + cx: &CodegenCx<'ll, '_>, + def_id: DefId, + global: &'ll Value, +) { if cx.dbg_cx.is_none() { return; } @@ -1559,7 +1563,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( /// given type. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_vtable_di_node<'ll, 'tcx>( +pub(crate) fn create_vtable_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, poly_trait_ref: Option>, @@ -1604,7 +1608,7 @@ pub fn create_vtable_di_node<'ll, 'tcx>( } /// Creates an "extension" of an existing `DIScope` into another file. -pub fn extend_scope_to_file<'ll>( +pub(crate) fn extend_scope_to_file<'ll>( cx: &CodegenCx<'ll, '_>, scope_metadata: &'ll DIScope, file: &SourceFile, @@ -1613,7 +1617,7 @@ pub fn extend_scope_to_file<'ll>( unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) } } -pub fn tuple_field_name(field_index: usize) -> Cow<'static, str> { +fn tuple_field_name(field_index: usize) -> Cow<'static, str> { const TUPLE_FIELD_NAMES: [&'static str; 16] = [ "__0", "__1", "__2", "__3", "__4", "__5", "__6", "__7", "__8", "__9", "__10", "__11", "__12", "__13", "__14", "__15", diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index fc3adaf068111..373ccc77f9200 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -301,7 +301,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( /// ---> DW_TAG_structure_type (type of variant 3) /// /// ``` -pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( +fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, variant_index: VariantIdx, coroutine_type_and_layout: TyAndLayout<'tcx>, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 25b2df9c52c3a..6d21f4204e361 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -22,7 +22,7 @@ mod private { // `UniqueTypeId` from being constructed directly, without asserting // the preconditions. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, HashStable)] - pub struct HiddenZst; + pub(crate) struct HiddenZst; } /// A unique identifier for anything that we create a debuginfo node for. @@ -48,17 +48,17 @@ pub(super) enum UniqueTypeId<'tcx> { } impl<'tcx> UniqueTypeId<'tcx> { - pub fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { + pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)); UniqueTypeId::Ty(t, private::HiddenZst) } - pub fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { + pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty)); UniqueTypeId::VariantPart(enum_ty, private::HiddenZst) } - pub fn for_enum_variant_struct_type( + pub(crate) fn for_enum_variant_struct_type( tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>, variant_idx: VariantIdx, @@ -67,7 +67,7 @@ impl<'tcx> UniqueTypeId<'tcx> { UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst) } - pub fn for_enum_variant_struct_type_wrapper( + pub(crate) fn for_enum_variant_struct_type_wrapper( tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>, variant_idx: VariantIdx, @@ -76,7 +76,7 @@ impl<'tcx> UniqueTypeId<'tcx> { UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst) } - pub fn for_vtable_ty( + pub(crate) fn for_vtable_ty( tcx: TyCtxt<'tcx>, self_type: Ty<'tcx>, implemented_trait: Option>, @@ -93,7 +93,7 @@ impl<'tcx> UniqueTypeId<'tcx> { /// argument of the various `LLVMRustDIBuilderCreate*Type()` methods. /// /// Right now this takes the form of a hex-encoded opaque hash value. - pub fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String { + fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String { let mut hasher = StableHasher::new(); tcx.with_stable_hashing_context(|mut hcx| { hcx.while_hashing_spans(false, |hcx| self.hash_stable(hcx, &mut hasher)) @@ -101,7 +101,7 @@ impl<'tcx> UniqueTypeId<'tcx> { hasher.finish::().to_hex() } - pub fn expect_ty(self) -> Ty<'tcx> { + pub(crate) fn expect_ty(self) -> Ty<'tcx> { match self { UniqueTypeId::Ty(ty, _) => ty, _ => bug!("Expected `UniqueTypeId::Ty` but found `{:?}`", self), @@ -133,25 +133,25 @@ impl<'ll, 'tcx> TypeMap<'ll, 'tcx> { } } -pub struct DINodeCreationResult<'ll> { +pub(crate) struct DINodeCreationResult<'ll> { pub di_node: &'ll DIType, pub already_stored_in_typemap: bool, } impl<'ll> DINodeCreationResult<'ll> { - pub fn new(di_node: &'ll DIType, already_stored_in_typemap: bool) -> Self { + pub(crate) fn new(di_node: &'ll DIType, already_stored_in_typemap: bool) -> Self { DINodeCreationResult { di_node, already_stored_in_typemap } } } #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum Stub<'ll> { +pub(crate) enum Stub<'ll> { Struct, Union, VTableTy { vtable_holder: &'ll DIType }, } -pub struct StubInfo<'ll, 'tcx> { +pub(crate) struct StubInfo<'ll, 'tcx> { metadata: &'ll DIType, unique_type_id: UniqueTypeId<'tcx>, } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b23e05182ca1b..50d08441025a9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -40,13 +40,13 @@ use crate::llvm::debuginfo::{ use crate::value::Value; mod create_scope_map; -pub mod gdb; -pub mod metadata; +mod gdb; +pub(crate) mod metadata; mod namespace; mod utils; -pub use self::create_scope_map::compute_mir_scopes; -pub use self::metadata::build_global_var_di_node; +use self::create_scope_map::compute_mir_scopes; +pub(crate) use self::metadata::build_global_var_di_node; #[allow(non_upper_case_globals)] const DW_TAG_auto_variable: c_uint = 0x100; @@ -54,7 +54,7 @@ const DW_TAG_auto_variable: c_uint = 0x100; const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. -pub struct CodegenUnitDebugContext<'ll, 'tcx> { +pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, @@ -74,7 +74,7 @@ impl Drop for CodegenUnitDebugContext<'_, '_> { } impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { - pub fn new(llmod: &'ll llvm::Module) -> Self { + pub(crate) fn new(llmod: &'ll llvm::Module) -> Self { debug!("CodegenUnitDebugContext::new"); let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; // DIBuilder inherits context from the module, so we'd better use the same one @@ -90,7 +90,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { } } - pub fn finalize(&self, sess: &Session) { + pub(crate) fn finalize(&self, sess: &Session) { unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder); @@ -134,7 +134,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { } /// Creates any deferred debug metadata nodes -pub fn finalize(cx: &CodegenCx<'_, '_>) { +pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { if let Some(dbg_cx) = &cx.dbg_cx { debug!("finalize"); @@ -241,13 +241,13 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { // FIXME(eddyb) rename this to better indicate it's a duplicate of // `rustc_span::Loc` rather than `DILocation`, perhaps by making // `lookup_char_pos` return the right information instead. -pub struct DebugLoc { +struct DebugLoc { /// Information about the original source file. - pub file: Lrc, + file: Lrc, /// The (1-based) line number. - pub line: u32, + line: u32, /// The (1-based) column number. - pub col: u32, + col: u32, } impl CodegenCx<'_, '_> { @@ -255,7 +255,7 @@ impl CodegenCx<'_, '_> { // FIXME(eddyb) rename this to better indicate it's a duplicate of // `lookup_char_pos` rather than `dbg_loc`, perhaps by making // `lookup_char_pos` return the right information instead. - pub fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc { + fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc { let (file, line, col) = match self.sess().source_map().lookup_line(pos) { Ok(SourceFileAndLine { sf: file, line }) => { let line_pos = file.lines()[line]; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs index 5c4f8fe99e3d9..83d7a82dadc4d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs @@ -9,7 +9,7 @@ use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::DIScope; -pub fn mangled_name_of_instance<'a, 'tcx>( +pub(crate) fn mangled_name_of_instance<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, ) -> ty::SymbolName<'tcx> { @@ -17,7 +17,7 @@ pub fn mangled_name_of_instance<'a, 'tcx>( tcx.symbol_name(instance) } -pub fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { +pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) { return scope; } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index e542aa96e8a23..321553a3df0bd 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -11,7 +11,7 @@ use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope}; -pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool { +pub(crate) fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool { // The is_local_to_unit flag indicates whether a function is local to the // current compilation unit (i.e., if it is *static* in the C-sense). The // *reachable* set should provide a good approximation of this, as it @@ -24,7 +24,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool { } #[allow(non_snake_case)] -pub fn create_DIArray<'ll>( +pub(crate) fn create_DIArray<'ll>( builder: &DIBuilder<'ll>, arr: &[Option<&'ll DIDescriptor>], ) -> &'ll DIArray { @@ -32,7 +32,7 @@ pub fn create_DIArray<'ll>( } #[inline] -pub fn debug_context<'a, 'll, 'tcx>( +pub(crate) fn debug_context<'a, 'll, 'tcx>( cx: &'a CodegenCx<'ll, 'tcx>, ) -> &'a CodegenUnitDebugContext<'ll, 'tcx> { cx.dbg_cx.as_ref().unwrap() @@ -40,11 +40,11 @@ pub fn debug_context<'a, 'll, 'tcx>( #[inline] #[allow(non_snake_case)] -pub fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { +pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { cx.dbg_cx.as_ref().unwrap().builder } -pub fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { +pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { item_namespace(cx, cx.tcx.parent(def_id)) } diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 2aa349b278234..4e4500b637328 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -65,7 +65,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// return its Value instead. - pub fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { + pub(crate) fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) } } @@ -77,7 +77,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - pub fn declare_cfn( + pub(crate) fn declare_cfn( &self, name: &str, unnamed: llvm::UnnamedAddr, @@ -100,7 +100,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - pub fn declare_entry_fn( + pub(crate) fn declare_entry_fn( &self, name: &str, callconv: llvm::CallConv, @@ -119,7 +119,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - pub fn declare_fn( + pub(crate) fn declare_fn( &self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, @@ -199,7 +199,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// return `None` if the name already has a definition associated with it. In that /// case an error should be reported to the user, because it usually happens due /// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes). - pub fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> { + pub(crate) fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> { if self.get_defined_value(name).is_some() { None } else { @@ -210,19 +210,19 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// Declare a private global /// /// Use this function when you intend to define a global without a name. - pub fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { + pub(crate) fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) } } /// Gets declared value by name. - pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { + pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { debug!("get_declared_value(name={:?})", name); unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) } } /// Gets defined or externally defined (AvailableExternally linkage) value by /// name. - pub fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { + pub(crate) fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { self.get_declared_value(name).and_then(|val| { let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 }; if !declaration { Some(val) } else { None } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 7e53d32ce8cd3..766f8db1788fa 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -214,13 +214,13 @@ pub(crate) struct CopyBitcode { #[derive(Diagnostic)] #[diag(codegen_llvm_unknown_debuginfo_compression)] -pub struct UnknownCompression { +pub(crate) struct UnknownCompression { pub algorithm: &'static str, } #[derive(Diagnostic)] #[diag(codegen_llvm_mismatch_data_layout)] -pub struct MismatchedDataLayout<'a> { +pub(crate) struct MismatchedDataLayout<'a> { pub rustc_target: &'a str, pub rustc_layout: &'a str, pub llvm_target: &'a str, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 43164390a1c6c..7f26bbd7f8757 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -16,6 +16,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::any::Any; @@ -45,11 +46,11 @@ use rustc_session::Session; use rustc_span::symbol::Symbol; mod back { - pub mod archive; - pub mod lto; - pub mod owned_target_machine; + pub(crate) mod archive; + pub(crate) mod lto; + pub(crate) mod owned_target_machine; mod profiling; - pub mod write; + pub(crate) mod write; } mod abi; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 9fd8ca43789dd..7af5eb9278f38 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -136,14 +136,14 @@ unsafe fn configure_llvm(sess: &Session) { unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) }; } -pub fn time_trace_profiler_finish(file_name: &Path) { +pub(crate) fn time_trace_profiler_finish(file_name: &Path) { unsafe { let file_name = path_to_c_string(file_name); llvm::LLVMRustTimeTraceProfilerFinish(file_name.as_ptr()); } } -pub enum TargetFeatureFoldStrength<'a> { +enum TargetFeatureFoldStrength<'a> { // The feature is only tied when enabling the feature, disabling // this feature shouldn't disable the tied feature. EnableOnly(&'a str), @@ -160,28 +160,28 @@ impl<'a> TargetFeatureFoldStrength<'a> { } } -pub struct LLVMFeature<'a> { - pub llvm_feature_name: &'a str, - pub dependency: Option>, +pub(crate) struct LLVMFeature<'a> { + llvm_feature_name: &'a str, + dependency: Option>, } impl<'a> LLVMFeature<'a> { - pub fn new(llvm_feature_name: &'a str) -> Self { + fn new(llvm_feature_name: &'a str) -> Self { Self { llvm_feature_name, dependency: None } } - pub fn with_dependency( + fn with_dependency( llvm_feature_name: &'a str, dependency: TargetFeatureFoldStrength<'a>, ) -> Self { Self { llvm_feature_name, dependency: Some(dependency) } } - pub fn contains(&self, feat: &str) -> bool { + fn contains(&self, feat: &str) -> bool { self.iter().any(|dep| dep == feat) } - pub fn iter(&'a self) -> impl Iterator { + fn iter(&'a self) -> impl Iterator { let dependencies = self.dependency.iter().map(|feat| feat.as_str()); std::iter::once(self.llvm_feature_name).chain(dependencies) } @@ -209,7 +209,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> { // Though note that Rust can also be build with an external precompiled version of LLVM // which might lead to failures if the oldest tested / supported LLVM version // doesn't yet support the relevant intrinsics -pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { +pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { let arch = if sess.target.arch == "x86_64" { "x86" } else if sess.target.arch == "arm64ec" { @@ -257,7 +257,7 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { /// Given a map from target_features to whether they are enabled or disabled, /// ensure only valid combinations are allowed. -pub fn check_tied_features( +pub(crate) fn check_tied_features( sess: &Session, features: &FxHashMap<&str, bool>, ) -> Option<&'static [&'static str]> { @@ -337,19 +337,19 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec { .collect() } -pub fn print_version() { +pub(crate) fn print_version() { let (major, minor, patch) = get_version(); println!("LLVM version: {major}.{minor}.{patch}"); } -pub fn get_version() -> (u32, u32, u32) { +pub(crate) fn get_version() -> (u32, u32, u32) { // Can be called without initializing LLVM unsafe { (llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch()) } } -pub fn print_passes() { +pub(crate) fn print_passes() { // Can be called without initializing LLVM unsafe { llvm::LLVMRustPrintPasses(); @@ -479,7 +479,7 @@ fn handle_native(name: &str) -> &str { } } -pub fn target_cpu(sess: &Session) -> &str { +pub(crate) fn target_cpu(sess: &Session) -> &str { match sess.opts.cg.target_cpu { Some(ref name) => handle_native(name), None => handle_native(sess.target.cpu.as_ref()), @@ -699,7 +699,7 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> { Some(feature) } -pub fn tune_cpu(sess: &Session) -> Option<&str> { +pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> { let name = sess.opts.unstable_opts.tune_cpu.as_ref()?; Some(handle_native(name)) } diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 7e3ab19898d36..ec1e2cb809421 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -12,7 +12,7 @@ use rustc_target::abi::{AddressSpace, Align, Integer, Size}; use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::context::CodegenCx; -pub use crate::llvm::Type; +pub(crate) use crate::llvm::Type; use crate::llvm::{Bool, False, True}; use crate::type_of::LayoutLlvmExt; use crate::value::Value; diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 4755fa08afb7c..6e429a1674ade 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -139,21 +139,21 @@ fn struct_llfields<'a, 'tcx>( } impl<'a, 'tcx> CodegenCx<'a, 'tcx> { - pub fn align_of(&self, ty: Ty<'tcx>) -> Align { + pub(crate) fn align_of(&self, ty: Ty<'tcx>) -> Align { self.layout_of(ty).align.abi } - pub fn size_of(&self, ty: Ty<'tcx>) -> Size { + pub(crate) fn size_of(&self, ty: Ty<'tcx>) -> Size { self.layout_of(ty).size } - pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { + pub(crate) fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { let layout = self.layout_of(ty); (layout.size, layout.align.abi) } } -pub trait LayoutLlvmExt<'tcx> { +pub(crate) trait LayoutLlvmExt<'tcx> { fn is_llvm_immediate(&self) -> bool; fn is_llvm_scalar_pair(&self) -> bool; fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; diff --git a/compiler/rustc_codegen_llvm/src/value.rs b/compiler/rustc_codegen_llvm/src/value.rs index 6295b0de35649..2eabac3be8c56 100644 --- a/compiler/rustc_codegen_llvm/src/value.rs +++ b/compiler/rustc_codegen_llvm/src/value.rs @@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher}; use std::{fmt, ptr}; use crate::llvm; -pub use crate::llvm::Value; +pub(crate) use crate::llvm::Value; impl PartialEq for Value { fn eq(&self, other: &Self) -> bool { From cc8444274b33ffd01fd8cb35199f02697e632852 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 6 Jul 2024 22:30:39 +1000 Subject: [PATCH 020/102] Add `warn(unreachable_pub)` to `rustc_codegen_ssa`. --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 ++-- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/lib.rs | 1 + compiler/rustc_codegen_ssa/src/mir/analyze.rs | 8 ++++---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7bad9d33e7d31..8d271f61a9c75 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1207,7 +1207,7 @@ mod win { /// Get the Windows system OEM code page. This is most notably the code page /// used for link.exe's output. - pub fn oem_code_page() -> u32 { + pub(super) fn oem_code_page() -> u32 { unsafe { let mut cp: u32 = 0; // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32. @@ -1230,7 +1230,7 @@ mod win { /// /// It will fail if the multi-byte string is longer than `i32::MAX` or if it contains /// any invalid bytes for the expected encoding. - pub fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option { + pub(super) fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option { // `MultiByteToWideChar` requires a length to be a "positive integer". if s.len() > isize::MAX as usize { return None; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 70b45a852ca0e..7ad31802454f2 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -754,7 +754,7 @@ pub(crate) enum WorkItem { } impl WorkItem { - pub fn module_kind(&self) -> ModuleKind { + fn module_kind(&self) -> ModuleKind { match *self { WorkItem::Optimize(ref m) => m.kind, WorkItem::CopyPostLtoArtifacts(_) | WorkItem::LTO(_) => ModuleKind::Regular, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index cb6d9d6f66e78..c89bfca668789 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -12,6 +12,7 @@ #![feature(rustdoc_internals)] #![feature(strict_provenance)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 6794365c9beef..5f3766421f0f1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -13,7 +13,7 @@ use tracing::debug; use super::FunctionCx; use crate::traits::*; -pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, ) -> BitSet { let mir = fx.mir; @@ -251,14 +251,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> } #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum CleanupKind { +pub(crate) enum CleanupKind { NotCleanup, Funclet, Internal { funclet: mir::BasicBlock }, } impl CleanupKind { - pub fn funclet_bb(self, for_bb: mir::BasicBlock) -> Option { + pub(crate) fn funclet_bb(self, for_bb: mir::BasicBlock) -> Option { match self { CleanupKind::NotCleanup => None, CleanupKind::Funclet => Some(for_bb), @@ -270,7 +270,7 @@ impl CleanupKind { /// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only /// branch to itself or to its parent. Luckily, the code we generates matches this pattern. /// Recover that structure in an analyze pass. -pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { +pub(crate) fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { fn discover_masters<'tcx>( result: &mut IndexSlice, mir: &mir::Body<'tcx>, From 803cbaf5fb5021eafaa60578ed33d708370ba3c0 Mon Sep 17 00:00:00 2001 From: Rezwan ahmed sami Date: Sun, 18 Aug 2024 01:11:18 +0600 Subject: [PATCH 021/102] Add f16 and f128 to tests/ui/consts/const-float-bits-conv.rs --- tests/ui/consts/const-float-bits-conv.rs | 65 +++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs index 45e8ea570ed73..2c4df96562a9d 100644 --- a/tests/ui/consts/const-float-bits-conv.rs +++ b/tests/ui/consts/const-float-bits-conv.rs @@ -3,8 +3,9 @@ #![feature(const_float_bits_conv)] #![feature(const_float_classify)] +#![feature(f16)] +#![feature(f128)] #![allow(unused_macro_rules)] - // Don't promote const fn nop(x: T) -> T { x } @@ -28,6 +29,36 @@ fn has_broken_floats() -> bool { std::env::var("TARGET").is_ok_and(|v| v.contains("i586")) } +fn f16(){ + const_assert!((1f16).to_bits(), 0x3c00); + const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00); + const_assert!((12.5f16).to_bits(), 0x4a40); + const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40); + const_assert!((1337f16).to_bits(), 0x6539); + const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539); + const_assert!((-14.25f16).to_bits(), 0xcb20); + const_assert!(f16::from_bits(0x3c00), 1.0); + const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0); + const_assert!(f16::from_bits(0x4a40), 12.5); + const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5); + const_assert!(f16::from_bits(0x5be0), 252.0); + const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0); + const_assert!(f16::from_bits(0xcb20), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply! + const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155; + const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA; + + const_assert!(f16::from_bits(QUIET_NAN).is_nan()); + const_assert!(f16::from_bits(SIGNALING_NAN).is_nan()); + const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN); + if !has_broken_floats() { + const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN); + } +} + fn f32() { const_assert!((1f32).to_bits(), 0x3f800000); const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000); @@ -88,7 +119,39 @@ fn f64() { } } +fn f128() { + const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); + const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); + const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000); + const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000); + const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000); + const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000); + const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000); + const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0); + const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0); + const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5); + const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5); + const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0); + assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0); + const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply! + const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA; + const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555; + + const_assert!(f128::from_bits(QUIET_NAN).is_nan()); + const_assert!(f128::from_bits(SIGNALING_NAN).is_nan()); + const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN); + if !has_broken_floats() { + const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN); + } +} + fn main() { + f16(); f32(); f64(); + f128(); } From 9f39427228d09d7a06b9dd55a4f52b4b9ac15817 Mon Sep 17 00:00:00 2001 From: Rezwan ahmed sami Date: Sun, 18 Aug 2024 11:12:40 +0600 Subject: [PATCH 022/102] Added #[cfg(target_arch = x86_64)] to f16 and f128 --- tests/ui/consts/const-float-bits-conv.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs index 2c4df96562a9d..3a526c54dc376 100644 --- a/tests/ui/consts/const-float-bits-conv.rs +++ b/tests/ui/consts/const-float-bits-conv.rs @@ -29,6 +29,7 @@ fn has_broken_floats() -> bool { std::env::var("TARGET").is_ok_and(|v| v.contains("i586")) } +#[cfg(target_arch = "x86_64")] fn f16(){ const_assert!((1f16).to_bits(), 0x3c00); const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00); @@ -119,6 +120,7 @@ fn f64() { } } +#[cfg(target_arch = "x86_64")] fn f128() { const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); @@ -150,8 +152,11 @@ fn f128() { } fn main() { - f16(); + #[cfg(target_arch = "x86_64")] + { + f16(); + f128(); + } f32(); f64(); - f128(); } From 9b5a004bf8a388cfe1fc6b844d65e528cca6e2fd Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 20:57:50 +0000 Subject: [PATCH 023/102] feat(core): Add implementations for `unbounded_shl`/`unbounded_shr` --- library/core/src/num/int_macros.rs | 60 +++++++++++++++++++++++++++++ library/core/src/num/uint_macros.rs | 54 ++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 17cf2a7b261fd..0ec178448e476 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1312,6 +1312,33 @@ macro_rules! int_impl { } } + /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` + /// + /// If `rhs` is larger or equal to the number of bits in `self`, + /// the entire value is shifted out, and `0` is returned. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] + /// ``` + #[unstable(feature = "unbounded_shifts", issue = "129375")] + #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn unbounded_shl(self, v: u32) -> $SelfT{ + if v < Self::BITS{ + // SAFETY: + // v is just checked to be in-range above + unsafe{self.unchecked_shl(v)} + }else{ + 0 + } + } + /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is /// larger than or equal to the number of bits in `self`. /// @@ -1410,6 +1437,39 @@ macro_rules! int_impl { } } + /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs` + /// + /// If `rhs` is larger or equal to the number of bits in `self`, + /// the entire value is shifted out, which yields `0` for a positive number, + /// and `-1` for a negative number. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")] + /// ``` + #[unstable(feature = "unbounded_shifts", issue = "129375")] + #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn unbounded_shr(self, v: u32) -> $SelfT{ + if v < Self::BITS{ + // SAFETY: + // v is just checked to be in-range above + unsafe{self.unchecked_shr(v)} + }else{ + // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits. + + // SAFETY: + // `Self::BITS-1` is guaranteed to be less than `Self::BITS` + unsafe{self.unchecked_shr(Self::BITS - 1)} + } + } + /// Checked absolute value. Computes `self.abs()`, returning `None` if /// `self == MIN`. /// diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 719a6a55940dc..5a2f1876ca2b8 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1501,6 +1501,33 @@ macro_rules! uint_impl { } } + /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` + /// + /// If `rhs` is larger or equal to the number of bits in `self`, + /// the entire value is shifted out, and `0` is returned. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] + /// ``` + #[unstable(feature = "unbounded_shifts", issue = "129375")] + #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn unbounded_shl(self, v: u32) -> $SelfT{ + if v < Self::BITS{ + // SAFETY: + // v is just checked to be in-range above + unsafe{self.unchecked_shl(v)} + }else{ + 0 + } + } + /// Checked shift right. Computes `self >> rhs`, returning `None` /// if `rhs` is larger than or equal to the number of bits in `self`. /// @@ -1599,6 +1626,33 @@ macro_rules! uint_impl { } } + /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs` + /// + /// If `rhs` is larger or equal to the number of bits in `self`, + /// the entire value is shifted out, and `0` is returned. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x10);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] + /// ``` + #[unstable(feature = "unbounded_shifts", issue = "129375")] + #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn unbounded_shr(self, v: u32) -> $SelfT{ + if v < Self::BITS{ + // SAFETY: + // v is just checked to be in-range above + unsafe{self.unchecked_shr(v)} + }else{ + 0 + } + } + /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if /// overflow occurred. /// From c89bae0ea8f2b6c04ff26a14f8dd37eaa9bc2f0b Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 21:16:18 +0000 Subject: [PATCH 024/102] Manually format functions and use `rhs` instead of `v` from my CE testing --- library/core/src/num/int_macros.rs | 18 +++++++++--------- library/core/src/num/uint_macros.rs | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 0ec178448e476..b22311da1e354 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1329,11 +1329,11 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn unbounded_shl(self, v: u32) -> $SelfT{ - if v < Self::BITS{ + pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{ + if rhs < Self::BITS{ // SAFETY: - // v is just checked to be in-range above - unsafe{self.unchecked_shl(v)} + // rhs is just checked to be in-range above + unsafe { self.unchecked_shl(rhs) } }else{ 0 } @@ -1456,17 +1456,17 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn unbounded_shr(self, v: u32) -> $SelfT{ - if v < Self::BITS{ + pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{ + if rhs < Self::BITS{ // SAFETY: - // v is just checked to be in-range above - unsafe{self.unchecked_shr(v)} + // rhs is just checked to be in-range above + unsafe { self.unchecked_shr(rhs) } }else{ // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits. // SAFETY: // `Self::BITS-1` is guaranteed to be less than `Self::BITS` - unsafe{self.unchecked_shr(Self::BITS - 1)} + unsafe { self.unchecked_shr(Self::BITS - 1) } } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 5a2f1876ca2b8..b8ca299f67ddd 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1518,11 +1518,11 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn unbounded_shl(self, v: u32) -> $SelfT{ - if v < Self::BITS{ + pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{ + if rhs < Self::BITS{ // SAFETY: - // v is just checked to be in-range above - unsafe{self.unchecked_shl(v)} + // rhs is just checked to be in-range above + unsafe { self.unchecked_shl(rhs) } }else{ 0 } @@ -1643,11 +1643,11 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn unbounded_shr(self, v: u32) -> $SelfT{ - if v < Self::BITS{ + pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{ + if rhs < Self::BITS{ // SAFETY: - // v is just checked to be in-range above - unsafe{self.unchecked_shr(v)} + // rhs is just checked to be in-range above + unsafe { self.unchecked_shr(rhs) } }else{ 0 } From 38b5a2a67e64e8a02c4bee9bd0314e5023a559cb Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 21:23:25 +0000 Subject: [PATCH 025/102] chore: Also format the control flow --- library/core/src/num/int_macros.rs | 8 ++++---- library/core/src/num/uint_macros.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index b22311da1e354..b48b05577c96c 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1330,11 +1330,11 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{ - if rhs < Self::BITS{ + if rhs < Self::BITS { // SAFETY: // rhs is just checked to be in-range above unsafe { self.unchecked_shl(rhs) } - }else{ + } else { 0 } } @@ -1457,11 +1457,11 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{ - if rhs < Self::BITS{ + if rhs < Self::BITS { // SAFETY: // rhs is just checked to be in-range above unsafe { self.unchecked_shr(rhs) } - }else{ + } else { // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits. // SAFETY: diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index b8ca299f67ddd..f09fd604dc6a4 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1519,11 +1519,11 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{ - if rhs < Self::BITS{ + if rhs < Self::BITS { // SAFETY: // rhs is just checked to be in-range above unsafe { self.unchecked_shl(rhs) } - }else{ + } else { 0 } } @@ -1644,11 +1644,11 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{ - if rhs < Self::BITS{ + if rhs < Self::BITS { // SAFETY: // rhs is just checked to be in-range above unsafe { self.unchecked_shr(rhs) } - }else{ + } else { 0 } } From 79cbb878c7ca739b5136c9b87402860f017919d2 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 21:37:50 +0000 Subject: [PATCH 026/102] chore: `x fmt` and hopefully fix the tidy issue --- library/core/src/num/int_macros.rs | 12 ++++++------ library/core/src/num/uint_macros.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index b48b05577c96c..8c4f6a37fa91e 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1313,12 +1313,12 @@ macro_rules! int_impl { } /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` - /// - /// If `rhs` is larger or equal to the number of bits in `self`, + /// + /// If `rhs` is larger or equal to the number of bits in `self`, /// the entire value is shifted out, and `0` is returned. /// /// # Examples - /// + /// /// Basic usage: /// ``` #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] @@ -1438,13 +1438,13 @@ macro_rules! int_impl { } /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs` - /// - /// If `rhs` is larger or equal to the number of bits in `self`, + /// + /// If `rhs` is larger or equal to the number of bits in `self`, /// the entire value is shifted out, which yields `0` for a positive number, /// and `-1` for a negative number. /// /// # Examples - /// + /// /// Basic usage: /// ``` #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f09fd604dc6a4..643a76d23e415 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1502,12 +1502,12 @@ macro_rules! uint_impl { } /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` - /// - /// If `rhs` is larger or equal to the number of bits in `self`, + /// + /// If `rhs` is larger or equal to the number of bits in `self`, /// the entire value is shifted out, and `0` is returned. /// /// # Examples - /// + /// /// Basic usage: /// ``` #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] @@ -1627,12 +1627,12 @@ macro_rules! uint_impl { } /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs` - /// - /// If `rhs` is larger or equal to the number of bits in `self`, + /// + /// If `rhs` is larger or equal to the number of bits in `self`, /// the entire value is shifted out, and `0` is returned. /// /// # Examples - /// + /// /// Basic usage: /// ``` #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x10);")] From 9907f617ab8c0fc1a36161d5b33cd86780fb9b09 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 23:22:07 +0000 Subject: [PATCH 027/102] fix(core): Add `#![feature(unbounded_shifts)]` to doctests for `unbounded_shr`/`unbounded_shl` --- library/core/src/num/int_macros.rs | 4 +++- library/core/src/num/uint_macros.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 8c4f6a37fa91e..91d70473a6613 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1321,6 +1321,7 @@ macro_rules! int_impl { /// /// Basic usage: /// ``` + /// #![feature(unbounded_shifts)] #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] /// ``` @@ -1447,10 +1448,11 @@ macro_rules! int_impl { /// /// Basic usage: /// ``` + /// #![feature(unbounded_shifts)] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")] - /// ``` + /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] #[rustc_allow_const_fn_unstable(unchecked_shifts)] #[must_use = "this returns the result of the operation, \ diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 643a76d23e415..161ee649c841b 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1501,7 +1501,7 @@ macro_rules! uint_impl { } } - /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` + /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs` /// /// If `rhs` is larger or equal to the number of bits in `self`, /// the entire value is shifted out, and `0` is returned. @@ -1510,6 +1510,7 @@ macro_rules! uint_impl { /// /// Basic usage: /// ``` + /// #![feature(unbounded_shifts)] #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")] #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] /// ``` @@ -1635,6 +1636,7 @@ macro_rules! uint_impl { /// /// Basic usage: /// ``` + /// #![feature(unbounded_shifts)] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x10);")] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] /// ``` From 27b63b85ec7f8a767b91dd75bad7ca18399901a6 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Wed, 21 Aug 2024 23:38:04 +0000 Subject: [PATCH 028/102] chore: `x fmt` --- library/core/src/num/int_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 91d70473a6613..c11cae1666f20 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1452,7 +1452,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")] - /// ``` + /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] #[rustc_allow_const_fn_unstable(unchecked_shifts)] #[must_use = "this returns the result of the operation, \ From 2cf48eaebc9aa696aa7e7170e8d340123daddaa4 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Thu, 22 Aug 2024 00:08:03 +0000 Subject: [PATCH 029/102] fix(core): Use correct operations/values in `unbounded_shr` doctests --- library/core/src/num/int_macros.rs | 2 +- library/core/src/num/uint_macros.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index c11cae1666f20..d3dd68a9d610c 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1449,7 +1449,7 @@ macro_rules! int_impl { /// Basic usage: /// ``` /// #![feature(unbounded_shifts)] - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")] /// ``` diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 161ee649c841b..2e4e367af9b90 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1637,7 +1637,7 @@ macro_rules! uint_impl { /// Basic usage: /// ``` /// #![feature(unbounded_shifts)] - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x10);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")] #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] From f4dc7830ed64a713ef7d4e3c63032b9002c2040a Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Thu, 22 Aug 2024 10:28:48 +0000 Subject: [PATCH 030/102] feat(core): Make `unbounded_shl{l,r}` unstably const and remove `rustc_allow_const_fn_unstable` --- library/core/src/num/int_macros.rs | 4 ++-- library/core/src/num/uint_macros.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index d3dd68a9d610c..229cd89bea3f0 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1326,7 +1326,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1454,7 +1454,7 @@ macro_rules! int_impl { #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")] /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 2e4e367af9b90..0d0bbc5256f78 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1515,7 +1515,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")] /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1641,7 +1641,7 @@ macro_rules! uint_impl { #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")] /// ``` #[unstable(feature = "unbounded_shifts", issue = "129375")] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From e91f32829ccfb60e13fcb07dab4947c382a376c9 Mon Sep 17 00:00:00 2001 From: Stephen Lazaro Date: Tue, 20 Aug 2024 17:53:30 -0700 Subject: [PATCH 031/102] Deduplicate Spans in Uninitialized Check Prevents reporting labels or diagnostics on spans that are produced multiple times. --- .../src/diagnostics/conflict_errors.rs | 5 +++-- tests/ui/duplicate-label-E0381-issue-129274.rs | 13 +++++++++++++ .../ui/duplicate-label-E0381-issue-129274.stderr | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/ui/duplicate-label-E0381-issue-129274.rs create mode 100644 tests/ui/duplicate-label-E0381-issue-129274.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2b46e5597f778..4106a5de070a5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -678,14 +678,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { let inits = &self.move_data.init_path_map[mpi]; let move_path = &self.move_data.move_paths[mpi]; let decl_span = self.body.local_decls[move_path.place.local].source_info.span; - let mut spans = vec![]; + let mut spans_set = FxIndexSet::default(); for init_idx in inits { let init = &self.move_data.inits[*init_idx]; let span = init.span(self.body); if !span.is_dummy() { - spans.push(span); + spans_set.insert(span); } } + let spans: Vec<_> = spans_set.into_iter().collect(); let (name, desc) = match self.describe_place_with_options( moved_place, diff --git a/tests/ui/duplicate-label-E0381-issue-129274.rs b/tests/ui/duplicate-label-E0381-issue-129274.rs new file mode 100644 index 0000000000000..b2156e630c87f --- /dev/null +++ b/tests/ui/duplicate-label-E0381-issue-129274.rs @@ -0,0 +1,13 @@ +fn main() { + fn test() { + loop { + let blah: Option; + if true { + blah = Some("".to_string()); + } + if let Some(blah) = blah.as_ref() { //~ ERROR E0381 + } + } + } + println!("{:?}", test()) +} diff --git a/tests/ui/duplicate-label-E0381-issue-129274.stderr b/tests/ui/duplicate-label-E0381-issue-129274.stderr new file mode 100644 index 0000000000000..7f8bddb17c5a8 --- /dev/null +++ b/tests/ui/duplicate-label-E0381-issue-129274.stderr @@ -0,0 +1,15 @@ +error[E0381]: used binding `blah` is possibly-uninitialized + --> $DIR/duplicate-label-E0381-issue-129274.rs:8:33 + | +LL | let blah: Option; + | ---- binding declared here but left uninitialized +LL | if true { +LL | blah = Some("".to_string()); + | ---- binding initialized here in some conditions +LL | } +LL | if let Some(blah) = blah.as_ref() { + | ^^^^ `blah` used here but it is possibly-uninitialized + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`. From f62b9e0179434218040f42ee58bb99c1bf27c6d7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Jul 2024 20:27:17 +0300 Subject: [PATCH 032/102] rustc: Simplify getting sysroot library directory --- compiler/rustc_codegen_ssa/src/back/link.rs | 27 +++++++++------------ compiler/rustc_session/src/filesearch.rs | 16 +----------- compiler/rustc_session/src/session.rs | 16 ++---------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7bad9d33e7d31..ca439460adc11 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1317,11 +1317,9 @@ fn link_sanitizer_runtime( name: &str, ) { fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf { - let session_tlib = - filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple()); - let path = session_tlib.join(filename); + let path = sess.target_tlib_path.dir.join(filename); if path.exists() { - return session_tlib; + return sess.target_tlib_path.dir.clone(); } else { let default_sysroot = filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); @@ -1612,19 +1610,18 @@ fn print_native_static_libs( } fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf { - let fs = sess.target_filesearch(PathKind::Native); - let file_path = fs.get_lib_path().join(name); + let file_path = sess.target_tlib_path.dir.join(name); if file_path.exists() { return file_path; } // Special directory with objects used only in self-contained linkage mode if self_contained { - let file_path = fs.get_self_contained_lib_path().join(name); + let file_path = sess.target_tlib_path.dir.join("self-contained").join(name); if file_path.exists() { return file_path; } } - for search_path in fs.search_paths() { + for search_path in sess.target_filesearch(PathKind::Native).search_paths() { let file_path = search_path.dir.join(name); if file_path.exists() { return file_path; @@ -2131,7 +2128,7 @@ fn add_library_search_dirs( | LinkSelfContainedComponents::UNWIND | LinkSelfContainedComponents::MINGW, ) { - let lib_path = sess.target_filesearch(PathKind::Native).get_self_contained_lib_path(); + let lib_path = sess.target_tlib_path.dir.join("self-contained"); cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); } @@ -2146,8 +2143,7 @@ fn add_library_search_dirs( || sess.target.os == "fuchsia" || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty() { - let lib_path = sess.target_filesearch(PathKind::Native).get_lib_path(); - cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); + cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir)); } // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks @@ -2859,15 +2855,14 @@ fn add_upstream_native_libraries( // // The returned path will always have `fix_windows_verbatim_for_gcc()` applied to it. fn rehome_sysroot_lib_dir(sess: &Session, lib_dir: &Path) -> PathBuf { - let sysroot_lib_path = sess.target_filesearch(PathKind::All).get_lib_path(); + let sysroot_lib_path = &sess.target_tlib_path.dir; let canonical_sysroot_lib_path = - { try_canonicalize(&sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) }; + { try_canonicalize(sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) }; let canonical_lib_dir = try_canonicalize(lib_dir).unwrap_or_else(|_| lib_dir.to_path_buf()); if canonical_lib_dir == canonical_sysroot_lib_path { - // This path, returned by `target_filesearch().get_lib_path()`, has - // already had `fix_windows_verbatim_for_gcc()` applied if needed. - sysroot_lib_path + // This path already had `fix_windows_verbatim_for_gcc()` applied if needed. + sysroot_lib_path.clone() } else { fix_windows_verbatim_for_gcc(lib_dir) } diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 63ca5fefd9faf..d78f4a78de732 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -5,14 +5,11 @@ use std::{env, fs}; use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use smallvec::{smallvec, SmallVec}; -use tracing::debug; use crate::search_paths::{PathKind, SearchPath}; #[derive(Clone)] pub struct FileSearch<'a> { - sysroot: &'a Path, - triple: &'a str, cli_search_paths: &'a [SearchPath], tlib_path: &'a SearchPath, kind: PathKind, @@ -32,23 +29,12 @@ impl<'a> FileSearch<'a> { .chain(std::iter::once(self.tlib_path)) } - pub fn get_lib_path(&self) -> PathBuf { - make_target_lib_path(self.sysroot, self.triple) - } - - pub fn get_self_contained_lib_path(&self) -> PathBuf { - self.get_lib_path().join("self-contained") - } - pub fn new( - sysroot: &'a Path, - triple: &'a str, cli_search_paths: &'a [SearchPath], tlib_path: &'a SearchPath, kind: PathKind, ) -> FileSearch<'a> { - debug!("using sysroot = {}, triple = {}", sysroot.display(), triple); - FileSearch { sysroot, triple, cli_search_paths, tlib_path, kind } + FileSearch { cli_search_paths, tlib_path, kind } } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 693867c3853da..b073950a750b4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -439,22 +439,10 @@ impl Session { } pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { - filesearch::FileSearch::new( - &self.sysroot, - self.opts.target_triple.triple(), - &self.opts.search_paths, - &self.target_tlib_path, - kind, - ) + filesearch::FileSearch::new(&self.opts.search_paths, &self.target_tlib_path, kind) } pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { - filesearch::FileSearch::new( - &self.sysroot, - config::host_triple(), - &self.opts.search_paths, - &self.host_tlib_path, - kind, - ) + filesearch::FileSearch::new(&self.opts.search_paths, &self.host_tlib_path, kind) } /// Returns a list of directories where target-specific tool binaries are located. Some fallback From 988bc1c654a1319a7b6fb198184459d503b249be Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 22 Aug 2024 14:25:54 -0400 Subject: [PATCH 033/102] fix typos in new pointer conversion docs --- library/core/src/ptr/const_ptr.rs | 2 +- library/core/src/ptr/mod.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 8 ++++---- library/core/src/ptr/non_null.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8b9f7b57d0053..d7eea937ef847 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -239,7 +239,7 @@ impl *const T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index b2fb365d22745..a7d6602287b90 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -87,7 +87,7 @@ //! even if they only modify `UnsafeCell` data. //! //! If a pointer follows all of these rules, it is said to be -//! *convertable to a reference*. +//! *convertible to a reference*. // ^ we use this term instead of saying that the produced reference must // be valid, as the validity of a reference is easily confused for the // validity of the thing it refers to, and while the two concepts are diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fb393ffadd5cd..d7bb18590ed5e 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -247,7 +247,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -296,7 +296,7 @@ impl *mut T { /// /// # Safety /// - /// When calling this method, you have to ensure that the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion) + /// When calling this method, you have to ensure that the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) /// /// # Examples /// @@ -330,7 +330,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// Note that because the created reference is to `MaybeUninit`, the /// source pointer can point to uninitialized memory. /// @@ -566,7 +566,7 @@ impl *mut T { /// /// When calling this method, you have to ensure that *either* /// the pointer is null *or* - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// /// # Examples diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 1e1cf780c28f0..5d5d9d401a295 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -129,7 +129,7 @@ impl NonNull { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// Note that because the created reference is to `MaybeUninit`, the /// source pointer can point to uninitialized memory. #[inline] @@ -153,7 +153,7 @@ impl NonNull { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convirtible to a reference](crate::ptr#pointer-to-reference-conversion). + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// Note that because the created reference is to `MaybeUninit`, the /// source pointer can point to uninitialized memory. #[inline] From 2540070fd45defe48d02aa7af974c8f295b326a4 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Mon, 12 Aug 2024 22:52:59 +0000 Subject: [PATCH 034/102] document & impl the transmutation modeled by `BikeshedIntrinsicFrom` Documents that `BikeshedIntrinsicFrom` models transmute-via-union, which is slightly more expressive than the transmute-via-cast implemented by `transmute_copy`. Additionally, we provide an implementation of transmute-via-union as a method on the `BikeshedIntrinsicFrom` trait with additional documentation on the boundary between trait invariants and caller obligations. Whether or not transmute-via-union is the right kind of transmute to model remains up for discussion [1]. Regardless, it seems wise to document the present behavior. [1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20'kind'.20of.20transmute.20to.20model.3F/near/426331967 --- compiler/rustc_ty_utils/src/instance.rs | 5 + library/core/src/mem/transmutability.rs | 371 +++++++++++++++++- .../issue_72181_1.main.built.after.mir | 2 +- ...inhabited.LowerIntrinsics.panic-abort.diff | 2 +- ...nhabited.LowerIntrinsics.panic-unwind.diff | 2 +- ...e_ref_dst.LowerIntrinsics.panic-abort.diff | 2 +- ..._ref_dst.LowerIntrinsics.panic-unwind.diff | 2 +- ...inhabited.LowerIntrinsics.panic-abort.diff | 2 +- ...nhabited.LowerIntrinsics.panic-unwind.diff | 2 +- ...inhabited.LowerIntrinsics.panic-abort.diff | 2 +- ...nhabited.LowerIntrinsics.panic-unwind.diff | 2 +- ...inhabited.LowerIntrinsics.panic-abort.diff | 2 +- ...nhabited.LowerIntrinsics.panic-unwind.diff | 2 +- ...inhabited.LowerIntrinsics.panic-abort.diff | 2 +- ...nhabited.LowerIntrinsics.panic-unwind.diff | 2 +- .../closures/coerce-unsafe-to-closure.stderr | 4 +- tests/ui/intrinsics/reify-intrinsic.stderr | 4 +- 17 files changed, 372 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index c7ed6e6110fab..d77c3a277bfe8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -363,6 +363,11 @@ fn resolve_associated_item<'tcx>( tcx.item_name(trait_item_id) ), } + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::TransmuteTrait) { + let name = tcx.item_name(trait_item_id); + assert_eq!(name, sym::transmute); + let args = tcx.erase_regions(rcvr_args); + Some(ty::Instance::new(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index ea73c5b80ba44..62d454a5289b1 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -1,10 +1,88 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy}; -/// Are values of a type transmutable into values of another type? +/// Marks that `Src` is transmutable into `Self`. /// -/// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of -/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`, -/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied. +/// # Implementation +/// +/// This trait cannot be implemented explicitly. It is implemented on-the-fly by +/// the compiler for all types `Src` and `Self` such that, given a set of safety +/// obligations on the programmer (see [`Assume`]), the compiler has proved that +/// the bits of a value of type `Src` can be soundly reinterpreted as a `Self`. +/// +/// # Safety +/// +/// If `Dst: BikeshedIntrinsicFrom`, the compiler guarantees +/// that `Src` is soundly *union-transmutable* into a value of type `Dst`, +/// provided that the programmer has guaranteed that the given +/// [`ASSUMPTIONS`](Assume) are satisfied. +/// +/// A union-transmute is any bit-reinterpretation conversion in the form of: +/// +/// ```rust +/// pub unsafe fn transmute_via_union(src: Src) -> Dst { +/// use core::mem::ManuallyDrop; +/// +/// #[repr(C)] +/// union Transmute { +/// src: ManuallyDrop, +/// dst: ManuallyDrop, +/// } +/// +/// let transmute = Transmute { +/// src: ManuallyDrop::new(src), +/// }; +/// +/// let dst = transmute.dst; +/// +/// ManuallyDrop::into_inner(dst) +/// } +/// ``` +/// +/// Note that this construction is more permissive than +/// [`mem::transmute_copy`](super::transmute_copy); union-transmutes permit +/// conversions that extend the bits of `Src` with trailing padding to fill +/// trailing uninitialized bytes of `Self`; e.g.: +/// +#[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] +#[cfg_attr(not(bootstrap), doc = "```rust")] +/// #![feature(transmutability)] +/// +/// use core::mem::{Assume, BikeshedIntrinsicFrom}; +/// +/// let src = 42u8; // size = 1 +/// +/// #[repr(C, align(2))] +/// struct Dst(u8); // size = 2 +// +/// let _ = unsafe { +/// >::transmute(src) +/// }; +/// ``` +/// +/// # Caveats +/// +/// ## Portability +/// +/// Implementations of this trait do not provide any guarantee of portability +/// across toolchains, targets or compilations. This trait may be implemented +/// for certain combinations of `Src`, `Self` and `ASSUME` on some toolchains, +/// targets or compilations, but not others. For example, if the layouts of +/// `Src` or `Self` are non-deterministic, the presence or absence of an +/// implementation of this trait may also be non-deterministic. Even if `Src` +/// and `Self` have deterministic layouts (e.g., they are `repr(C)` structs), +/// Rust does not specify the alignments of its primitive integer types, and +/// layouts that involve these types may vary across toolchains, targets or +/// compilations. +/// +/// ## Stability +/// +/// Implementations of this trait do not provide any guarantee of SemVer +/// stability across the crate versions that define the `Src` and `Self` types. +/// If SemVer stability is crucial to your application, you must consult the +/// documentation of `Src` and `Self`s' defining crates. Note that the presence +/// of `repr(C)`, alone, does not carry a safety invariant of SemVer stability. +/// Furthermore, stability does not imply portability. For example, the size of +/// `usize` is stable, but not portable. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_trait"] #[rustc_deny_explicit_impl(implement_via_object = false)] @@ -13,28 +91,207 @@ pub unsafe trait BikeshedIntrinsicFrom Self + where + Src: Sized, + Self: Sized, + { + use super::ManuallyDrop; + + #[repr(C)] + union Transmute { + src: ManuallyDrop, + dst: ManuallyDrop, + } + + let transmute = Transmute { src: ManuallyDrop::new(src) }; + + // SAFETY: It is safe to reinterpret the bits of `src` as a value of + // type `Self`, because, by combination of invariant on this trait and + // contract on the caller, `src` has been proven to satisfy both the + // language and library invariants of `Self`. For all invariants not + // `ASSUME`'d by the caller, the safety obligation is supplied by the + // compiler. Conversely, for all invariants `ASSUME`'d by the caller, + // the safety obligation is supplied by contract on the caller. + let dst = unsafe { transmute.dst }; + + ManuallyDrop::into_inner(dst) + } } -/// What transmutation safety conditions shall the compiler assume that *you* are checking? +/// Configurable proof assumptions of [`BikeshedIntrinsicFrom`]. +/// +/// When `false`, the respective proof obligation belongs to the compiler. When +/// `true`, the onus of the safety proof belongs to the programmer. +/// [`BikeshedIntrinsicFrom`]. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_opts"] #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct Assume { - /// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that - /// destination referents do not have stricter alignment requirements than source referents. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the the alignment requirements of + /// references; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::{align_of, BikeshedIntrinsicFrom}; + /// + /// assert_eq!(align_of::<[u8; 2]>(), 1); + /// assert_eq!(align_of::(), 2); + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// // SAFETY: No safety obligations. + /// let dst: &u16 = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that references in the transmuted value satisfy the alignment + /// requirements of their referent types; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(pointer_is_aligned_to, transmutability)] + /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom}; + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::()) { + /// // SAFETY: We have checked above that the address of `src` satisfies the + /// // alignment requirements of `u16`. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::ALIGNMENT }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert!(matches!(maybe_dst, Some(&u16::MAX) | None)); + /// ``` pub alignment: bool, - /// When `true`, the compiler assume that *you* are ensuring that lifetimes are not extended in a manner - /// that violates Rust's memory model. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that extend the lifetimes of references. + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that references in the transmuted value do not outlive their referents. pub lifetimes: bool, - /// When `true`, the compiler assumes that *you* have ensured that no - /// unsoundness will arise from violating the safety invariants of the - /// destination type (and sometimes of the source type, too). + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the library safety invariants of the + /// destination type; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::BikeshedIntrinsicFrom; + /// + /// let src: u8 = 3; + /// + /// struct EvenU8 { + /// // SAFETY: `val` must be an even number. + /// val: u8, + /// } + /// + /// // SAFETY: No safety obligations. + /// let dst: EvenU8 = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that undefined behavior does not arise from using the transmuted value; + /// e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::{Assume, BikeshedIntrinsicFrom}; + /// + /// let src: u8 = 42; + /// + /// struct EvenU8 { + /// // SAFETY: `val` must be an even number. + /// val: u8, + /// } + /// + /// let maybe_dst: Option = if src % 2 == 0 { + /// // SAFETY: We have checked above that the value of `src` is even. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::SAFETY }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert!(matches!(maybe_dst, Some(EvenU8 { val: 42 }))); + /// ``` pub safety: bool, - /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid - /// instance of the destination type. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the language-level bit-validity + /// invariant of the destination type; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::BikeshedIntrinsicFrom; + /// + /// let src: u8 = 3; + /// + /// // SAFETY: No safety obligations. + /// let dst: bool = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that the value being transmuted is a bit-valid instance of the + /// transmuted value; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::{Assume, BikeshedIntrinsicFrom}; + /// + /// let src: u8 = 1; + /// + /// let maybe_dst: Option = if src == 0 || src == 1 { + /// // SAFETY: We have checked above that the value of `src` is a bit-valid + /// // instance of `bool`. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::VALIDITY }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert_eq!(maybe_dst, Some(true)); + /// ``` pub validity: bool, } @@ -44,29 +301,87 @@ impl ConstParamTy_ for Assume {} impl UnsizedConstParamTy for Assume {} impl Assume { - /// Do not assume that *you* have ensured any safety properties are met. + /// With this, [`BikeshedIntrinsicFrom`] does not assume you have ensured + /// any safety obligations are met, and relies only upon its own analysis to + /// (dis)prove transmutability. #[unstable(feature = "transmutability", issue = "99571")] pub const NOTHING: Self = Self { alignment: false, lifetimes: false, safety: false, validity: false }; - /// Assume only that alignment conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that references in the transmuted value satisfy the alignment + /// requirements of their referent types. See [`Assume::alignment`] for + /// examples. #[unstable(feature = "transmutability", issue = "99571")] pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING }; - /// Assume only that lifetime conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that references in the transmuted value do not outlive their referents. + /// See [`Assume::lifetimes`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING }; - /// Assume only that safety conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that undefined behavior does not arise from using the transmuted value. + /// See [`Assume::safety`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING }; - /// Assume only that dynamically-satisfiable validity conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that the value being transmuted is a bit-valid instance of the + /// transmuted value. See [`Assume::validity`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING }; - /// Assume both `self` and `other_assumptions`. + /// Combine the assumptions of `self` and `other_assumptions`. + /// + /// This is especially useful for extending [`Assume`] in generic contexts; + /// e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] #[unstable(feature = "transmutability", issue = "99571")] + /// #![feature( + /// adt_const_params, + /// generic_const_exprs, + /// pointer_is_aligned_to, + /// transmutability, + /// )] + /// #![allow(incomplete_features)] + /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom}; + /// + /// /// Attempts to transmute `src` to `&Dst`. + /// /// + /// /// Returns `None` if `src` violates the alignment requirements of `&Dst`. + /// /// + /// /// # Safety + /// /// + /// /// The caller guarantees that the obligations required by `ASSUME`, except + /// /// alignment, are satisfied. + /// unsafe fn try_transmute_ref<'a, Src, Dst, const ASSUME: Assume>(src: &'a Src) -> Option<&'a Dst> + /// where + /// &'a Dst: BikeshedIntrinsicFrom<&'a Src, { ASSUME.and(Assume::ALIGNMENT) }>, + /// { + /// if <*const _>::is_aligned_to(src, align_of::()) { + /// // SAFETY: By the above dynamic check, we have ensured that the address + /// // of `src` satisfies the alignment requirements of `&Dst`. By contract + /// // on the caller, the safety obligations required by `ASSUME` have also + /// // been satisfied. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { ASSUME.and(Assume::ALIGNMENT) }>>::transmute(src) + /// }) + /// } else { + /// None + /// } + /// } + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// // SAFETY: No safety obligations. + /// let maybe_dst: Option<&u16> = unsafe { + /// try_transmute_ref::<_, _, { Assume::NOTHING }>(src) + /// }; + ///``` pub const fn and(self, other_assumptions: Self) -> Self { Self { alignment: self.alignment || other_assumptions.alignment, @@ -76,7 +391,21 @@ impl Assume { } } - /// Assume `self`, excepting `other_assumptions`. + /// Remove `other_assumptions` the obligations of `self`; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::Assume; + /// + /// let assumptions = Assume::ALIGNMENT.and(Assume::SAFETY); + /// let to_be_removed = Assume::SAFETY.and(Assume::VALIDITY); + /// + /// assert_eq!( + /// assumptions.but_not(to_be_removed), + /// Assume::ALIGNMENT, + /// ); + /// ``` #[unstable(feature = "transmutability", issue = "99571")] pub const fn but_not(self, other_assumptions: Self) -> Self { Self { diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir index e8ad5cd8d16a8..293aa37944dd2 100644 --- a/tests/mir-opt/issue_72181_1.main.built.after.mir +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -19,7 +19,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); _3 = (); - _2 = transmute::<(), Void>(move _3) -> bb4; + _2 = std::intrinsics::transmute::<(), Void>(move _3) -> bb4; } bb1: { diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff index 71e84fdd8816e..b1104c70e4696 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as i8 (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff index 71e84fdd8816e..b1104c70e4696 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as i8 (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff index 37232b826c129..169e48a31ddb9 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as *const T (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff index 37232b826c129..169e48a31ddb9 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as *const T (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff index 8ac70f99ad2f0..7098b4d316882 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as std::boxed::Box (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff index 8ac70f99ad2f0..7098b4d316882 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as std::boxed::Box (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff index c2c4ec0003c26..06225fffd7c2d 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &mut Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff index c2c4ec0003c26..06225fffd7c2d 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &mut Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff index 1b516a1f53b39..dd6ab3a9c97e5 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff index 1b516a1f53b39..dd6ab3a9c97e5 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff index eab969e9fe5bb..6571f3d9db81a 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<(), Never>(move _2) -> unwind unreachable; +- _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable; + _0 = move _2 as Never (Transmute); + unreachable; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff index eab969e9fe5bb..6571f3d9db81a 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<(), Never>(move _2) -> unwind unreachable; +- _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable; + _0 = move _2 as Never (Transmute); + unreachable; } diff --git a/tests/ui/closures/coerce-unsafe-to-closure.stderr b/tests/ui/closures/coerce-unsafe-to-closure.stderr index cb718ca160f8b..2538fc0361c37 100644 --- a/tests/ui/closures/coerce-unsafe-to-closure.stderr +++ b/tests/ui/closures/coerce-unsafe-to-closure.stderr @@ -1,4 +1,4 @@ -error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` +error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` --> $DIR/coerce-unsafe-to-closure.rs:2:44 | LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); @@ -6,7 +6,7 @@ LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); | | | required by a bound introduced by this call | - = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` + = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr index 0119a1a6650d0..21b7bf4e1cb83 100644 --- a/tests/ui/intrinsics/reify-intrinsic.stderr +++ b/tests/ui/intrinsics/reify-intrinsic.stderr @@ -7,9 +7,9 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr | expected due to this | = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize` - found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` + found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` -error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid +error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid --> $DIR/reify-intrinsic.rs:11:13 | LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize; From 681a866067610390f76e493e10f805d84a5ff459 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Fri, 23 Aug 2024 16:09:56 -0700 Subject: [PATCH 035/102] Add Trusty OS as tier 3 target --- compiler/rustc_target/src/spec/mod.rs | 3 ++ .../spec/targets/aarch64_unknown_trusty.rs | 34 ++++++++++++ .../src/spec/targets/armv7_unknown_trusty.rs | 37 +++++++++++++ src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 + src/doc/rustc/src/platform-support/trusty.md | 53 +++++++++++++++++++ tests/assembly/targets/targets-elf.rs | 6 +++ tests/ui/check-cfg/well-known-values.stderr | 4 +- 8 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs create mode 100644 compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs create mode 100644 src/doc/rustc/src/platform-support/trusty.md diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 80f89a0ab2be0..d5f227a84a4ca 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1750,6 +1750,9 @@ supported_targets! { ("x86_64-unikraft-linux-musl", x86_64_unikraft_linux_musl), + ("armv7-unknown-trusty", armv7_unknown_trusty), + ("aarch64-unknown-trusty", aarch64_unknown_trusty), + ("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf), ("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf), ("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs new file mode 100644 index 0000000000000..1525faf9b7e1d --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs @@ -0,0 +1,34 @@ +// Trusty OS target for AArch64. + +use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "aarch64-unknown-unknown-musl".into(), + metadata: crate::spec::TargetMetadata { + description: Some("ARM64 Trusty".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+neon,+fp-armv8,+reserve-x18".into(), + executables: true, + max_atomic_width: Some(128), + panic_strategy: PanicStrategy::Abort, + os: "trusty".into(), + position_independent_executables: true, + static_position_independent_executables: true, + crt_static_default: true, + crt_static_respected: true, + dynamic_linking: false, + link_self_contained: LinkSelfContainedDefault::InferredForMusl, + relro_level: RelroLevel::Full, + mcount: "\u{1}_mcount".into(), + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs new file mode 100644 index 0000000000000..11784788651ee --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs @@ -0,0 +1,37 @@ +use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it + // to determine the calling convention and float ABI, and it doesn't + // support the "musleabi" value. + llvm_target: "armv7-unknown-unknown-gnueabi".into(), + metadata: crate::spec::TargetMetadata { + description: Some("Armv7-A Trusty".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: "arm".into(), + options: TargetOptions { + abi: "eabi".into(), + features: "+v7,+thumb2,+soft-float,-neon,+reserve-x18".into(), + max_atomic_width: Some(64), + mcount: "\u{1}mcount".into(), + os: "trusty".into(), + link_self_contained: LinkSelfContainedDefault::InferredForMusl, + dynamic_linking: false, + executables: true, + crt_static_default: true, + crt_static_respected: true, + relro_level: RelroLevel::Full, + panic_strategy: PanicStrategy::Abort, + position_independent_executables: true, + static_position_independent_executables: true, + + ..Default::default() + }, + } +} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 4e34e2667cfc0..b3a74a7716bb3 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -49,6 +49,7 @@ - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md) - [\*-espidf](platform-support/esp-idf.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) + - [\*-unknown-trusty](platform-support/trusty.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index dd478e9df379e..0d79e5f4114e3 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -264,6 +264,7 @@ target | std | host | notes [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS +[`aarch64-unknown-trusty`](platform-support/trusty.md) | ? | | `aarch64-uwp-windows-msvc` | ✓ | | [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) @@ -283,6 +284,7 @@ target | std | host | notes [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float +[`armv7-unknown-trusty`](platform-support/trusty.md) | ? | | [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md new file mode 100644 index 0000000000000..97a03d3de04c2 --- /dev/null +++ b/src/doc/rustc/src/platform-support/trusty.md @@ -0,0 +1,53 @@ +# `aarch64-unknown-trusty` and `armv7-unknown-trusty` + +**Tier: 3** + +[Trusty] is a secure Operating System that provides a Trusted Execution +Environment (TEE) for Android. + +## Target maintainers + +- Nicole LeGare (@randomPoison) +- Stephen Crane (@rinon) +- As a fallback trusty-dev-team@google.com can be contacted + +## Requirements + +This target is cross-compiled. It has no special requirements for the host. + +It fully supports alloc with the default allocator, and partially supports std. +Notably, most I/O functionality is not supported, e.g. filesystem support and +networking support are not present and any APIs that rely on them will panic at +runtime. + +Trusty uses the ELF file format. + +## Building the target + +The targets can be built by enabling them for a `rustc` build, for example: + +```toml +[build] +build-stage = 1 +target = ["aarch64-unknown-trusty", "armv7-unknown-trusty"] +``` + +## Building Rust programs + +There is currently no supported way to build a Trusty app with Cargo. You can +follow the [Trusty build instructions] to build the Trusty kernel along with any +Rust apps that are setup in the project. + +## Testing + +See the [Trusty build instructions] for information on how to build Rust code +within the main Trusty project. The main project also includes infrastructure +for testing Rust applications within a QEMU emulator. + +## Cross-compilation toolchains and C code + +See the [Trusty build instructions] for information on how C code is built +within Trusty. + +[Trusty]: https://source.android.com/docs/security/features/trusty +[Trusty build instructions]: https://source.android.com/docs/security/features/trusty/download-and-build diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index c3a083321e229..6f0a200a08cf3 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -66,6 +66,9 @@ //@ revisions: aarch64_unknown_teeos //@ [aarch64_unknown_teeos] compile-flags: --target aarch64-unknown-teeos //@ [aarch64_unknown_teeos] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_trusty +//@ [aarch64_unknown_trusty] compile-flags: --target aarch64-unknown-trusty +//@ [aarch64_unknown_trusty] needs-llvm-components: aarch64 //@ revisions: aarch64_wrs_vxworks //@ [aarch64_wrs_vxworks] compile-flags: --target aarch64-wrs-vxworks //@ [aarch64_wrs_vxworks] needs-llvm-components: aarch64 @@ -153,6 +156,9 @@ //@ revisions: armv7_unknown_netbsd_eabihf //@ [armv7_unknown_netbsd_eabihf] compile-flags: --target armv7-unknown-netbsd-eabihf //@ [armv7_unknown_netbsd_eabihf] needs-llvm-components: arm +//@ revisions: armv7_unknown_trusty +//@ [armv7_unknown_trusty] compile-flags: --target armv7-unknown-trusty +//@ [armv7_unknown_trusty] needs-llvm-components: arm //@ revisions: armv7_wrs_vxworks_eabihf //@ [armv7_wrs_vxworks_eabihf] compile-flags: --target armv7-wrs-vxworks-eabihf //@ [armv7_wrs_vxworks_eabihf] needs-llvm-components: arm diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index d780e04e729a2..103a7564a0f87 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -285,7 +285,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 29 warnings emitted From 1ed9ee7b035553dc8e719e959e1f3d03d5678a00 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Fri, 23 Aug 2024 16:26:20 -0700 Subject: [PATCH 036/102] Remove `reserve-x18` from armv7-unknown-trusty --- compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs index 11784788651ee..ae73de5e64dc5 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs @@ -17,7 +17,7 @@ pub fn target() -> Target { arch: "arm".into(), options: TargetOptions { abi: "eabi".into(), - features: "+v7,+thumb2,+soft-float,-neon,+reserve-x18".into(), + features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64), mcount: "\u{1}mcount".into(), os: "trusty".into(), From 53435501420733c79231653763c69c3bd2f8710f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 24 Aug 2024 17:14:31 +0200 Subject: [PATCH 037/102] const checking: properly compute the set of transient locals --- .../src/check_consts/check.rs | 62 ++++++++++++++----- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 86a5afa65ba87..d7594c9ae75f6 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -1,6 +1,7 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. use std::assert_matches::assert_matches; +use std::borrow::Cow; use std::mem; use std::ops::Deref; @@ -15,7 +16,9 @@ use rustc_middle::mir::*; use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt}; -use rustc_mir_dataflow::Analysis; +use rustc_mir_dataflow::impls::MaybeStorageLive; +use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; @@ -188,8 +191,9 @@ pub struct Checker<'mir, 'tcx> { /// The span of the current statement. span: Span, - /// A set that stores for each local whether it has a `StorageDead` for it somewhere. - local_has_storage_dead: Option>, + /// A set that stores for each local whether it is "transient", i.e. guaranteed to be dead + /// when this MIR body returns. + transient_locals: Option>, error_emitted: Option, secondary_errors: Vec>, @@ -209,7 +213,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { span: ccx.body.span, ccx, qualifs: Default::default(), - local_has_storage_dead: None, + transient_locals: None, error_emitted: None, secondary_errors: Vec::new(), } @@ -264,23 +268,47 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { } } - fn local_has_storage_dead(&mut self, local: Local) -> bool { + fn local_is_transient(&mut self, local: Local) -> bool { let ccx = self.ccx; - self.local_has_storage_dead + self.transient_locals .get_or_insert_with(|| { - struct StorageDeads { - locals: BitSet, + // A local is "transient" if it is guaranteed dead at all `Return`. + // So first compute the say of "maybe live" locals at each program point. + let always_live_locals = &always_storage_live_locals(&ccx.body); + let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals)) + .into_engine(ccx.tcx, &ccx.body) + .iterate_to_fixpoint() + .into_results_cursor(&ccx.body); + + // And then check all `Return` in the MIR, and if a local is "maybe live" at a + // `Return` then it is definitely not transient. + struct TransientLocalVisitor<'a, 'tcx> { + maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>, + transient: BitSet, } - impl<'tcx> Visitor<'tcx> for StorageDeads { - fn visit_statement(&mut self, stmt: &Statement<'tcx>, _: Location) { - if let StatementKind::StorageDead(l) = stmt.kind { - self.locals.insert(l); + impl<'a, 'tcx> Visitor<'tcx> for TransientLocalVisitor<'a, 'tcx> { + fn visit_terminator( + &mut self, + terminator: &Terminator<'tcx>, + location: Location, + ) { + if matches!(terminator.kind, TerminatorKind::Return) { + self.maybe_storage_live.seek_after_primary_effect(location); + for local in self.maybe_storage_live.get().iter() { + // If a local may be live here, it is definitely not transient. + self.transient.remove(local); + } } } } - let mut v = StorageDeads { locals: BitSet::new_empty(ccx.body.local_decls.len()) }; - v.visit_body(ccx.body); - v.locals + + let mut v = TransientLocalVisitor { + maybe_storage_live, + transient: BitSet::new_filled(ccx.body.local_decls.len()), + }; + v.visit_body(&ccx.body); + + v.transient }) .contains(local) } @@ -375,7 +403,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // `StorageDead` in every control flow path leading to a `return` terminator. // The good news is that interning will detect if any unexpected mutable // pointer slips through. - if place.is_indirect() || self.local_has_storage_dead(place.local) { + if place.is_indirect() || self.local_is_transient(place.local) { self.check_op(ops::TransientMutBorrow(kind)); } else { self.check_op(ops::MutBorrow(kind)); @@ -526,7 +554,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // `StorageDead` in every control flow path leading to a `return` terminator. // The good news is that interning will detect if any unexpected mutable // pointer slips through. - if self.local_has_storage_dead(place.local) { + if self.local_is_transient(place.local) { self.check_op(ops::TransientCellBorrow); } else { self.check_op(ops::CellBorrow); From bb17fda3845bda0da7bcdcf28cd17e4823e58c9d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 3 Jul 2024 07:01:50 +0000 Subject: [PATCH 038/102] Do not call source_span when not tracking dependencies. --- compiler/rustc_interface/src/callbacks.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 786e2bb511ffd..f66b9eb3a2856 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -18,11 +18,19 @@ use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug; use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode}; fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { - tls::with_opt(|tcx| { - if let Some(tcx) = tcx { - let _span = tcx.source_span(def_id); - // Sanity check: relative span's parent must be an absolute span. - debug_assert_eq!(_span.data_untracked().parent, None); + tls::with_context_opt(|icx| { + if let Some(icx) = icx { + // `track_span_parent` gets called a lot from HIR lowering code. + // Skip doing anything if we aren't tracking dependencies. + let tracks_deps = match icx.task_deps { + TaskDepsRef::Allow(..) => true, + TaskDepsRef::EvalAlways | TaskDepsRef::Ignore | TaskDepsRef::Forbid => false, + }; + if tracks_deps { + let _span = icx.tcx.source_span(def_id); + // Sanity check: relative span's parent must be an absolute span. + debug_assert_eq!(_span.data_untracked().parent, None); + } } }) } From ec67cdf98ac081e1392a324ec47a0543743f697e Mon Sep 17 00:00:00 2001 From: "rongfu.leng" Date: Thu, 27 Jun 2024 22:54:14 +0800 Subject: [PATCH 039/102] Enable f16 in assembly on aarch64 platforms that support it Signed-off-by: rongfu.leng --- compiler/rustc_target/src/asm/aarch64.rs | 6 ++--- tests/assembly/asm/aarch64-types.rs | 29 +++++++++++++++++++++++- tests/ui/asm/aarch64/type-check-3.stderr | 6 ++--- tests/ui/asm/aarch64/type-f16.rs | 21 +++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 tests/ui/asm/aarch64/type-f16.rs diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 358efb4174df0..041582b7df97d 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -59,11 +59,11 @@ impl AArch64InlineAsmRegClass { _arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option)] { match self { - Self::reg => types! { _: I8, I16, I32, I64, F32, F64; }, + Self::reg => types! { _: I8, I16, I32, I64, F16, F32, F64; }, Self::vreg | Self::vreg_low16 => types! { - neon: I8, I16, I32, I64, F32, F64, + neon: I8, I16, I32, I64, F16, F32, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1), - VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(4),VecF16(8), VecF32(4), VecF64(2); }, Self::preg => &[], } diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs index 3e2a4773703a3..4b506f180d83e 100644 --- a/tests/assembly/asm/aarch64-types.rs +++ b/tests/assembly/asm/aarch64-types.rs @@ -5,7 +5,7 @@ //@ [arm64ec] compile-flags: --target arm64ec-pc-windows-msvc //@ [arm64ec] needs-llvm-components: aarch64 -#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)] +#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16)] #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] @@ -39,6 +39,10 @@ pub struct i32x2(i32, i32); #[repr(simd)] pub struct i64x1(i64); #[repr(simd)] +pub struct f16x4(f16, f16, f16, f16); +#[repr(simd)] +pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16); +#[repr(simd)] pub struct f32x2(f32, f32); #[repr(simd)] pub struct f64x1(f64); @@ -57,6 +61,7 @@ pub struct f64x2(f64, f64); impl Copy for i8 {} impl Copy for i16 {} +impl Copy for f16 {} impl Copy for i32 {} impl Copy for f32 {} impl Copy for i64 {} @@ -67,11 +72,13 @@ impl Copy for i16x4 {} impl Copy for i32x2 {} impl Copy for i64x1 {} impl Copy for f32x2 {} +impl Copy for f16x4 {} impl Copy for f64x1 {} impl Copy for i8x16 {} impl Copy for i16x8 {} impl Copy for i32x4 {} impl Copy for i64x2 {} +impl Copy for f16x8 {} impl Copy for f32x4 {} impl Copy for f64x2 {} @@ -165,6 +172,12 @@ check!(reg_i16 i16 reg "mov" ""); // CHECK: //NO_APP check!(reg_i32 i32 reg "mov" ""); +// CHECK-LABEL: reg_f16: +// CHECK: @APP +// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} +// CHECK: @NO_APP +check!(reg_f16 f16 reg "mov"); + // CHECK-LABEL: {{("#)?}}reg_f32{{"?}} // CHECK: //APP // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} @@ -255,6 +268,20 @@ check!(vreg_i32x2 i32x2 vreg "fmov" "s"); // CHECK: //NO_APP check!(vreg_i64x1 i64x1 vreg "fmov" "s"); +// neon-LABEL: vreg_f16x4: +// neon: @APP +// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}} +// neon: @NO_APP +#[cfg(neon)] +check!(vreg_f16x4 f16x4 vreg "vmov.f64"); + +// neon-LABEL: vreg_f16x8: +// neon: @APP +// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}} +// neon: @NO_APP +#[cfg(neon)] +check!(vreg_f16x8 f16x8 vreg "vmov"); + // CHECK-LABEL: {{("#)?}}vreg_f32x2{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} diff --git a/tests/ui/asm/aarch64/type-check-3.stderr b/tests/ui/asm/aarch64/type-check-3.stderr index 9e37bb4c203f5..4bd97b93867bb 100644 --- a/tests/ui/asm/aarch64/type-check-3.stderr +++ b/tests/ui/asm/aarch64/type-check-3.stderr @@ -95,7 +95,7 @@ error: type `i128` cannot be used with this register class LL | asm!("{}", in(reg) 0i128); | ^^^^^ | - = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64 + = note: register class `reg` supports these types: i8, i16, i32, i64, f16, f32, f64 error: type `float64x2_t` cannot be used with this register class --> $DIR/type-check-3.rs:75:28 @@ -103,7 +103,7 @@ error: type `float64x2_t` cannot be used with this register class LL | asm!("{}", in(reg) f64x2); | ^^^^^ | - = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64 + = note: register class `reg` supports these types: i8, i16, i32, i64, f16, f32, f64 error: type `Simd256bit` cannot be used with this register class --> $DIR/type-check-3.rs:77:29 @@ -111,7 +111,7 @@ error: type `Simd256bit` cannot be used with this register class LL | asm!("{}", in(vreg) f64x4); | ^^^^^ | - = note: register class `vreg` supports these types: i8, i16, i32, i64, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i8, i16, i32, i64, f16, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f16x4, f16x8, f32x4, f64x2 error: incompatible types for asm inout argument --> $DIR/type-check-3.rs:88:33 diff --git a/tests/ui/asm/aarch64/type-f16.rs b/tests/ui/asm/aarch64/type-f16.rs new file mode 100644 index 0000000000000..763ea4684da37 --- /dev/null +++ b/tests/ui/asm/aarch64/type-f16.rs @@ -0,0 +1,21 @@ +//@ only-aarch64 +//@ run-pass + +#![feature(f16, f128)] +use std::arch::asm; +#[inline(never)] +pub fn f32_to_f16_asm(a: f32) -> f16 { + let ret: f16; + unsafe { + asm!( + "fcvt {ret:h}, {a:s}", + a = in(vreg) a, + ret = lateout(vreg) ret, + options(nomem, nostack), + ); + } + ret +} +fn main() { + assert_eq!(f32_to_f16_asm(1.0 as f32), 1.0); +} From abd44fc5f4211a0684da4b37a15c3d07b17a436e Mon Sep 17 00:00:00 2001 From: beetrees Date: Sun, 25 Aug 2024 00:13:25 +0100 Subject: [PATCH 040/102] Add `f16` and `f128` inline ASM support for `aarch64` --- compiler/rustc_codegen_llvm/src/asm.rs | 14 ++- compiler/rustc_target/src/asm/aarch64.rs | 6 +- tests/assembly/asm/aarch64-types.rs | 133 ++++++++++++++++++----- tests/ui/asm/aarch64/type-check-3.stderr | 2 +- tests/ui/asm/aarch64/type-f16.rs | 14 ++- 5 files changed, 130 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index f931698c38f91..1d91c3fb17ddc 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -913,8 +913,10 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty Primitive::Int(Integer::I16, _) => cx.type_i16(), Primitive::Int(Integer::I32, _) => cx.type_i32(), Primitive::Int(Integer::I64, _) => cx.type_i64(), + Primitive::Float(Float::F16) => cx.type_f16(), Primitive::Float(Float::F32) => cx.type_f32(), Primitive::Float(Float::F64) => cx.type_f64(), + Primitive::Float(Float::F128) => cx.type_f128(), // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()), _ => unreachable!(), @@ -948,7 +950,9 @@ fn llvm_fixup_input<'ll, 'tcx>( value } } - (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => { + (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) + if s.primitive() != Primitive::Float(Float::F128) => + { let elem_ty = llvm_asm_scalar_type(bx.cx, s); let count = 16 / layout.size.bytes(); let vec_ty = bx.cx.type_vector(elem_ty, count); @@ -1090,7 +1094,9 @@ fn llvm_fixup_output<'ll, 'tcx>( value } } - (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => { + (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) + if s.primitive() != Primitive::Float(Float::F128) => + { value = bx.extract_element(value, bx.const_i32(0)); if let Primitive::Pointer(_) = s.primitive() { value = bx.inttoptr(value, layout.llvm_type(bx.cx)); @@ -1222,7 +1228,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>( layout.llvm_type(cx) } } - (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => { + (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) + if s.primitive() != Primitive::Float(Float::F128) => + { let elem_ty = llvm_asm_scalar_type(cx, s); let count = 16 / layout.size.bytes(); cx.type_vector(elem_ty, count) diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 041582b7df97d..daf5162e8ac10 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -61,9 +61,9 @@ impl AArch64InlineAsmRegClass { match self { Self::reg => types! { _: I8, I16, I32, I64, F16, F32, F64; }, Self::vreg | Self::vreg_low16 => types! { - neon: I8, I16, I32, I64, F16, F32, F64, - VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1), - VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(4),VecF16(8), VecF32(4), VecF64(2); + neon: I8, I16, I32, I64, F16, F32, F64, F128, + VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1), + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); }, Self::preg => &[], } diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs index 4b506f180d83e..f36345670e329 100644 --- a/tests/assembly/asm/aarch64-types.rs +++ b/tests/assembly/asm/aarch64-types.rs @@ -5,10 +5,12 @@ //@ [arm64ec] compile-flags: --target arm64ec-pc-windows-msvc //@ [arm64ec] needs-llvm-components: aarch64 -#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16)] +#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16, f128)] #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] +// FIXME(f16_f128): Only needed for FIXME in check! and check_reg! +#![feature(auto_traits)] #[rustc_builtin_macro] macro_rules! asm { @@ -41,8 +43,6 @@ pub struct i64x1(i64); #[repr(simd)] pub struct f16x4(f16, f16, f16, f16); #[repr(simd)] -pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16); -#[repr(simd)] pub struct f32x2(f32, f32); #[repr(simd)] pub struct f64x1(f64); @@ -55,6 +55,8 @@ pub struct i32x4(i32, i32, i32, i32); #[repr(simd)] pub struct i64x2(i64, i64); #[repr(simd)] +pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16); +#[repr(simd)] pub struct f32x4(f32, f32, f32, f32); #[repr(simd)] pub struct f64x2(f64, f64); @@ -66,13 +68,14 @@ impl Copy for i32 {} impl Copy for f32 {} impl Copy for i64 {} impl Copy for f64 {} +impl Copy for f128 {} impl Copy for ptr {} impl Copy for i8x8 {} impl Copy for i16x4 {} impl Copy for i32x2 {} impl Copy for i64x1 {} -impl Copy for f32x2 {} impl Copy for f16x4 {} +impl Copy for f32x2 {} impl Copy for f64x1 {} impl Copy for i8x16 {} impl Copy for i16x8 {} @@ -82,6 +85,12 @@ impl Copy for f16x8 {} impl Copy for f32x4 {} impl Copy for f64x2 {} +// FIXME(f16_f128): Only needed for FIXME in check! and check_reg! +#[lang = "freeze"] +unsafe auto trait Freeze {} +#[lang = "unpin"] +auto trait Unpin {} + extern "C" { fn extern_func(); static extern_static: u8; @@ -118,38 +127,44 @@ pub unsafe fn issue_75761() { macro_rules! check { ($func:ident $ty:ident $class:ident $mov:literal $modifier:literal) => { + // FIXME(f16_f128): Change back to `$func(x: $ty) -> $ty` once arm64ec can pass and return + // `f16` and `f128` without LLVM erroring. + // LLVM issue: #[no_mangle] - pub unsafe fn $func(x: $ty) -> $ty { + pub unsafe fn $func(inp: &$ty, out: &mut $ty) { // Hack to avoid function merging extern "Rust" { fn dont_merge(s: &str); } dont_merge(stringify!($func)); + let x = *inp; let y; asm!( concat!($mov, " {:", $modifier, "}, {:", $modifier, "}"), out($class) y, in($class) x ); - y + *out = y; } }; } macro_rules! check_reg { ($func:ident $ty:ident $reg:tt $mov:literal) => { + // FIXME(f16_f128): See FIXME in `check!` #[no_mangle] - pub unsafe fn $func(x: $ty) -> $ty { + pub unsafe fn $func(inp: &$ty, out: &mut $ty) { // Hack to avoid function merging extern "Rust" { fn dont_merge(s: &str); } dont_merge(stringify!($func)); + let x = *inp; let y; asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); - y + *out = y; } }; } @@ -166,18 +181,18 @@ check!(reg_i8 i8 reg "mov" ""); // CHECK: //NO_APP check!(reg_i16 i16 reg "mov" ""); +// CHECK-LABEL: {{("#)?}}reg_f16{{"?}} +// CHECK: //APP +// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} +// CHECK: //NO_APP +check!(reg_f16 f16 reg "mov" ""); + // CHECK-LABEL: {{("#)?}}reg_i32{{"?}} // CHECK: //APP // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} // CHECK: //NO_APP check!(reg_i32 i32 reg "mov" ""); -// CHECK-LABEL: reg_f16: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_f16 f16 reg "mov"); - // CHECK-LABEL: {{("#)?}}reg_f32{{"?}} // CHECK: //APP // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} @@ -214,6 +229,12 @@ check!(vreg_i8 i8 vreg "fmov" "s"); // CHECK: //NO_APP check!(vreg_i16 i16 vreg "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_f16{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_f16 f16 vreg "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_i32{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -238,6 +259,12 @@ check!(vreg_i64 i64 vreg "fmov" "s"); // CHECK: //NO_APP check!(vreg_f64 f64 vreg "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_f128{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_f128 f128 vreg "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_ptr{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -268,19 +295,11 @@ check!(vreg_i32x2 i32x2 vreg "fmov" "s"); // CHECK: //NO_APP check!(vreg_i64x1 i64x1 vreg "fmov" "s"); -// neon-LABEL: vreg_f16x4: -// neon: @APP -// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}} -// neon: @NO_APP -#[cfg(neon)] -check!(vreg_f16x4 f16x4 vreg "vmov.f64"); - -// neon-LABEL: vreg_f16x8: -// neon: @APP -// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}} -// neon: @NO_APP -#[cfg(neon)] -check!(vreg_f16x8 f16x8 vreg "vmov"); +// CHECK-LABEL: {{("#)?}}vreg_f16x4{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_f16x4 f16x4 vreg "fmov" "s"); // CHECK-LABEL: {{("#)?}}vreg_f32x2{{"?}} // CHECK: //APP @@ -318,6 +337,12 @@ check!(vreg_i32x4 i32x4 vreg "fmov" "s"); // CHECK: //NO_APP check!(vreg_i64x2 i64x2 vreg "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_f16x8{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_f16x8 f16x8 vreg "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_f32x4{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -342,6 +367,12 @@ check!(vreg_low16_i8 i8 vreg_low16 "fmov" "s"); // CHECK: //NO_APP check!(vreg_low16_i16 i16 vreg_low16 "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_low16_f16{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_low16_f16 f16 vreg_low16 "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_low16_f32{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -360,6 +391,12 @@ check!(vreg_low16_i64 i64 vreg_low16 "fmov" "s"); // CHECK: //NO_APP check!(vreg_low16_f64 f64 vreg_low16 "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_low16_f128{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_low16_f128 f128 vreg_low16 "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_low16_ptr{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -390,6 +427,12 @@ check!(vreg_low16_i32x2 i32x2 vreg_low16 "fmov" "s"); // CHECK: //NO_APP check!(vreg_low16_i64x1 i64x1 vreg_low16 "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_low16_f16x4{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_low16_f16x4 f16x4 vreg_low16 "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_low16_f32x2{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -426,6 +469,12 @@ check!(vreg_low16_i32x4 i32x4 vreg_low16 "fmov" "s"); // CHECK: //NO_APP check!(vreg_low16_i64x2 i64x2 vreg_low16 "fmov" "s"); +// CHECK-LABEL: {{("#)?}}vreg_low16_f16x8{{"?}} +// CHECK: //APP +// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} +// CHECK: //NO_APP +check!(vreg_low16_f16x8 f16x8 vreg_low16 "fmov" "s"); + // CHECK-LABEL: {{("#)?}}vreg_low16_f32x4{{"?}} // CHECK: //APP // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}} @@ -450,6 +499,12 @@ check_reg!(x0_i8 i8 "x0" "mov"); // CHECK: //NO_APP check_reg!(x0_i16 i16 "x0" "mov"); +// CHECK-LABEL: {{("#)?}}x0_f16{{"?}} +// CHECK: //APP +// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} +// CHECK: //NO_APP +check_reg!(x0_f16 f16 "x0" "mov"); + // CHECK-LABEL: {{("#)?}}x0_i32{{"?}} // CHECK: //APP // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}} @@ -492,6 +547,12 @@ check_reg!(v0_i8 i8 "s0" "fmov"); // CHECK: //NO_APP check_reg!(v0_i16 i16 "s0" "fmov"); +// CHECK-LABEL: {{("#)?}}v0_f16{{"?}} +// CHECK: //APP +// CHECK: fmov s0, s0 +// CHECK: //NO_APP +check_reg!(v0_f16 f16 "s0" "fmov"); + // CHECK-LABEL: {{("#)?}}v0_i32{{"?}} // CHECK: //APP // CHECK: fmov s0, s0 @@ -516,6 +577,12 @@ check_reg!(v0_i64 i64 "s0" "fmov"); // CHECK: //NO_APP check_reg!(v0_f64 f64 "s0" "fmov"); +// CHECK-LABEL: {{("#)?}}v0_f128{{"?}} +// CHECK: //APP +// CHECK: fmov s0, s0 +// CHECK: //NO_APP +check_reg!(v0_f128 f128 "s0" "fmov"); + // CHECK-LABEL: {{("#)?}}v0_ptr{{"?}} // CHECK: //APP // CHECK: fmov s0, s0 @@ -546,6 +613,12 @@ check_reg!(v0_i32x2 i32x2 "s0" "fmov"); // CHECK: //NO_APP check_reg!(v0_i64x1 i64x1 "s0" "fmov"); +// CHECK-LABEL: {{("#)?}}v0_f16x4{{"?}} +// CHECK: //APP +// CHECK: fmov s0, s0 +// CHECK: //NO_APP +check_reg!(v0_f16x4 f16x4 "s0" "fmov"); + // CHECK-LABEL: {{("#)?}}v0_f32x2{{"?}} // CHECK: //APP // CHECK: fmov s0, s0 @@ -582,6 +655,12 @@ check_reg!(v0_i32x4 i32x4 "s0" "fmov"); // CHECK: //NO_APP check_reg!(v0_i64x2 i64x2 "s0" "fmov"); +// CHECK-LABEL: {{("#)?}}v0_f16x8{{"?}} +// CHECK: //APP +// CHECK: fmov s0, s0 +// CHECK: //NO_APP +check_reg!(v0_f16x8 f16x8 "s0" "fmov"); + // CHECK-LABEL: {{("#)?}}v0_f32x4{{"?}} // CHECK: //APP // CHECK: fmov s0, s0 diff --git a/tests/ui/asm/aarch64/type-check-3.stderr b/tests/ui/asm/aarch64/type-check-3.stderr index 4bd97b93867bb..9d84d2666b33c 100644 --- a/tests/ui/asm/aarch64/type-check-3.stderr +++ b/tests/ui/asm/aarch64/type-check-3.stderr @@ -111,7 +111,7 @@ error: type `Simd256bit` cannot be used with this register class LL | asm!("{}", in(vreg) f64x4); | ^^^^^ | - = note: register class `vreg` supports these types: i8, i16, i32, i64, f16, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f16x4, f16x8, f32x4, f64x2 + = note: register class `vreg` supports these types: i8, i16, i32, i64, f16, f32, f64, f128, i8x8, i16x4, i32x2, i64x1, f16x4, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: incompatible types for asm inout argument --> $DIR/type-check-3.rs:88:33 diff --git a/tests/ui/asm/aarch64/type-f16.rs b/tests/ui/asm/aarch64/type-f16.rs index 763ea4684da37..e62d8130c933d 100644 --- a/tests/ui/asm/aarch64/type-f16.rs +++ b/tests/ui/asm/aarch64/type-f16.rs @@ -1,21 +1,25 @@ //@ only-aarch64 //@ run-pass +//@ needs-asm-support + +#![feature(f16)] -#![feature(f16, f128)] use std::arch::asm; + #[inline(never)] pub fn f32_to_f16_asm(a: f32) -> f16 { let ret: f16; unsafe { asm!( - "fcvt {ret:h}, {a:s}", - a = in(vreg) a, - ret = lateout(vreg) ret, - options(nomem, nostack), + "fcvt {ret:h}, {a:s}", + a = in(vreg) a, + ret = lateout(vreg) ret, + options(nomem, nostack), ); } ret } + fn main() { assert_eq!(f32_to_f16_asm(1.0 as f32), 1.0); } From 172c05cca2aef927a6379b404489c0fc0f143f0e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 11:42:20 +0200 Subject: [PATCH 041/102] only visit reachable blocks, do not use a visitor --- .../src/check_consts/check.rs | 44 +++++++------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index d7594c9ae75f6..13afb1afa828e 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; -use rustc_mir_dataflow::{Analysis, ResultsCursor}; +use rustc_mir_dataflow::Analysis; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; @@ -275,40 +275,28 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // A local is "transient" if it is guaranteed dead at all `Return`. // So first compute the say of "maybe live" locals at each program point. let always_live_locals = &always_storage_live_locals(&ccx.body); - let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals)) - .into_engine(ccx.tcx, &ccx.body) - .iterate_to_fixpoint() - .into_results_cursor(&ccx.body); + let mut maybe_storage_live = + MaybeStorageLive::new(Cow::Borrowed(always_live_locals)) + .into_engine(ccx.tcx, &ccx.body) + .iterate_to_fixpoint() + .into_results_cursor(&ccx.body); // And then check all `Return` in the MIR, and if a local is "maybe live" at a // `Return` then it is definitely not transient. - struct TransientLocalVisitor<'a, 'tcx> { - maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>, - transient: BitSet, - } - impl<'a, 'tcx> Visitor<'tcx> for TransientLocalVisitor<'a, 'tcx> { - fn visit_terminator( - &mut self, - terminator: &Terminator<'tcx>, - location: Location, - ) { - if matches!(terminator.kind, TerminatorKind::Return) { - self.maybe_storage_live.seek_after_primary_effect(location); - for local in self.maybe_storage_live.get().iter() { - // If a local may be live here, it is definitely not transient. - self.transient.remove(local); - } + let mut transient = BitSet::new_filled(ccx.body.local_decls.len()); + // Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise. + for (bb, data) in traversal::reachable(&ccx.body) { + if matches!(data.terminator().kind, TerminatorKind::Return) { + let location = ccx.body.terminator_loc(bb); + maybe_storage_live.seek_after_primary_effect(location); + for local in maybe_storage_live.get().iter() { + // If a local may be live here, it is definitely not transient. + transient.remove(local); } } } - let mut v = TransientLocalVisitor { - maybe_storage_live, - transient: BitSet::new_filled(ccx.body.local_decls.len()), - }; - v.visit_body(&ccx.body); - - v.transient + transient }) .contains(local) } From 74a21425cca6742f08a6df25bb153a3b7a43f56a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 12:33:55 +0200 Subject: [PATCH 042/102] dont iterate over the bitset --- compiler/rustc_const_eval/src/check_consts/check.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 13afb1afa828e..9f93776a7b9e2 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -289,10 +289,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { if matches!(data.terminator().kind, TerminatorKind::Return) { let location = ccx.body.terminator_loc(bb); maybe_storage_live.seek_after_primary_effect(location); - for local in maybe_storage_live.get().iter() { - // If a local may be live here, it is definitely not transient. - transient.remove(local); - } + // If a local may be live here, it is definitely not transient. + transient.subtract(maybe_storage_live.get()); } } From 5412499ad54b333b03a6aa798f19dc8552fb2936 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 13:49:16 +0200 Subject: [PATCH 043/102] make it possible to enable const_precise_live_drops per-function --- .../src/check_consts/post_drop_elaboration.rs | 10 ++++++++-- ...rop-allow-const-fn-unstable.not_allow.stderr | 12 ++++++++++++ .../precise-drop-allow-const-fn-unstable.rs | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr create mode 100644 tests/ui/consts/precise-drop-allow-const-fn-unstable.rs diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index c4f06e5af0be5..f0998300dc843 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -9,13 +9,19 @@ use super::check::Qualifs; use super::ops::{self, NonConstOp}; use super::qualifs::{NeedsNonConstDrop, Qualif}; use super::ConstCx; +use crate::check_consts::rustc_allow_const_fn_unstable; /// Returns `true` if we should use the more precise live drop checker that runs after drop /// elaboration. pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool { - // Const-stable functions must always use the stable live drop checker. + // Const-stable functions must always use the stable live drop checker... if ccx.is_const_stable_const_fn() { - return false; + // ...except if they have the feature flag set via `rustc_allow_const_fn_unstable`. + return rustc_allow_const_fn_unstable( + ccx.tcx, + ccx.body.source.def_id().expect_local(), + sym::const_precise_live_drops, + ); } ccx.tcx.features().const_precise_live_drops diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr new file mode 100644 index 0000000000000..6038c6d332fec --- /dev/null +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr @@ -0,0 +1,12 @@ +error[E0493]: destructor of `Option` cannot be evaluated at compile-time + --> $DIR/precise-drop-allow-const-fn-unstable.rs:11:24 + | +LL | pub const fn unwrap(this: Option) -> T { + | ^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs new file mode 100644 index 0000000000000..56155e519dca4 --- /dev/null +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs @@ -0,0 +1,17 @@ +//@ revisions: allow not_allow +//@ compile-flags: --crate-type=lib -Cinstrument-coverage -Zno-profiler-runtime +//@[allow] check-pass + +#![feature(staged_api, rustc_allow_const_fn_unstable)] +#![stable(feature = "rust_test", since = "1.0.0")] + +#[stable(feature = "rust_test", since = "1.0.0")] +#[rustc_const_stable(feature = "rust_test", since = "1.0.0")] +#[cfg_attr(allow, rustc_allow_const_fn_unstable(const_precise_live_drops))] +pub const fn unwrap(this: Option) -> T { +//[not_allow]~^ ERROR: cannot be evaluated + match this { + Some(x) => x, + None => panic!(), + } +} From b581fed15ef93b4d048097afe728dd052e5668ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Aug 2024 16:18:59 +0200 Subject: [PATCH 044/102] Generate missing source link on impl associated types --- src/librustdoc/html/render/mod.rs | 2 ++ tests/rustdoc/anchors.no_type_anchor2.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index c1b2ee7d8ae92..47f321a4c4a2a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1730,6 +1730,7 @@ fn render_impl( let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write!(w, "
"); + render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. write!(w, "§"); @@ -1751,6 +1752,7 @@ fn render_impl( let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write!(w, "
"); + render_rightside(w, cx, item, render_mode); if trait_.is_some() { // Anchors are only used on trait impls. write!(w, "§"); diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors.no_type_anchor2.html index 71e93990e29e9..9127104ded4af 100644 --- a/tests/rustdoc/anchors.no_type_anchor2.html +++ b/tests/rustdoc/anchors.no_type_anchor2.html @@ -1 +1 @@ -

pub type Y = u32

\ No newline at end of file +
source

pub type Y = u32

\ No newline at end of file From ca6be7414a4f01d4369ebc21773008532f8081ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Aug 2024 16:19:17 +0200 Subject: [PATCH 045/102] Add regression test for impl associated types source link --- tests/rustdoc/assoc-type-source-link.rs | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/rustdoc/assoc-type-source-link.rs diff --git a/tests/rustdoc/assoc-type-source-link.rs b/tests/rustdoc/assoc-type-source-link.rs new file mode 100644 index 0000000000000..34b156b964957 --- /dev/null +++ b/tests/rustdoc/assoc-type-source-link.rs @@ -0,0 +1,26 @@ +// This test ensures that the source links are generated for impl associated types. + +#![crate_name = "foo"] +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +//@ has 'foo/struct.Bar.html' +pub struct Bar; + +impl Bar { + //@ has - '//*[@id="implementations-list"]//*[@id="associatedtype.Y"]/a' 'source' + //@ has - '//*[@id="implementations-list"]//*[@id="associatedtype.Y"]/a/@href' \ + // '../src/foo/assoc-type-source-link.rs.html#14' + pub type Y = u8; +} + +pub trait Foo { + type Z; +} + +impl Foo for Bar { + //@ has - '//*[@id="trait-implementations-list"]//*[@id="associatedtype.Z"]/a' 'source' + //@ has - '//*[@id="trait-implementations-list"]//*[@id="associatedtype.Z"]/a/@href' \ + // '../src/foo/assoc-type-source-link.rs.html#25' + type Z = u8; +} From 3153b7d7b4e2d528e13c40559e644bfca0735389 Mon Sep 17 00:00:00 2001 From: Jack O'Connor Date: Sat, 24 Aug 2024 18:14:52 -0700 Subject: [PATCH 046/102] link to Future::poll from the Poll docs The most important thing about Poll is that Future::poll returns it, but previously the docs didn't emphasize this. --- library/core/src/task/poll.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index bfa1cf096e237..6aab22177ab9d 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -5,6 +5,8 @@ use crate::ops::{self, ControlFlow}; /// Indicates whether a value is available or if the current task has been /// scheduled to receive a wakeup instead. +/// +/// This is returned by [`Future::poll`](core::future::Future::poll). #[must_use = "this `Poll` may be a `Pending` variant, which should be handled"] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] #[lang = "Poll"] From 21dd88f963f8047fa6a3d0492fc7dcf86f5e5f4d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 17:12:12 +0200 Subject: [PATCH 047/102] exit: explain our expectations for the exit handlers registered in a Rust program --- library/std/src/process.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 9ffdebe1b6ffe..bbea27ebc1056 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -2296,6 +2296,15 @@ impl Child { /// } /// ``` /// +/// In its current implementation, this function will execute exit handlers registered with `atexit` +/// as well as other platform-specific exit handlers (e.g. `fini` sections of ELF shared objects). +/// This means that Rust requires that all exit handlers are safe to execute at any time. In +/// particular, if an exit handler cleans up some state that might be concurrently accessed by other +/// threads, it is required that the exit handler performs suitable synchronization with those +/// threads. (The alternative to this requirement would be to not run exit handlers at all, which is +/// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an +/// unsafe operation is not an option.) +/// /// ## Platform-specific behavior /// /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit` From 687c8a1eabf039be5cccc9cfefb55dd825378b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Sun, 25 Aug 2024 20:49:23 +0200 Subject: [PATCH 048/102] pal/hermit: correctly round up microseconds in `Thread::sleep` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- library/std/src/sys/pal/hermit/thread.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index 6321f92e3d9d0..bc70b3ac1705c 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -77,8 +77,10 @@ impl Thread { #[inline] pub fn sleep(dur: Duration) { + let micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 }; + unsafe { - hermit_abi::usleep(dur.as_micros() as u64); + hermit_abi::usleep(micros as u64); } } From edeefc532f645386db828a956cb50702e15f8b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Mon, 26 Aug 2024 00:04:00 +0200 Subject: [PATCH 049/102] pal/hermit: saturate `usleep` microseconds at `u64::MAX` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- library/std/src/sys/pal/hermit/thread.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index bc70b3ac1705c..4c0c0919f4799 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -78,9 +78,10 @@ impl Thread { #[inline] pub fn sleep(dur: Duration) { let micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 }; + let micros = u64::try_from(micros).unwrap_or(u64::MAX); unsafe { - hermit_abi::usleep(micros as u64); + hermit_abi::usleep(micros); } } From 5b374631df79f879560f3a4d041290e152c05ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 15:02:13 +0000 Subject: [PATCH 050/102] compiletest: implement `needs-lvm-zstd` directive --- src/tools/compiletest/src/command-list.rs | 1 + src/tools/compiletest/src/header.rs | 101 ++++++++++++++++++++++ src/tools/compiletest/src/header/needs.rs | 10 ++- 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index 7f8080235c870..a559d6f81a240 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -141,6 +141,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-force-clang-based-tests", "needs-git-hash", "needs-llvm-components", + "needs-llvm-zstd", "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 1fc24301c85e6..933913eb47c34 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1203,6 +1203,107 @@ pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option { None } +/// For tests using the `needs-llvm-zstd` directive: +/// - for local LLVM builds, try to find the static zstd library in the llvm-config system libs. +/// - for `download-ci-llvm`, see if `lld` was built with zstd support. +pub fn llvm_has_libzstd(config: &Config) -> bool { + // Strategy 1: works for local builds but not with `download-ci-llvm`. + // + // We check whether `llvm-config` returns the zstd library. Bootstrap's `llvm.libzstd` will only + // ask to statically link it when building LLVM, so we only check if the list of system libs + // contains a path to that static lib, and that it exists. + // + // See compiler/rustc_llvm/build.rs for more details and similar expectations. + fn is_zstd_in_config(llvm_bin_dir: &Path) -> Option<()> { + let llvm_config_path = llvm_bin_dir.join("llvm-config"); + let output = Command::new(llvm_config_path).arg("--system-libs").output().ok()?; + assert!(output.status.success(), "running llvm-config --system-libs failed"); + + let libs = String::from_utf8(output.stdout).ok()?; + for lib in libs.split_whitespace() { + if lib.ends_with("libzstd.a") && Path::new(lib).exists() { + return Some(()); + } + } + + None + } + + // Strategy 2: `download-ci-llvm`'s `llvm-config --system-libs` will not return any libs to + // use. + // + // The CI artifacts also don't contain the bootstrap config used to build them: otherwise we + // could have looked at the `llvm.libzstd` config. + // + // We infer whether `LLVM_ENABLE_ZSTD` was used to build LLVM as a byproduct of testing whether + // `lld` supports it. If not, an error will be emitted: "LLVM was not built with + // LLVM_ENABLE_ZSTD or did not find zstd at build time". + #[cfg(unix)] + fn is_lld_built_with_zstd(llvm_bin_dir: &Path) -> Option<()> { + let lld_path = llvm_bin_dir.join("lld"); + if lld_path.exists() { + // We can't call `lld` as-is, it expects to be invoked by a compiler driver using a + // different name. Prepare a temporary symlink to do that. + let lld_symlink_path = llvm_bin_dir.join("ld.lld"); + if !lld_symlink_path.exists() { + std::os::unix::fs::symlink(lld_path, &lld_symlink_path).ok()?; + } + + // Run `lld` with a zstd flag. We expect this command to always error here, we don't + // want to link actual files and don't pass any. + let output = Command::new(&lld_symlink_path) + .arg("--compress-debug-sections=zstd") + .output() + .ok()?; + assert!(!output.status.success()); + + // Look for a specific error caused by LLVM not being built with zstd support. We could + // also look for the "no input files" message, indicating the zstd flag was accepted. + let stderr = String::from_utf8(output.stderr).ok()?; + let zstd_available = !stderr.contains("LLVM was not built with LLVM_ENABLE_ZSTD"); + + // We don't particularly need to clean the link up (so the previous commands could fail + // in theory but won't in practice), but we can try. + std::fs::remove_file(lld_symlink_path).ok()?; + + if zstd_available { + return Some(()); + } + } + + None + } + + #[cfg(not(unix))] + fn is_lld_built_with_zstd(_llvm_bin_dir: &Path) -> Option<()> { + None + } + + if let Some(llvm_bin_dir) = &config.llvm_bin_dir { + // Strategy 1: for local LLVM builds. + if is_zstd_in_config(llvm_bin_dir).is_some() { + return true; + } + + // Strategy 2: for LLVM artifacts built on CI via `download-ci-llvm`. + // + // It doesn't work for cases where the artifacts don't contain the linker, but it's + // best-effort: CI has `llvm.libzstd` and `lld` enabled on the x64 linux artifacts, so it + // will at least work there. + // + // If this can be improved and expanded to less common cases in the future, it should. + if config.target == "x86_64-unknown-linux-gnu" + && config.host == config.target + && is_lld_built_with_zstd(llvm_bin_dir).is_some() + { + return true; + } + } + + // Otherwise, all hope is lost. + false +} + /// Takes a directive of the form " [- ]", /// returns the numeric representation of and as /// tuple: ( as u32, as u32) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 8f935d5b74441..e04abea0bf987 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -1,5 +1,5 @@ use crate::common::{Config, Sanitizer}; -use crate::header::IgnoreDecision; +use crate::header::{llvm_has_libzstd, IgnoreDecision}; pub(super) fn handle_needs( cache: &CachedNeedsConditions, @@ -144,6 +144,11 @@ pub(super) fn handle_needs( condition: cache.symlinks, ignore_reason: "ignored if symlinks are unavailable", }, + Need { + name: "needs-llvm-zstd", + condition: cache.llvm_zstd, + ignore_reason: "ignored if LLVM wasn't build with zstd for ELF section compression", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { @@ -210,6 +215,8 @@ pub(super) struct CachedNeedsConditions { rust_lld: bool, dlltool: bool, symlinks: bool, + /// Whether LLVM built with zstd, for the `needs-llvm-zstd` directive. + llvm_zstd: bool, } impl CachedNeedsConditions { @@ -253,6 +260,7 @@ impl CachedNeedsConditions { .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" }) .exists(), + llvm_zstd: llvm_has_libzstd(&config), dlltool: find_dlltool(&config), symlinks: has_symlinks(), } From 79f3c51a01693b264419f74b5527c146b4d52e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 15:09:20 +0000 Subject: [PATCH 051/102] mark `rust-lld-compress-debug-sections` test as needing zstd also make it fail if there's a compression issue --- .../rust-lld-compress-debug-sections/rmake.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs b/tests/run-make/rust-lld-compress-debug-sections/rmake.rs index ea4997fab8099..9889659046ea7 100644 --- a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs +++ b/tests/run-make/rust-lld-compress-debug-sections/rmake.rs @@ -1,12 +1,13 @@ // Checks the `compress-debug-sections` option on rust-lld. //@ needs-rust-lld +//@ needs-llvm-zstd //@ only-linux //@ ignore-cross-compile // FIXME: This test isn't comprehensive and isn't covering all possible combinations. -use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc}; +use run_make_support::{llvm_readobj, run_in_tmpdir, rustc}; fn check_compression(compression: &str, to_find: &str) { run_in_tmpdir(|| { @@ -17,19 +18,8 @@ fn check_compression(compression: &str, to_find: &str) { .arg("-Cdebuginfo=full") .link_arg(&format!("-Wl,--compress-debug-sections={compression}")) .input("main.rs") - .run_unchecked(); - let stderr = out.stderr_utf8(); - if stderr.is_empty() { - llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); - } else { - assert_contains( - stderr, - format!( - "LLVM was not built with LLVM_ENABLE_{to_find} \ - or did not find {compression} at build time" - ), - ); - } + .run(); + llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); }); } From 802222fefca2e374a254877c54beb051843cd974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 16:22:04 +0000 Subject: [PATCH 052/102] prepare test for expanding scope --- .../main.rs | 0 .../rmake.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/run-make/{rust-lld-compress-debug-sections => compressed-debuginfo-zstd}/main.rs (100%) rename tests/run-make/{rust-lld-compress-debug-sections => compressed-debuginfo-zstd}/rmake.rs (100%) diff --git a/tests/run-make/rust-lld-compress-debug-sections/main.rs b/tests/run-make/compressed-debuginfo-zstd/main.rs similarity index 100% rename from tests/run-make/rust-lld-compress-debug-sections/main.rs rename to tests/run-make/compressed-debuginfo-zstd/main.rs diff --git a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs similarity index 100% rename from tests/run-make/rust-lld-compress-debug-sections/rmake.rs rename to tests/run-make/compressed-debuginfo-zstd/rmake.rs From 1935e21029d28af3022064f57b36fff85b8db9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 16:59:00 +0000 Subject: [PATCH 053/102] expand zstd debuginfo compression test it now checks zlib and zstd, via rustc and rust-lld --- .../compressed-debuginfo-zstd/rmake.rs | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs index 9889659046ea7..8356373e949aa 100644 --- a/tests/run-make/compressed-debuginfo-zstd/rmake.rs +++ b/tests/run-make/compressed-debuginfo-zstd/rmake.rs @@ -1,24 +1,37 @@ -// Checks the `compress-debug-sections` option on rust-lld. +// Checks debuginfo compression both for the always-enabled zlib, and when the optional zstd is +// enabled: +// - via rustc's `debuginfo-compression`, +// - and via rust-lld's `compress-debug-sections` -//@ needs-rust-lld -//@ needs-llvm-zstd +//@ needs-llvm-zstd: we want LLVM/LLD to be built with zstd support +//@ needs-rust-lld: the system linker will most likely not support zstd //@ only-linux //@ ignore-cross-compile -// FIXME: This test isn't comprehensive and isn't covering all possible combinations. - -use run_make_support::{llvm_readobj, run_in_tmpdir, rustc}; +use run_make_support::{llvm_readobj, run_in_tmpdir, Rustc}; fn check_compression(compression: &str, to_find: &str) { + // check compressed debug sections via rustc flag + prepare_and_check(to_find, |rustc| { + rustc.arg(&format!("-Zdebuginfo-compression={compression}")) + }); + + // check compressed debug sections via rust-lld flag + prepare_and_check(to_find, |rustc| { + rustc.link_arg(&format!("-Wl,--compress-debug-sections={compression}")) + }); +} + +fn prepare_and_check &mut Rustc>(to_find: &str, prepare_rustc: F) { run_in_tmpdir(|| { - let out = rustc() + let mut rustc = Rustc::new(); + rustc .arg("-Zlinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .arg("-Cdebuginfo=full") - .link_arg(&format!("-Wl,--compress-debug-sections={compression}")) - .input("main.rs") - .run(); + .input("main.rs"); + prepare_rustc(&mut rustc).run(); llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); }); } From 62c8c693bdda3932dbb049f8a2707f2f616d29eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 22:25:22 +0000 Subject: [PATCH 054/102] move and rename zstd script move it where it's used, and name it like the other scripts --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 6 +++--- .../zstd.sh => host-x86_64/dist-x86_64-linux/build-zstd.sh} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename src/ci/docker/{scripts/zstd.sh => host-x86_64/dist-x86_64-linux/build-zstd.sh} (100%) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 61e9694f1e2ae..e857f38e68a85 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -62,9 +62,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/ RUN ./build-clang.sh ENV CC=clang CXX=clang++ -# rustc's LLVM needs zstd. -COPY scripts/zstd.sh /tmp/ -RUN ./zstd.sh +# Build zstd to enable `llvm.libzstd`. +COPY host-x86_64/dist-x86_64-linux/build-zstd.sh /tmp/ +RUN ./build-zstd.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/scripts/zstd.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh similarity index 100% rename from src/ci/docker/scripts/zstd.sh rename to src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh From 7963beda2481deb5bd01286b61386d599536a3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 11 Aug 2024 15:02:13 +0000 Subject: [PATCH 055/102] strip whitespace for ignored tests reason comments --- src/tools/compiletest/src/header/needs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index e04abea0bf987..72b1b9c6d480a 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -174,7 +174,7 @@ pub(super) fn handle_needs( } else { return IgnoreDecision::Ignore { reason: if let Some(comment) = comment { - format!("{} ({comment})", need.ignore_reason) + format!("{} ({})", need.ignore_reason, comment.trim()) } else { need.ignore_reason.into() }, From 650ba7fdf001353664a60be43efb2d96c3c0295b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 11 Aug 2024 19:05:30 +0000 Subject: [PATCH 056/102] enable `llvm.libzstd` on test x64 linux builder --- src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile index 19683317126ab..83c2aa8cfb3b7 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile @@ -28,5 +28,6 @@ ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-sanitizers \ --enable-profiler \ - --enable-compiler-docs + --enable-compiler-docs \ + --set llvm.libzstd=true ENV SCRIPT python3 ../x.py --stage 2 test From 5d83cb27c886137887c087fbce77032069f5ec8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 20 Aug 2024 14:04:44 +0000 Subject: [PATCH 057/102] allow `llvm.libzstd` with `download-ci-llvm = true` but warn about it --- src/bootstrap/src/core/config/config.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ce23b7735f8bd..bdfee55d8d183 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1885,6 +1885,22 @@ impl Config { warn("link-shared"); } + // FIXME(#129153): instead of all the ad-hoc `download-ci-llvm` checks that follow, + // use the `builder-config` present in tarballs since #128822 to compare the local + // config to the ones used to build the LLVM artifacts on CI, and only notify users + // if they've chosen a different value. + + if libzstd.is_some() { + println!( + "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ + like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ + artifacts builder config." + ); + println!( + "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." + ); + } + // None of the LLVM options, except assertions, are supported // when using downloaded LLVM. We could just ignore these but // that's potentially confusing, so force them to not be @@ -1894,7 +1910,6 @@ impl Config { check_ci_llvm!(optimize_toml); check_ci_llvm!(thin_lto); check_ci_llvm!(release_debuginfo); - check_ci_llvm!(libzstd); check_ci_llvm!(targets); check_ci_llvm!(experimental_targets); check_ci_llvm!(clang_cl); From 4f3ef2ac90d957c5b36e1d7e662dba1f7b533db8 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 25 Aug 2024 17:53:53 -0400 Subject: [PATCH 058/102] Remove cfg(test) from library/core --- library/core/src/error.rs | 3 - library/core/tests/lib.rs | 1 - library/core/tests/num/int_macros.rs | 759 +++++++++++++------------- library/core/tests/num/mod.rs | 2 +- library/core/tests/num/uint_macros.rs | 543 +++++++++--------- 5 files changed, 649 insertions(+), 659 deletions(-) diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 6cc91849e1dc9..cac00b37d1fa7 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -1,9 +1,6 @@ #![doc = include_str!("error.md")] #![stable(feature = "error_in_core", since = "1.81.0")] -#[cfg(test)] -mod tests; - use crate::any::TypeId; use crate::fmt::{Debug, Display, Formatter, Result}; diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 073429c7628f0..c205f028dd3a7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -141,7 +141,6 @@ mod intrinsics; mod io; mod iter; mod lazy; -#[cfg(test)] mod macros; mod manually_drop; mod mem; diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 165d9a296176e..7cd3b54e3f39a 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -1,427 +1,424 @@ macro_rules! int_module { ($T:ident) => { - #[cfg(test)] - mod tests { - use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; - use core::$T::*; - - use crate::num; - - #[test] - fn test_overflows() { - assert!(MAX > 0); - assert!(MIN <= 0); - assert_eq!(MIN + MAX + 1, 0); - } + use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; + use core::$T::*; - #[test] - fn test_num() { - num::test_num(10 as $T, 2 as $T); - } + use crate::num; - #[test] - fn test_rem_euclid() { - assert_eq!((-1 as $T).rem_euclid(MIN), MAX); - } + #[test] + fn test_overflows() { + assert!(MAX > 0); + assert!(MIN <= 0); + assert_eq!(MIN + MAX + 1, 0); + } - #[test] - pub fn test_abs() { - assert_eq!((1 as $T).abs(), 1 as $T); - assert_eq!((0 as $T).abs(), 0 as $T); - assert_eq!((-1 as $T).abs(), 1 as $T); - } + #[test] + fn test_num() { + num::test_num(10 as $T, 2 as $T); + } - #[test] - fn test_signum() { - assert_eq!((1 as $T).signum(), 1 as $T); - assert_eq!((0 as $T).signum(), 0 as $T); - assert_eq!((-0 as $T).signum(), 0 as $T); - assert_eq!((-1 as $T).signum(), -1 as $T); - } + #[test] + fn test_rem_euclid() { + assert_eq!((-1 as $T).rem_euclid(MIN), MAX); + } - #[test] - fn test_is_positive() { - assert!((1 as $T).is_positive()); - assert!(!(0 as $T).is_positive()); - assert!(!(-0 as $T).is_positive()); - assert!(!(-1 as $T).is_positive()); - } + #[test] + pub fn test_abs() { + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); + } - #[test] - fn test_is_negative() { - assert!(!(1 as $T).is_negative()); - assert!(!(0 as $T).is_negative()); - assert!(!(-0 as $T).is_negative()); - assert!((-1 as $T).is_negative()); - } + #[test] + fn test_signum() { + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); + } - #[test] - fn test_bitwise_operators() { - assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); - assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); - assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); - assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); - assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); - assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); - } + #[test] + fn test_is_positive() { + assert!((1 as $T).is_positive()); + assert!(!(0 as $T).is_positive()); + assert!(!(-0 as $T).is_positive()); + assert!(!(-1 as $T).is_positive()); + } - const A: $T = 0b0101100; - const B: $T = 0b0100001; - const C: $T = 0b1111001; + #[test] + fn test_is_negative() { + assert!(!(1 as $T).is_negative()); + assert!(!(0 as $T).is_negative()); + assert!(!(-0 as $T).is_negative()); + assert!((-1 as $T).is_negative()); + } - const _0: $T = 0; - const _1: $T = !0; + #[test] + fn test_bitwise_operators() { + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); + } - #[test] - fn test_count_ones() { - assert_eq!(A.count_ones(), 3); - assert_eq!(B.count_ones(), 2); - assert_eq!(C.count_ones(), 5); - } + const A: $T = 0b0101100; + const B: $T = 0b0100001; + const C: $T = 0b1111001; - #[test] - fn test_count_zeros() { - assert_eq!(A.count_zeros(), $T::BITS - 3); - assert_eq!(B.count_zeros(), $T::BITS - 2); - assert_eq!(C.count_zeros(), $T::BITS - 5); - } + const _0: $T = 0; + const _1: $T = !0; - #[test] - fn test_leading_trailing_ones() { - let a: $T = 0b0101_1111; - assert_eq!(a.trailing_ones(), 5); - assert_eq!((!a).leading_ones(), $T::BITS - 7); + #[test] + fn test_count_ones() { + assert_eq!(A.count_ones(), 3); + assert_eq!(B.count_ones(), 2); + assert_eq!(C.count_ones(), 5); + } - assert_eq!(a.reverse_bits().leading_ones(), 5); + #[test] + fn test_count_zeros() { + assert_eq!(A.count_zeros(), $T::BITS - 3); + assert_eq!(B.count_zeros(), $T::BITS - 2); + assert_eq!(C.count_zeros(), $T::BITS - 5); + } - assert_eq!(_1.leading_ones(), $T::BITS); - assert_eq!(_1.trailing_ones(), $T::BITS); + #[test] + fn test_leading_trailing_ones() { + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), $T::BITS - 7); - assert_eq!((_1 << 1).trailing_ones(), 0); - assert_eq!(MAX.leading_ones(), 0); + assert_eq!(a.reverse_bits().leading_ones(), 5); - assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1); - assert_eq!(MAX.trailing_ones(), $T::BITS - 1); + assert_eq!(_1.leading_ones(), $T::BITS); + assert_eq!(_1.trailing_ones(), $T::BITS); - assert_eq!(_0.leading_ones(), 0); - assert_eq!(_0.trailing_ones(), 0); + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!(MAX.leading_ones(), 0); - let x: $T = 0b0010_1100; - assert_eq!(x.leading_ones(), 0); - assert_eq!(x.trailing_ones(), 0); - } + assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1); + assert_eq!(MAX.trailing_ones(), $T::BITS - 1); - #[test] - fn test_rotate() { - assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); - assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B); - assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C); - - // Rotating these should make no difference - // - // We test using 124 bits because to ensure that overlong bit shifts do - // not cause undefined behaviour. See #10183. - assert_eq!(_0.rotate_left(124), _0); - assert_eq!(_1.rotate_left(124), _1); - assert_eq!(_0.rotate_right(124), _0); - assert_eq!(_1.rotate_right(124), _1); - - // Rotating by 0 should have no effect - assert_eq!(A.rotate_left(0), A); - assert_eq!(B.rotate_left(0), B); - assert_eq!(C.rotate_left(0), C); - // Rotating by a multiple of word size should also have no effect - assert_eq!(A.rotate_left(128), A); - assert_eq!(B.rotate_left(128), B); - assert_eq!(C.rotate_left(128), C); - } + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); - #[test] - fn test_swap_bytes() { - assert_eq!(A.swap_bytes().swap_bytes(), A); - assert_eq!(B.swap_bytes().swap_bytes(), B); - assert_eq!(C.swap_bytes().swap_bytes(), C); + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } - // Swapping these should make no difference - assert_eq!(_0.swap_bytes(), _0); - assert_eq!(_1.swap_bytes(), _1); - } + #[test] + fn test_rotate() { + assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); + assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B); + assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C); + + // Rotating these should make no difference + // + // We test using 124 bits because to ensure that overlong bit shifts do + // not cause undefined behaviour. See #10183. + assert_eq!(_0.rotate_left(124), _0); + assert_eq!(_1.rotate_left(124), _1); + assert_eq!(_0.rotate_right(124), _0); + assert_eq!(_1.rotate_right(124), _1); + + // Rotating by 0 should have no effect + assert_eq!(A.rotate_left(0), A); + assert_eq!(B.rotate_left(0), B); + assert_eq!(C.rotate_left(0), C); + // Rotating by a multiple of word size should also have no effect + assert_eq!(A.rotate_left(128), A); + assert_eq!(B.rotate_left(128), B); + assert_eq!(C.rotate_left(128), C); + } - #[test] - fn test_le() { - assert_eq!($T::from_le(A.to_le()), A); - assert_eq!($T::from_le(B.to_le()), B); - assert_eq!($T::from_le(C.to_le()), C); - assert_eq!($T::from_le(_0), _0); - assert_eq!($T::from_le(_1), _1); - assert_eq!(_0.to_le(), _0); - assert_eq!(_1.to_le(), _1); - } + #[test] + fn test_swap_bytes() { + assert_eq!(A.swap_bytes().swap_bytes(), A); + assert_eq!(B.swap_bytes().swap_bytes(), B); + assert_eq!(C.swap_bytes().swap_bytes(), C); - #[test] - fn test_be() { - assert_eq!($T::from_be(A.to_be()), A); - assert_eq!($T::from_be(B.to_be()), B); - assert_eq!($T::from_be(C.to_be()), C); - assert_eq!($T::from_be(_0), _0); - assert_eq!($T::from_be(_1), _1); - assert_eq!(_0.to_be(), _0); - assert_eq!(_1.to_be(), _1); - } + // Swapping these should make no difference + assert_eq!(_0.swap_bytes(), _0); + assert_eq!(_1.swap_bytes(), _1); + } - #[test] - fn test_signed_checked_div() { - assert_eq!((10 as $T).checked_div(2), Some(5)); - assert_eq!((5 as $T).checked_div(0), None); - assert_eq!(isize::MIN.checked_div(-1), None); - } + #[test] + fn test_le() { + assert_eq!($T::from_le(A.to_le()), A); + assert_eq!($T::from_le(B.to_le()), B); + assert_eq!($T::from_le(C.to_le()), C); + assert_eq!($T::from_le(_0), _0); + assert_eq!($T::from_le(_1), _1); + assert_eq!(_0.to_le(), _0); + assert_eq!(_1.to_le(), _1); + } - #[test] - fn test_saturating_abs() { - assert_eq!((0 as $T).saturating_abs(), 0); - assert_eq!((123 as $T).saturating_abs(), 123); - assert_eq!((-123 as $T).saturating_abs(), 123); - assert_eq!((MAX - 2).saturating_abs(), MAX - 2); - assert_eq!((MAX - 1).saturating_abs(), MAX - 1); - assert_eq!(MAX.saturating_abs(), MAX); - assert_eq!((MIN + 2).saturating_abs(), MAX - 1); - assert_eq!((MIN + 1).saturating_abs(), MAX); - assert_eq!(MIN.saturating_abs(), MAX); - } + #[test] + fn test_be() { + assert_eq!($T::from_be(A.to_be()), A); + assert_eq!($T::from_be(B.to_be()), B); + assert_eq!($T::from_be(C.to_be()), C); + assert_eq!($T::from_be(_0), _0); + assert_eq!($T::from_be(_1), _1); + assert_eq!(_0.to_be(), _0); + assert_eq!(_1.to_be(), _1); + } - #[test] - fn test_saturating_neg() { - assert_eq!((0 as $T).saturating_neg(), 0); - assert_eq!((123 as $T).saturating_neg(), -123); - assert_eq!((-123 as $T).saturating_neg(), 123); - assert_eq!((MAX - 2).saturating_neg(), MIN + 3); - assert_eq!((MAX - 1).saturating_neg(), MIN + 2); - assert_eq!(MAX.saturating_neg(), MIN + 1); - assert_eq!((MIN + 2).saturating_neg(), MAX - 1); - assert_eq!((MIN + 1).saturating_neg(), MAX); - assert_eq!(MIN.saturating_neg(), MAX); - } + #[test] + fn test_signed_checked_div() { + assert_eq!((10 as $T).checked_div(2), Some(5)); + assert_eq!((5 as $T).checked_div(0), None); + assert_eq!(isize::MIN.checked_div(-1), None); + } - #[test] - fn test_from_str() { - fn from_str(t: &str) -> Option { - std::str::FromStr::from_str(t).ok() - } - assert_eq!(from_str::<$T>("0"), Some(0 as $T)); - assert_eq!(from_str::<$T>("3"), Some(3 as $T)); - assert_eq!(from_str::<$T>("10"), Some(10 as $T)); - assert_eq!(from_str::("123456789"), Some(123456789 as i32)); - assert_eq!(from_str::<$T>("00100"), Some(100 as $T)); - - assert_eq!(from_str::<$T>("-1"), Some(-1 as $T)); - assert_eq!(from_str::<$T>("-3"), Some(-3 as $T)); - assert_eq!(from_str::<$T>("-10"), Some(-10 as $T)); - assert_eq!(from_str::("-123456789"), Some(-123456789 as i32)); - assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T)); - - assert_eq!(from_str::<$T>(""), None); - assert_eq!(from_str::<$T>(" "), None); - assert_eq!(from_str::<$T>("x"), None); - } + #[test] + fn test_saturating_abs() { + assert_eq!((0 as $T).saturating_abs(), 0); + assert_eq!((123 as $T).saturating_abs(), 123); + assert_eq!((-123 as $T).saturating_abs(), 123); + assert_eq!((MAX - 2).saturating_abs(), MAX - 2); + assert_eq!((MAX - 1).saturating_abs(), MAX - 1); + assert_eq!(MAX.saturating_abs(), MAX); + assert_eq!((MIN + 2).saturating_abs(), MAX - 1); + assert_eq!((MIN + 1).saturating_abs(), MAX); + assert_eq!(MIN.saturating_abs(), MAX); + } - #[test] - fn test_from_str_radix() { - assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T)); - assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T)); - assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T)); - assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32)); - assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32)); - assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32)); - assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T)); - assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T)); - - assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T)); - assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T)); - assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T)); - assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32)); - assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32)); - assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32)); - assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T)); - assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T)); - - assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>); - assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>); - } + #[test] + fn test_saturating_neg() { + assert_eq!((0 as $T).saturating_neg(), 0); + assert_eq!((123 as $T).saturating_neg(), -123); + assert_eq!((-123 as $T).saturating_neg(), 123); + assert_eq!((MAX - 2).saturating_neg(), MIN + 3); + assert_eq!((MAX - 1).saturating_neg(), MIN + 2); + assert_eq!(MAX.saturating_neg(), MIN + 1); + assert_eq!((MIN + 2).saturating_neg(), MAX - 1); + assert_eq!((MIN + 1).saturating_neg(), MAX); + assert_eq!(MIN.saturating_neg(), MAX); + } - #[test] - fn test_pow() { - let mut r = 2 as $T; - assert_eq!(r.pow(2), 4 as $T); - assert_eq!(r.pow(0), 1 as $T); - assert_eq!(r.wrapping_pow(2), 4 as $T); - assert_eq!(r.wrapping_pow(0), 1 as $T); - assert_eq!(r.checked_pow(2), Some(4 as $T)); - assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T, false)); - assert_eq!(r.overflowing_pow(0), (1 as $T, false)); - assert_eq!(r.saturating_pow(2), 4 as $T); - assert_eq!(r.saturating_pow(0), 1 as $T); - - r = MAX; - // use `^` to represent .pow() with no overflow. - // if itest::MAX == 2^j-1, then itest is a `j` bit int, - // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, - // thussaturating_pow the overflowing result is exactly 1. - assert_eq!(r.wrapping_pow(2), 1 as $T); - assert_eq!(r.checked_pow(2), None); - assert_eq!(r.overflowing_pow(2), (1 as $T, true)); - assert_eq!(r.saturating_pow(2), MAX); - //test for negative exponent. - r = -2 as $T; - assert_eq!(r.pow(2), 4 as $T); - assert_eq!(r.pow(3), -8 as $T); - assert_eq!(r.pow(0), 1 as $T); - assert_eq!(r.wrapping_pow(2), 4 as $T); - assert_eq!(r.wrapping_pow(3), -8 as $T); - assert_eq!(r.wrapping_pow(0), 1 as $T); - assert_eq!(r.checked_pow(2), Some(4 as $T)); - assert_eq!(r.checked_pow(3), Some(-8 as $T)); - assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T, false)); - assert_eq!(r.overflowing_pow(3), (-8 as $T, false)); - assert_eq!(r.overflowing_pow(0), (1 as $T, false)); - assert_eq!(r.saturating_pow(2), 4 as $T); - assert_eq!(r.saturating_pow(3), -8 as $T); - assert_eq!(r.saturating_pow(0), 1 as $T); + #[test] + fn test_from_str() { + fn from_str(t: &str) -> Option { + std::str::FromStr::from_str(t).ok() } + assert_eq!(from_str::<$T>("0"), Some(0 as $T)); + assert_eq!(from_str::<$T>("3"), Some(3 as $T)); + assert_eq!(from_str::<$T>("10"), Some(10 as $T)); + assert_eq!(from_str::("123456789"), Some(123456789 as i32)); + assert_eq!(from_str::<$T>("00100"), Some(100 as $T)); + + assert_eq!(from_str::<$T>("-1"), Some(-1 as $T)); + assert_eq!(from_str::<$T>("-3"), Some(-3 as $T)); + assert_eq!(from_str::<$T>("-10"), Some(-10 as $T)); + assert_eq!(from_str::("-123456789"), Some(-123456789 as i32)); + assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T)); + + assert_eq!(from_str::<$T>(""), None); + assert_eq!(from_str::<$T>(" "), None); + assert_eq!(from_str::<$T>("x"), None); + } - #[test] - fn test_isqrt() { - assert_eq!($T::MIN.checked_isqrt(), None); - assert_eq!((-1 as $T).checked_isqrt(), None); - assert_eq!((0 as $T).isqrt(), 0 as $T); - assert_eq!((1 as $T).isqrt(), 1 as $T); - assert_eq!((2 as $T).isqrt(), 1 as $T); - assert_eq!((99 as $T).isqrt(), 9 as $T); - assert_eq!((100 as $T).isqrt(), 10 as $T); - } + #[test] + fn test_from_str_radix() { + assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T)); + assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T)); + assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T)); + assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32)); + assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32)); + assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32)); + assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T)); + assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T)); + + assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T)); + assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T)); + assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T)); + assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32)); + assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32)); + assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32)); + assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T)); + assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T)); + + assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>); + assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>); + } - #[cfg(not(miri))] // Miri is too slow - #[test] - fn test_lots_of_isqrt() { - let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; - for n in 0..=n_max { - let isqrt: $T = n.isqrt(); - - assert!(isqrt.pow(2) <= n); - let (square, overflow) = (isqrt + 1).overflowing_pow(2); - assert!(overflow || square > n); - } - - for n in ($T::MAX - 127)..=$T::MAX { - let isqrt: $T = n.isqrt(); - - assert!(isqrt.pow(2) <= n); - let (square, overflow) = (isqrt + 1).overflowing_pow(2); - assert!(overflow || square > n); - } - } + #[test] + fn test_pow() { + let mut r = 2 as $T; + assert_eq!(r.pow(2), 4 as $T); + assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); + assert_eq!(r.saturating_pow(2), 4 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); + + r = MAX; + // use `^` to represent .pow() with no overflow. + // if itest::MAX == 2^j-1, then itest is a `j` bit int, + // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, + // thussaturating_pow the overflowing result is exactly 1. + assert_eq!(r.wrapping_pow(2), 1 as $T); + assert_eq!(r.checked_pow(2), None); + assert_eq!(r.overflowing_pow(2), (1 as $T, true)); + assert_eq!(r.saturating_pow(2), MAX); + //test for negative exponent. + r = -2 as $T; + assert_eq!(r.pow(2), 4 as $T); + assert_eq!(r.pow(3), -8 as $T); + assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); + assert_eq!(r.wrapping_pow(3), -8 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(3), Some(-8 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(3), (-8 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); + assert_eq!(r.saturating_pow(2), 4 as $T); + assert_eq!(r.saturating_pow(3), -8 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); + } - #[test] - fn test_div_floor() { - let a: $T = 8; - let b = 3; - assert_eq!(a.div_floor(b), 2); - assert_eq!(a.div_floor(-b), -3); - assert_eq!((-a).div_floor(b), -3); - assert_eq!((-a).div_floor(-b), 2); - } + #[test] + fn test_isqrt() { + assert_eq!($T::MIN.checked_isqrt(), None); + assert_eq!((-1 as $T).checked_isqrt(), None); + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + } - #[test] - fn test_div_ceil() { - let a: $T = 8; - let b = 3; - assert_eq!(a.div_ceil(b), 3); - assert_eq!(a.div_ceil(-b), -2); - assert_eq!((-a).div_ceil(b), -2); - assert_eq!((-a).div_ceil(-b), 3); - } + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); - #[test] - fn test_next_multiple_of() { - assert_eq!((16 as $T).next_multiple_of(8), 16); - assert_eq!((23 as $T).next_multiple_of(8), 24); - assert_eq!((16 as $T).next_multiple_of(-8), 16); - assert_eq!((23 as $T).next_multiple_of(-8), 16); - assert_eq!((-16 as $T).next_multiple_of(8), -16); - assert_eq!((-23 as $T).next_multiple_of(8), -16); - assert_eq!((-16 as $T).next_multiple_of(-8), -16); - assert_eq!((-23 as $T).next_multiple_of(-8), -24); - assert_eq!(MIN.next_multiple_of(-1), MIN); + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); } - #[test] - fn test_checked_next_multiple_of() { - assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16)); - assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24)); - assert_eq!((16 as $T).checked_next_multiple_of(-8), Some(16)); - assert_eq!((23 as $T).checked_next_multiple_of(-8), Some(16)); - assert_eq!((-16 as $T).checked_next_multiple_of(8), Some(-16)); - assert_eq!((-23 as $T).checked_next_multiple_of(8), Some(-16)); - assert_eq!((-16 as $T).checked_next_multiple_of(-8), Some(-16)); - assert_eq!((-23 as $T).checked_next_multiple_of(-8), Some(-24)); - assert_eq!((1 as $T).checked_next_multiple_of(0), None); - assert_eq!(MAX.checked_next_multiple_of(2), None); - assert_eq!(MIN.checked_next_multiple_of(-3), None); - assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN)); - } + for n in ($T::MAX - 127)..=$T::MAX { + let isqrt: $T = n.isqrt(); - #[test] - fn test_carrying_add() { - assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true)); - assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true)); - assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true)); - assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false)); - assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow - assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true)); - assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow - assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true)); - assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false)); + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); } + } - #[test] - fn test_borrowing_sub() { - assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); - assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); - assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); - assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false)); - assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow - assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true)); - assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow - assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true)); - assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false)); - } + #[test] + fn test_div_floor() { + let a: $T = 8; + let b = 3; + assert_eq!(a.div_floor(b), 2); + assert_eq!(a.div_floor(-b), -3); + assert_eq!((-a).div_floor(b), -3); + assert_eq!((-a).div_floor(-b), 2); + } - #[test] - fn test_midpoint() { - assert_eq!(<$T>::midpoint(1, 3), 2); - assert_eq!(<$T>::midpoint(3, 1), 2); - - assert_eq!(<$T>::midpoint(0, 0), 0); - assert_eq!(<$T>::midpoint(0, 2), 1); - assert_eq!(<$T>::midpoint(2, 0), 1); - assert_eq!(<$T>::midpoint(2, 2), 2); - - assert_eq!(<$T>::midpoint(1, 4), 2); - assert_eq!(<$T>::midpoint(4, 1), 2); - assert_eq!(<$T>::midpoint(3, 4), 3); - assert_eq!(<$T>::midpoint(4, 3), 3); - - assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1); - assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1); - assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); - assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); - - assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); - assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); - assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3); - assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3); - } + #[test] + fn test_div_ceil() { + let a: $T = 8; + let b = 3; + assert_eq!(a.div_ceil(b), 3); + assert_eq!(a.div_ceil(-b), -2); + assert_eq!((-a).div_ceil(b), -2); + assert_eq!((-a).div_ceil(-b), 3); + } + + #[test] + fn test_next_multiple_of() { + assert_eq!((16 as $T).next_multiple_of(8), 16); + assert_eq!((23 as $T).next_multiple_of(8), 24); + assert_eq!((16 as $T).next_multiple_of(-8), 16); + assert_eq!((23 as $T).next_multiple_of(-8), 16); + assert_eq!((-16 as $T).next_multiple_of(8), -16); + assert_eq!((-23 as $T).next_multiple_of(8), -16); + assert_eq!((-16 as $T).next_multiple_of(-8), -16); + assert_eq!((-23 as $T).next_multiple_of(-8), -24); + assert_eq!(MIN.next_multiple_of(-1), MIN); + } + + #[test] + fn test_checked_next_multiple_of() { + assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16)); + assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24)); + assert_eq!((16 as $T).checked_next_multiple_of(-8), Some(16)); + assert_eq!((23 as $T).checked_next_multiple_of(-8), Some(16)); + assert_eq!((-16 as $T).checked_next_multiple_of(8), Some(-16)); + assert_eq!((-23 as $T).checked_next_multiple_of(8), Some(-16)); + assert_eq!((-16 as $T).checked_next_multiple_of(-8), Some(-16)); + assert_eq!((-23 as $T).checked_next_multiple_of(-8), Some(-24)); + assert_eq!((1 as $T).checked_next_multiple_of(0), None); + assert_eq!(MAX.checked_next_multiple_of(2), None); + assert_eq!(MIN.checked_next_multiple_of(-3), None); + assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN)); + } + + #[test] + fn test_carrying_add() { + assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true)); + assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true)); + assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true)); + assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false)); + assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow + assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true)); + assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow + assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true)); + assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false)); + } + + #[test] + fn test_borrowing_sub() { + assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); + assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false)); + assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow + assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true)); + assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow + assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true)); + assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false)); + } + + #[test] + fn test_midpoint() { + assert_eq!(<$T>::midpoint(1, 3), 2); + assert_eq!(<$T>::midpoint(3, 1), 2); + + assert_eq!(<$T>::midpoint(0, 0), 0); + assert_eq!(<$T>::midpoint(0, 2), 1); + assert_eq!(<$T>::midpoint(2, 0), 1); + assert_eq!(<$T>::midpoint(2, 2), 2); + + assert_eq!(<$T>::midpoint(1, 4), 2); + assert_eq!(<$T>::midpoint(4, 1), 2); + assert_eq!(<$T>::midpoint(3, 4), 3); + assert_eq!(<$T>::midpoint(4, 3), 3); + + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1); + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); + + assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3); } }; } diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 53ff5ab1cedd1..dad46ad88fe19 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -178,7 +178,7 @@ fn test_can_not_overflow() { // Check u128 separately: for base in 2..=36 { - let num = u128::MAX as u128; + let num = ::MAX; let max_len_string = format_radix(num, base as u128); // base 16 fits perfectly for u128 and won't overflow: assert_eq!(can_overflow::(base, &max_len_string), base != 16); diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index d009ad89d5ce7..f4fa789461eb8 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -1,320 +1,317 @@ macro_rules! uint_module { ($T:ident) => { - #[cfg(test)] - mod tests { - use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; - use core::$T::*; - use std::str::FromStr; - - use crate::num; - - #[test] - fn test_overflows() { - assert!(MAX > 0); - assert!(MIN <= 0); - assert!((MIN + MAX).wrapping_add(1) == 0); - } + use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; + use core::$T::*; + use std::str::FromStr; - #[test] - fn test_num() { - num::test_num(10 as $T, 2 as $T); - } + use crate::num; - #[test] - fn test_bitwise_operators() { - assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); - assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); - assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); - assert!(0b1110 as $T == (0b0111 as $T).shl(1)); - assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not()); - } + #[test] + fn test_overflows() { + assert!(MAX > 0); + assert!(MIN <= 0); + assert!((MIN + MAX).wrapping_add(1) == 0); + } - const A: $T = 0b0101100; - const B: $T = 0b0100001; - const C: $T = 0b1111001; + #[test] + fn test_num() { + num::test_num(10 as $T, 2 as $T); + } - const _0: $T = 0; - const _1: $T = !0; + #[test] + fn test_bitwise_operators() { + assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); + assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); + assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); + assert!(0b1110 as $T == (0b0111 as $T).shl(1)); + assert!(0b0111 as $T == (0b1110 as $T).shr(1)); + assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not()); + } - #[test] - fn test_count_ones() { - assert!(A.count_ones() == 3); - assert!(B.count_ones() == 2); - assert!(C.count_ones() == 5); - } + const A: $T = 0b0101100; + const B: $T = 0b0100001; + const C: $T = 0b1111001; - #[test] - fn test_count_zeros() { - assert!(A.count_zeros() == $T::BITS - 3); - assert!(B.count_zeros() == $T::BITS - 2); - assert!(C.count_zeros() == $T::BITS - 5); - } + const _0: $T = 0; + const _1: $T = !0; - #[test] - fn test_leading_trailing_ones() { - let a: $T = 0b0101_1111; - assert_eq!(a.trailing_ones(), 5); - assert_eq!((!a).leading_ones(), $T::BITS - 7); + #[test] + fn test_count_ones() { + assert!(A.count_ones() == 3); + assert!(B.count_ones() == 2); + assert!(C.count_ones() == 5); + } - assert_eq!(a.reverse_bits().leading_ones(), 5); + #[test] + fn test_count_zeros() { + assert!(A.count_zeros() == $T::BITS - 3); + assert!(B.count_zeros() == $T::BITS - 2); + assert!(C.count_zeros() == $T::BITS - 5); + } - assert_eq!(_1.leading_ones(), $T::BITS); - assert_eq!(_1.trailing_ones(), $T::BITS); + #[test] + fn test_leading_trailing_ones() { + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), $T::BITS - 7); - assert_eq!((_1 << 1).trailing_ones(), 0); - assert_eq!((_1 >> 1).leading_ones(), 0); + assert_eq!(a.reverse_bits().leading_ones(), 5); - assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1); - assert_eq!((_1 >> 1).trailing_ones(), $T::BITS - 1); + assert_eq!(_1.leading_ones(), $T::BITS); + assert_eq!(_1.trailing_ones(), $T::BITS); - assert_eq!(_0.leading_ones(), 0); - assert_eq!(_0.trailing_ones(), 0); + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!((_1 >> 1).leading_ones(), 0); - let x: $T = 0b0010_1100; - assert_eq!(x.leading_ones(), 0); - assert_eq!(x.trailing_ones(), 0); - } + assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1); + assert_eq!((_1 >> 1).trailing_ones(), $T::BITS - 1); - #[test] - fn test_rotate() { - assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); - assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B); - assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C); - - // Rotating these should make no difference - // - // We test using 124 bits because to ensure that overlong bit shifts do - // not cause undefined behaviour. See #10183. - assert_eq!(_0.rotate_left(124), _0); - assert_eq!(_1.rotate_left(124), _1); - assert_eq!(_0.rotate_right(124), _0); - assert_eq!(_1.rotate_right(124), _1); - - // Rotating by 0 should have no effect - assert_eq!(A.rotate_left(0), A); - assert_eq!(B.rotate_left(0), B); - assert_eq!(C.rotate_left(0), C); - // Rotating by a multiple of word size should also have no effect - assert_eq!(A.rotate_left(128), A); - assert_eq!(B.rotate_left(128), B); - assert_eq!(C.rotate_left(128), C); - } + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); - #[test] - fn test_swap_bytes() { - assert_eq!(A.swap_bytes().swap_bytes(), A); - assert_eq!(B.swap_bytes().swap_bytes(), B); - assert_eq!(C.swap_bytes().swap_bytes(), C); + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } - // Swapping these should make no difference - assert_eq!(_0.swap_bytes(), _0); - assert_eq!(_1.swap_bytes(), _1); - } + #[test] + fn test_rotate() { + assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); + assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B); + assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C); + + // Rotating these should make no difference + // + // We test using 124 bits because to ensure that overlong bit shifts do + // not cause undefined behaviour. See #10183. + assert_eq!(_0.rotate_left(124), _0); + assert_eq!(_1.rotate_left(124), _1); + assert_eq!(_0.rotate_right(124), _0); + assert_eq!(_1.rotate_right(124), _1); + + // Rotating by 0 should have no effect + assert_eq!(A.rotate_left(0), A); + assert_eq!(B.rotate_left(0), B); + assert_eq!(C.rotate_left(0), C); + // Rotating by a multiple of word size should also have no effect + assert_eq!(A.rotate_left(128), A); + assert_eq!(B.rotate_left(128), B); + assert_eq!(C.rotate_left(128), C); + } - #[test] - fn test_reverse_bits() { - assert_eq!(A.reverse_bits().reverse_bits(), A); - assert_eq!(B.reverse_bits().reverse_bits(), B); - assert_eq!(C.reverse_bits().reverse_bits(), C); + #[test] + fn test_swap_bytes() { + assert_eq!(A.swap_bytes().swap_bytes(), A); + assert_eq!(B.swap_bytes().swap_bytes(), B); + assert_eq!(C.swap_bytes().swap_bytes(), C); - // Swapping these should make no difference - assert_eq!(_0.reverse_bits(), _0); - assert_eq!(_1.reverse_bits(), _1); - } + // Swapping these should make no difference + assert_eq!(_0.swap_bytes(), _0); + assert_eq!(_1.swap_bytes(), _1); + } - #[test] - fn test_le() { - assert_eq!($T::from_le(A.to_le()), A); - assert_eq!($T::from_le(B.to_le()), B); - assert_eq!($T::from_le(C.to_le()), C); - assert_eq!($T::from_le(_0), _0); - assert_eq!($T::from_le(_1), _1); - assert_eq!(_0.to_le(), _0); - assert_eq!(_1.to_le(), _1); - } + #[test] + fn test_reverse_bits() { + assert_eq!(A.reverse_bits().reverse_bits(), A); + assert_eq!(B.reverse_bits().reverse_bits(), B); + assert_eq!(C.reverse_bits().reverse_bits(), C); - #[test] - fn test_be() { - assert_eq!($T::from_be(A.to_be()), A); - assert_eq!($T::from_be(B.to_be()), B); - assert_eq!($T::from_be(C.to_be()), C); - assert_eq!($T::from_be(_0), _0); - assert_eq!($T::from_be(_1), _1); - assert_eq!(_0.to_be(), _0); - assert_eq!(_1.to_be(), _1); - } + // Swapping these should make no difference + assert_eq!(_0.reverse_bits(), _0); + assert_eq!(_1.reverse_bits(), _1); + } - #[test] - fn test_unsigned_checked_div() { - assert!((10 as $T).checked_div(2) == Some(5)); - assert!((5 as $T).checked_div(0) == None); - } + #[test] + fn test_le() { + assert_eq!($T::from_le(A.to_le()), A); + assert_eq!($T::from_le(B.to_le()), B); + assert_eq!($T::from_le(C.to_le()), C); + assert_eq!($T::from_le(_0), _0); + assert_eq!($T::from_le(_1), _1); + assert_eq!(_0.to_le(), _0); + assert_eq!(_1.to_le(), _1); + } - fn from_str(t: &str) -> Option { - FromStr::from_str(t).ok() - } + #[test] + fn test_be() { + assert_eq!($T::from_be(A.to_be()), A); + assert_eq!($T::from_be(B.to_be()), B); + assert_eq!($T::from_be(C.to_be()), C); + assert_eq!($T::from_be(_0), _0); + assert_eq!($T::from_be(_1), _1); + assert_eq!(_0.to_be(), _0); + assert_eq!(_1.to_be(), _1); + } - #[test] - pub fn test_from_str() { - assert_eq!(from_str::<$T>("0"), Some(0 as $T)); - assert_eq!(from_str::<$T>("3"), Some(3 as $T)); - assert_eq!(from_str::<$T>("10"), Some(10 as $T)); - assert_eq!(from_str::("123456789"), Some(123456789 as u32)); - assert_eq!(from_str::<$T>("00100"), Some(100 as $T)); - - assert_eq!(from_str::<$T>(""), None); - assert_eq!(from_str::<$T>(" "), None); - assert_eq!(from_str::<$T>("x"), None); - } + #[test] + fn test_unsigned_checked_div() { + assert!((10 as $T).checked_div(2) == Some(5)); + assert!((5 as $T).checked_div(0) == None); + } - #[test] - pub fn test_parse_bytes() { - assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T)); - assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T)); - assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T)); - assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16)); - assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16)); - assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T)); - - assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>); - assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>); - } + fn from_str(t: &str) -> Option { + FromStr::from_str(t).ok() + } - #[test] - fn test_pow() { - let mut r = 2 as $T; - assert_eq!(r.pow(2), 4 as $T); - assert_eq!(r.pow(0), 1 as $T); - assert_eq!(r.wrapping_pow(2), 4 as $T); - assert_eq!(r.wrapping_pow(0), 1 as $T); - assert_eq!(r.checked_pow(2), Some(4 as $T)); - assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T, false)); - assert_eq!(r.overflowing_pow(0), (1 as $T, false)); - assert_eq!(r.saturating_pow(2), 4 as $T); - assert_eq!(r.saturating_pow(0), 1 as $T); - - r = MAX; - // use `^` to represent .pow() with no overflow. - // if itest::MAX == 2^j-1, then itest is a `j` bit int, - // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, - // thussaturating_pow the overflowing result is exactly 1. - assert_eq!(r.wrapping_pow(2), 1 as $T); - assert_eq!(r.checked_pow(2), None); - assert_eq!(r.overflowing_pow(2), (1 as $T, true)); - assert_eq!(r.saturating_pow(2), MAX); - } + #[test] + pub fn test_from_str() { + assert_eq!(from_str::<$T>("0"), Some(0 as $T)); + assert_eq!(from_str::<$T>("3"), Some(3 as $T)); + assert_eq!(from_str::<$T>("10"), Some(10 as $T)); + assert_eq!(from_str::("123456789"), Some(123456789 as u32)); + assert_eq!(from_str::<$T>("00100"), Some(100 as $T)); + + assert_eq!(from_str::<$T>(""), None); + assert_eq!(from_str::<$T>(" "), None); + assert_eq!(from_str::<$T>("x"), None); + } - #[test] - fn test_isqrt() { - assert_eq!((0 as $T).isqrt(), 0 as $T); - assert_eq!((1 as $T).isqrt(), 1 as $T); - assert_eq!((2 as $T).isqrt(), 1 as $T); - assert_eq!((99 as $T).isqrt(), 9 as $T); - assert_eq!((100 as $T).isqrt(), 10 as $T); - assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); - } + #[test] + pub fn test_parse_bytes() { + assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T)); + assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T)); + assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T)); + assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16)); + assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16)); + assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T)); + + assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>); + assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>); + } - #[cfg(not(miri))] // Miri is too slow - #[test] - fn test_lots_of_isqrt() { - let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; - for n in 0..=n_max { - let isqrt: $T = n.isqrt(); + #[test] + fn test_pow() { + let mut r = 2 as $T; + assert_eq!(r.pow(2), 4 as $T); + assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); + assert_eq!(r.saturating_pow(2), 4 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); + + r = MAX; + // use `^` to represent .pow() with no overflow. + // if itest::MAX == 2^j-1, then itest is a `j` bit int, + // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, + // thussaturating_pow the overflowing result is exactly 1. + assert_eq!(r.wrapping_pow(2), 1 as $T); + assert_eq!(r.checked_pow(2), None); + assert_eq!(r.overflowing_pow(2), (1 as $T, true)); + assert_eq!(r.saturating_pow(2), MAX); + } - assert!(isqrt.pow(2) <= n); - assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); - } + #[test] + fn test_isqrt() { + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); + } - for n in ($T::MAX - 255)..=$T::MAX { - let isqrt: $T = n.isqrt(); + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); - assert!(isqrt.pow(2) <= n); - assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); - } + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); } - #[test] - fn test_div_floor() { - assert_eq!((8 as $T).div_floor(3), 2); - } + for n in ($T::MAX - 255)..=$T::MAX { + let isqrt: $T = n.isqrt(); - #[test] - fn test_div_ceil() { - assert_eq!((8 as $T).div_ceil(3), 3); + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); } + } - #[test] - fn test_next_multiple_of() { - assert_eq!((16 as $T).next_multiple_of(8), 16); - assert_eq!((23 as $T).next_multiple_of(8), 24); - assert_eq!(MAX.next_multiple_of(1), MAX); - } + #[test] + fn test_div_floor() { + assert_eq!((8 as $T).div_floor(3), 2); + } - #[test] - fn test_checked_next_multiple_of() { - assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16)); - assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24)); - assert_eq!((1 as $T).checked_next_multiple_of(0), None); - assert_eq!(MAX.checked_next_multiple_of(2), None); - } + #[test] + fn test_div_ceil() { + assert_eq!((8 as $T).div_ceil(3), 3); + } - #[test] - fn test_is_next_multiple_of() { - assert!((12 as $T).is_multiple_of(4)); - assert!(!(12 as $T).is_multiple_of(5)); - assert!((0 as $T).is_multiple_of(0)); - assert!(!(12 as $T).is_multiple_of(0)); - } + #[test] + fn test_next_multiple_of() { + assert_eq!((16 as $T).next_multiple_of(8), 16); + assert_eq!((23 as $T).next_multiple_of(8), 24); + assert_eq!(MAX.next_multiple_of(1), MAX); + } - #[test] - fn test_carrying_add() { - assert_eq!($T::MAX.carrying_add(1, false), (0, true)); - assert_eq!($T::MAX.carrying_add(0, true), (0, true)); - assert_eq!($T::MAX.carrying_add(1, true), (1, true)); + #[test] + fn test_checked_next_multiple_of() { + assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16)); + assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24)); + assert_eq!((1 as $T).checked_next_multiple_of(0), None); + assert_eq!(MAX.checked_next_multiple_of(2), None); + } - assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false)); - assert_eq!($T::MIN.carrying_add(0, true), (1, false)); - assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true)); - } + #[test] + fn test_is_next_multiple_of() { + assert!((12 as $T).is_multiple_of(4)); + assert!(!(12 as $T).is_multiple_of(5)); + assert!((0 as $T).is_multiple_of(0)); + assert!(!(12 as $T).is_multiple_of(0)); + } - #[test] - fn test_borrowing_sub() { - assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); - assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); - assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); + #[test] + fn test_carrying_add() { + assert_eq!($T::MAX.carrying_add(1, false), (0, true)); + assert_eq!($T::MAX.carrying_add(0, true), (0, true)); + assert_eq!($T::MAX.carrying_add(1, true), (1, true)); - assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false)); - assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false)); - assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true)); - } + assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false)); + assert_eq!($T::MIN.carrying_add(0, true), (1, false)); + assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true)); + } - #[test] - fn test_midpoint() { - assert_eq!(<$T>::midpoint(1, 3), 2); - assert_eq!(<$T>::midpoint(3, 1), 2); - - assert_eq!(<$T>::midpoint(0, 0), 0); - assert_eq!(<$T>::midpoint(0, 2), 1); - assert_eq!(<$T>::midpoint(2, 0), 1); - assert_eq!(<$T>::midpoint(2, 2), 2); - - assert_eq!(<$T>::midpoint(1, 4), 2); - assert_eq!(<$T>::midpoint(4, 1), 2); - assert_eq!(<$T>::midpoint(3, 4), 3); - assert_eq!(<$T>::midpoint(4, 3), 3); - - assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2); - assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2); - assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); - assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); - - assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); - assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); - assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3); - assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3); - } + #[test] + fn test_borrowing_sub() { + assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true)); + assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true)); + + assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false)); + assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false)); + assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true)); + } + + #[test] + fn test_midpoint() { + assert_eq!(<$T>::midpoint(1, 3), 2); + assert_eq!(<$T>::midpoint(3, 1), 2); + + assert_eq!(<$T>::midpoint(0, 0), 0); + assert_eq!(<$T>::midpoint(0, 2), 1); + assert_eq!(<$T>::midpoint(2, 0), 1); + assert_eq!(<$T>::midpoint(2, 2), 2); + + assert_eq!(<$T>::midpoint(1, 4), 2); + assert_eq!(<$T>::midpoint(4, 1), 2); + assert_eq!(<$T>::midpoint(3, 4), 3); + assert_eq!(<$T>::midpoint(4, 3), 3); + + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2); + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); + + assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3); } }; } From c31b9fa42556bc5961b779122522b569b2845a47 Mon Sep 17 00:00:00 2001 From: bohan Date: Mon, 26 Aug 2024 09:24:42 +0800 Subject: [PATCH 059/102] mv `build_reduced_graph_for_external_crate_res` into Resolver --- .../rustc_resolve/src/build_reduced_graph.rs | 139 +++++++++--------- 1 file changed, 71 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index fee42ba87c95b..2ac7b200452f4 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -197,8 +197,77 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) { for child in self.tcx.module_children(module.def_id()) { let parent_scope = ParentScope::module(module, self); - BuildReducedGraphVisitor { r: self, parent_scope } - .build_reduced_graph_for_external_crate_res(child); + self.build_reduced_graph_for_external_crate_res(child, parent_scope) + } + } + + /// Builds the reduced graph for a single item in an external crate. + fn build_reduced_graph_for_external_crate_res( + &mut self, + child: &ModChild, + parent_scope: ParentScope<'a>, + ) { + let parent = parent_scope.module; + let ModChild { ident, res, vis, ref reexport_chain } = *child; + let span = self.def_span( + reexport_chain + .first() + .and_then(|reexport| reexport.id()) + .unwrap_or_else(|| res.def_id()), + ); + let res = res.expect_non_local(); + let expansion = parent_scope.expansion; + // Record primary definitions. + match res { + Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => { + let module = self.expect_module(def_id); + self.define(parent, ident, TypeNS, (module, vis, span, expansion)); + } + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Variant + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::OpaqueTy + | DefKind::TraitAlias + | DefKind::AssocTy, + _, + ) + | Res::PrimTy(..) + | Res::ToolMod => self.define(parent, ident, TypeNS, (res, vis, span, expansion)), + Res::Def( + DefKind::Fn + | DefKind::AssocFn + | DefKind::Static { .. } + | DefKind::Const + | DefKind::AssocConst + | DefKind::Ctor(..), + _, + ) => self.define(parent, ident, ValueNS, (res, vis, span, expansion)), + Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { + self.define(parent, ident, MacroNS, (res, vis, span, expansion)) + } + Res::Def( + DefKind::TyParam + | DefKind::ConstParam + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Closure + | DefKind::Impl { .. }, + _, + ) + | Res::Local(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + | Res::SelfCtor(..) + | Res::Err => bug!("unexpected resolution: {:?}", res), } } } @@ -967,72 +1036,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } } - /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) { - let parent = self.parent_scope.module; - let ModChild { ident, res, vis, ref reexport_chain } = *child; - let span = self.r.def_span( - reexport_chain - .first() - .and_then(|reexport| reexport.id()) - .unwrap_or_else(|| res.def_id()), - ); - let res = res.expect_non_local(); - let expansion = self.parent_scope.expansion; - // Record primary definitions. - match res { - Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => { - let module = self.r.expect_module(def_id); - self.r.define(parent, ident, TypeNS, (module, vis, span, expansion)); - } - Res::Def( - DefKind::Struct - | DefKind::Union - | DefKind::Variant - | DefKind::TyAlias - | DefKind::ForeignTy - | DefKind::OpaqueTy - | DefKind::TraitAlias - | DefKind::AssocTy, - _, - ) - | Res::PrimTy(..) - | Res::ToolMod => self.r.define(parent, ident, TypeNS, (res, vis, span, expansion)), - Res::Def( - DefKind::Fn - | DefKind::AssocFn - | DefKind::Static { .. } - | DefKind::Const - | DefKind::AssocConst - | DefKind::Ctor(..), - _, - ) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)), - Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.r.define(parent, ident, MacroNS, (res, vis, span, expansion)) - } - Res::Def( - DefKind::TyParam - | DefKind::ConstParam - | DefKind::ExternCrate - | DefKind::Use - | DefKind::ForeignMod - | DefKind::AnonConst - | DefKind::InlineConst - | DefKind::Field - | DefKind::LifetimeParam - | DefKind::GlobalAsm - | DefKind::Closure - | DefKind::Impl { .. }, - _, - ) - | Res::Local(..) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } - | Res::SelfCtor(..) - | Res::Err => bug!("unexpected resolution: {:?}", res), - } - } - fn add_macro_use_binding( &mut self, name: Symbol, From 6982785f18de964e8f678ad3af7fb0af5d01daa8 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 Aug 2024 06:46:56 +0000 Subject: [PATCH 060/102] Tie `impl_trait_overcaptures` lint to Rust 2024 The `impl_trait_overcaptures` lint is part of the migration to Rust 2024 and the Lifetime Capture Rules 2024. Now that we've stabilized precise capturing (RFC 3617), let's tie this lint to the `rust_2024_compatibility` lint group. --- .../rustc_lint/src/impl_trait_overcaptures.rs | 10 ++++++---- .../precise-capturing/overcaptures-2024.fixed | 4 ++++ .../precise-capturing/overcaptures-2024.rs | 4 ++++ .../overcaptures-2024.stderr | 20 +++++++++++++------ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 990fb2d16f9dd..49767842266cc 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -10,7 +10,9 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_session::lint::FutureIncompatibilityReason; use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::edition::Edition; use rustc_span::Span; use crate::{fluent_generated as fluent, LateContext, LateLintPass}; @@ -54,10 +56,10 @@ declare_lint! { pub IMPL_TRAIT_OVERCAPTURES, Allow, "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", - //@future_incompatible = FutureIncompatibleInfo { - // reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - // reference: "", - //}; + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + reference: "", + }; } declare_lint! { diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed index 6bca8ef12ecc3..89a3f3136c82a 100644 --- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed @@ -5,14 +5,17 @@ fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x } //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 fn implicit(x: &i32) -> impl Sized + use<> { *x } //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 struct W; impl W { fn hello(&self, x: &i32) -> impl Sized + '_ + use<'_> { self } //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 + //~| WARN this changes meaning in Rust 2024 } trait Higher<'a> { @@ -24,5 +27,6 @@ impl Higher<'_> for () { fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized + use<>> {} //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs index 5b6726b49e025..18c04f9f799cb 100644 --- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs @@ -5,14 +5,17 @@ fn named<'a>(x: &'a i32) -> impl Sized { *x } //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 fn implicit(x: &i32) -> impl Sized { *x } //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 struct W; impl W { fn hello(&self, x: &i32) -> impl Sized + '_ { self } //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 + //~| WARN this changes meaning in Rust 2024 } trait Higher<'a> { @@ -24,5 +27,6 @@ impl Higher<'_> for () { fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 +//~| WARN this changes meaning in Rust 2024 fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr index fec640aa83aa9..94dafb04d64ad 100644 --- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr @@ -4,6 +4,8 @@ error: `impl Sized` will capture more lifetimes than possibly intended in editio LL | fn named<'a>(x: &'a i32) -> impl Sized { *x } | ^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see note: specifically, this lifetime is in scope but not mentioned in the type's bounds --> $DIR/overcaptures-2024.rs:6:10 | @@ -21,13 +23,15 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x } | +++++++ error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 - --> $DIR/overcaptures-2024.rs:9:25 + --> $DIR/overcaptures-2024.rs:10:25 | LL | fn implicit(x: &i32) -> impl Sized { *x } | ^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see note: specifically, this lifetime is in scope but not mentioned in the type's bounds - --> $DIR/overcaptures-2024.rs:9:16 + --> $DIR/overcaptures-2024.rs:10:16 | LL | fn implicit(x: &i32) -> impl Sized { *x } | ^ @@ -38,13 +42,15 @@ LL | fn implicit(x: &i32) -> impl Sized + use<> { *x } | +++++++ error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 - --> $DIR/overcaptures-2024.rs:14:33 + --> $DIR/overcaptures-2024.rs:16:33 | LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } | ^^^^^^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see note: specifically, this lifetime is in scope but not mentioned in the type's bounds - --> $DIR/overcaptures-2024.rs:14:24 + --> $DIR/overcaptures-2024.rs:16:24 | LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } | ^ @@ -55,13 +61,15 @@ LL | fn hello(&self, x: &i32) -> impl Sized + '_ + use<'_> { self } | +++++++++ error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 - --> $DIR/overcaptures-2024.rs:25:47 + --> $DIR/overcaptures-2024.rs:28:47 | LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} | ^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see note: specifically, this lifetime is in scope but not mentioned in the type's bounds - --> $DIR/overcaptures-2024.rs:25:23 + --> $DIR/overcaptures-2024.rs:28:23 | LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} | ^^ From fe2975076f1f84ff892cf95655268985e3550948 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 16:03:29 +0200 Subject: [PATCH 061/102] float types: document NaN bit pattern guarantees --- library/core/src/num/f128.rs | 30 ++++++++----- library/core/src/num/f16.rs | 30 ++++++++----- library/core/src/num/f32.rs | 14 +++--- library/core/src/num/f64.rs | 14 +++--- library/core/src/primitive_docs.rs | 71 ++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 36 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 38e69e7641ab4..d4236e47bfe3b 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -454,11 +454,14 @@ impl f128 { } /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with - /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any - /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that - /// the bit pattern of NaNs are conserved over arithmetic operations, the result of - /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. - /// See [explanation of NaN as a special value](f128) for more info. + /// positive sign bit and positive infinity. + /// + /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of + /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are + /// conserved over arithmetic operations, the result of `is_sign_positive` on + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// #![feature(f128)] @@ -477,11 +480,14 @@ impl f128 { } /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with - /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any - /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that - /// the bit pattern of NaNs are conserved over arithmetic operations, the result of - /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. - /// See [explanation of NaN as a special value](f128) for more info. + /// negative sign bit and negative infinity. + /// + /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of + /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are + /// conserved over arithmetic operations, the result of `is_sign_negative` on + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// #![feature(f128)] @@ -750,7 +756,7 @@ impl f128 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f128) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] @@ -791,7 +797,7 @@ impl f128 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f128) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index bb0cc1c60ba5a..1e2f841aca733 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -464,11 +464,14 @@ impl f16 { } /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with - /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any - /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that - /// the bit pattern of NaNs are conserved over arithmetic operations, the result of - /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. - /// See [explanation of NaN as a special value](f16) for more info. + /// positive sign bit and positive infinity. + /// + /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of + /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are + /// conserved over arithmetic operations, the result of `is_sign_positive` on + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// #![feature(f16)] @@ -490,11 +493,14 @@ impl f16 { } /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with - /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any - /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that - /// the bit pattern of NaNs are conserved over arithmetic operations, the result of - /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. - /// See [explanation of NaN as a special value](f16) for more info. + /// negative sign bit and negative infinity. + /// + /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of + /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are + /// conserved over arithmetic operations, the result of `is_sign_negative` on + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// #![feature(f16)] @@ -762,7 +768,7 @@ impl f16 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f16) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] @@ -802,7 +808,7 @@ impl f16 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f16) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 719727e2f1e0a..c1adcc753f2e5 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -700,8 +700,9 @@ impl f32 { /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are /// conserved over arithmetic operations, the result of `is_sign_positive` on - /// a NaN might produce an unexpected result in some cases. See [explanation - /// of NaN as a special value](f32) for more info. + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// let f = 7.0_f32; @@ -724,8 +725,9 @@ impl f32 { /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are /// conserved over arithmetic operations, the result of `is_sign_negative` on - /// a NaN might produce an unexpected result in some cases. See [explanation - /// of NaN as a special value](f32) for more info. + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// let f = 7.0f32; @@ -954,7 +956,7 @@ impl f32 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -989,7 +991,7 @@ impl f32 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 85eb152ad1f19..e6406771ad333 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -695,8 +695,9 @@ impl f64 { /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are /// conserved over arithmetic operations, the result of `is_sign_positive` on - /// a NaN might produce an unexpected result in some cases. See [explanation - /// of NaN as a special value](f32) for more info. + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// let f = 7.0_f64; @@ -728,8 +729,9 @@ impl f64 { /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are /// conserved over arithmetic operations, the result of `is_sign_negative` on - /// a NaN might produce an unexpected result in some cases. See [explanation - /// of NaN as a special value](f32) for more info. + /// a NaN might produce an unexpected or non-portable result. See the [specification + /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0` + /// if you need fully portable behavior (will return `false` for all NaNs). /// /// ``` /// let f = 7.0_f64; @@ -968,7 +970,7 @@ impl f64 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -1003,7 +1005,7 @@ impl f64 { /// Note that this follows the semantics specified in IEEE 754-2019. /// /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN - /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. + /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 09ebef89fb0c2..e0593b1c0e75d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1190,6 +1190,11 @@ mod prim_f16 {} /// portable or even fully deterministic! This means that there may be some /// surprising results upon inspecting the bit patterns, /// as the same calculations might produce NaNs with different bit patterns. +/// This also affects the sign of the NaN: checking `is_sign_positive` or `is_sign_negative` on +/// a NaN is the most common way to run into these surprising results. +/// (Checking `x >= 0.0` or `x <= 0.0` avoids those surprises, but also how negative/positive +/// zero are treated.) +/// See the section below for what exactly is guaranteed about the bit pattern of a NaN. /// /// When a primitive operation (addition, subtraction, multiplication, or /// division) is performed on this type, the result is rounded according to the @@ -1211,6 +1216,72 @@ mod prim_f16 {} /// *[See also the `std::f32::consts` module](crate::f32::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format +/// +/// # NaN bit patterns +/// +/// This section defines the possible NaN bit patterns returned by non-"bitwise" floating point +/// operations. The bitwise operations are unary `-`, `abs`, `copysign`; those are guaranteed to +/// exactly preserve the bit pattern of their input except for possibly changing the sign bit. +/// +/// A floating-point NaN value consists of: +/// - a sign bit +/// - a quiet/signaling bit +/// - a payload, which makes up the rest of the significand (i.e., the mantissa) except for the +/// quiet/signaling bit. +/// +/// Rust assumes that the quiet/signaling bit being set to `1` indicates a quiet NaN (QNaN), and a +/// value of `0` indicates a signaling NaN (SNaN). In the following we will hence just call it the +/// "quiet bit". +/// +/// The following rules apply when a NaN value is returned: the result has a non-deterministic sign. +/// The quiet bit and payload are non-deterministically chosen from the following set of options: +/// +/// - **Preferred NaN**: The quiet bit is set and the payload is all-zero. +/// - **Quieting NaN propagation**: The quiet bit is set and the payload is copied from any input +/// operand that is a NaN. If the inputs and outputs do not have the same payload size (i.e., for +/// `as` casts), then +/// - If the output is smaller than the input, low-order bits of the payload get dropped. +/// - If the output is larger than the input, the payload gets filled up with 0s in the low-order +/// bits. +/// - **Unchanged NaN propagation**: The quiet bit and payload are copied from any input operand +/// that is a NaN. If the inputs and outputs do not have the same size (i.e., for `as` casts), the +/// same rules as for "quieting NaN propagation" apply, with one caveat: if the output is smaller +/// than the input, droppig the low-order bits may result in a payload of 0; a payload of 0 is not +/// possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN +/// propagation cannot occur with some inputs. +/// - **Target-specific NaN**: The quiet bit is set and the payload is picked from a target-specific +/// set of "extra" possible NaN payloads. The set can depend on the input operand values. This set +/// is empty on x86, ARM, and RISC-V (32bit and 64bit), but can be non-empty on other +/// architectures. Targets where this set is non-empty should document this in a suitable +/// location, e.g. their platform support page. (For instance, on wasm, if any input NaN does not +/// have the preferred all-zero payload or any input NaN is an SNaN, then this set contains all +/// possible payloads; otherwise, it is empty. On SPARC, this set consists of the all-one +/// payload.) +/// +/// In particular, if all input NaNs are quiet (or if there are no input NaNs), then the output NaN +/// is definitely quiet. Signaling NaN outputs can only occur if they are provided as an input +/// value. Similarly, if all input NaNs are preferred (or if there are no input NaNs) and the target +/// does not have any "extra" NaN payloads, then the output NaN is guaranteed to be preferred. +/// +/// The non-deterministic choice happens when the operation is executed; i.e., the result of a +/// NaN-producing floating point operation is a stable bit pattern (looking at these bits multiple +/// times will yield consistent results), but running the same operation twice with the same inputs +/// can produce different results. +/// +/// These guarantees are neither stronger nor weaker than those of IEEE 754: IEEE 754 guarantees +/// that an operation never returns a signaling NaN, whereas it is possible for operations like +/// `SNAN * 1.0` to return a signaling NaN in Rust. Conversely, IEEE 754 makes no statement at all +/// about which quiet NaN is returned, whereas Rust restricts the set of possible results to the +/// ones listed above. +/// +/// Unless noted otherwise, the same rules also apply to NaNs returned by other library functions +/// (e.g. `min`, `minimum`, `max`, `maximum`); other aspects of their semantics and which IEEE 754 +/// operation they correspond to are documented with the respective functions. +/// +/// When a floating-point operation is executed in `const` context, the same rules apply: no +/// guarantee is made about which of the NaN bit patterns described above will be returned. The +/// result does not have to match what happens when executing the same code at runtime, and the +/// result can vary depending on factors such as compiler version and flags. #[stable(feature = "rust1", since = "1.0.0")] mod prim_f32 {} From 53d4544628c0134a6b4d7edd971539dd8e655269 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2024 17:16:53 +0200 Subject: [PATCH 062/102] move per-target NaN info into a table --- library/core/src/primitive_docs.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index e0593b1c0e75d..7f35c7789e281 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1250,13 +1250,8 @@ mod prim_f16 {} /// possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN /// propagation cannot occur with some inputs. /// - **Target-specific NaN**: The quiet bit is set and the payload is picked from a target-specific -/// set of "extra" possible NaN payloads. The set can depend on the input operand values. This set -/// is empty on x86, ARM, and RISC-V (32bit and 64bit), but can be non-empty on other -/// architectures. Targets where this set is non-empty should document this in a suitable -/// location, e.g. their platform support page. (For instance, on wasm, if any input NaN does not -/// have the preferred all-zero payload or any input NaN is an SNaN, then this set contains all -/// possible payloads; otherwise, it is empty. On SPARC, this set consists of the all-one -/// payload.) +/// set of "extra" possible NaN payloads. The set can depend on the input operand values. +/// See the table below for the concrete NaNs this set contains on various targets. /// /// In particular, if all input NaNs are quiet (or if there are no input NaNs), then the output NaN /// is definitely quiet. Signaling NaN outputs can only occur if they are provided as an input @@ -1282,6 +1277,18 @@ mod prim_f16 {} /// guarantee is made about which of the NaN bit patterns described above will be returned. The /// result does not have to match what happens when executing the same code at runtime, and the /// result can vary depending on factors such as compiler version and flags. +/// +/// ### Target-specific "extra" NaN values +// FIXME: Is there a better place to put this? +/// +/// | `target_arch` | Extra payloads possible on this platform | +/// |---------------|---------| +/// | `x86`, `x86_64`, `arm`, `aarch64`, `riscv32`, `riscv64` | None | +/// | `sparc`, `sparc64` | The all-one payload | +/// | `wasm32`, `wasm64` | If all input NaNs are quiet with all-zero payload: None.
Otherwise: all possible payloads. | +/// +/// For targets not in this table, all payloads are possible. + #[stable(feature = "rust1", since = "1.0.0")] mod prim_f32 {} From 0c7d6c45e6b664fa4875741e78d185845d374f07 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Aug 2024 17:25:24 +0200 Subject: [PATCH 063/102] also update copysign docs --- library/std/src/f128.rs | 10 +++++----- library/std/src/f16.rs | 10 +++++----- library/std/src/f32.rs | 10 +++++----- library/std/src/f64.rs | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index f6df6259137bf..506d708d0d2eb 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -248,11 +248,11 @@ impl f128 { /// Returns a number composed of the magnitude of `self` and the sign of /// `sign`. /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of - /// `sign` is returned. Note, however, that conserving the sign bit on NaN - /// across arithmetical operations is not generally guaranteed. - /// See [explanation of NaN as a special value](primitive@f128) for more info. + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations + /// is not generally guaranteed. See [specification of NaN bit + /// patterns](primitive@f32#nan-bit-patterns) for more info. /// /// # Examples /// diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index 10908332762d5..033a3d4500932 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -247,11 +247,11 @@ impl f16 { /// Returns a number composed of the magnitude of `self` and the sign of /// `sign`. /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of - /// `sign` is returned. Note, however, that conserving the sign bit on NaN - /// across arithmetical operations is not generally guaranteed. - /// See [explanation of NaN as a special value](primitive@f16) for more info. + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations + /// is not generally guaranteed. See [specification of NaN bit + /// patterns](primitive@f32#nan-bit-patterns) for more info. /// /// # Examples /// diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 12433d25bfa45..35c2a77b5338d 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -226,11 +226,11 @@ impl f32 { /// Returns a number composed of the magnitude of `self` and the sign of /// `sign`. /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of - /// `sign` is returned. Note, however, that conserving the sign bit on NaN - /// across arithmetical operations is not generally guaranteed. - /// See [explanation of NaN as a special value](primitive@f32) for more info. + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations + /// is not generally guaranteed. See [specification of NaN bit + /// patterns](primitive@f32#nan-bit-patterns) for more info. /// /// # Examples /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index a343e19173e59..c177f74a97e15 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -226,11 +226,11 @@ impl f64 { /// Returns a number composed of the magnitude of `self` and the sign of /// `sign`. /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of - /// `sign` is returned. Note, however, that conserving the sign bit on NaN - /// across arithmetical operations is not generally guaranteed. - /// See [explanation of NaN as a special value](primitive@f32) for more info. + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations + /// is not generally guaranteed. See [specification of NaN bit + /// patterns](primitive@f32#nan-bit-patterns) for more info. /// /// # Examples /// From 00c435d9b37540d16489862446d934e98e58dfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Aug 2024 18:59:26 +0000 Subject: [PATCH 064/102] Do not ICE on non-ADT rcvr type when looking for crate version collision When looking for multiple versions of the same crate, do not blindly construct the receiver type. Follow up to #128786. Fix #129205. --- .../rustc_hir_typeck/src/method/suggest.rs | 14 ++++++++------ .../missing-method-on-type-parameter.rs | 6 ++++++ .../missing-method-on-type-parameter.stderr | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 tests/ui/methods/missing-method-on-type-parameter.rs create mode 100644 tests/ui/methods/missing-method-on-type-parameter.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index ffd46ea13b908..8b8bb29dacdbd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3498,7 +3498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err, pick.item.def_id, rcvr.hir_id, - *rcvr_ty, + Some(*rcvr_ty), ); if pick.autoderefs == 0 && !trait_in_other_version_found { err.span_label( @@ -3689,8 +3689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::QPath(ty) = source && !valid_out_of_scope_traits.is_empty() && let hir::TyKind::Path(path) = ty.kind - && let hir::QPath::Resolved(_, path) = path - && let Some(def_id) = path.res.opt_def_id() + && let hir::QPath::Resolved(..) = path && let Some(assoc) = self .tcx .associated_items(valid_out_of_scope_traits[0]) @@ -3700,7 +3699,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // See if the `Type::function(val)` where `function` wasn't found corresponds to a // `Trait` that is imported directly, but `Type` came from a different version of the // same crate. - let rcvr_ty = self.tcx.type_of(def_id).instantiate_identity(); + + let rcvr_ty = self.node_ty_opt(ty.hir_id); trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions( err, assoc.def_id, @@ -4080,7 +4080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err: &mut Diag<'_>, item_def_id: DefId, hir_id: hir::HirId, - rcvr_ty: Ty<'_>, + rcvr_ty: Option>, ) -> bool { let hir_id = self.tcx.parent_hir_id(hir_id); let Some(traits) = self.tcx.in_scope_traits(hir_id) else { return false }; @@ -4110,8 +4110,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut multi_span: MultiSpan = trait_span.into(); multi_span.push_span_label(trait_span, format!("this is the trait that is needed")); let descr = self.tcx.associated_item(item_def_id).descr(); + let rcvr_ty = + rcvr_ty.map(|t| format!("`{t}`")).unwrap_or_else(|| "the receiver".to_string()); multi_span - .push_span_label(item_span, format!("the {descr} is available for `{rcvr_ty}` here")); + .push_span_label(item_span, format!("the {descr} is available for {rcvr_ty} here")); for (def_id, import_def_id) in candidates { if let Some(import_def_id) = import_def_id { multi_span.push_span_label( diff --git a/tests/ui/methods/missing-method-on-type-parameter.rs b/tests/ui/methods/missing-method-on-type-parameter.rs new file mode 100644 index 0000000000000..cbcbeea4d4cd0 --- /dev/null +++ b/tests/ui/methods/missing-method-on-type-parameter.rs @@ -0,0 +1,6 @@ +// Regression test for https://github.com/rust-lang/rust/issues/129205 +fn x() { + T::try_from(); //~ ERROR E0599 +} + +fn main() {} diff --git a/tests/ui/methods/missing-method-on-type-parameter.stderr b/tests/ui/methods/missing-method-on-type-parameter.stderr new file mode 100644 index 0000000000000..c53d7afe4e2d9 --- /dev/null +++ b/tests/ui/methods/missing-method-on-type-parameter.stderr @@ -0,0 +1,19 @@ +error[E0599]: no function or associated item named `try_from` found for type parameter `T` in the current scope + --> $DIR/missing-method-on-type-parameter.rs:3:8 + | +LL | fn x() { + | - function or associated item `try_from` not found for this type parameter +LL | T::try_from(); + | ^^^^^^^^ function or associated item not found in `T` + | + = help: items from traits can only be used if the trait is in scope +help: there is an associated function `from` with a similar name + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL +help: trait `TryFrom` which provides `try_from` is implemented but not in scope; perhaps you want to import it + | +LL + use std::convert::TryFrom; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. From 4a088d90708830ac6217554545badb89904f19b0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 26 Aug 2024 13:07:01 -0400 Subject: [PATCH 065/102] Remove crashes from type_of on resolution that doesn't have a type_of --- tests/crashes/129205.rs | 5 ----- tests/crashes/129216.rs | 12 ------------ 2 files changed, 17 deletions(-) delete mode 100644 tests/crashes/129205.rs delete mode 100644 tests/crashes/129216.rs diff --git a/tests/crashes/129205.rs b/tests/crashes/129205.rs deleted file mode 100644 index f328fca247ac5..0000000000000 --- a/tests/crashes/129205.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: rust-lang/rust#129205 - -fn x() { - T::try_from(); -} diff --git a/tests/crashes/129216.rs b/tests/crashes/129216.rs deleted file mode 100644 index 0ad6bc5c71baf..0000000000000 --- a/tests/crashes/129216.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: rust-lang/rust#129216 -//@ only-linux - -trait Mirror { - type Assoc; -} - -struct Foo; - -fn main() { - ::Assoc::new(); -} From ebf46f760774f63a8025f1ead3cf359e88aaa103 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 18 Jul 2024 12:44:59 -0300 Subject: [PATCH 066/102] Add unsafe to extern blocks in style guide --- src/doc/style-guide/src/items.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 8e1b1d80fb644..5ea8b6cd54294 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -449,8 +449,8 @@ entries, format it across multiple lines as with a type alias. ## extern items When writing extern items (such as `extern "C" fn`), always specify the ABI. -For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or -`extern "C" { ... }`. +For example, write `extern "C" fn foo ...` or `unsafe extern "C" { ...}` +and avoid `extern fn foo ...` and `unsafe extern { ... }`. ## Imports (`use` statements) From 5d0ce4c3918b1d5cd925c945ecf37f49bf11d4e4 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Mon, 26 Aug 2024 12:22:17 -0700 Subject: [PATCH 067/102] Note that std support is WIP --- src/doc/rustc/src/platform-support/trusty.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md index 97a03d3de04c2..dec3b96ff6449 100644 --- a/src/doc/rustc/src/platform-support/trusty.md +++ b/src/doc/rustc/src/platform-support/trusty.md @@ -13,12 +13,10 @@ Environment (TEE) for Android. ## Requirements -This target is cross-compiled. It has no special requirements for the host. +These targets are cross-compiled. They have no special requirements for the host. -It fully supports alloc with the default allocator, and partially supports std. -Notably, most I/O functionality is not supported, e.g. filesystem support and -networking support are not present and any APIs that rely on them will panic at -runtime. +Support for the standard library is work-in-progress. It is expected that +they will support alloc with the default allocator, and partially support std. Trusty uses the ELF file format. From b11e0a883b0e932edb79ebba17e09952c8eb0084 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 26 Aug 2024 12:36:58 -0700 Subject: [PATCH 068/102] Apply suggestions from code review --- library/core/src/ptr/const_ptr.rs | 4 ++-- library/core/src/ptr/mod.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 8 ++++---- library/core/src/ptr/non_null.rs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index d7eea937ef847..77fb2e8abb9f0 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -286,7 +286,7 @@ impl *const T { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// @@ -317,7 +317,7 @@ impl *const T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index a7d6602287b90..338659c46ed9c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -72,7 +72,7 @@ //! * The pointer must point to a valid value of type `T`. //! This means that the created reference can only refer to //! uninitialized memory through careful use of `MaybeUninit`, -//! or if the uninitialized memory is entirly contained within +//! or if the uninitialized memory is entirely contained within //! padding bytes, since //! [padding has the same validity invariant as `MaybeUninit`][ucg-pad]. //! diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index d7bb18590ed5e..64ed5a98bce8e 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -247,7 +247,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// @@ -296,7 +296,7 @@ impl *mut T { /// /// # Safety /// - /// When calling this method, you have to ensure that the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// When calling this method, you have to ensure that the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// @@ -616,7 +616,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// @@ -651,7 +651,7 @@ impl *mut T { /// # Safety /// /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 5d5d9d401a295..ee9f23d61c787 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -342,7 +342,7 @@ impl NonNull { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// /// # Examples /// @@ -379,7 +379,7 @@ impl NonNull { /// # Safety /// /// When calling this method, you have to ensure that - /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion) + /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// # Examples /// /// ``` From 4e1555462f136d3d1f312537d189c9b8d7bc921a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:52:14 +0000 Subject: [PATCH 069/102] Remove a couple of unused feature enables --- compiler/rustc_infer/src/lib.rs | 2 -- compiler/rustc_macros/src/lib.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 25ac8ba974bb6..30dc666128cb1 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -27,8 +27,6 @@ #![feature(iterator_try_collect)] #![feature(let_chains)] #![feature(rustdoc_internals)] -#![feature(try_blocks)] -#![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index c59f86b0a9bbe..929bc2df6f6b5 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,7 +1,5 @@ // tidy-alphabetical-start -#![allow(internal_features)] #![allow(rustc::default_hash_types)] -#![feature(allow_internal_unstable)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(never_type)] From b4d3fa4829c5366d1b7837f0d73c67def517b66d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 26 Aug 2024 14:41:21 -0400 Subject: [PATCH 070/102] Remove ParamMode::ExplicitNamed --- compiler/rustc_ast_lowering/src/item.rs | 13 +------------ compiler/rustc_ast_lowering/src/lib.rs | 2 -- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index eef87879c2492..258a6cdf60e8b 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -764,18 +764,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, (index, f): (usize, &FieldDef), ) -> hir::FieldDef<'hir> { - let ty = if let TyKind::Path(qself, path) = &f.ty.kind { - let t = self.lower_path_ty( - &f.ty, - qself, - path, - ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124) - ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy), - ); - self.arena.alloc(t) - } else { - self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)) - }; + let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)); let hir_id = self.lower_node_id(f.id); self.lower_attrs(hir_id, &f.attrs); hir::FieldDef { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4b8c47ac4b411..b968860a85e6a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -481,8 +481,6 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { enum ParamMode { /// Any path in a type context. Explicit, - /// Path in a type definition, where the anonymous lifetime `'_` is not allowed. - ExplicitNamed, /// The `module::Type` in `module::Type::method` in an expression. Optional, } From 2db1d2e261187fd8031af91b6af168100f453e4f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 26 Aug 2024 13:59:21 -0400 Subject: [PATCH 071/102] Rename ParenthesizedGenericArgs to GenericArgsMode --- compiler/rustc_ast_lowering/src/delegation.rs | 4 +- compiler/rustc_ast_lowering/src/expr.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 37 +++++++++---------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 9c073130827c8..800773482041a 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -51,7 +51,7 @@ use rustc_span::Span; use rustc_target::spec::abi; use {rustc_ast as ast, rustc_hir as hir}; -use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; +use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; use crate::{ImplTraitPosition, ResolverAstLoweringExt}; pub(crate) struct DelegationResults<'hir> { @@ -323,7 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> { delegation.path.span, ast_segment, ParamMode::Optional, - ParenthesizedGenericArgs::Err, + GenericArgsMode::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index bb86e5c9325f9..a6c7714a182bf 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -20,7 +20,7 @@ use super::errors::{ NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign, }; use super::{ - ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs, ResolverAstLoweringExt, + GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt, }; use crate::errors::YieldInClosure; use crate::{fluent_generated, FnDeclKind, ImplTraitPosition}; @@ -107,7 +107,7 @@ impl<'hir> LoweringContext<'_, 'hir> { e.span, seg, ParamMode::Optional, - ParenthesizedGenericArgs::Err, + GenericArgsMode::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), // Method calls can't have bound modifiers None, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4b8c47ac4b411..939517d7ef5a0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -487,7 +487,7 @@ enum ParamMode { Optional, } -enum ParenthesizedGenericArgs { +enum GenericArgsMode { ParenSugar, Err, } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 077b06acd7c8c..2ab30eff6d864 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -15,8 +15,8 @@ use super::errors::{ GenericTypeWithParentheses, UseAngleBrackets, }; use super::{ - GenericArgsCtor, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode, - ParenthesizedGenericArgs, ResolverAstLoweringExt, + GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode, + ResolverAstLoweringExt, }; use crate::ImplTraitPosition; @@ -90,10 +90,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { _ => param_mode, }; - let parenthesized_generic_args = match base_res { + let generic_args_mode = match base_res { // `a::b::Trait(Args)` Res::Def(DefKind::Trait, _) if i + 1 == proj_start => { - ParenthesizedGenericArgs::ParenSugar + GenericArgsMode::ParenSugar } // `a::b::Trait(Args)::TraitItem` Res::Def(DefKind::AssocFn, _) @@ -101,19 +101,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => { - ParenthesizedGenericArgs::ParenSugar + GenericArgsMode::ParenSugar } // Avoid duplicated errors. - Res::Err => ParenthesizedGenericArgs::ParenSugar, + Res::Err => GenericArgsMode::ParenSugar, // An error - _ => ParenthesizedGenericArgs::Err, + _ => GenericArgsMode::Err, }; self.lower_path_segment( p.span, segment, param_mode, - parenthesized_generic_args, + generic_args_mode, itctx, bound_modifier_allowed_features.clone(), ) @@ -168,7 +168,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p.span, segment, param_mode, - ParenthesizedGenericArgs::Err, + GenericArgsMode::Err, itctx, None, )); @@ -210,7 +210,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p.span, segment, param_mode, - ParenthesizedGenericArgs::Err, + GenericArgsMode::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ) @@ -224,7 +224,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path_span: Span, segment: &PathSegment, param_mode: ParamMode, - parenthesized_generic_args: ParenthesizedGenericArgs, + generic_args_mode: GenericArgsMode, itctx: ImplTraitContext, // Additional features ungated with a bound modifier like `async`. // This is passed down to the implicit associated type binding in @@ -237,14 +237,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } - GenericArgs::Parenthesized(data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::ParenSugar => self - .lower_parenthesized_parameter_data( - data, - itctx, - bound_modifier_allowed_features, - ), - ParenthesizedGenericArgs::Err => { + GenericArgs::Parenthesized(data) => match generic_args_mode { + GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data( + data, + itctx, + bound_modifier_allowed_features, + ), + GenericArgsMode::Err => { // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` let sub = if !data.inputs.is_empty() { // Start of the span to the 1st character of 1st argument From 4609841c078cde37c0e2ffb481059cb1bd330233 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 1 Aug 2024 13:05:17 -0400 Subject: [PATCH 072/102] Stop using a special inner body for the coroutine by-move body for async closures --- .../rustc_const_eval/src/interpret/call.rs | 1 - compiler/rustc_hir/src/def.rs | 11 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 3 +- compiler/rustc_hir_analysis/src/lib.rs | 4 - compiler/rustc_interface/src/passes.rs | 16 ++ compiler/rustc_metadata/src/rmeta/encoder.rs | 39 ++- compiler/rustc_metadata/src/rmeta/table.rs | 1 + compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 17 -- compiler/rustc_middle/src/mir/mono.rs | 1 - compiler/rustc_middle/src/mir/visit.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 15 + compiler/rustc_middle/src/ty/context.rs | 18 ++ compiler/rustc_middle/src/ty/instance.rs | 16 +- compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_mir_transform/src/coroutine.rs | 2 +- .../src/coroutine/by_move_body.rs | 264 +++++++++--------- compiler/rustc_mir_transform/src/inline.rs | 1 - .../rustc_mir_transform/src/inline/cycle.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 42 ++- .../rustc_mir_transform/src/pass_manager.rs | 6 - compiler/rustc_mir_transform/src/shim.rs | 12 +- compiler/rustc_mir_transform/src/validate.rs | 19 -- compiler/rustc_monomorphize/src/collector.rs | 1 - .../rustc_monomorphize/src/partitioning.rs | 2 - .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 3 +- .../rustc_resolve/src/build_reduced_graph.rs | 1 + .../rustc_smir/src/rustc_smir/convert/ty.rs | 1 - compiler/rustc_smir/src/rustc_smir/mod.rs | 4 +- compiler/rustc_symbol_mangling/src/legacy.rs | 3 - compiler/rustc_symbol_mangling/src/v0.rs | 1 - compiler/rustc_ty_utils/src/abi.rs | 33 --- compiler/rustc_ty_utils/src/implied_bounds.rs | 3 +- compiler/rustc_ty_utils/src/opaque_types.rs | 3 +- compiler/rustc_ty_utils/src/sig_types.rs | 2 +- src/librustdoc/formats/item_type.rs | 3 +- .../passes/collect_intra_doc_links.rs | 4 +- .../lint/unused/lint-unused-variables.stderr | 12 +- .../param-attrs-cfg.stderr | 12 +- 40 files changed, 283 insertions(+), 303 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 917a2fa7c6dd4..f99283c49f5ab 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -576,7 +576,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::InstanceKind::ReifyShim(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::FnPtrShim(..) | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 59204d799281f..b329432d1e1c0 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -133,6 +133,9 @@ pub enum DefKind { /// we treat them all the same, and code which needs to distinguish them can match /// or `hir::ClosureKind` or `type_of`. Closure, + /// The definition of a synthetic coroutine body created by the lowering of a + /// coroutine-closure, such as an async closure. + SyntheticCoroutineBody, } impl DefKind { @@ -177,6 +180,7 @@ impl DefKind { DefKind::Closure => "closure", DefKind::ExternCrate => "extern crate", DefKind::GlobalAsm => "global assembly block", + DefKind::SyntheticCoroutineBody => "synthetic mir body", } } @@ -236,7 +240,8 @@ impl DefKind { | DefKind::ForeignMod | DefKind::GlobalAsm | DefKind::Impl { .. } - | DefKind::OpaqueTy => None, + | DefKind::OpaqueTy + | DefKind::SyntheticCoroutineBody => None, } } @@ -276,6 +281,7 @@ impl DefKind { DefKind::GlobalAsm => DefPathData::GlobalAsm, DefKind::Impl { .. } => DefPathData::Impl, DefKind::Closure => DefPathData::Closure, + DefKind::SyntheticCoroutineBody => DefPathData::Closure, } } @@ -291,7 +297,8 @@ impl DefKind { | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure - | DefKind::Static { .. } => true, + | DefKind::Static { .. } + | DefKind::SyntheticCoroutineBody => true, DefKind::Mod | DefKind::Struct | DefKind::Union diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index fb9bcc113c64c..cb66179ec8047 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2174,7 +2174,8 @@ fn lint_redundant_lifetimes<'tcx>( | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Closure => return, + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => return, } // The ordering of this lifetime map is a bit subtle. diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 291d57f2a176f..6dbaf4fcffa73 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -200,10 +200,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } }); - // Freeze definitions as we don't add new ones at this point. This improves performance by - // allowing lock-free access to them. - tcx.untracked().definitions.freeze(); - // FIXME: Remove this when we implement creating `DefId`s // for anon constants during their parents' typeck. // Typeck all body owners in parallel will produce queries diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 96a6f52d60b6c..2a4367965eef3 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -784,7 +784,22 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { } ); }); + rustc_hir_analysis::check_crate(tcx); + sess.time("MIR_coroutine_by_move_body", || { + tcx.hir().par_body_owners(|def_id| { + if tcx.needs_coroutine_by_move_body_def_id(def_id) { + tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id); + } + }); + }); + // Freeze definitions as we don't add new ones at this point. + // We need to wait until now since we synthesize a by-move body + // This improves performance by allowing lock-free access to them. + // FIXME(async_closures): We could force `coroutine_by_move_body_def_id` + // immediately after typeck, then freeze after that. + tcx.untracked().definitions.freeze(); + sess.time("MIR_borrow_checking", || { tcx.hir().par_body_owners(|def_id| { // Run unsafety check because it's responsible for stealing and @@ -816,6 +831,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { ); } }); + sess.time("layout_testing", || layout_test::test_layout(tcx)); sess.time("abi_testing", || abi_test::test_abi(tcx)); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 0d83f8c6c5c93..3125fb245e7e3 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -872,7 +872,8 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::OpaqueTy | DefKind::Field | DefKind::Impl { .. } - | DefKind::Closure => true, + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => true, DefKind::ForeignMod | DefKind::GlobalAsm => false, } } @@ -902,6 +903,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { // https://github.com/model-checking/kani and is not a performance // or maintenance issue for us. DefKind::Closure => true, + DefKind::SyntheticCoroutineBody => false, DefKind::TyParam | DefKind::ConstParam | DefKind::Ctor(..) @@ -948,7 +950,8 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool { | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Closure => false, + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => false, } } @@ -984,7 +987,8 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::GlobalAsm | DefKind::Impl { .. } | DefKind::Closure - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, } } @@ -1019,7 +1023,8 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::InlineConst | DefKind::GlobalAsm | DefKind::Closure - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, } } @@ -1061,6 +1066,8 @@ fn should_encode_mir( } // Coroutines require optimized MIR to compute layout. DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true), + // FIXME: lol + DefKind::SyntheticCoroutineBody => (false, true), // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { let generics = tcx.generics_of(def_id); @@ -1109,7 +1116,8 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def | DefKind::InlineConst | DefKind::GlobalAsm | DefKind::Closure - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, DefKind::TyAlias => tcx.type_alias_is_lazy(def_id), } } @@ -1137,7 +1145,8 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::Impl { .. } | DefKind::Field | DefKind::TyParam - | DefKind::Closure => true, + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => true, DefKind::Mod | DefKind::ForeignMod | DefKind::ConstParam @@ -1168,7 +1177,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::Closure | DefKind::ConstParam | DefKind::AnonConst - | DefKind::InlineConst => true, + | DefKind::InlineConst + | DefKind::SyntheticCoroutineBody => true, DefKind::OpaqueTy => { let origin = tcx.opaque_type_origin(def_id); @@ -1240,7 +1250,8 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool { | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, } } @@ -1277,7 +1288,8 @@ fn should_encode_constness(def_kind: DefKind) -> bool { | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, } } @@ -1310,7 +1322,8 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::Use | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::ExternCrate => false, + | DefKind::ExternCrate + | DefKind::SyntheticCoroutineBody => false, } } @@ -1366,6 +1379,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); } + // FIXME(async_closures): We should just use `tcx.attrs` rather than going + // through the HIR. Historically, though, this has been inefficient apparently. + // For now, it's kind of pointless to fix, because coroutine-closures' coroutine + // bodies have no attrs anyways. if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } @@ -1458,7 +1475,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.associated_type_for_effects[def_id] <- assoc_def_id); } } - if def_kind == DefKind::Closure + if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) { self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind)) diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 617372a97b5b2..3a6f3543317f6 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -171,6 +171,7 @@ fixed_size_enum! { ( Macro(MacroKind::Bang) ) ( Macro(MacroKind::Attr) ) ( Macro(MacroKind::Derive) ) + ( SyntheticCoroutineBody ) } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0f85998204ccb..3d346b9cc5d0a 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -307,7 +307,7 @@ impl<'hir> Map<'hir> { } DefKind::InlineConst => BodyOwnerKind::Const { inline: true }, DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn, - DefKind::Closure => BodyOwnerKind::Closure, + DefKind::Closure | DefKind::SyntheticCoroutineBody => BodyOwnerKind::Closure, DefKind::Static { safety: _, mutability, nested: false } => { BodyOwnerKind::Static(mutability) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 5b2aac781ebad..7b90191503702 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -267,18 +267,6 @@ pub struct CoroutineInfo<'tcx> { /// Coroutine drop glue. This field is populated after the state transform pass. pub coroutine_drop: Option>, - /// The body of the coroutine, modified to take its upvars by move rather than by ref. - /// - /// This is used by coroutine-closures, which must return a different flavor of coroutine - /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which - /// is run right after building the initial MIR, and will only be populated for coroutines - /// which come out of the async closure desugaring. - /// - /// This body should be processed in lockstep with the containing body -- any optimization - /// passes, etc, should be applied to this body as well. This is done automatically if - /// using `run_passes`. - pub by_move_body: Option>, - /// The layout of a coroutine. This field is populated after the state transform pass. pub coroutine_layout: Option>, @@ -298,7 +286,6 @@ impl<'tcx> CoroutineInfo<'tcx> { coroutine_kind, yield_ty: Some(yield_ty), resume_ty: Some(resume_ty), - by_move_body: None, coroutine_drop: None, coroutine_layout: None, } @@ -665,10 +652,6 @@ impl<'tcx> Body<'tcx> { self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop.as_ref()) } - pub fn coroutine_by_move_body(&self) -> Option<&Body<'tcx>> { - self.coroutine.as_ref()?.by_move_body.as_ref() - } - #[inline] pub fn coroutine_kind(&self) -> Option { self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind) diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 336a9388a561e..1d94c364ae3af 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -415,7 +415,6 @@ impl<'tcx> CodegenUnit<'tcx> { | InstanceKind::Virtual(..) | InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::CloneShim(..) | InstanceKind::ThreadLocalShim(..) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index bfb129495ce83..64898a8495e26 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -349,7 +349,6 @@ macro_rules! make_mir_visitor { coroutine_closure_def_id: _def_id, receiver_by_ref: _, } | - ty::InstanceKind::CoroutineKindShim { coroutine_def_id: _def_id } | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) | ty::InstanceKind::DropGlue(_def_id, None) => {} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 75166624f95a4..b748f85253f10 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -326,6 +326,7 @@ rustc_queries! { query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } + feedable } query opaque_types_defined_by( @@ -498,6 +499,7 @@ rustc_queries! { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html query mir_built(key: LocalDefId) -> &'tcx Steal> { desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } + feedable } /// Try to build an abstract representation of the given constant. @@ -742,6 +744,7 @@ rustc_queries! { query constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } separate_provide_extern + feedable } query asyncness(key: DefId) -> ty::Asyncness { @@ -760,10 +763,22 @@ rustc_queries! { desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) } } + /// The body of the coroutine, modified to take its upvars by move rather than by ref. + /// + /// This is used by coroutine-closures, which must return a different flavor of coroutine + /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which + /// is run right after building the initial MIR, and will only be populated for coroutines + /// which come out of the async closure desugaring. + query coroutine_by_move_body_def_id(def_id: DefId) -> DefId { + desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine. query coroutine_kind(def_id: DefId) -> Option { desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) } separate_provide_extern + feedable } query coroutine_for_closure(def_id: DefId) -> DefId { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index cad3515f06809..8effb67a1f695 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1579,6 +1579,12 @@ impl<'tcx> TyCtxt<'tcx> { ) } + // Whether the body owner is synthetic, which in this case means it does not correspond to + // meaningful HIR. This is currently used to skip over MIR borrowck. + pub fn is_synthetic_mir(self, def_id: impl Into) -> bool { + matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody) + } + /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`. /// This means it is neither an `async` or `gen` construct. pub fn is_general_coroutine(self, def_id: DefId) -> bool { @@ -3168,6 +3174,18 @@ impl<'tcx> TyCtxt<'tcx> { self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) } + pub fn needs_coroutine_by_move_body_def_id(self, def_id: LocalDefId) -> bool { + if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = + self.coroutine_kind(def_id) + && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind() + && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce) + { + true + } else { + false + } + } + /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]` pub fn do_not_recommend_impl(self, def_id: DefId) -> bool { matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true }) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ecb3943e78836..7d5f0f1e9c415 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -141,14 +141,6 @@ pub enum InstanceKind<'tcx> { receiver_by_ref: bool, }, - /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce` - /// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or - /// similarly for `AsyncFnMut`. - /// - /// This will select the body that is produced by the `ByMoveBody` transform, and thus - /// take and use all of its upvars by-move rather than by-ref. - CoroutineKindShim { coroutine_def_id: DefId }, - /// Compiler-generated accessor for thread locals which returns a reference to the thread local /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking /// native support. @@ -248,7 +240,6 @@ impl<'tcx> InstanceKind<'tcx> { coroutine_closure_def_id: def_id, receiver_by_ref: _, } - | ty::InstanceKind::CoroutineKindShim { coroutine_def_id: def_id } | InstanceKind::DropGlue(def_id, _) | InstanceKind::CloneShim(def_id, _) | InstanceKind::FnPtrAddrShim(def_id, _) @@ -270,7 +261,6 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::Intrinsic(..) | InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::CloneShim(..) @@ -377,7 +367,6 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false, InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::Item(_) @@ -452,7 +441,6 @@ pub fn fmt_instance( InstanceKind::FnPtrShim(_, ty) => write!(f, " - shim({ty})"), InstanceKind::ClosureOnceShim { .. } => write!(f, " - shim"), InstanceKind::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"), - InstanceKind::CoroutineKindShim { .. } => write!(f, " - shim"), InstanceKind::DropGlue(_, None) => write!(f, " - shim(None)"), InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"), @@ -850,7 +838,9 @@ impl<'tcx> Instance<'tcx> { Some(Instance { def: ty::InstanceKind::Item(coroutine_def_id), args }) } else { Some(Instance { - def: ty::InstanceKind::CoroutineKindShim { coroutine_def_id }, + def: ty::InstanceKind::Item( + tcx.coroutine_by_move_body_def_id(coroutine_def_id), + ), args, }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1e3b5800cbac6..e41ea7507efff 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1756,7 +1756,6 @@ impl<'tcx> TyCtxt<'tcx> { | ty::InstanceKind::Virtual(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) | ty::InstanceKind::ThreadLocalShim(..) @@ -1874,7 +1873,8 @@ impl<'tcx> TyCtxt<'tcx> { identity_kind_ty.to_opt_closure_kind(), Some(ClosureKind::Fn | ClosureKind::FnMut) ); - mir.coroutine_by_move_body().unwrap().coroutine_layout_raw() + self.optimized_mir(self.coroutine_by_move_body_def_id(def_id)) + .coroutine_layout_raw() } } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 703339bf5bca8..d9d2abc554a65 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -53,7 +53,7 @@ mod by_move_body; use std::{iter, ops}; -pub use by_move_body::ByMoveBody; +pub use by_move_body::coroutine_by_move_body_def_id; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; use rustc_hir as hir; diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 7ea36f08232e2..ebe8d2eff4ff3 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -69,161 +69,167 @@ //! in case precise captures (edition 2021 closure capture rules) caused the inner coroutine //! to split one field capture into two. +use rustc_data_structures::steal::Steal; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::{self, dump_mir, MirPass}; +use rustc_middle::mir::{self, dump_mir}; use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt}; +use rustc_span::symbol::kw; use rustc_target::abi::{FieldIdx, VariantIdx}; -use crate::pass_manager::validate_body; - -pub struct ByMoveBody; +pub fn coroutine_by_move_body_def_id<'tcx>( + tcx: TyCtxt<'tcx>, + coroutine_def_id: LocalDefId, +) -> DefId { + let body = tcx.mir_built(coroutine_def_id).borrow(); -impl<'tcx> MirPass<'tcx> for ByMoveBody { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { - // We only need to generate by-move coroutine bodies for coroutines that come - // from coroutine-closures. - let Some(coroutine_def_id) = body.source.def_id().as_local() else { - return; - }; - let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = - tcx.coroutine_kind(coroutine_def_id) - else { - return; - }; + let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = + tcx.coroutine_kind(coroutine_def_id) + else { + bug!("should only be invoked on coroutine-closures"); + }; - // Also, let's skip processing any bodies with errors, since there's no guarantee - // the MIR body will be constructed well. - let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty; - if coroutine_ty.references_error() { - return; - } + // Also, let's skip processing any bodies with errors, since there's no guarantee + // the MIR body will be constructed well. + let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty; - // We don't need to generate a by-move coroutine if the coroutine body was - // produced by the `CoroutineKindShim`, since it's already by-move. - if matches!(body.source.instance, ty::InstanceKind::CoroutineKindShim { .. }) { - return; - } + let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") }; + let args = args.as_coroutine(); - let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") }; - let args = args.as_coroutine(); + let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap(); - let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap(); + let parent_def_id = tcx.local_parent(coroutine_def_id); + let ty::CoroutineClosure(_, parent_args) = + *tcx.type_of(parent_def_id).instantiate_identity().kind() + else { + bug!(); + }; + if parent_args.references_error() { + return coroutine_def_id.to_def_id(); + } - let parent_def_id = tcx.local_parent(coroutine_def_id); - let ty::CoroutineClosure(_, parent_args) = - *tcx.type_of(parent_def_id).instantiate_identity().kind() - else { - bug!(); - }; - let parent_closure_args = parent_args.as_coroutine_closure(); - let num_args = parent_closure_args - .coroutine_closure_sig() - .skip_binder() - .tupled_inputs_ty - .tuple_fields() - .len(); + let parent_closure_args = parent_args.as_coroutine_closure(); + let num_args = parent_closure_args + .coroutine_closure_sig() + .skip_binder() + .tupled_inputs_ty + .tuple_fields() + .len(); - let field_remapping: UnordMap<_, _> = ty::analyze_coroutine_closure_captures( - tcx.closure_captures(parent_def_id).iter().copied(), - tcx.closure_captures(coroutine_def_id).iter().skip(num_args).copied(), - |(parent_field_idx, parent_capture), (child_field_idx, child_capture)| { - // Store this set of additional projections (fields and derefs). - // We need to re-apply them later. - let mut child_precise_captures = child_capture.place.projections - [parent_capture.place.projections.len()..] - .to_vec(); + let field_remapping: UnordMap<_, _> = ty::analyze_coroutine_closure_captures( + tcx.closure_captures(parent_def_id).iter().copied(), + tcx.closure_captures(coroutine_def_id).iter().skip(num_args).copied(), + |(parent_field_idx, parent_capture), (child_field_idx, child_capture)| { + // Store this set of additional projections (fields and derefs). + // We need to re-apply them later. + let mut child_precise_captures = + child_capture.place.projections[parent_capture.place.projections.len()..].to_vec(); - // If the parent capture is by-ref, then we need to apply an additional - // deref before applying any further projections to this place. - if parent_capture.is_by_ref() { - child_precise_captures.insert( - 0, - Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref }, - ); - } - // If the child capture is by-ref, then we need to apply a "ref" - // projection (i.e. `&`) at the end. But wait! We don't have that - // as a projection kind. So instead, we can apply its dual and - // *peel* a deref off of the place when it shows up in the MIR body. - // Luckily, by construction this is always possible. - let peel_deref = if child_capture.is_by_ref() { - assert!( - parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce, - "`FnOnce` coroutine-closures return coroutines that capture from \ + // If the parent capture is by-ref, then we need to apply an additional + // deref before applying any further projections to this place. + if parent_capture.is_by_ref() { + child_precise_captures.insert( + 0, + Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref }, + ); + } + // If the child capture is by-ref, then we need to apply a "ref" + // projection (i.e. `&`) at the end. But wait! We don't have that + // as a projection kind. So instead, we can apply its dual and + // *peel* a deref off of the place when it shows up in the MIR body. + // Luckily, by construction this is always possible. + let peel_deref = if child_capture.is_by_ref() { + assert!( + parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce, + "`FnOnce` coroutine-closures return coroutines that capture from \ their body; it will always result in a borrowck error!" - ); - true - } else { - false - }; + ); + true + } else { + false + }; - // Regarding the behavior above, you may think that it's redundant to both - // insert a deref and then peel a deref if the parent and child are both - // captured by-ref. This would be correct, except for the case where we have - // precise capturing projections, since the inserted deref is to the *beginning* - // and the peeled deref is at the *end*. I cannot seem to actually find a - // case where this happens, though, but let's keep this code flexible. + // Regarding the behavior above, you may think that it's redundant to both + // insert a deref and then peel a deref if the parent and child are both + // captured by-ref. This would be correct, except for the case where we have + // precise capturing projections, since the inserted deref is to the *beginning* + // and the peeled deref is at the *end*. I cannot seem to actually find a + // case where this happens, though, but let's keep this code flexible. - // Finally, store the type of the parent's captured place. We need - // this when building the field projection in the MIR body later on. - let mut parent_capture_ty = parent_capture.place.ty(); - parent_capture_ty = match parent_capture.info.capture_kind { - ty::UpvarCapture::ByValue => parent_capture_ty, - ty::UpvarCapture::ByRef(kind) => Ty::new_ref( - tcx, - tcx.lifetimes.re_erased, - parent_capture_ty, - kind.to_mutbl_lossy(), - ), - }; + // Finally, store the type of the parent's captured place. We need + // this when building the field projection in the MIR body later on. + let mut parent_capture_ty = parent_capture.place.ty(); + parent_capture_ty = match parent_capture.info.capture_kind { + ty::UpvarCapture::ByValue => parent_capture_ty, + ty::UpvarCapture::ByRef(kind) => Ty::new_ref( + tcx, + tcx.lifetimes.re_erased, + parent_capture_ty, + kind.to_mutbl_lossy(), + ), + }; + ( + FieldIdx::from_usize(child_field_idx + num_args), ( - FieldIdx::from_usize(child_field_idx + num_args), - ( - FieldIdx::from_usize(parent_field_idx + num_args), - parent_capture_ty, - peel_deref, - child_precise_captures, - ), - ) - }, - ) - .collect(); + FieldIdx::from_usize(parent_field_idx + num_args), + parent_capture_ty, + peel_deref, + child_precise_captures, + ), + ) + }, + ) + .collect(); - if coroutine_kind == ty::ClosureKind::FnOnce { - assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len()); - return; - } + if coroutine_kind == ty::ClosureKind::FnOnce { + assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len()); + // The by-move body is just the body :) + return coroutine_def_id.to_def_id(); + } - let by_move_coroutine_ty = tcx - .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig()) - .to_coroutine_given_kind_and_upvars( - tcx, - parent_closure_args.parent_args(), - coroutine_def_id.to_def_id(), - ty::ClosureKind::FnOnce, - tcx.lifetimes.re_erased, - parent_closure_args.tupled_upvars_ty(), - parent_closure_args.coroutine_captures_by_ref_ty(), - ); + let by_move_coroutine_ty = tcx + .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig()) + .to_coroutine_given_kind_and_upvars( + tcx, + parent_closure_args.parent_args(), + coroutine_def_id.to_def_id(), + ty::ClosureKind::FnOnce, + tcx.lifetimes.re_erased, + parent_closure_args.tupled_upvars_ty(), + parent_closure_args.coroutine_captures_by_ref_ty(), + ); - let mut by_move_body = body.clone(); - MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body); - dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(())); + let mut by_move_body = body.clone(); + MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body); + dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(())); - // Let's just always validate this body. - validate_body(tcx, &mut by_move_body, "Initial coroutine_by_move body".to_string()); + let body_def = tcx.create_def(coroutine_def_id, kw::Empty, DefKind::SyntheticCoroutineBody); + by_move_body.source = + mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id())); - // FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body. - by_move_body.source = mir::MirSource::from_instance(InstanceKind::CoroutineKindShim { - coroutine_def_id: coroutine_def_id.to_def_id(), - }); - body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body); - } + // Inherited from the by-ref coroutine. + body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone()); + body_def.constness(tcx.constness(coroutine_def_id).clone()); + body_def.coroutine_kind(tcx.coroutine_kind(coroutine_def_id).clone()); + body_def.def_ident_span(tcx.def_ident_span(coroutine_def_id)); + body_def.def_span(tcx.def_span(coroutine_def_id)); + body_def.explicit_predicates_of(tcx.explicit_predicates_of(coroutine_def_id).clone()); + body_def.generics_of(tcx.generics_of(coroutine_def_id).clone()); + body_def.param_env(tcx.param_env(coroutine_def_id).clone()); + body_def.predicates_of(tcx.predicates_of(coroutine_def_id).clone()); + + // The type of the coroutine is the `by_move_coroutine_ty`. + body_def.type_of(ty::EarlyBinder::bind(by_move_coroutine_ty)); + + body_def.mir_built(tcx.arena.alloc(Steal::new(by_move_body))); + + body_def.def_id().to_def_id() } struct MakeByMoveBody<'tcx> { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 61fc5fc881606..2d6950be55d85 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -341,7 +341,6 @@ impl<'tcx> Inliner<'tcx> { | InstanceKind::FnPtrShim(..) | InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::CloneShim(..) | InstanceKind::ThreadLocalShim(..) diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index f5274c664cfa7..56e8905bead3c 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -88,7 +88,6 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( | InstanceKind::FnPtrShim(..) | InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::ThreadLocalShim { .. } | InstanceKind::CloneShim(..) => {} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 1f214bc42cbe6..88094b44edf21 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -135,6 +135,7 @@ pub fn provide(providers: &mut Providers) { mir_inliner_callees: inline::cycle::mir_inliner_callees, promoted_mir, deduced_param_attrs: deduce_param_attrs::deduced_param_attrs, + coroutine_by_move_body_def_id: coroutine::coroutine_by_move_body_def_id, ..providers.queries }; } @@ -293,10 +294,6 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { &Lint(check_packed_ref::CheckPackedRef), &Lint(check_const_item_mutation::CheckConstItemMutation), &Lint(function_item_references::FunctionItemReferences), - // If this is an async closure's output coroutine, generate - // by-move and by-mut bodies if needed. We do this first so - // they can be optimized in lockstep with their parent bodies. - &coroutine::ByMoveBody, // What we need to do constant evaluation. &simplify::SimplifyCfg::Initial, &rustc_peek::SanityCheck, // Just a lint @@ -329,8 +326,15 @@ fn mir_promoted( | DefKind::AnonConst => tcx.mir_const_qualif(def), _ => ConstQualifs::default(), }; - // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. + + // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run. tcx.ensure_with_value().has_ffi_unwind_calls(def); + + // the `by_move_body` query uses the raw mir, so make sure it is run. + if tcx.needs_coroutine_by_move_body_def_id(def) { + tcx.ensure_with_value().coroutine_by_move_body_def_id(def); + } + let mut body = tcx.mir_built(def).steal(); if let Some(error_reported) = const_qualifs.tainted_by_errors { body.tainted_by_errors = Some(error_reported); @@ -339,14 +343,6 @@ fn mir_promoted( // Collect `required_consts` *before* promotion, so if there are any consts being promoted // we still add them to the list in the outer MIR body. RequiredConstsVisitor::compute_required_consts(&mut body); - // If this has an associated by-move async closure body, that doesn't get run through these - // passes itself, it gets "tagged along" by the pass manager. `RequiredConstsVisitor` is not - // a regular pass so we have to also apply it manually to the other body. - if let Some(coroutine) = body.coroutine.as_mut() { - if let Some(by_move_body) = coroutine.by_move_body.as_mut() { - RequiredConstsVisitor::compute_required_consts(by_move_body); - } - } // What we need to run borrowck etc. let promote_pass = promote_consts::PromoteTemps::default(); @@ -398,7 +394,10 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & if tcx.is_coroutine(def.to_def_id()) { tcx.ensure_with_value().mir_coroutine_witnesses(def); } - let mir_borrowck = tcx.mir_borrowck(def); + + // We only need to borrowck non-synthetic MIR. + let tainted_by_errors = + if !tcx.is_synthetic_mir(def) { tcx.mir_borrowck(def).tainted_by_errors } else { None }; let is_fn_like = tcx.def_kind(def).is_fn_like(); if is_fn_like { @@ -410,7 +409,8 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & let (body, _) = tcx.mir_promoted(def); let mut body = body.steal(); - if let Some(error_reported) = mir_borrowck.tainted_by_errors { + + if let Some(error_reported) = tainted_by_errors { body.tainted_by_errors = Some(error_reported); } @@ -660,14 +660,6 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { // visited does not depend on the optimization level. // We do not use `run_passes` for this as that might skip the pass if `injection_phase` is set. mentioned_items::MentionedItems.run_pass(tcx, &mut body); - // If this has an associated by-move async closure body, that doesn't get run through these - // passes itself, it gets "tagged along" by the pass manager. Since we're not using the pass - // manager we have to do this by hand. - if let Some(coroutine) = body.coroutine.as_mut() { - if let Some(by_move_body) = coroutine.by_move_body.as_mut() { - mentioned_items::MentionedItems.run_pass(tcx, by_move_body); - } - } // If `mir_drops_elaborated_and_const_checked` found that the current body has unsatisfiable // predicates, it will shrink the MIR to a single `unreachable` terminator. @@ -690,7 +682,9 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec( body.pass_count = 1; } - - if let Some(coroutine) = body.coroutine.as_mut() { - if let Some(by_move_body) = coroutine.by_move_body.as_mut() { - run_passes_inner(tcx, by_move_body, passes, phase_change, validate_each); - } - } } pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) { diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 09b4e5e07113b..86eada0183f87 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -78,15 +78,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< receiver_by_ref, } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref), - ty::InstanceKind::CoroutineKindShim { coroutine_def_id } => { - return tcx.optimized_mir(coroutine_def_id).coroutine_by_move_body().unwrap().clone(); - } - ty::InstanceKind::DropGlue(def_id, ty) => { // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end // of this function. Is this intentional? - if let Some(ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) { - let coroutine_body = tcx.optimized_mir(*coroutine_def_id); + if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) { + let coroutine_body = tcx.optimized_mir(coroutine_def_id); let ty::Coroutine(_, id_args) = *tcx.type_of(coroutine_def_id).skip_binder().kind() else { @@ -105,7 +101,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(), ty::ClosureKind::FnOnce ); - coroutine_body.coroutine_by_move_body().unwrap().coroutine_drop().unwrap() + tcx.optimized_mir(tcx.coroutine_by_move_body_def_id(coroutine_def_id)) + .coroutine_drop() + .unwrap() }; let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args); diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 36908036796c1..99e06f59dd04d 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -102,25 +102,6 @@ impl<'tcx> MirPass<'tcx> for Validator { } } } - - // Enforce that coroutine-closure layouts are identical. - if let Some(layout) = body.coroutine_layout_raw() - && let Some(by_move_body) = body.coroutine_by_move_body() - && let Some(by_move_layout) = by_move_body.coroutine_layout_raw() - { - // FIXME(async_closures): We could do other validation here? - if layout.variant_fields.len() != by_move_layout.variant_fields.len() { - cfg_checker.fail( - Location::START, - format!( - "Coroutine layout has different number of variant fields from \ - by-move coroutine layout:\n\ - layout: {layout:#?}\n\ - by_move_layout: {by_move_layout:#?}", - ), - ); - } - } } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ff4207fbefda8..36fb2e89af141 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -920,7 +920,6 @@ fn visit_instance_use<'tcx>( | ty::InstanceKind::ReifyShim(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::Item(..) | ty::InstanceKind::FnPtrShim(..) | ty::InstanceKind::CloneShim(..) diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 610ad41ce5210..2f0088fb34ffd 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -626,7 +626,6 @@ fn characteristic_def_id_of_mono_item<'tcx>( | ty::InstanceKind::FnPtrShim(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::Virtual(..) @@ -796,7 +795,6 @@ fn mono_item_visibility<'tcx>( | InstanceKind::Intrinsic(..) | InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::CloneShim(..) diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 5a24202db65ec..b59c7bcffa9c7 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -127,7 +127,7 @@ fn mark_used_by_default_parameters<'tcx>( unused_parameters: &mut UnusedGenericParams, ) { match tcx.def_kind(def_id) { - DefKind::Closure => { + DefKind::Closure | DefKind::SyntheticCoroutineBody => { for param in &generics.own_params { debug!(?param, "(closure/gen)"); unused_parameters.mark_used(param.index); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d1d1e5e901f29..9f78215bfd1f9 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -626,7 +626,8 @@ impl<'tcx> EmbargoVisitor<'tcx> { | DefKind::Field | DefKind::GlobalAsm | DefKind::Impl { .. } - | DefKind::Closure => (), + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => (), } } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2ac7b200452f4..3ea782b62f179 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -260,6 +260,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure + | DefKind::SyntheticCoroutineBody | DefKind::Impl { .. }, _, ) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 332fe22d86955..9afd732486c28 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -851,7 +851,6 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { | ty::InstanceKind::FnPtrAddrShim(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::ThreadLocalShim(..) | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 41e9698242bbd..9b27b94fb5a56 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -114,7 +114,9 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { | DefKind::GlobalAsm => { unreachable!("Not a valid item kind: {kind:?}"); } - DefKind::Closure | DefKind::AssocFn | DefKind::Fn => ItemKind::Fn, + DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { + ItemKind::Fn + } DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { ItemKind::Const } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 0f91684a3a48b..59ccd6dff8588 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -92,9 +92,6 @@ pub(super) fn mangle<'tcx>( .write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" }) .unwrap(); } - ty::InstanceKind::CoroutineKindShim { .. } => { - printer.write_str("{{by-move-body-shim}}").unwrap(); - } _ => {} } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 3a606f244e37a..75f4499352b99 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -56,7 +56,6 @@ pub(super) fn mangle<'tcx>( ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { Some("by_ref") } - ty::InstanceKind::CoroutineKindShim { .. } => Some("by_move_body"), _ => None, }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 7e3c30f238388..16cd147b7d432 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -169,39 +169,6 @@ fn fn_sig_for_fn_abi<'tcx>( kind: ty::BoundRegionKind::BrEnv, }; - let mut ty = ty; - // When this `Closure` comes from a `CoroutineKindShim`, - // make sure we respect the `target_kind` in that shim. - // FIXME(async_closures): This shouldn't be needed, and we should be populating - // a separate def-id for these bodies. - if let InstanceKind::CoroutineKindShim { .. } = instance.def { - // Grab the parent coroutine-closure. It has the same args for the purposes - // of instantiation, so this will be okay to do. - let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx - .instantiate_and_normalize_erasing_regions( - args, - param_env, - tcx.type_of(tcx.parent(did)), - ) - .kind() - else { - bug!("CoroutineKindShim comes from calling a coroutine-closure"); - }; - let coroutine_closure_args = coroutine_closure_args.as_coroutine_closure(); - ty = tcx.instantiate_bound_regions_with_erased( - coroutine_closure_args.coroutine_closure_sig().map_bound(|sig| { - sig.to_coroutine_given_kind_and_upvars( - tcx, - coroutine_closure_args.parent_args(), - did, - ty::ClosureKind::FnOnce, - tcx.lifetimes.re_erased, - coroutine_closure_args.tupled_upvars_ty(), - coroutine_closure_args.coroutine_captures_by_ref_ty(), - ) - }), - ); - } let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty); let pin_did = tcx.require_lang_item(LangItem::Pin, None); diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 8812260b3af31..70321a071a208 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -144,7 +144,8 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Closure => ty::List::empty(), + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => ty::List::empty(), } } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 6680b451b7cc7..e899284674c8c 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -348,7 +348,8 @@ fn opaque_types_defined_by<'tcx>( | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl { .. } => {} + | DefKind::Impl { .. } + | DefKind::SyntheticCoroutineBody => {} // Closures and coroutines are type checked with their parent, so we need to allow all // opaques from the closure signature *and* from the parent body. DefKind::Closure | DefKind::InlineConst => { diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 568b9383ffbc4..6f1cbb0fee700 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -87,7 +87,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( // These are not part of a public API, they can only appear as hidden types, and there // the interesting parts are solely in the signature of the containing item's opaque type // or dyn type. - DefKind::InlineConst | DefKind::Closure => {} + DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {} DefKind::Impl { of_trait } => { if of_trait { let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 3dcef15b552b2..9754e1e6f74d4 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -162,7 +162,8 @@ impl ItemType { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Impl { .. } - | DefKind::Closure => Self::ForeignType, + | DefKind::Closure + | DefKind::SyntheticCoroutineBody => Self::ForeignType, } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ab03f620230bd..eae12b848396c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1950,7 +1950,9 @@ fn resolution_failure( | TraitAlias | TyParam | Static { .. } => "associated item", - Impl { .. } | GlobalAsm => unreachable!("not a path"), + Impl { .. } | GlobalAsm | SyntheticCoroutineBody => { + unreachable!("not a path") + } } } else { "associated item" diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index 09729eeba7923..ef590d85aef78 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -16,6 +16,12 @@ error: unused variable: `a` LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:68:9 + | +LL | a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: unused variable: `b` --> $DIR/lint-unused-variables.rs:14:5 | @@ -58,12 +64,6 @@ error: unused variable: `b` LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` -error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:68:9 - | -LL | a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - error: unused variable: `b` --> $DIR/lint-unused-variables.rs:74:9 | diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr index 16e1af46059a4..9b92166bcb766 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -16,6 +16,12 @@ error: unused variable: `a` LL | #[cfg(something)] a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:107:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:30:23 | @@ -100,12 +106,6 @@ error: unused variable: `c` LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` -error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:107:27 - | -LL | #[cfg(something)] a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:113:27 | From 93295ff6dc48782ea3114e98313836b266f3e54a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Aug 2024 13:24:46 -0400 Subject: [PATCH 073/102] Remove some unnecessary TODOs --- compiler/rustc_interface/src/passes.rs | 2 -- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 ----- 2 files changed, 7 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2a4367965eef3..779b98d073dab 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -796,8 +796,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // Freeze definitions as we don't add new ones at this point. // We need to wait until now since we synthesize a by-move body // This improves performance by allowing lock-free access to them. - // FIXME(async_closures): We could force `coroutine_by_move_body_def_id` - // immediately after typeck, then freeze after that. tcx.untracked().definitions.freeze(); sess.time("MIR_borrow_checking", || { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3125fb245e7e3..9c93726ca37f5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1066,7 +1066,6 @@ fn should_encode_mir( } // Coroutines require optimized MIR to compute layout. DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true), - // FIXME: lol DefKind::SyntheticCoroutineBody => (false, true), // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { @@ -1379,10 +1378,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); } - // FIXME(async_closures): We should just use `tcx.attrs` rather than going - // through the HIR. Historically, though, this has been inefficient apparently. - // For now, it's kind of pointless to fix, because coroutine-closures' coroutine - // bodies have no attrs anyways. if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } From 56d861134dcdd5b4f363835b9ab22895c6e70228 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 22 Jul 2024 14:53:26 -0400 Subject: [PATCH 074/102] Fix tidy --- src/tools/tidy/src/edition.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 6a58d58dbde14..08f6a3909f806 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -1,4 +1,4 @@ -//! Tidy check to ensure that crate `edition` is '2018' or '2021'. +//! Tidy check to ensure that crate `edition` is '2021' or '2024'. use std::path::Path; @@ -12,7 +12,9 @@ pub fn check(path: &Path, bad: &mut bool) { return; } - let is_2021 = contents.lines().any(|line| line.trim() == "edition = \"2021\""); + let is_current_edition = contents + .lines() + .any(|line| line.trim() == "edition = \"2021\"" || line.trim() == "edition = \"2024\""); let is_workspace = contents.lines().any(|line| line.trim() == "[workspace]"); let is_package = contents.lines().any(|line| line.trim() == "[package]"); @@ -20,10 +22,10 @@ pub fn check(path: &Path, bad: &mut bool) { // Check that all packages use the 2021 edition. Virtual workspaces don't allow setting an // edition, so these shouldn't be checked. - if is_package && !is_2021 { + if is_package && !is_current_edition { tidy_error!( bad, - "{} doesn't have `edition = \"2021\"` on a separate line", + "{} doesn't have `edition = \"2021\"` or `edition = \"2024\"` on a separate line", file.display() ); } From 38e62b98418c22d3a00f5af689ae538e4216fb5f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 26 Aug 2024 19:40:43 -0400 Subject: [PATCH 075/102] Use unsafe extern blocks throughout the compiler --- compiler/rustc_codegen_llvm/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 42 +++++++++---------- compiler/rustc_driver_impl/src/lib.rs | 1 + .../rustc_driver_impl/src/signal_handler.rs | 2 +- compiler/rustc_llvm/src/lib.rs | 5 ++- compiler/rustc_middle/src/lib.rs | 2 +- compiler/rustc_middle/src/ty/list.rs | 2 +- 7 files changed, 29 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 43164390a1c6c..f7b0ce25b4ab3 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(unsafe_extern_blocks))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index faabbcb020d5f..a774ea3339706 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -564,12 +564,12 @@ pub enum ArchiveKind { } // LLVMRustThinLTOData -extern "C" { +unsafe extern "C" { pub type ThinLTOData; } // LLVMRustThinLTOBuffer -extern "C" { +unsafe extern "C" { pub type ThinLTOBuffer; } @@ -621,7 +621,7 @@ pub enum MemoryEffects { InaccessibleMemOnly, } -extern "C" { +unsafe extern "C" { type Opaque; } #[repr(C)] @@ -631,54 +631,54 @@ struct InvariantOpaque<'a> { } // Opaque pointer types -extern "C" { +unsafe extern "C" { pub type Module; } -extern "C" { +unsafe extern "C" { pub type Context; } -extern "C" { +unsafe extern "C" { pub type Type; } -extern "C" { +unsafe extern "C" { pub type Value; } -extern "C" { +unsafe extern "C" { pub type ConstantInt; } -extern "C" { +unsafe extern "C" { pub type Attribute; } -extern "C" { +unsafe extern "C" { pub type Metadata; } -extern "C" { +unsafe extern "C" { pub type BasicBlock; } #[repr(C)] pub struct Builder<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); -extern "C" { +unsafe extern "C" { pub type Pass; } -extern "C" { +unsafe extern "C" { pub type TargetMachine; } -extern "C" { +unsafe extern "C" { pub type Archive; } #[repr(C)] pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct ArchiveChild<'a>(InvariantOpaque<'a>); -extern "C" { +unsafe extern "C" { pub type Twine; } -extern "C" { +unsafe extern "C" { pub type DiagnosticInfo; } -extern "C" { +unsafe extern "C" { pub type SMDiagnostic; } #[repr(C)] @@ -688,7 +688,7 @@ pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct Linker<'a>(InvariantOpaque<'a>); -extern "C" { +unsafe extern "C" { pub type DiagnosticHandler; } @@ -823,7 +823,7 @@ bitflags! { } } -extern "C" { +unsafe extern "C" { pub type ModuleBuffer; } @@ -834,7 +834,7 @@ pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void); pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void; pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void; -extern "C" { +unsafe extern "C" { // Create and destroy contexts. pub fn LLVMContextDispose(C: &'static mut Context); pub fn LLVMGetMDKindIDInContext(C: &Context, Name: *const c_char, SLen: c_uint) -> c_uint; @@ -1518,7 +1518,7 @@ extern "C" { } #[link(name = "llvm-wrapper", kind = "static")] -extern "C" { +unsafe extern "C" { pub fn LLVMRustInstallErrorHandlers(); pub fn LLVMRustDisableSystemDialogsOnCrash(); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2b7dc040f6411..ed072cd10b7a0 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -7,6 +7,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable +#![cfg_attr(bootstrap, feature(unsafe_extern_blocks))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(decl_macro)] diff --git a/compiler/rustc_driver_impl/src/signal_handler.rs b/compiler/rustc_driver_impl/src/signal_handler.rs index 51f2a508cf90c..e1f868c2522d9 100644 --- a/compiler/rustc_driver_impl/src/signal_handler.rs +++ b/compiler/rustc_driver_impl/src/signal_handler.rs @@ -6,7 +6,7 @@ use std::{fmt, mem, ptr}; use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE}; -extern "C" { +unsafe extern "C" { fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int); } diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 939e5e4dbd4ff..96e370c5b2648 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(unsafe_attributes, unsafe_extern_blocks))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] @@ -28,7 +29,7 @@ impl RustString { } /// Appending to a Rust string -- used by RawRustStringOstream. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn LLVMRustStringWriteImpl( sr: &RustString, ptr: *const c_char, @@ -46,7 +47,7 @@ pub fn initialize_available_targets() { ($cfg:meta, $($method:ident),*) => { { #[cfg($cfg)] fn init() { - extern "C" { + unsafe extern "C" { $(fn $method();)* } unsafe { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 6886562d9b76d..ce330b4744bf6 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -28,7 +28,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns, unsafe_extern_blocks))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 1a1acf36d77a4..af76d5b7d9267 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -58,7 +58,7 @@ impl Default for &List { } } -extern "C" { +unsafe extern "C" { /// A dummy type used to force `List` to be unsized while not requiring /// references to it be wide pointers. type OpaqueListContents; From e81fad2b4d0c907445c6df76adea65602134fda8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 11:47:25 +1000 Subject: [PATCH 076/102] Add `warn(unreachable_pub)` to `rustc_driver_impl`. --- compiler/rustc_driver_impl/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2b7dc040f6411..970ac5627491b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -15,6 +15,7 @@ #![feature(panic_update_hook)] #![feature(result_flattening)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cmp::max; From d607cfb33602750ba9b8adc090abfde2087e0fd6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 11:49:59 +1000 Subject: [PATCH 077/102] Add `warn(unreachable_pub)` to `rustc_error_codes`. --- compiler/rustc_error_codes/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 2a7bc2501c081..150f99a3ee743 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -6,6 +6,7 @@ #![deny(rustdoc::invalid_codeblock_attributes)] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used From 2b5621280c118ca72eb84470129c72b069e22907 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 11:52:08 +1000 Subject: [PATCH 078/102] Add `warn(unreachable_pub)` to `rustc_error_messages`. --- compiler/rustc_error_messages/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 87dee2898daf0..e84d7be45d7a0 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -4,6 +4,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; From 5fd503ab445b2a70897026e495dd4df4343333eb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:03:37 +1000 Subject: [PATCH 079/102] Add `warn(unreachable_pub)` to `rustc_errors`. --- compiler/rustc_errors/src/diagnostic.rs | 2 +- compiler/rustc_errors/src/emitter.rs | 2 +- compiler/rustc_errors/src/lib.rs | 5 ++-- compiler/rustc_errors/src/lock.rs | 4 +-- compiler/rustc_errors/src/markdown/parse.rs | 2 +- compiler/rustc_errors/src/markdown/term.rs | 4 +-- compiler/rustc_errors/src/snippet.rs | 32 ++++++++++----------- compiler/rustc_errors/src/styled_buffer.rs | 20 ++++++------- 8 files changed, 36 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index fae8b5647fc9a..3303e4ee752c2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -204,7 +204,7 @@ pub trait LintDiagnostic<'a, G: EmissionGuarantee> { } #[derive(Clone, Debug, Encodable, Decodable)] -pub struct DiagLocation { +pub(crate) struct DiagLocation { file: Cow<'static, str>, line: u32, col: u32, diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 9ce5d77ef6c07..2bc29dabd18a1 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2387,7 +2387,7 @@ enum DisplaySuggestion { impl FileWithAnnotatedLines { /// Preprocess all the annotations so that they are grouped by file and by line number /// This helps us quickly iterate over the whole message (including secondary file spans) - pub fn collect_annotations( + pub(crate) fn collect_annotations( emitter: &dyn Emitter, args: &FluentArgs<'_>, msp: &MultiSpan, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fd203c3831897..99ee8fb17d7dc 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,6 +25,7 @@ #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_errors; @@ -1701,7 +1702,7 @@ impl DiagCtxtInner { } /// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`. - pub fn eagerly_translate<'a>( + fn eagerly_translate<'a>( &self, message: DiagMessage, args: impl Iterator>, @@ -1710,7 +1711,7 @@ impl DiagCtxtInner { } /// Translate `message` eagerly with `args` to `String`. - pub fn eagerly_translate_to_string<'a>( + fn eagerly_translate_to_string<'a>( &self, message: DiagMessage, args: impl Iterator>, diff --git a/compiler/rustc_errors/src/lock.rs b/compiler/rustc_errors/src/lock.rs index 915542c909240..7557969f374ac 100644 --- a/compiler/rustc_errors/src/lock.rs +++ b/compiler/rustc_errors/src/lock.rs @@ -12,7 +12,7 @@ use std::any::Any; #[cfg(windows)] -pub fn acquire_global_lock(name: &str) -> Box { +pub(crate) fn acquire_global_lock(name: &str) -> Box { use std::ffi::CString; use std::io; @@ -80,6 +80,6 @@ pub fn acquire_global_lock(name: &str) -> Box { } #[cfg(not(windows))] -pub fn acquire_global_lock(_name: &str) -> Box { +pub(crate) fn acquire_global_lock(_name: &str) -> Box { Box::new(()) } diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs index 46f8959b6f246..b1db44dd215b8 100644 --- a/compiler/rustc_errors/src/markdown/parse.rs +++ b/compiler/rustc_errors/src/markdown/parse.rs @@ -74,7 +74,7 @@ enum ParseOpt { } /// Parse a buffer -pub fn entrypoint(txt: &str) -> MdStream<'_> { +pub(crate) fn entrypoint(txt: &str) -> MdStream<'_> { let ctx = Context { top_block: true, prev: Prev::Newline }; normalize(parse_recursive(txt.trim().as_bytes(), ctx), &mut Vec::new()) } diff --git a/compiler/rustc_errors/src/markdown/term.rs b/compiler/rustc_errors/src/markdown/term.rs index 06c1333d93dd0..579e00b8b85bd 100644 --- a/compiler/rustc_errors/src/markdown/term.rs +++ b/compiler/rustc_errors/src/markdown/term.rs @@ -15,7 +15,7 @@ thread_local! { } /// Print to terminal output to a buffer -pub fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result<()> { +pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result<()> { #[cfg(not(test))] if let Some((w, _)) = termize::dimensions() { WIDTH.with(|c| c.set(std::cmp::min(w, DEFAULT_COLUMN_WIDTH))); @@ -47,7 +47,7 @@ fn write_stream( Ok(()) } -pub fn write_tt(tt: &MdTree<'_>, buf: &mut Buffer, indent: usize) -> io::Result<()> { +fn write_tt(tt: &MdTree<'_>, buf: &mut Buffer, indent: usize) -> io::Result<()> { match tt { MdTree::CodeBlock { txt, lang: _ } => { buf.set_color(ColorSpec::new().set_dimmed(true))?; diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs index 50abf8a49c268..8485d7087cfc5 100644 --- a/compiler/rustc_errors/src/snippet.rs +++ b/compiler/rustc_errors/src/snippet.rs @@ -5,13 +5,13 @@ use rustc_macros::{Decodable, Encodable}; use crate::{Level, Loc}; #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] -pub struct Line { +pub(crate) struct Line { pub line_index: usize, pub annotations: Vec, } #[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Default)] -pub struct AnnotationColumn { +pub(crate) struct AnnotationColumn { /// the (0-indexed) column for *display* purposes, counted in characters, not utf-8 bytes pub display: usize, /// the (0-indexed) column in the file, counted in characters, not utf-8 bytes. @@ -31,13 +31,13 @@ pub struct AnnotationColumn { } impl AnnotationColumn { - pub fn from_loc(loc: &Loc) -> AnnotationColumn { + pub(crate) fn from_loc(loc: &Loc) -> AnnotationColumn { AnnotationColumn { display: loc.col_display, file: loc.col.0 } } } #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] -pub struct MultilineAnnotation { +pub(crate) struct MultilineAnnotation { pub depth: usize, pub line_start: usize, pub line_end: usize, @@ -49,19 +49,19 @@ pub struct MultilineAnnotation { } impl MultilineAnnotation { - pub fn increase_depth(&mut self) { + pub(crate) fn increase_depth(&mut self) { self.depth += 1; } /// Compare two `MultilineAnnotation`s considering only the `Span` they cover. - pub fn same_span(&self, other: &MultilineAnnotation) -> bool { + pub(crate) fn same_span(&self, other: &MultilineAnnotation) -> bool { self.line_start == other.line_start && self.line_end == other.line_end && self.start_col == other.start_col && self.end_col == other.end_col } - pub fn as_start(&self) -> Annotation { + pub(crate) fn as_start(&self) -> Annotation { Annotation { start_col: self.start_col, end_col: AnnotationColumn { @@ -76,7 +76,7 @@ impl MultilineAnnotation { } } - pub fn as_end(&self) -> Annotation { + pub(crate) fn as_end(&self) -> Annotation { Annotation { start_col: AnnotationColumn { // these might not correspond to the same place anymore, @@ -91,7 +91,7 @@ impl MultilineAnnotation { } } - pub fn as_line(&self) -> Annotation { + pub(crate) fn as_line(&self) -> Annotation { Annotation { start_col: Default::default(), end_col: Default::default(), @@ -103,7 +103,7 @@ impl MultilineAnnotation { } #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] -pub enum AnnotationType { +pub(crate) enum AnnotationType { /// Annotation under a single line of code Singleline, @@ -129,7 +129,7 @@ pub enum AnnotationType { } #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] -pub struct Annotation { +pub(crate) struct Annotation { /// Start column. /// Note that it is important that this field goes /// first, so that when we sort, we sort orderings by start @@ -152,12 +152,12 @@ pub struct Annotation { impl Annotation { /// Whether this annotation is a vertical line placeholder. - pub fn is_line(&self) -> bool { + pub(crate) fn is_line(&self) -> bool { matches!(self.annotation_type, AnnotationType::MultilineLine(_)) } /// Length of this annotation as displayed in the stderr output - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { // Account for usize underflows if self.end_col.display > self.start_col.display { self.end_col.display - self.start_col.display @@ -166,7 +166,7 @@ impl Annotation { } } - pub fn has_label(&self) -> bool { + pub(crate) fn has_label(&self) -> bool { if let Some(ref label) = self.label { // Consider labels with no text as effectively not being there // to avoid weird output with unnecessary vertical lines, like: @@ -184,7 +184,7 @@ impl Annotation { } } - pub fn takes_space(&self) -> bool { + pub(crate) fn takes_space(&self) -> bool { // Multiline annotations always have to keep vertical space. matches!( self.annotation_type, @@ -194,7 +194,7 @@ impl Annotation { } #[derive(Debug)] -pub struct StyledString { +pub(crate) struct StyledString { pub text: String, pub style: Style, } diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 9aa14e1f21485..5ca9e9b18f341 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -3,7 +3,7 @@ use crate::snippet::{Style, StyledString}; #[derive(Debug)] -pub struct StyledBuffer { +pub(crate) struct StyledBuffer { lines: Vec>, } @@ -22,12 +22,12 @@ impl StyledChar { } impl StyledBuffer { - pub fn new() -> StyledBuffer { + pub(crate) fn new() -> StyledBuffer { StyledBuffer { lines: vec![] } } /// Returns content of `StyledBuffer` split by lines and line styles - pub fn render(&self) -> Vec> { + pub(crate) fn render(&self) -> Vec> { // Tabs are assumed to have been replaced by spaces in calling code. debug_assert!(self.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t'))); @@ -70,7 +70,7 @@ impl StyledBuffer { /// Sets `chr` with `style` for given `line`, `col`. /// If `line` does not exist in our buffer, adds empty lines up to the given /// and fills the last line with unstyled whitespace. - pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { + pub(crate) fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { self.ensure_lines(line); if col >= self.lines[line].len() { self.lines[line].resize(col + 1, StyledChar::SPACE); @@ -81,7 +81,7 @@ impl StyledBuffer { /// Sets `string` with `style` for given `line`, starting from `col`. /// If `line` does not exist in our buffer, adds empty lines up to the given /// and fills the last line with unstyled whitespace. - pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) { + pub(crate) fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) { let mut n = col; for c in string.chars() { self.putc(line, n, c, style); @@ -91,7 +91,7 @@ impl StyledBuffer { /// For given `line` inserts `string` with `style` before old content of that line, /// adding lines if needed - pub fn prepend(&mut self, line: usize, string: &str, style: Style) { + pub(crate) fn prepend(&mut self, line: usize, string: &str, style: Style) { self.ensure_lines(line); let string_len = string.chars().count(); @@ -107,7 +107,7 @@ impl StyledBuffer { /// For given `line` inserts `string` with `style` after old content of that line, /// adding lines if needed - pub fn append(&mut self, line: usize, string: &str, style: Style) { + pub(crate) fn append(&mut self, line: usize, string: &str, style: Style) { if line >= self.lines.len() { self.puts(line, 0, string, style); } else { @@ -116,14 +116,14 @@ impl StyledBuffer { } } - pub fn num_lines(&self) -> usize { + pub(crate) fn num_lines(&self) -> usize { self.lines.len() } /// Set `style` for `line`, `col_start..col_end` range if: /// 1. That line and column range exist in `StyledBuffer` /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation` - pub fn set_style_range( + pub(crate) fn set_style_range( &mut self, line: usize, col_start: usize, @@ -139,7 +139,7 @@ impl StyledBuffer { /// Set `style` for `line`, `col` if: /// 1. That line and column exist in `StyledBuffer` /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation` - pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { + fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { if let Some(ref mut line) = self.lines.get_mut(line) { if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { if overwrite || matches!(s, Style::NoStyle | Style::Quotation) { From df5fbf05a15a391192c40680af968733524d99d0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:40:38 +1000 Subject: [PATCH 080/102] Add `warn(unreachable_pub)` to `rustc_expand`. Plus a tiny bit of reformatting. --- compiler/rustc_expand/src/errors.rs | 14 +++++++------- compiler/rustc_expand/src/lib.rs | 1 + compiler/rustc_expand/src/mbe/diagnostics.rs | 7 ++++--- compiler/rustc_expand/src/mbe/macro_parser.rs | 2 +- compiler/rustc_expand/src/mbe/quoted.rs | 11 +++++------ compiler/rustc_expand/src/placeholders.rs | 4 ++-- compiler/rustc_expand/src/proc_macro_server.rs | 4 ++-- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index f6b5cd394b620..0fdccb0891899 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -350,7 +350,7 @@ pub(crate) struct ModuleMultipleCandidates { #[derive(Diagnostic)] #[diag(expand_trace_macro)] -pub struct TraceMacro { +pub(crate) struct TraceMacro { #[primary_span] pub span: Span, } @@ -402,14 +402,14 @@ pub(crate) struct CustomAttributePanickedHelp { #[derive(Diagnostic)] #[diag(expand_proc_macro_derive_tokens)] -pub struct ProcMacroDeriveTokens { +pub(crate) struct ProcMacroDeriveTokens { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(expand_duplicate_matcher_binding)] -pub struct DuplicateMatcherBinding { +pub(crate) struct DuplicateMatcherBinding { #[primary_span] #[label] pub span: Span, @@ -421,7 +421,7 @@ pub struct DuplicateMatcherBinding { #[diag(expand_missing_fragment_specifier)] #[note] #[help(expand_valid)] -pub struct MissingFragmentSpecifier { +pub(crate) struct MissingFragmentSpecifier { #[primary_span] pub span: Span, #[suggestion( @@ -437,7 +437,7 @@ pub struct MissingFragmentSpecifier { #[derive(Diagnostic)] #[diag(expand_invalid_fragment_specifier)] #[help] -pub struct InvalidFragmentSpecifier { +pub(crate) struct InvalidFragmentSpecifier { #[primary_span] pub span: Span, pub fragment: Ident, @@ -446,7 +446,7 @@ pub struct InvalidFragmentSpecifier { #[derive(Diagnostic)] #[diag(expand_expected_paren_or_brace)] -pub struct ExpectedParenOrBrace<'a> { +pub(crate) struct ExpectedParenOrBrace<'a> { #[primary_span] pub span: Span, pub token: Cow<'a, str>, @@ -479,7 +479,7 @@ pub(crate) struct GlobDelegationTraitlessQpath { #[derive(Diagnostic)] #[diag(expand_proc_macro_back_compat)] #[note] -pub struct ProcMacroBackCompat { +pub(crate) struct ProcMacroBackCompat { pub crate_name: String, pub fixed_version: String, } diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 4222c9fe90616..777044e3f33bf 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -13,6 +13,7 @@ #![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate proc_macro as pm; diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 628c6bfeb7932..5778f6616227a 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -196,13 +196,14 @@ impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> { } } -/// Currently used by macro_rules! compilation to extract a little information from the `Failure` case. -pub struct FailureForwarder<'matcher> { +/// Currently used by macro_rules! compilation to extract a little information from the `Failure` +/// case. +pub(crate) struct FailureForwarder<'matcher> { expected_token: Option<&'matcher Token>, } impl<'matcher> FailureForwarder<'matcher> { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { expected_token: None } } } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index e5b9c62742967..9011d02da3358 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -407,7 +407,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool { // Note: the vectors could be created and dropped within `parse_tt`, but to avoid excess // allocations we have a single vector for each kind that is cleared and reused repeatedly. -pub struct TtParser { +pub(crate) struct TtParser { macro_name: Ident, /// The set of current mps to be processed. This should be empty by the end of a successful diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index b2f7c8f5183a2..5df0aebfe57bd 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -14,12 +14,11 @@ use crate::mbe::macro_parser::count_metavar_decls; use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree}; const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ - `literal`, `path`, `meta`, `tt`, `item` and `vis`"; -pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \ - `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \ - `item` and `vis`"; + `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \ + `item` and `vis`"; +pub(crate) const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \ + `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, \ + `meta`, `tt`, `item` and `vis`"; /// Takes a `tokenstream::TokenStream` and returns a `Vec`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 1e455d465e4d1..469bed3cd5926 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -191,12 +191,12 @@ pub(crate) fn placeholder( } #[derive(Default)] -pub struct PlaceholderExpander { +pub(crate) struct PlaceholderExpander { expanded_fragments: FxHashMap, } impl PlaceholderExpander { - pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { + pub(crate) fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { fragment.mut_visit_with(self); self.expanded_fragments.insert(id, fragment); } diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1438d1ad11f57..4ff5da1a4bdfa 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -414,7 +414,7 @@ impl ToInternal for Level { } } -pub struct FreeFunctions; +pub(crate) struct FreeFunctions; pub(crate) struct Rustc<'a, 'b> { ecx: &'a mut ExtCtxt<'b>, @@ -426,7 +426,7 @@ pub(crate) struct Rustc<'a, 'b> { } impl<'a, 'b> Rustc<'a, 'b> { - pub fn new(ecx: &'a mut ExtCtxt<'b>) -> Self { + pub(crate) fn new(ecx: &'a mut ExtCtxt<'b>) -> Self { let expn_data = ecx.current_expansion.id.expn_data(); Rustc { def_site: ecx.with_def_site_ctxt(expn_data.def_site), From 0d8d05c07f8be4c90adf27141c0f64f76c318f64 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:55:54 +1000 Subject: [PATCH 081/102] Add `warn(unreachable_pub)` to `rustc_feature`. --- compiler/rustc_feature/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index dcc1c3202ea28..adaaba3cd235e 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -15,6 +15,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod accepted; From a510813e03966582ca9f1a06cb62e1d009ed0278 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:56:54 +1000 Subject: [PATCH 082/102] Add `warn(unreachable_pub)` to `rustc_fluent_macro`. --- compiler/rustc_fluent_macro/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 0a04e6743a8b8..6e5add24bcc4f 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -6,6 +6,7 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use proc_macro::TokenStream; From fa1814099426482e08a5a9900017858a525e9304 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:58:29 +1000 Subject: [PATCH 083/102] Add `warn(unreachable_pub)` to `rustc_graphviz`. --- compiler/rustc_graphviz/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index c8f8fd5be0237..b5774f64b66b2 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -277,6 +277,7 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::borrow::Cow; From bffa2244edd9cc210c7cd267fbacb77935cceaa6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 12:59:20 +1000 Subject: [PATCH 084/102] Add `warn(unreachable_pub)` to `rustc_hir`. --- compiler/rustc_hir/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index e517c3fd07a1d..c1a4a4497c7a9 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -10,6 +10,7 @@ #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] +#![warn(unreachable_pub)] // tidy-alphabetical-end extern crate self as rustc_hir; From 5acf4e7b4b257993aee8a71f958dac2ba4ce38c7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 13:14:50 +1000 Subject: [PATCH 085/102] Add `warn(unreachable_pub)` to `rustc_hir_analysis`. --- compiler/rustc_hir_analysis/src/bounds.rs | 14 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/check/errs.rs | 4 +- .../rustc_hir_analysis/src/check/region.rs | 4 +- .../rustc_hir_analysis/src/check_unused.rs | 2 +- .../src/coherence/builtin.rs | 2 +- .../src/coherence/inherent_impls.rs | 9 +- .../src/coherence/inherent_impls_overlap.rs | 5 +- .../rustc_hir_analysis/src/coherence/mod.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 2 +- .../rustc_hir_analysis/src/collect/type_of.rs | 2 +- .../src/constrained_generic_params.rs | 10 +- compiler/rustc_hir_analysis/src/errors.rs | 180 +++++++++--------- .../src/errors/pattern_types.rs | 2 +- .../src/errors/precise_captures.rs | 14 +- .../errors/wrong_number_of_generic_args.rs | 6 +- .../src/hir_ty_lowering/cmse.rs | 2 +- .../rustc_hir_analysis/src/hir_wf_check.rs | 2 +- .../rustc_hir_analysis/src/impl_wf_check.rs | 5 +- compiler/rustc_hir_analysis/src/lib.rs | 1 + .../src/outlives/explicit.rs | 4 +- .../rustc_hir_analysis/src/outlives/mod.rs | 2 +- .../src/variance/constraints.rs | 8 +- .../rustc_hir_analysis/src/variance/mod.rs | 2 +- .../rustc_hir_analysis/src/variance/solve.rs | 2 +- .../rustc_hir_analysis/src/variance/terms.rs | 10 +- .../rustc_hir_analysis/src/variance/xform.rs | 2 +- 27 files changed, 155 insertions(+), 145 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index c30a6f1eeb910..d0b0c08aa798b 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -26,13 +26,13 @@ use rustc_span::Span; /// Our representation is a bit mixed here -- in some cases, we /// include the self type (e.g., `trait_bounds`) but in others we do not #[derive(Default, PartialEq, Eq, Clone, Debug)] -pub struct Bounds<'tcx> { +pub(crate) struct Bounds<'tcx> { clauses: Vec<(ty::Clause<'tcx>, Span)>, effects_min_tys: FxIndexMap, Span>, } impl<'tcx> Bounds<'tcx> { - pub fn push_region_bound( + pub(crate) fn push_region_bound( &mut self, tcx: TyCtxt<'tcx>, region: ty::PolyTypeOutlivesPredicate<'tcx>, @@ -42,7 +42,7 @@ impl<'tcx> Bounds<'tcx> { .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span)); } - pub fn push_trait_bound( + pub(crate) fn push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, defining_def_id: DefId, @@ -154,7 +154,7 @@ impl<'tcx> Bounds<'tcx> { self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); } - pub fn push_projection_bound( + pub(crate) fn push_projection_bound( &mut self, tcx: TyCtxt<'tcx>, projection: ty::PolyProjectionPredicate<'tcx>, @@ -166,14 +166,14 @@ impl<'tcx> Bounds<'tcx> { )); } - pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { + pub(crate) fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); // Preferable to put this obligation first, since we report better errors for sized ambiguity. self.clauses.insert(0, (trait_ref.upcast(tcx), span)); } - pub fn clauses( + pub(crate) fn clauses( &self, // FIXME(effects): remove tcx _tcx: TyCtxt<'tcx>, @@ -181,7 +181,7 @@ impl<'tcx> Bounds<'tcx> { self.clauses.iter().cloned() } - pub fn effects_min_tys(&self) -> impl Iterator> + '_ { + pub(crate) fn effects_min_tys(&self) -> impl Iterator> + '_ { self.effects_min_tys.keys().copied() } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 728c3790098e7..d414bcdb95b34 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1053,7 +1053,7 @@ fn check_impl_items_against_trait<'tcx>( } } -pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { +fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { let t = tcx.type_of(def_id).instantiate_identity(); if let ty::Adt(def, args) = t.kind() && def.is_struct() diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 19a0476e63016..22d7d1fea9cb4 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -6,7 +6,7 @@ use rustc_span::Span; use crate::errors; /// Check for shared or mutable references of `static mut` inside expression -pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { +pub(crate) fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { let span = expr.span; let hir_id = expr.hir_id; if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind @@ -26,7 +26,7 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { } /// Check for shared or mutable references of `static mut` inside statement -pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { +pub(crate) fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { if let hir::StmtKind::Let(loc) = stmt.kind && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(rmutbl) = ba.0 diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index bc6641c688ccf..483351739792b 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -22,7 +22,7 @@ use rustc_span::source_map; use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut}; #[derive(Debug, Copy, Clone)] -pub struct Context { +struct Context { /// The scope that contains any new variables declared, plus its depth in /// the scope tree. var_parent: Option<(Scope, ScopeDepth)>, @@ -893,7 +893,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { /// re-use in incremental scenarios. We may sometimes need to rerun the /// type checker even when the HIR hasn't changed, and in those cases /// we can avoid reconstructing the region scope tree. -pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { +pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { let typeck_root_def_id = tcx.typeck_root_def_id(def_id); if typeck_root_def_id != def_id { return tcx.region_scope_tree(typeck_root_def_id); diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index ed23dc2a827b4..ca9e2e8a3cc6a 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -5,7 +5,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { check_unused_traits, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index fecd78bc38f47..23f1adfe302e3 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -332,7 +332,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() } } -pub fn coerce_unsized_info<'tcx>( +pub(crate) fn coerce_unsized_info<'tcx>( tcx: TyCtxt<'tcx>, impl_did: LocalDefId, ) -> Result { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 89acb778d6c29..bd8b43e28e540 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -19,7 +19,7 @@ use rustc_span::ErrorGuaranteed; use crate::errors; /// On-demand query: yields a map containing all types mapped to their inherent impls. -pub fn crate_inherent_impls( +pub(crate) fn crate_inherent_impls( tcx: TyCtxt<'_>, (): (), ) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> { @@ -32,7 +32,7 @@ pub fn crate_inherent_impls( Ok(tcx.arena.alloc(collect.impls_map)) } -pub fn crate_incoherent_impls( +pub(crate) fn crate_incoherent_impls( tcx: TyCtxt<'_>, simp: SimplifiedType, ) -> Result<&[DefId], ErrorGuaranteed> { @@ -43,7 +43,10 @@ pub fn crate_incoherent_impls( } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> Result<&[DefId], ErrorGuaranteed> { +pub(crate) fn inherent_impls( + tcx: TyCtxt<'_>, + ty_def_id: LocalDefId, +) -> Result<&[DefId], ErrorGuaranteed> { let crate_map = tcx.crate_inherent_impls(())?; Ok(match crate_map.inherent_impls.get(&ty_def_id) { Some(v) => &v[..], diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index cd5cc33d65abc..00bbbf7130f83 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -11,7 +11,10 @@ use rustc_span::{ErrorGuaranteed, Symbol}; use rustc_trait_selection::traits::{self, SkipLeakCheck}; use smallvec::SmallVec; -pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { +pub(crate) fn crate_inherent_impls_overlap_check( + tcx: TyCtxt<'_>, + (): (), +) -> Result<(), ErrorGuaranteed> { let mut inherent_overlap_checker = InherentOverlapChecker { tcx }; let mut res = Ok(()); for id in tcx.hir().items() { diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 8e4da90ca2646..3d800bb165cb4 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -123,7 +123,7 @@ fn enforce_empty_impls_for_marker_traits( .emit()) } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { use self::builtin::coerce_unsized_info; use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls}; use self::inherent_impls_overlap::crate_inherent_impls_overlap_check; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 0cf9e128bceef..e38492d9e6497 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -2071,7 +2071,7 @@ fn is_late_bound_map( } } -pub fn deny_non_region_late_bound( +fn deny_non_region_late_bound( tcx: TyCtxt<'_>, bound_vars: &mut FxIndexMap, where_: &str, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8cb4ba6c6691d..96256b91b9f9d 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -725,7 +725,7 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) { } } -pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { +pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { use hir::intravisit::Visitor; if tcx.features().lazy_type_alias { return true; diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 620170164f535..edf6524566418 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -6,7 +6,7 @@ use rustc_span::Span; use rustc_type_ir::fold::TypeFoldable; #[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct Parameter(pub u32); +pub(crate) struct Parameter(pub u32); impl From for Parameter { fn from(param: ty::ParamTy) -> Self { @@ -27,7 +27,7 @@ impl From for Parameter { } /// Returns the set of parameters constrained by the impl header. -pub fn parameters_for_impl<'tcx>( +pub(crate) fn parameters_for_impl<'tcx>( tcx: TyCtxt<'tcx>, impl_self_ty: Ty<'tcx>, impl_trait_ref: Option>, @@ -44,7 +44,7 @@ pub fn parameters_for_impl<'tcx>( /// uniquely determined by `value` (see RFC 447). If it is true, return the list /// of parameters whose values are needed in order to constrain `value` - these /// differ, with the latter being a superset, in the presence of projections. -pub fn parameters_for<'tcx>( +pub(crate) fn parameters_for<'tcx>( tcx: TyCtxt<'tcx>, value: impl TypeFoldable>, include_nonconstraining: bool, @@ -102,7 +102,7 @@ impl<'tcx> TypeVisitor> for ParameterCollector { } } -pub fn identify_constrained_generic_params<'tcx>( +pub(crate) fn identify_constrained_generic_params<'tcx>( tcx: TyCtxt<'tcx>, predicates: ty::GenericPredicates<'tcx>, impl_trait_ref: Option>, @@ -156,7 +156,7 @@ pub fn identify_constrained_generic_params<'tcx>( /// which is determined by 1, which requires `U`, that is determined /// by 0. I should probably pick a less tangled example, but I can't /// think of any. -pub fn setup_constraining_predicates<'tcx>( +pub(crate) fn setup_constraining_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: &mut [(ty::Clause<'tcx>, Span)], impl_trait_ref: Option>, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 821f79505f0b4..39df18ff658cd 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -11,15 +11,15 @@ use rustc_span::{Span, Symbol}; use crate::fluent_generated as fluent; mod pattern_types; -pub use pattern_types::*; -pub mod wrong_number_of_generic_args; +pub(crate) use pattern_types::*; +pub(crate) mod wrong_number_of_generic_args; mod precise_captures; pub(crate) use precise_captures::*; #[derive(Diagnostic)] #[diag(hir_analysis_ambiguous_assoc_item)] -pub struct AmbiguousAssocItem<'a> { +pub(crate) struct AmbiguousAssocItem<'a> { #[primary_span] #[label] pub span: Span, @@ -30,7 +30,7 @@ pub struct AmbiguousAssocItem<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_assoc_kind_mismatch)] -pub struct AssocKindMismatch { +pub(crate) struct AssocKindMismatch { #[primary_span] #[label] pub span: Span, @@ -52,7 +52,7 @@ pub struct AssocKindMismatch { hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg, applicability = "maybe-incorrect" )] -pub struct AssocKindMismatchWrapInBracesSugg { +pub(crate) struct AssocKindMismatchWrapInBracesSugg { #[suggestion_part(code = "{{ ")] pub lo: Span, #[suggestion_part(code = " }}")] @@ -61,7 +61,7 @@ pub struct AssocKindMismatchWrapInBracesSugg { #[derive(Diagnostic)] #[diag(hir_analysis_assoc_item_is_private, code = E0624)] -pub struct AssocItemIsPrivate { +pub(crate) struct AssocItemIsPrivate { #[primary_span] #[label] pub span: Span, @@ -73,7 +73,7 @@ pub struct AssocItemIsPrivate { #[derive(Diagnostic)] #[diag(hir_analysis_assoc_item_not_found, code = E0220)] -pub struct AssocItemNotFound<'a> { +pub(crate) struct AssocItemNotFound<'a> { #[primary_span] pub span: Span, pub assoc_name: Ident, @@ -86,7 +86,7 @@ pub struct AssocItemNotFound<'a> { } #[derive(Subdiagnostic)] -pub enum AssocItemNotFoundLabel<'a> { +pub(crate) enum AssocItemNotFoundLabel<'a> { #[label(hir_analysis_assoc_item_not_found_label)] NotFound { #[primary_span] @@ -105,7 +105,7 @@ pub enum AssocItemNotFoundLabel<'a> { #[derive(Subdiagnostic)] -pub enum AssocItemNotFoundSugg<'a> { +pub(crate) enum AssocItemNotFoundSugg<'a> { #[suggestion( hir_analysis_assoc_item_not_found_similar_sugg, code = "{suggested_name}", @@ -162,7 +162,7 @@ pub enum AssocItemNotFoundSugg<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)] -pub struct UnrecognizedAtomicOperation<'a> { +pub(crate) struct UnrecognizedAtomicOperation<'a> { #[primary_span] #[label] pub span: Span, @@ -171,7 +171,7 @@ pub struct UnrecognizedAtomicOperation<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = E0094)] -pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { +pub(crate) struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[primary_span] #[label] pub span: Span, @@ -183,7 +183,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_unrecognized_intrinsic_function, code = E0093)] #[help] -pub struct UnrecognizedIntrinsicFunction { +pub(crate) struct UnrecognizedIntrinsicFunction { #[primary_span] #[label] pub span: Span, @@ -192,7 +192,7 @@ pub struct UnrecognizedIntrinsicFunction { #[derive(Diagnostic)] #[diag(hir_analysis_lifetimes_or_bounds_mismatch_on_trait, code = E0195)] -pub struct LifetimesOrBoundsMismatchOnTrait { +pub(crate) struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, @@ -208,14 +208,14 @@ pub struct LifetimesOrBoundsMismatchOnTrait { #[derive(Diagnostic)] #[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)] -pub struct DropImplOnWrongItem { +pub(crate) struct DropImplOnWrongItem { #[primary_span] #[label] pub span: Span, } #[derive(Diagnostic)] -pub enum FieldAlreadyDeclared { +pub(crate) enum FieldAlreadyDeclared { #[diag(hir_analysis_field_already_declared, code = E0124)] NotNested { field_name: Symbol, @@ -272,14 +272,14 @@ pub enum FieldAlreadyDeclared { #[derive(Subdiagnostic)] #[help(hir_analysis_field_already_declared_nested_help)] -pub struct FieldAlreadyDeclaredNestedHelp { +pub(crate) struct FieldAlreadyDeclaredNestedHelp { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_analysis_copy_impl_on_type_with_dtor, code = E0184)] -pub struct CopyImplOnTypeWithDtor { +pub(crate) struct CopyImplOnTypeWithDtor { #[primary_span] #[label] pub span: Span, @@ -287,14 +287,14 @@ pub struct CopyImplOnTypeWithDtor { #[derive(Diagnostic)] #[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)] -pub struct MultipleRelaxedDefaultBounds { +pub(crate) struct MultipleRelaxedDefaultBounds { #[primary_span] pub spans: Vec, } #[derive(Diagnostic)] #[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)] -pub struct CopyImplOnNonAdt { +pub(crate) struct CopyImplOnNonAdt { #[primary_span] #[label] pub span: Span, @@ -302,7 +302,7 @@ pub struct CopyImplOnNonAdt { #[derive(Diagnostic)] #[diag(hir_analysis_const_param_ty_impl_on_unsized)] -pub struct ConstParamTyImplOnUnsized { +pub(crate) struct ConstParamTyImplOnUnsized { #[primary_span] #[label] pub span: Span, @@ -310,7 +310,7 @@ pub struct ConstParamTyImplOnUnsized { #[derive(Diagnostic)] #[diag(hir_analysis_const_param_ty_impl_on_non_adt)] -pub struct ConstParamTyImplOnNonAdt { +pub(crate) struct ConstParamTyImplOnNonAdt { #[primary_span] #[label] pub span: Span, @@ -318,7 +318,7 @@ pub struct ConstParamTyImplOnNonAdt { #[derive(Diagnostic)] #[diag(hir_analysis_trait_object_declared_with_no_traits, code = E0224)] -pub struct TraitObjectDeclaredWithNoTraits { +pub(crate) struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, #[label(hir_analysis_alias_span)] @@ -327,14 +327,14 @@ pub struct TraitObjectDeclaredWithNoTraits { #[derive(Diagnostic)] #[diag(hir_analysis_ambiguous_lifetime_bound, code = E0227)] -pub struct AmbiguousLifetimeBound { +pub(crate) struct AmbiguousLifetimeBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)] -pub struct AssocItemConstraintsNotAllowedHere { +pub(crate) struct AssocItemConstraintsNotAllowedHere { #[primary_span] #[label] pub span: Span, @@ -383,7 +383,7 @@ pub(crate) struct EscapingBoundVarInTyOfAssocConstBinding<'tcx> { #[derive(Subdiagnostic)] #[help(hir_analysis_parenthesized_fn_trait_expansion)] -pub struct ParenthesizedFnTraitExpansion { +pub(crate) struct ParenthesizedFnTraitExpansion { #[primary_span] pub span: Span, @@ -392,7 +392,7 @@ pub struct ParenthesizedFnTraitExpansion { #[derive(Diagnostic)] #[diag(hir_analysis_typeof_reserved_keyword_used, code = E0516)] -pub struct TypeofReservedKeywordUsed<'tcx> { +pub(crate) struct TypeofReservedKeywordUsed<'tcx> { pub ty: Ty<'tcx>, #[primary_span] #[label] @@ -403,7 +403,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> { #[derive(Diagnostic)] #[diag(hir_analysis_value_of_associated_struct_already_specified, code = E0719)] -pub struct ValueOfAssociatedStructAlreadySpecified { +pub(crate) struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] pub span: Span, @@ -416,7 +416,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified { #[derive(Diagnostic)] #[diag(hir_analysis_unconstrained_opaque_type)] #[note] -pub struct UnconstrainedOpaqueType { +pub(crate) struct UnconstrainedOpaqueType { #[primary_span] pub span: Span, pub name: Symbol, @@ -426,7 +426,7 @@ pub struct UnconstrainedOpaqueType { #[derive(Diagnostic)] #[diag(hir_analysis_tait_forward_compat)] #[note] -pub struct TaitForwardCompat { +pub(crate) struct TaitForwardCompat { #[primary_span] pub span: Span, #[note] @@ -436,7 +436,7 @@ pub struct TaitForwardCompat { #[derive(Diagnostic)] #[diag(hir_analysis_tait_forward_compat2)] #[note] -pub struct TaitForwardCompat2 { +pub(crate) struct TaitForwardCompat2 { #[primary_span] pub span: Span, #[note(hir_analysis_opaque)] @@ -444,7 +444,7 @@ pub struct TaitForwardCompat2 { pub opaque_type: String, } -pub struct MissingTypeParams { +pub(crate) struct MissingTypeParams { pub span: Span, pub def_span: Span, pub span_snippet: Option, @@ -512,7 +512,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams { #[derive(Diagnostic)] #[diag(hir_analysis_manual_implementation, code = E0183)] #[help] -pub struct ManualImplementation { +pub(crate) struct ManualImplementation { #[primary_span] #[label] pub span: Span, @@ -521,14 +521,14 @@ pub struct ManualImplementation { #[derive(Diagnostic)] #[diag(hir_analysis_generic_args_on_overridden_impl)] -pub struct GenericArgsOnOverriddenImpl { +pub(crate) struct GenericArgsOnOverriddenImpl { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_analysis_const_impl_for_non_const_trait)] -pub struct ConstImplForNonConstTrait { +pub(crate) struct ConstImplForNonConstTrait { #[primary_span] pub trait_ref_span: Span, pub trait_name: String, @@ -542,7 +542,7 @@ pub struct ConstImplForNonConstTrait { #[derive(Diagnostic)] #[diag(hir_analysis_const_bound_for_non_const_trait)] -pub struct ConstBoundForNonConstTrait { +pub(crate) struct ConstBoundForNonConstTrait { #[primary_span] pub span: Span, pub modifier: &'static str, @@ -550,7 +550,7 @@ pub struct ConstBoundForNonConstTrait { #[derive(Diagnostic)] #[diag(hir_analysis_self_in_impl_self)] -pub struct SelfInImplSelf { +pub(crate) struct SelfInImplSelf { #[primary_span] pub span: MultiSpan, #[note] @@ -567,7 +567,7 @@ pub(crate) struct LinkageType { #[derive(Diagnostic)] #[help] #[diag(hir_analysis_auto_deref_reached_recursion_limit, code = E0055)] -pub struct AutoDerefReachedRecursionLimit<'a> { +pub(crate) struct AutoDerefReachedRecursionLimit<'a> { #[primary_span] #[label] pub span: Span, @@ -736,7 +736,7 @@ pub(crate) struct InvalidUnionField { #[derive(Diagnostic)] #[diag(hir_analysis_invalid_unnamed_field_ty)] -pub struct InvalidUnnamedFieldTy { +pub(crate) struct InvalidUnnamedFieldTy { #[primary_span] pub span: Span, } @@ -894,7 +894,7 @@ pub(crate) struct SIMDFFIHighlyExperimental { } #[derive(Diagnostic)] -pub enum ImplNotMarkedDefault { +pub(crate) enum ImplNotMarkedDefault { #[diag(hir_analysis_impl_not_marked_default, code = E0520)] #[note] Ok { @@ -1137,7 +1137,7 @@ pub(crate) enum LateBoundInApit { #[derive(LintDiagnostic)] #[diag(hir_analysis_unused_associated_type_bounds)] #[note] -pub struct UnusedAssociatedTypeBounds { +pub(crate) struct UnusedAssociatedTypeBounds { #[suggestion(code = "")] pub span: Span, } @@ -1162,7 +1162,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_ty_outside, code = E0390)] #[help] -pub struct InherentTyOutside { +pub(crate) struct InherentTyOutside { #[primary_span] #[help(hir_analysis_span_help)] pub span: Span, @@ -1170,7 +1170,7 @@ pub struct InherentTyOutside { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub struct DispatchFromDynCoercion<'a> { +pub(crate) struct DispatchFromDynCoercion<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1182,7 +1182,7 @@ pub struct DispatchFromDynCoercion<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)] -pub struct DispatchFromDynRepr { +pub(crate) struct DispatchFromDynRepr { #[primary_span] pub span: Span, } @@ -1190,7 +1190,7 @@ pub struct DispatchFromDynRepr { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)] #[help] -pub struct InherentTyOutsideRelevant { +pub(crate) struct InherentTyOutsideRelevant { #[primary_span] pub span: Span, #[help(hir_analysis_span_help)] @@ -1200,7 +1200,7 @@ pub struct InherentTyOutsideRelevant { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_ty_outside_new, code = E0116)] #[note] -pub struct InherentTyOutsideNew { +pub(crate) struct InherentTyOutsideNew { #[primary_span] #[label] pub span: Span, @@ -1209,7 +1209,7 @@ pub struct InherentTyOutsideNew { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_ty_outside_primitive, code = E0390)] #[help] -pub struct InherentTyOutsidePrimitive { +pub(crate) struct InherentTyOutsidePrimitive { #[primary_span] pub span: Span, #[help(hir_analysis_span_help)] @@ -1219,7 +1219,7 @@ pub struct InherentTyOutsidePrimitive { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_primitive_ty, code = E0390)] #[help] -pub struct InherentPrimitiveTy<'a> { +pub(crate) struct InherentPrimitiveTy<'a> { #[primary_span] pub span: Span, #[subdiagnostic] @@ -1228,14 +1228,14 @@ pub struct InherentPrimitiveTy<'a> { #[derive(Subdiagnostic)] #[note(hir_analysis_inherent_primitive_ty_note)] -pub struct InherentPrimitiveTyNote<'a> { +pub(crate) struct InherentPrimitiveTyNote<'a> { pub subty: Ty<'a>, } #[derive(Diagnostic)] #[diag(hir_analysis_inherent_dyn, code = E0785)] #[note] -pub struct InherentDyn { +pub(crate) struct InherentDyn { #[primary_span] #[label] pub span: Span, @@ -1244,7 +1244,7 @@ pub struct InherentDyn { #[derive(Diagnostic)] #[diag(hir_analysis_inherent_nominal, code = E0118)] #[note] -pub struct InherentNominal { +pub(crate) struct InherentNominal { #[primary_span] #[label] pub span: Span, @@ -1253,7 +1253,7 @@ pub struct InherentNominal { #[derive(Diagnostic)] #[diag(hir_analysis_dispatch_from_dyn_zst, code = E0378)] #[note] -pub struct DispatchFromDynZST<'a> { +pub(crate) struct DispatchFromDynZST<'a> { #[primary_span] pub span: Span, pub name: Symbol, @@ -1262,7 +1262,7 @@ pub struct DispatchFromDynZST<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub struct DispatchFromDynSingle<'a> { +pub(crate) struct DispatchFromDynSingle<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1273,7 +1273,7 @@ pub struct DispatchFromDynSingle<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)] #[note] -pub struct DispatchFromDynMulti { +pub(crate) struct DispatchFromDynMulti { #[primary_span] pub span: Span, #[note(hir_analysis_coercions_note)] @@ -1284,7 +1284,7 @@ pub struct DispatchFromDynMulti { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0376)] -pub struct DispatchFromDynStruct<'a> { +pub(crate) struct DispatchFromDynStruct<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1292,7 +1292,7 @@ pub struct DispatchFromDynStruct<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0377)] -pub struct DispatchFromDynSame<'a> { +pub(crate) struct DispatchFromDynSame<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1304,7 +1304,7 @@ pub struct DispatchFromDynSame<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0374)] -pub struct CoerceUnsizedOneField<'a> { +pub(crate) struct CoerceUnsizedOneField<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1315,7 +1315,7 @@ pub struct CoerceUnsizedOneField<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_multi, code = E0375)] #[note] -pub struct CoerceUnsizedMulti { +pub(crate) struct CoerceUnsizedMulti { #[primary_span] #[label] pub span: Span, @@ -1327,7 +1327,7 @@ pub struct CoerceUnsizedMulti { #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub struct CoerceUnsizedMay<'a> { +pub(crate) struct CoerceUnsizedMay<'a> { #[primary_span] pub span: Span, pub trait_name: &'a str, @@ -1335,7 +1335,7 @@ pub struct CoerceUnsizedMay<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)] -pub struct TraitCannotImplForTy { +pub(crate) struct TraitCannotImplForTy { #[primary_span] pub span: Span, pub trait_name: String, @@ -1347,7 +1347,7 @@ pub struct TraitCannotImplForTy { #[derive(Subdiagnostic)] #[note(hir_analysis_requires_note)] -pub struct ImplForTyRequires { +pub(crate) struct ImplForTyRequires { #[primary_span] pub span: MultiSpan, pub error_predicate: String, @@ -1358,7 +1358,7 @@ pub struct ImplForTyRequires { #[derive(Diagnostic)] #[diag(hir_analysis_traits_with_defualt_impl, code = E0321)] #[note] -pub struct TraitsWithDefaultImpl<'a> { +pub(crate) struct TraitsWithDefaultImpl<'a> { #[primary_span] pub span: Span, pub traits: String, @@ -1368,7 +1368,7 @@ pub struct TraitsWithDefaultImpl<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_cross_crate_traits, code = E0321)] -pub struct CrossCrateTraits<'a> { +pub(crate) struct CrossCrateTraits<'a> { #[primary_span] #[label] pub span: Span, @@ -1378,7 +1378,7 @@ pub struct CrossCrateTraits<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_cross_crate_traits_defined, code = E0321)] -pub struct CrossCrateTraitsDefined { +pub(crate) struct CrossCrateTraitsDefined { #[primary_span] #[label] pub span: Span, @@ -1390,7 +1390,7 @@ pub struct CrossCrateTraitsDefined { #[derive(Diagnostic)] #[diag(hir_analysis_ty_param_first_local, code = E0210)] #[note] -pub struct TyParamFirstLocal<'tcx> { +pub(crate) struct TyParamFirstLocal<'tcx> { #[primary_span] #[label] pub span: Span, @@ -1403,7 +1403,7 @@ pub struct TyParamFirstLocal<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_analysis_ty_param_first_local, code = E0210)] #[note] -pub struct TyParamFirstLocalLint<'tcx> { +pub(crate) struct TyParamFirstLocalLint<'tcx> { #[label] pub span: Span, #[note(hir_analysis_case_note)] @@ -1415,7 +1415,7 @@ pub struct TyParamFirstLocalLint<'tcx> { #[derive(Diagnostic)] #[diag(hir_analysis_ty_param_some, code = E0210)] #[note] -pub struct TyParamSome { +pub(crate) struct TyParamSome { #[primary_span] #[label] pub span: Span, @@ -1427,7 +1427,7 @@ pub struct TyParamSome { #[derive(LintDiagnostic)] #[diag(hir_analysis_ty_param_some, code = E0210)] #[note] -pub struct TyParamSomeLint { +pub(crate) struct TyParamSomeLint { #[label] pub span: Span, #[note(hir_analysis_only_note)] @@ -1436,7 +1436,7 @@ pub struct TyParamSomeLint { } #[derive(Diagnostic)] -pub enum OnlyCurrentTraits { +pub(crate) enum OnlyCurrentTraits { #[diag(hir_analysis_only_current_traits_outside, code = E0117)] Outside { #[primary_span] @@ -1465,20 +1465,20 @@ pub enum OnlyCurrentTraits { #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_opaque)] -pub struct OnlyCurrentTraitsOpaque { +pub(crate) struct OnlyCurrentTraitsOpaque { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_foreign)] -pub struct OnlyCurrentTraitsForeign { +pub(crate) struct OnlyCurrentTraitsForeign { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_name)] -pub struct OnlyCurrentTraitsName<'a> { +pub(crate) struct OnlyCurrentTraitsName<'a> { #[primary_span] pub span: Span, pub name: &'a str, @@ -1486,7 +1486,7 @@ pub struct OnlyCurrentTraitsName<'a> { #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_pointer)] -pub struct OnlyCurrentTraitsPointer<'a> { +pub(crate) struct OnlyCurrentTraitsPointer<'a> { #[primary_span] pub span: Span, pub pointer: Ty<'a>, @@ -1494,7 +1494,7 @@ pub struct OnlyCurrentTraitsPointer<'a> { #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_ty)] -pub struct OnlyCurrentTraitsTy<'a> { +pub(crate) struct OnlyCurrentTraitsTy<'a> { #[primary_span] pub span: Span, pub ty: Ty<'a>, @@ -1502,7 +1502,7 @@ pub struct OnlyCurrentTraitsTy<'a> { #[derive(Subdiagnostic)] #[label(hir_analysis_only_current_traits_adt)] -pub struct OnlyCurrentTraitsAdt { +pub(crate) struct OnlyCurrentTraitsAdt { #[primary_span] pub span: Span, pub name: String, @@ -1513,11 +1513,11 @@ pub struct OnlyCurrentTraitsAdt { hir_analysis_only_current_traits_pointer_sugg, applicability = "maybe-incorrect" )] -pub struct OnlyCurrentTraitsPointerSugg<'a> { +pub(crate) struct OnlyCurrentTraitsPointerSugg<'a> { #[suggestion_part(code = "WrapperType")] pub wrapper_span: Span, #[suggestion_part(code = "struct WrapperType(*{mut_key}{ptr_ty});\n\n")] - pub struct_span: Span, + pub(crate) struct_span: Span, pub mut_key: &'a str, pub ptr_ty: Ty<'a>, } @@ -1525,7 +1525,7 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_static_mut_ref, code = E0796)] #[note] -pub struct StaticMutRef<'a> { +pub(crate) struct StaticMutRef<'a> { #[primary_span] #[label] pub span: Span, @@ -1535,7 +1535,7 @@ pub struct StaticMutRef<'a> { } #[derive(Subdiagnostic)] -pub enum MutRefSugg { +pub(crate) enum MutRefSugg { #[multipart_suggestion( hir_analysis_suggestion, style = "verbose", @@ -1565,7 +1565,7 @@ pub enum MutRefSugg { #[diag(hir_analysis_static_mut_refs_lint)] #[note] #[note(hir_analysis_why_note)] -pub struct RefOfMutStatic<'a> { +pub(crate) struct RefOfMutStatic<'a> { #[label] pub span: Span, #[subdiagnostic] @@ -1575,7 +1575,7 @@ pub struct RefOfMutStatic<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_not_supported_delegation)] -pub struct UnsupportedDelegation<'a> { +pub(crate) struct UnsupportedDelegation<'a> { #[primary_span] pub span: Span, pub descr: &'a str, @@ -1585,7 +1585,7 @@ pub struct UnsupportedDelegation<'a> { #[derive(Diagnostic)] #[diag(hir_analysis_method_should_return_future)] -pub struct MethodShouldReturnFuture { +pub(crate) struct MethodShouldReturnFuture { #[primary_span] pub span: Span, pub method_name: Symbol, @@ -1649,7 +1649,7 @@ pub(crate) struct UnconstrainedGenericParameter { } #[derive(Diagnostic)] -pub enum UnnamedFieldsRepr<'a> { +pub(crate) enum UnnamedFieldsRepr<'a> { #[diag(hir_analysis_unnamed_fields_repr_missing_repr_c)] MissingReprC { #[primary_span] @@ -1678,14 +1678,14 @@ pub enum UnnamedFieldsRepr<'a> { #[derive(Subdiagnostic)] #[note(hir_analysis_unnamed_fields_repr_field_defined)] -pub struct UnnamedFieldsReprFieldDefined { +pub(crate) struct UnnamedFieldsReprFieldDefined { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)] -pub struct OpaqueCapturesHigherRankedLifetime { +pub(crate) struct OpaqueCapturesHigherRankedLifetime { #[primary_span] pub span: Span, #[label] @@ -1697,7 +1697,7 @@ pub struct OpaqueCapturesHigherRankedLifetime { #[derive(Diagnostic)] #[diag(hir_analysis_pattern_type_non_const_range)] -pub struct NonConstRange { +pub(crate) struct NonConstRange { #[primary_span] pub span: Span, } @@ -1706,7 +1706,7 @@ pub struct NonConstRange { #[diag(hir_analysis_invalid_receiver_ty, code = E0307)] #[note] #[help(hir_analysis_invalid_receiver_ty_help)] -pub struct InvalidReceiverTy<'tcx> { +pub(crate) struct InvalidReceiverTy<'tcx> { #[primary_span] pub span: Span, pub receiver_ty: Ty<'tcx>, @@ -1716,12 +1716,12 @@ pub struct InvalidReceiverTy<'tcx> { #[diag(hir_analysis_effects_without_next_solver)] #[note] #[help] -pub struct EffectsWithoutNextSolver; +pub(crate) struct EffectsWithoutNextSolver; #[derive(Diagnostic)] #[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)] #[note] -pub struct CmseCallInputsStackSpill { +pub(crate) struct CmseCallInputsStackSpill { #[primary_span] #[label] pub span: Span, @@ -1732,7 +1732,7 @@ pub struct CmseCallInputsStackSpill { #[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)] #[note(hir_analysis_note1)] #[note(hir_analysis_note2)] -pub struct CmseCallOutputStackSpill { +pub(crate) struct CmseCallOutputStackSpill { #[primary_span] #[label] pub span: Span, @@ -1740,7 +1740,7 @@ pub struct CmseCallOutputStackSpill { #[derive(Diagnostic)] #[diag(hir_analysis_cmse_call_generic, code = E0798)] -pub struct CmseCallGeneric { +pub(crate) struct CmseCallGeneric { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs index 008d26989890d..bb771d6ea170e 100644 --- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs +++ b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs @@ -3,7 +3,7 @@ use rustc_span::Span; #[derive(Diagnostic)] #[diag(hir_analysis_pattern_type_wild_pat)] -pub struct WildPatTy { +pub(crate) struct WildPatTy { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs index 8a9b5fe636967..af2bb053c0ab4 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -4,7 +4,7 @@ use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(hir_analysis_param_not_captured)] #[note] -pub struct ParamNotCaptured { +pub(crate) struct ParamNotCaptured { #[primary_span] pub opaque_span: Span, #[label] @@ -15,7 +15,7 @@ pub struct ParamNotCaptured { #[derive(Diagnostic)] #[diag(hir_analysis_self_ty_not_captured)] #[note] -pub struct SelfTyNotCaptured { +pub(crate) struct SelfTyNotCaptured { #[primary_span] pub opaque_span: Span, #[label] @@ -24,7 +24,7 @@ pub struct SelfTyNotCaptured { #[derive(Diagnostic)] #[diag(hir_analysis_lifetime_not_captured)] -pub struct LifetimeNotCaptured { +pub(crate) struct LifetimeNotCaptured { #[primary_span] pub use_span: Span, #[label(hir_analysis_param_label)] @@ -35,7 +35,7 @@ pub struct LifetimeNotCaptured { #[derive(Diagnostic)] #[diag(hir_analysis_bad_precise_capture)] -pub struct BadPreciseCapture { +pub(crate) struct BadPreciseCapture { #[primary_span] pub span: Span, pub kind: &'static str, @@ -44,7 +44,7 @@ pub struct BadPreciseCapture { #[derive(Diagnostic)] #[diag(hir_analysis_precise_capture_self_alias)] -pub struct PreciseCaptureSelfAlias { +pub(crate) struct PreciseCaptureSelfAlias { #[primary_span] pub span: Span, #[label] @@ -54,7 +54,7 @@ pub struct PreciseCaptureSelfAlias { #[derive(Diagnostic)] #[diag(hir_analysis_duplicate_precise_capture)] -pub struct DuplicatePreciseCapture { +pub(crate) struct DuplicatePreciseCapture { #[primary_span] pub first_span: Span, pub name: Symbol, @@ -64,7 +64,7 @@ pub struct DuplicatePreciseCapture { #[derive(Diagnostic)] #[diag(hir_analysis_lifetime_must_be_first)] -pub struct LifetimesMustBeFirst { +pub(crate) struct LifetimesMustBeFirst { #[primary_span] pub lifetime_span: Span, pub name: Symbol, diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 8ecf53bfacb94..f8b2469dfea45 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -8,7 +8,7 @@ use rustc_span::def_id::DefId; use GenericArgsInfo::*; /// Handles the `wrong number of type / lifetime / ... arguments` family of error messages. -pub struct WrongNumberOfGenericArgs<'a, 'tcx> { +pub(crate) struct WrongNumberOfGenericArgs<'a, 'tcx> { pub(crate) tcx: TyCtxt<'tcx>, pub(crate) angle_brackets: AngleBrackets, @@ -49,7 +49,7 @@ pub(crate) enum AngleBrackets { // Information about the kind of arguments that are either missing or are unexpected #[derive(Debug)] -pub enum GenericArgsInfo { +pub(crate) enum GenericArgsInfo { MissingLifetimes { num_missing_args: usize, }, @@ -87,7 +87,7 @@ pub enum GenericArgsInfo { } impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { - pub fn new( + pub(crate) fn new( tcx: TyCtxt<'tcx>, gen_args_info: GenericArgsInfo, path_segment: &'a hir::PathSegment<'_>, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index e99717ce00f8c..1b73cecd6664b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -11,7 +11,7 @@ use crate::errors; /// Check conditions on inputs and outputs that the cmse ABIs impose: arguments and results MUST be /// returned via registers (i.e. MUST NOT spill to the stack). LLVM will also validate these /// conditions, but by checking them here rustc can emit nicer error messages. -pub fn validate_cmse_abi<'tcx>( +pub(crate) fn validate_cmse_abi<'tcx>( tcx: TyCtxt<'tcx>, dcx: DiagCtxtHandle<'_>, hir_id: HirId, diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 7d2cabd3f2c7e..3ecf61501f6d3 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -11,7 +11,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt}; use crate::collect::ItemCtxt; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { diagnostic_hir_wf_check, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 02520c472b9de..7f183324f0433 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -53,7 +53,10 @@ mod min_specialization; /// impl<'a> Trait for Bar { type X = &'a i32; } /// // ^ 'a is unused and appears in assoc type, error /// ``` -pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { +pub(crate) fn check_impl_wf( + tcx: TyCtxt<'_>, + impl_def_id: LocalDefId, +) -> Result<(), ErrorGuaranteed> { let min_specialization = tcx.features().min_specialization; let mut res = Ok(()); debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 291d57f2a176f..f6d96003ce9e3 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -72,6 +72,7 @@ This API is completely unstable and subject to change. #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index bbfadbb5c3087..f576499ecac38 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -5,12 +5,12 @@ use rustc_middle::ty::{self, OutlivesPredicate, TyCtxt}; use super::utils::*; #[derive(Debug)] -pub struct ExplicitPredicatesMap<'tcx> { +pub(crate) struct ExplicitPredicatesMap<'tcx> { map: FxIndexMap>>, } impl<'tcx> ExplicitPredicatesMap<'tcx> { - pub fn new() -> ExplicitPredicatesMap<'tcx> { + pub(crate) fn new() -> ExplicitPredicatesMap<'tcx> { ExplicitPredicatesMap { map: FxIndexMap::default() } } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index cb61ef7c64da0..e3cdb1bf5f7d6 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -9,7 +9,7 @@ mod explicit; mod implicit_infer; mod utils; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index ce9e73bf24503..4fb7a02f8c937 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -12,7 +12,7 @@ use rustc_middle::{bug, span_bug}; use super::terms::VarianceTerm::*; use super::terms::*; -pub struct ConstraintContext<'a, 'tcx> { +pub(crate) struct ConstraintContext<'a, 'tcx> { pub terms_cx: TermsContext<'a, 'tcx>, // These are pointers to common `ConstantTerm` instances @@ -27,7 +27,7 @@ pub struct ConstraintContext<'a, 'tcx> { /// Declares that the variable `decl_id` appears in a location with /// variance `variance`. #[derive(Copy, Clone)] -pub struct Constraint<'a> { +pub(crate) struct Constraint<'a> { pub inferred: InferredIndex, pub variance: &'a VarianceTerm<'a>, } @@ -41,11 +41,11 @@ pub struct Constraint<'a> { /// ``` /// then while we are visiting `Bar`, the `CurrentItem` would have /// the `DefId` and the start of `Foo`'s inferreds. -pub struct CurrentItem { +struct CurrentItem { inferred_start: InferredIndex, } -pub fn add_constraints_from_crate<'a, 'tcx>( +pub(crate) fn add_constraints_from_crate<'a, 'tcx>( terms_cx: TermsContext<'a, 'tcx>, ) -> ConstraintContext<'a, 'tcx> { let tcx = terms_cx.tcx; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 8a4114c3e4bca..e8e2caf7e62a5 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -28,7 +28,7 @@ pub(crate) mod dump; /// Code for transforming variances. mod xform; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { variances_of, crate_variances, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs index e64c6721fe018..4f1bac17e71be 100644 --- a/compiler/rustc_hir_analysis/src/variance/solve.rs +++ b/compiler/rustc_hir_analysis/src/variance/solve.rs @@ -21,7 +21,7 @@ struct SolveContext<'a, 'tcx> { solutions: Vec, } -pub fn solve_constraints<'tcx>( +pub(crate) fn solve_constraints<'tcx>( constraints_cx: ConstraintContext<'_, 'tcx>, ) -> ty::CrateVariancesMap<'tcx> { let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index 36bff60e01978..597699b37b1c5 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -18,13 +18,13 @@ use rustc_middle::ty::{self, TyCtxt}; use self::VarianceTerm::*; -pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>; +pub(crate) type VarianceTermPtr<'a> = &'a VarianceTerm<'a>; #[derive(Copy, Clone, Debug)] -pub struct InferredIndex(pub usize); +pub(crate) struct InferredIndex(pub usize); #[derive(Copy, Clone)] -pub enum VarianceTerm<'a> { +pub(crate) enum VarianceTerm<'a> { ConstantTerm(ty::Variance), TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>), InferredTerm(InferredIndex), @@ -45,7 +45,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> { /// The first pass over the crate simply builds up the set of inferreds. -pub struct TermsContext<'a, 'tcx> { +pub(crate) struct TermsContext<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, pub arena: &'a DroplessArena, @@ -62,7 +62,7 @@ pub struct TermsContext<'a, 'tcx> { pub inferred_terms: Vec>, } -pub fn determine_parameters_to_be_inferred<'a, 'tcx>( +pub(crate) fn determine_parameters_to_be_inferred<'a, 'tcx>( tcx: TyCtxt<'tcx>, arena: &'a DroplessArena, ) -> TermsContext<'a, 'tcx> { diff --git a/compiler/rustc_hir_analysis/src/variance/xform.rs b/compiler/rustc_hir_analysis/src/variance/xform.rs index 027f0859fcd54..2e9964788e6e5 100644 --- a/compiler/rustc_hir_analysis/src/variance/xform.rs +++ b/compiler/rustc_hir_analysis/src/variance/xform.rs @@ -1,6 +1,6 @@ use rustc_middle::ty; -pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { +pub(crate) fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { // Greatest lower bound of the variance lattice as // defined in The Paper: // From 3aae994ca2d2316b54d04b77064034d5edab878f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 13:25:40 +1000 Subject: [PATCH 086/102] Add `warn(unreachable_pub)` to `rustc_hir_pretty`. --- compiler/rustc_hir_pretty/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index cff21173f7982..ac6707f931602 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![recursion_limit = "256"] +#![warn(unreachable_pub)] // tidy-alphabetical-end use std::cell::Cell; From 7fc04443404914bb7c432c2269d94fd48d569244 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 14:22:07 +1000 Subject: [PATCH 087/102] Add `warn(unreachable_pub)` to `rustc_hir_typeck`. --- compiler/rustc_hir_typeck/src/_match.rs | 4 +- compiler/rustc_hir_typeck/src/autoderef.rs | 8 +- compiler/rustc_hir_typeck/src/callee.rs | 8 +- compiler/rustc_hir_typeck/src/coercion.rs | 28 ++--- compiler/rustc_hir_typeck/src/demand.rs | 24 ++-- compiler/rustc_hir_typeck/src/diverges.rs | 2 +- compiler/rustc_hir_typeck/src/errors.rs | 104 +++++++++--------- compiler/rustc_hir_typeck/src/expectation.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 8 +- compiler/rustc_hir_typeck/src/fallback.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 40 +++---- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 4 +- .../src/fn_ctxt/arg_matrix.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 12 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 18 +-- .../src/fn_ctxt/suggestions.rs | 12 +- compiler/rustc_hir_typeck/src/intrinsicck.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 1 + .../rustc_hir_typeck/src/method/confirm.rs | 6 +- compiler/rustc_hir_typeck/src/method/mod.rs | 20 ++-- compiler/rustc_hir_typeck/src/method/probe.rs | 22 ++-- .../rustc_hir_typeck/src/method/suggest.rs | 8 +- compiler/rustc_hir_typeck/src/op.rs | 6 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_hir_typeck/src/place_op.rs | 2 +- .../rustc_hir_typeck/src/rvalue_scopes.rs | 2 +- .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 4 +- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- 29 files changed, 183 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index bc0ed4a7fa99d..7427fb147166f 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn maybe_get_coercion_reason( + pub(crate) fn maybe_get_coercion_reason( &self, hir_id: hir::HirId, sp: Span, @@ -584,7 +584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (e.g. we're in the tail of a function body) // // Returns the `LocalDefId` of the RPIT, which is always identity-substituted. - pub fn return_position_impl_trait_from_match_expectation( + pub(crate) fn return_position_impl_trait_from_match_expectation( &self, expectation: Expectation<'tcx>, ) -> Option { diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index 69c4889d7a4b2..d2d6da8f32b30 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -13,11 +13,11 @@ use super::method::MethodCallee; use super::{FnCtxt, PlaceOp}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> { + pub(crate) fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> { Autoderef::new(self, self.param_env, self.body_id, span, base_ty) } - pub fn try_overloaded_deref( + pub(crate) fn try_overloaded_deref( &self, span: Span, base_ty: Ty<'tcx>, @@ -26,11 +26,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Returns the adjustment steps. - pub fn adjust_steps(&self, autoderef: &Autoderef<'a, 'tcx>) -> Vec> { + pub(crate) fn adjust_steps(&self, autoderef: &Autoderef<'a, 'tcx>) -> Vec> { self.register_infer_ok_obligations(self.adjust_steps_as_infer_ok(autoderef)) } - pub fn adjust_steps_as_infer_ok( + pub(crate) fn adjust_steps_as_infer_ok( &self, autoderef: &Autoderef<'a, 'tcx>, ) -> InferOk<'tcx, Vec>> { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 44cb08e44eb81..fc08b872efc2e 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -29,7 +29,7 @@ use crate::errors; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific /// method that is called). -pub fn check_legal_trait_for_method_call( +pub(crate) fn check_legal_trait_for_method_call( tcx: TyCtxt<'_>, span: Span, receiver: Option, @@ -62,7 +62,7 @@ enum CallStep<'tcx> { } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_call( + pub(crate) fn check_call( &self, call_expr: &'tcx hir::Expr<'tcx>, callee_expr: &'tcx hir::Expr<'tcx>, @@ -940,7 +940,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[derive(Debug)] -pub struct DeferredCallResolution<'tcx> { +pub(crate) struct DeferredCallResolution<'tcx> { call_expr: &'tcx hir::Expr<'tcx>, callee_expr: &'tcx hir::Expr<'tcx>, closure_ty: Ty<'tcx>, @@ -949,7 +949,7 @@ pub struct DeferredCallResolution<'tcx> { } impl<'a, 'tcx> DeferredCallResolution<'tcx> { - pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) { + pub(crate) fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) { debug!("DeferredCallResolution::resolve() {:?}", self); // we should not be invoked until the closure kind has been diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index b47d8a97bceea..dabc5a8939783 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -976,7 +976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// adjusted type of the expression, if successful. /// Adjustments are only recorded if the coercion succeeded. /// The expressions *must not* have any preexisting adjustments. - pub fn coerce( + pub(crate) fn coerce( &self, expr: &hir::Expr<'_>, expr_ty: Ty<'tcx>, @@ -1011,7 +1011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// Returns false if the coercion creates any obligations that result in /// errors. - pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool { + pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool { // FIXME(-Znext-solver): We need to structurally resolve both types here. let source = self.resolve_vars_with_obligations(expr_ty); debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); @@ -1032,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given a type and a target type, this function will calculate and return /// how many dereference steps needed to achieve `expr_ty <: target`. If /// it's not possible, return `None`. - pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option { + pub(crate) fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option { let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion let coerce = Coerce::new(self, cause, AllowTwoPhase::No); @@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// This function is for diagnostics only, since it does not register /// trait or region sub-obligations. (presumably we could, but it's not /// particularly important for diagnostics...) - pub fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option> { + pub(crate) fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option> { self.autoderef(DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| { self.infcx .type_implements_trait( @@ -1341,7 +1341,7 @@ pub fn can_coerce<'tcx>( /// } /// let final_ty = coerce.complete(fcx); /// ``` -pub struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> { +pub(crate) struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> { expected_ty: Ty<'tcx>, final_ty: Option>, expressions: Expressions<'tcx, 'exprs, E>, @@ -1350,7 +1350,7 @@ pub struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> { /// The type of a `CoerceMany` that is storing up the expressions into /// a buffer. We use this in `check/mod.rs` for things like `break`. -pub type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>; +pub(crate) type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>; enum Expressions<'tcx, 'exprs, E: AsCoercionSite> { Dynamic(Vec<&'tcx hir::Expr<'tcx>>), @@ -1361,7 +1361,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// The usual case; collect the set of expressions dynamically. /// If the full set of coercion sites is known before hand, /// consider `with_coercion_sites()` instead to avoid allocation. - pub fn new(expected_ty: Ty<'tcx>) -> Self { + pub(crate) fn new(expected_ty: Ty<'tcx>) -> Self { Self::make(expected_ty, Expressions::Dynamic(vec![])) } @@ -1370,7 +1370,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// expected to pass each element in the slice to `coerce(...)` in /// order. This is used with arrays in particular to avoid /// needlessly cloning the slice. - pub fn with_coercion_sites(expected_ty: Ty<'tcx>, coercion_sites: &'exprs [E]) -> Self { + pub(crate) fn with_coercion_sites(expected_ty: Ty<'tcx>, coercion_sites: &'exprs [E]) -> Self { Self::make(expected_ty, Expressions::UpFront(coercion_sites)) } @@ -1386,7 +1386,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// Typically, this is used as the expected type when /// type-checking each of the alternative expressions whose types /// we are trying to merge. - pub fn expected_ty(&self) -> Ty<'tcx> { + pub(crate) fn expected_ty(&self) -> Ty<'tcx> { self.expected_ty } @@ -1394,7 +1394,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// at the LUB of the expressions we've seen so far (if any). This /// isn't *final* until you call `self.complete()`, which will return /// the merged type. - pub fn merged_ty(&self) -> Ty<'tcx> { + pub(crate) fn merged_ty(&self) -> Ty<'tcx> { self.final_ty.unwrap_or(self.expected_ty) } @@ -1403,7 +1403,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// could coerce from. This will record `expression`, and later /// calls to `coerce` may come back and add adjustments and things /// if necessary. - pub fn coerce<'a>( + pub(crate) fn coerce<'a>( &mut self, fcx: &FnCtxt<'a, 'tcx>, cause: &ObligationCause<'tcx>, @@ -1425,7 +1425,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// The `augment_error` gives you a chance to extend the error /// message, in case any results (e.g., we use this to suggest /// removing a `;`). - pub fn coerce_forced_unit<'a>( + pub(crate) fn coerce_forced_unit<'a>( &mut self, fcx: &FnCtxt<'a, 'tcx>, cause: &ObligationCause<'tcx>, @@ -1920,7 +1920,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } - pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> { + pub(crate) fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> { if let Some(final_ty) = self.final_ty { final_ty } else { @@ -1934,7 +1934,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { /// Something that can be converted into an expression to which we can /// apply a coercion. -pub trait AsCoercionSite { +pub(crate) trait AsCoercionSite { fn as_coercion_site(&self) -> &hir::Expr<'_>; } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 0a9fa5c64a54e..89f27e807749e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -18,7 +18,7 @@ use super::method::probe; use crate::FnCtxt; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn emit_type_mismatch_suggestions( + pub(crate) fn emit_type_mismatch_suggestions( &self, err: &mut Diag<'_>, expr: &hir::Expr<'tcx>, @@ -70,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn emit_coerce_suggestions( + pub(crate) fn emit_coerce_suggestions( &self, err: &mut Diag<'_>, expr: &hir::Expr<'tcx>, @@ -165,13 +165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Requires that the two types unify, and prints an error message if /// they don't. - pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { + pub(crate) fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { if let Err(e) = self.demand_suptype_diag(sp, expected, actual) { e.emit(); } } - pub fn demand_suptype_diag( + pub(crate) fn demand_suptype_diag( &'a self, sp: Span, expected: Ty<'tcx>, @@ -193,13 +193,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) } - pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { + pub(crate) fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { if let Err(err) = self.demand_eqtype_diag(sp, expected, actual) { err.emit(); } } - pub fn demand_eqtype_diag( + pub(crate) fn demand_eqtype_diag( &'a self, sp: Span, expected: Ty<'tcx>, @@ -208,7 +208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } - pub fn demand_eqtype_with_origin( + pub(crate) fn demand_eqtype_with_origin( &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, @@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) } - pub fn demand_coerce( + pub(crate) fn demand_coerce( &self, expr: &'tcx hir::Expr<'tcx>, checked_ty: Ty<'tcx>, @@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Notes the point at which a variable is constrained to some type incompatible /// with some expectation given by `source`. - pub fn note_source_of_type_mismatch_constraint( + pub(crate) fn note_source_of_type_mismatch_constraint( &self, err: &mut Diag<'_>, expr: &hir::Expr<'_>, @@ -558,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // When encountering a type error on the value of a `break`, try to point at the reason for the // expected type. - pub fn annotate_loop_expected_due_to_inference( + pub(crate) fn annotate_loop_expected_due_to_inference( &self, err: &mut Diag<'_>, expr: &hir::Expr<'_>, @@ -964,7 +964,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - pub fn get_conversion_methods_for_diagnostic( + pub(crate) fn get_conversion_methods_for_diagnostic( &self, span: Span, expected: Ty<'tcx>, @@ -1186,7 +1186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -pub enum TypeMismatchSource<'tcx> { +pub(crate) enum TypeMismatchSource<'tcx> { /// Expected the binding to have the given type, but it was found to have /// a different type. Find out when that type first became incompatible. Ty(Ty<'tcx>), diff --git a/compiler/rustc_hir_typeck/src/diverges.rs b/compiler/rustc_hir_typeck/src/diverges.rs index aa30fb0f0af39..3066561a31d6d 100644 --- a/compiler/rustc_hir_typeck/src/diverges.rs +++ b/compiler/rustc_hir_typeck/src/diverges.rs @@ -8,7 +8,7 @@ use rustc_span::{Span, DUMMY_SP}; /// as diverging), with some manual adjustments for control-flow /// primitives (approximating a CFG). #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum Diverges { +pub(crate) enum Diverges { /// Potentially unknown, some cases converge, /// others require a CFG to determine them. Maybe, diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index c35f7a84c4fde..4d2770d2e50e2 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -17,7 +17,7 @@ use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)] -pub struct FieldMultiplySpecifiedInInitializer { +pub(crate) struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] pub span: Span, @@ -28,7 +28,7 @@ pub struct FieldMultiplySpecifiedInInitializer { #[derive(Diagnostic)] #[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)] -pub struct ReturnStmtOutsideOfFnBody { +pub(crate) struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, #[label(hir_typeck_encl_body_label)] @@ -38,7 +38,7 @@ pub struct ReturnStmtOutsideOfFnBody { pub statement_kind: ReturnLikeStatementKind, } -pub enum ReturnLikeStatementKind { +pub(crate) enum ReturnLikeStatementKind { Return, Become, } @@ -57,21 +57,21 @@ impl IntoDiagArg for ReturnLikeStatementKind { #[derive(Diagnostic)] #[diag(hir_typeck_rustcall_incorrect_args)] -pub struct RustCallIncorrectArgs { +pub(crate) struct RustCallIncorrectArgs { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)] -pub struct YieldExprOutsideOfCoroutine { +pub(crate) struct YieldExprOutsideOfCoroutine { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)] -pub struct StructExprNonExhaustive { +pub(crate) struct StructExprNonExhaustive { #[primary_span] pub span: Span, pub what: &'static str, @@ -79,21 +79,21 @@ pub struct StructExprNonExhaustive { #[derive(Diagnostic)] #[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)] -pub struct FunctionalRecordUpdateOnNonStruct { +pub(crate) struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_typeck_address_of_temporary_taken, code = E0745)] -pub struct AddressOfTemporaryTaken { +pub(crate) struct AddressOfTemporaryTaken { #[primary_span] #[label] pub span: Span, } #[derive(Subdiagnostic)] -pub enum AddReturnTypeSuggestion { +pub(crate) enum AddReturnTypeSuggestion { #[suggestion( hir_typeck_add_return_type_add, code = " -> {found}", @@ -116,7 +116,7 @@ pub enum AddReturnTypeSuggestion { } #[derive(Subdiagnostic)] -pub enum ExpectedReturnTypeLabel<'tcx> { +pub(crate) enum ExpectedReturnTypeLabel<'tcx> { #[label(hir_typeck_expected_default_return_type)] Unit { #[primary_span] @@ -132,7 +132,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { #[derive(Diagnostic)] #[diag(hir_typeck_explicit_destructor, code = E0040)] -pub struct ExplicitDestructorCall { +pub(crate) struct ExplicitDestructorCall { #[primary_span] #[label] pub span: Span, @@ -141,7 +141,7 @@ pub struct ExplicitDestructorCall { } #[derive(Subdiagnostic)] -pub enum ExplicitDestructorCallSugg { +pub(crate) enum ExplicitDestructorCallSugg { #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")] Empty(#[primary_span] Span), #[multipart_suggestion(hir_typeck_suggestion, style = "short")] @@ -155,7 +155,7 @@ pub enum ExplicitDestructorCallSugg { #[derive(Diagnostic)] #[diag(hir_typeck_missing_parentheses_in_range, code = E0689)] -pub struct MissingParenthesesInRange { +pub(crate) struct MissingParenthesesInRange { #[primary_span] #[label(hir_typeck_missing_parentheses_in_range)] pub span: Span, @@ -166,7 +166,7 @@ pub struct MissingParenthesesInRange { } #[derive(LintDiagnostic)] -pub enum NeverTypeFallbackFlowingIntoUnsafe { +pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] Call, @@ -187,7 +187,7 @@ pub enum NeverTypeFallbackFlowingIntoUnsafe { #[derive(LintDiagnostic)] #[help] #[diag(hir_typeck_dependency_on_unit_never_type_fallback)] -pub struct DependencyOnUnitNeverTypeFallback<'tcx> { +pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { #[note] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, @@ -199,7 +199,7 @@ pub struct DependencyOnUnitNeverTypeFallback<'tcx> { style = "verbose", applicability = "maybe-incorrect" )] -pub struct AddMissingParenthesesInRange { +pub(crate) struct AddMissingParenthesesInRange { pub func_name: String, #[suggestion_part(code = "(")] pub left: Span, @@ -207,7 +207,7 @@ pub struct AddMissingParenthesesInRange { pub right: Span, } -pub struct TypeMismatchFruTypo { +pub(crate) struct TypeMismatchFruTypo { /// Span of the LHS of the range pub expr_span: Span, /// Span of the `..RHS` part of the range @@ -246,7 +246,7 @@ impl Subdiagnostic for TypeMismatchFruTypo { #[derive(LintDiagnostic)] #[diag(hir_typeck_lossy_provenance_int2ptr)] #[help] -pub struct LossyProvenanceInt2Ptr<'tcx> { +pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, #[subdiagnostic] @@ -255,14 +255,14 @@ pub struct LossyProvenanceInt2Ptr<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_typeck_ptr_cast_add_auto_to_object)] -pub struct PtrCastAddAutoToObject { +pub(crate) struct PtrCastAddAutoToObject { pub traits_len: usize, pub traits: DiagSymbolList, } #[derive(Subdiagnostic)] #[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")] -pub struct LossyProvenanceInt2PtrSuggestion { +pub(crate) struct LossyProvenanceInt2PtrSuggestion { #[suggestion_part(code = "(...).with_addr(")] pub lo: Span, #[suggestion_part(code = ")")] @@ -272,7 +272,7 @@ pub struct LossyProvenanceInt2PtrSuggestion { #[derive(LintDiagnostic)] #[diag(hir_typeck_lossy_provenance_ptr2int)] #[help] -pub struct LossyProvenancePtr2Int<'tcx> { +pub(crate) struct LossyProvenancePtr2Int<'tcx> { pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, #[subdiagnostic] @@ -280,7 +280,7 @@ pub struct LossyProvenancePtr2Int<'tcx> { } #[derive(Subdiagnostic)] -pub enum LossyProvenancePtr2IntSuggestion<'tcx> { +pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> { #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")] NeedsParensCast { #[suggestion_part(code = "(")] @@ -314,7 +314,7 @@ pub enum LossyProvenancePtr2IntSuggestion<'tcx> { } #[derive(Subdiagnostic)] -pub enum HelpUseLatestEdition { +pub(crate) enum HelpUseLatestEdition { #[help(hir_typeck_help_set_edition_cargo)] #[note(hir_typeck_note_edition_guide)] Cargo { edition: Edition }, @@ -324,7 +324,7 @@ pub enum HelpUseLatestEdition { } impl HelpUseLatestEdition { - pub fn new() -> Self { + pub(crate) fn new() -> Self { let edition = LATEST_STABLE_EDITION; if rustc_session::utils::was_invoked_from_cargo() { Self::Cargo { edition } @@ -336,7 +336,7 @@ impl HelpUseLatestEdition { #[derive(Diagnostic)] #[diag(hir_typeck_invalid_callee, code = E0618)] -pub struct InvalidCallee { +pub(crate) struct InvalidCallee { #[primary_span] pub span: Span, pub ty: String, @@ -344,7 +344,7 @@ pub struct InvalidCallee { #[derive(Diagnostic)] #[diag(hir_typeck_int_to_fat, code = E0606)] -pub struct IntToWide<'tcx> { +pub(crate) struct IntToWide<'tcx> { #[primary_span] #[label(hir_typeck_int_to_fat_label)] pub span: Span, @@ -357,7 +357,7 @@ pub struct IntToWide<'tcx> { } #[derive(Subdiagnostic)] -pub enum OptionResultRefMismatch { +pub(crate) enum OptionResultRefMismatch { #[suggestion( hir_typeck_option_result_copied, code = ".copied()", @@ -396,7 +396,7 @@ pub enum OptionResultRefMismatch { // }, } -pub struct RemoveSemiForCoerce { +pub(crate) struct RemoveSemiForCoerce { pub expr: Span, pub ret: Span, pub semi: Span, @@ -426,7 +426,7 @@ impl Subdiagnostic for RemoveSemiForCoerce { #[derive(Diagnostic)] #[diag(hir_typeck_const_select_must_be_const)] #[help] -pub struct ConstSelectMustBeConst { +pub(crate) struct ConstSelectMustBeConst { #[primary_span] pub span: Span, } @@ -435,7 +435,7 @@ pub struct ConstSelectMustBeConst { #[diag(hir_typeck_const_select_must_be_fn)] #[note] #[help] -pub struct ConstSelectMustBeFn<'a> { +pub(crate) struct ConstSelectMustBeFn<'a> { #[primary_span] pub span: Span, pub ty: Ty<'a>, @@ -443,14 +443,14 @@ pub struct ConstSelectMustBeFn<'a> { #[derive(Diagnostic)] #[diag(hir_typeck_union_pat_multiple_fields)] -pub struct UnionPatMultipleFields { +pub(crate) struct UnionPatMultipleFields { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(hir_typeck_union_pat_dotdot)] -pub struct UnionPatDotDot { +pub(crate) struct UnionPatDotDot { #[primary_span] pub span: Span, } @@ -461,7 +461,7 @@ pub struct UnionPatDotDot { applicability = "maybe-incorrect", style = "verbose" )] -pub struct UseIsEmpty { +pub(crate) struct UseIsEmpty { #[suggestion_part(code = "!")] pub lo: Span, #[suggestion_part(code = ".is_empty()")] @@ -471,13 +471,13 @@ pub struct UseIsEmpty { #[derive(Diagnostic)] #[diag(hir_typeck_arg_mismatch_indeterminate)] -pub struct ArgMismatchIndeterminate { +pub(crate) struct ArgMismatchIndeterminate { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] -pub enum SuggestBoxing { +pub(crate) enum SuggestBoxing { #[note(hir_typeck_suggest_boxing_note)] #[multipart_suggestion( hir_typeck_suggest_boxing_when_appropriate, @@ -511,7 +511,7 @@ pub enum SuggestBoxing { style = "verbose", code = "core::ptr::null_mut()" )] -pub struct SuggestPtrNullMut { +pub(crate) struct SuggestPtrNullMut { #[primary_span] pub span: Span, } @@ -519,7 +519,7 @@ pub struct SuggestPtrNullMut { #[derive(LintDiagnostic)] #[diag(hir_typeck_trivial_cast)] #[help] -pub struct TrivialCast<'tcx> { +pub(crate) struct TrivialCast<'tcx> { pub numeric: bool, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, @@ -527,7 +527,7 @@ pub struct TrivialCast<'tcx> { #[derive(Diagnostic)] #[diag(hir_typeck_no_associated_item, code = E0599)] -pub struct NoAssociatedItem { +pub(crate) struct NoAssociatedItem { #[primary_span] pub span: Span, pub item_kind: &'static str, @@ -539,7 +539,7 @@ pub struct NoAssociatedItem { #[derive(Subdiagnostic)] #[note(hir_typeck_candidate_trait_note)] -pub struct CandidateTraitNote { +pub(crate) struct CandidateTraitNote { #[primary_span] pub span: Span, pub trait_name: String, @@ -549,7 +549,7 @@ pub struct CandidateTraitNote { #[derive(Diagnostic)] #[diag(hir_typeck_cannot_cast_to_bool, code = E0054)] -pub struct CannotCastToBool<'tcx> { +pub(crate) struct CannotCastToBool<'tcx> { #[primary_span] pub span: Span, pub expr_ty: Ty<'tcx>, @@ -559,14 +559,14 @@ pub struct CannotCastToBool<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_typeck_cast_enum_drop)] -pub struct CastEnumDrop<'tcx> { +pub(crate) struct CastEnumDrop<'tcx> { pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(hir_typeck_cast_unknown_pointer, code = E0641)] -pub struct CastUnknownPointer { +pub(crate) struct CastUnknownPointer { #[primary_span] pub span: Span, pub to: bool, @@ -574,7 +574,7 @@ pub struct CastUnknownPointer { pub sub: CastUnknownPointerSub, } -pub enum CastUnknownPointerSub { +pub(crate) enum CastUnknownPointerSub { To(Span), From(Span), } @@ -601,7 +601,7 @@ impl rustc_errors::Subdiagnostic for CastUnknownPointerSub { } #[derive(Subdiagnostic)] -pub enum CannotCastToBoolHelp { +pub(crate) enum CannotCastToBoolHelp { #[suggestion( hir_typeck_suggestion, applicability = "machine-applicable", @@ -615,7 +615,7 @@ pub enum CannotCastToBoolHelp { #[derive(Diagnostic)] #[diag(hir_typeck_ctor_is_private, code = E0603)] -pub struct CtorIsPrivate { +pub(crate) struct CtorIsPrivate { #[primary_span] pub span: Span, pub def: String, @@ -623,7 +623,7 @@ pub struct CtorIsPrivate { #[derive(Subdiagnostic)] #[note(hir_typeck_deref_is_empty)] -pub struct DerefImplsIsEmpty { +pub(crate) struct DerefImplsIsEmpty { #[primary_span] pub span: Span, pub deref_ty: String, @@ -635,7 +635,7 @@ pub struct DerefImplsIsEmpty { applicability = "machine-applicable", style = "verbose" )] -pub struct SuggestConvertViaMethod<'tcx> { +pub(crate) struct SuggestConvertViaMethod<'tcx> { #[suggestion_part(code = "{sugg}")] pub span: Span, #[suggestion_part(code = "")] @@ -647,13 +647,13 @@ pub struct SuggestConvertViaMethod<'tcx> { #[derive(Subdiagnostic)] #[note(hir_typeck_note_caller_chooses_ty_for_ty_param)] -pub struct NoteCallerChoosesTyForTyParam<'tcx> { +pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> { pub ty_param_name: Symbol, pub found_ty: Ty<'tcx>, } #[derive(Subdiagnostic)] -pub enum SuggestBoxingForReturnImplTrait { +pub(crate) enum SuggestBoxingForReturnImplTrait { #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")] ChangeReturnType { #[suggestion_part(code = "Box { +pub(crate) enum Expectation<'tcx> { /// We know nothing about what type this expression should have. NoExpectation, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 91778a366684b..dd33b947b0d06 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -51,7 +51,7 @@ use crate::{ }; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_expr_has_type_or_error( + pub(crate) fn check_expr_has_type_or_error( &self, expr: &'tcx hir::Expr<'tcx>, expected_ty: Ty<'tcx>, @@ -977,7 +977,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Check if the expression that could not be assigned to was a typoed expression that - pub fn check_for_missing_semi(&self, expr: &'tcx hir::Expr<'tcx>, err: &mut Diag<'_>) -> bool { + pub(crate) fn check_for_missing_semi( + &self, + expr: &'tcx hir::Expr<'tcx>, + err: &mut Diag<'_>, + ) -> bool { if let hir::ExprKind::Binary(binop, lhs, rhs) = expr.kind && let hir::BinOpKind::Mul = binop.node && self.tcx.sess.source_map().is_multiline(lhs.span.between(rhs.span)) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 6e1b7504626d3..b1dc19b377746 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -18,7 +18,7 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use crate::{errors, FnCtxt, TypeckRootCtxt}; #[derive(Copy, Clone)] -pub enum DivergingFallbackBehavior { +pub(crate) enum DivergingFallbackBehavior { /// Always fallback to `()` (aka "always spontaneous decay") ToUnit, /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 21e6ac9332cdf..2d205d1ede9cd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -132,18 +132,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default() } - pub fn tag(&self) -> String { + fn tag(&self) -> String { format!("{self:p}") } - pub fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { + pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) }) } #[inline] - pub fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { + pub(crate) fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); @@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn write_field_index( + pub(crate) fn write_field_index( &self, hir_id: HirId, index: FieldIdx, @@ -198,7 +198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_args(hir_id, method.args); } - pub fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) { + fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) { if !args.is_empty() { debug!("write_args({:?}, {:?}) in fcx {}", node_id, args, self.tag()); @@ -364,7 +364,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - pub fn require_type_meets( + pub(crate) fn require_type_meets( &self, ty: Ty<'tcx>, span: Span, @@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code)); } - pub fn require_type_is_sized( + pub(crate) fn require_type_is_sized( &self, ty: Ty<'tcx>, span: Span, @@ -386,7 +386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn require_type_is_sized_deferred( + pub(crate) fn require_type_is_sized_deferred( &self, ty: Ty<'tcx>, span: Span, @@ -397,7 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn require_type_has_static_alignment( + pub(crate) fn require_type_has_static_alignment( &self, ty: Ty<'tcx>, span: Span, @@ -426,7 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn register_bound( + pub(crate) fn register_bound( &self, ty: Ty<'tcx>, def_id: DefId, @@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { + pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { let ty = self.lowerer().lower_ty(hir_ty); self.register_wf_obligation(ty.into(), hir_ty.span, ObligationCauseCode::WellFormed(None)); LoweredTy::from_raw(self, hir_ty.span, ty) @@ -474,7 +474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> { + pub(crate) fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> { match length { hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span), hir::ArrayLen::Body(const_arg) => { @@ -486,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn lower_const_arg( + pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, param_def_id: DefId, @@ -515,7 +515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { t.has_free_regions() || t.has_aliases() || t.has_infer_types() } - pub fn node_ty(&self, id: HirId) -> Ty<'tcx> { + pub(crate) fn node_ty(&self, id: HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), @@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn node_ty_opt(&self, id: HirId) -> Option> { + pub(crate) fn node_ty_opt(&self, id: HirId) -> Option> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx, e)), @@ -538,7 +538,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Registers an obligation for checking later, during regionck, that `arg` is well-formed. - pub fn register_wf_obligation( + pub(crate) fn register_wf_obligation( &self, arg: ty::GenericArg<'tcx>, span: Span, @@ -555,7 +555,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Registers obligations that all `args` are well-formed. - pub fn add_wf_bounds(&self, args: GenericArgsRef<'tcx>, expr: &hir::Expr<'_>) { + pub(crate) fn add_wf_bounds(&self, args: GenericArgsRef<'tcx>, expr: &hir::Expr<'_>) { for arg in args.iter().filter(|arg| { matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..)) }) { @@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(arielb1): use this instead of field.ty everywhere // Only for fields! Returns for methods> // Indifferent to privacy flags - pub fn field_ty( + pub(crate) fn field_ty( &self, span: Span, field: &'tcx ty::FieldDef, @@ -897,7 +897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given a `HirId`, return the `HirId` of the enclosing function, its `FnDecl`, and whether a /// suggestion can be made, `None` otherwise. - pub fn get_fn_decl( + pub(crate) fn get_fn_decl( &self, blk_id: HirId, ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> { @@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// If no resolution is possible, then an error is reported. /// Numeric inference variables may be left unresolved. - pub fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + pub(crate) fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { let ty = self.try_structurally_resolve_type(sp, ty); if !ty.is_ty_var() { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 130fd130ec837..a8ba9f139cc7e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -12,7 +12,7 @@ use rustc_trait_selection::traits; use crate::FnCtxt; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn adjust_fulfillment_error_for_expr_obligation( + pub(crate) fn adjust_fulfillment_error_for_expr_obligation( &self, error: &mut traits::FulfillmentError<'tcx>, ) -> bool { @@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { * * This function only updates the error span. */ - pub fn blame_specific_expr_if_possible( + pub(crate) fn blame_specific_expr_if_possible( &self, error: &mut traits::FulfillmentError<'tcx>, expr: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index 788956894333b..cb77d3f85d935 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -17,7 +17,7 @@ rustc_index::newtype_index! { } impl ExpectedIdx { - pub fn to_provided_idx(self) -> ProvidedIdx { + pub(crate) fn to_provided_idx(self) -> ProvidedIdx { ProvidedIdx::from_usize(self.as_usize()) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index aca29d4758708..5333982c42029 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -45,7 +45,7 @@ use crate::{ }; #[derive(Clone, Copy, Default)] -pub enum DivergingBlockBehavior { +pub(crate) enum DivergingBlockBehavior { /// This is the current stable behavior: /// /// ```rust @@ -1556,7 +1556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_struct_path( + pub(crate) fn check_struct_path( &self, qpath: &QPath<'tcx>, hir_id: HirId, @@ -1622,7 +1622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_decl_initializer( + fn check_decl_initializer( &self, hir_id: HirId, pat: &'tcx hir::Pat<'tcx>, @@ -1700,7 +1700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Type check a `let` statement. - pub fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) { + fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) { self.check_decl(local.into()); if local.pat.is_never_pattern() { self.diverges.set(Diverges::Always { @@ -1710,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) { + fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) { // Don't do all the complex logic below for `DeclItem`. match stmt.kind { hir::StmtKind::Item(..) => return, @@ -1745,7 +1745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.diverges.set(self.diverges.get() | old_diverges); } - pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { + pub(crate) fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { let unit = self.tcx.types.unit; let ty = self.check_block_with_expected(blk, ExpectHasType(unit)); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 33f80dd3773fa..8e69a075030be 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -117,7 +117,7 @@ pub(crate) struct FnCtxt<'a, 'tcx> { } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn new( + pub(crate) fn new( root_ctxt: &'a TypeckRootCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, @@ -148,15 +148,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.root_ctxt.infcx.dcx() } - pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { + pub(crate) fn cause( + &self, + span: Span, + code: ObligationCauseCode<'tcx>, + ) -> ObligationCause<'tcx> { ObligationCause::new(span, self.body_id, code) } - pub fn misc(&self, span: Span) -> ObligationCause<'tcx> { + pub(crate) fn misc(&self, span: Span) -> ObligationCause<'tcx> { self.cause(span, ObligationCauseCode::Misc) } - pub fn sess(&self) -> &Session { + pub(crate) fn sess(&self) -> &Session { self.tcx.sess } @@ -165,7 +169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Use [`InferCtxtErrorExt::err_ctxt`] to start one without a `TypeckResults`. /// /// [`InferCtxtErrorExt::err_ctxt`]: rustc_trait_selection::error_reporting::InferCtxtErrorExt::err_ctxt - pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> { + pub(crate) fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> { let mut sub_relations = SubRelations::default(); sub_relations.add_constraints( self, @@ -365,7 +369,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { /// This is a bridge between the interface of HIR ty lowering, which outputs a raw /// `Ty`, and the API in this module, which expect `Ty` to be fully normalized. #[derive(Clone, Copy, Debug)] -pub struct LoweredTy<'tcx> { +pub(crate) struct LoweredTy<'tcx> { /// The unnormalized type provided by the user. pub raw: Ty<'tcx>, @@ -374,7 +378,7 @@ pub struct LoweredTy<'tcx> { } impl<'tcx> LoweredTy<'tcx> { - pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> { + fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> { // FIXME(-Znext-solver): We're still figuring out how to best handle // normalization and this doesn't feel too great. We should look at this // code again before stabilizing it. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 11c6e65a21101..031aa6159d2bc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -64,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// - Points out the method's return type as the reason for the expected type. /// - Possible missing semicolon. /// - Possible missing return type if the return type is the default, and not `fn main()`. - pub fn suggest_mismatched_types_on_tail( + pub(crate) fn suggest_mismatched_types_on_tail( &self, err: &mut Diag<'_>, expr: &'tcx hir::Expr<'tcx>, @@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.err_ctxt().extract_callable_info(self.body_id, self.param_env, ty) } - pub fn suggest_two_fn_call( + pub(crate) fn suggest_two_fn_call( &self, err: &mut Diag<'_>, lhs_expr: &'tcx hir::Expr<'tcx>, @@ -251,7 +251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn suggest_remove_last_method_call( + pub(crate) fn suggest_remove_last_method_call( &self, err: &mut Diag<'_>, expr: &hir::Expr<'tcx>, @@ -280,7 +280,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } - pub fn suggest_deref_ref_or_into( + pub(crate) fn suggest_deref_ref_or_into( &self, err: &mut Diag<'_>, expr: &hir::Expr<'tcx>, @@ -747,7 +747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// If the expression is the expression of a closure without block (`|| expr`), a /// block is needed to be added too (`|| { expr; }`). This is denoted by `needs_block`. - pub fn suggest_missing_semicolon( + pub(crate) fn suggest_missing_semicolon( &self, err: &mut Diag<'_>, expression: &'tcx hir::Expr<'tcx>, @@ -2077,7 +2077,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the expr is a while or for loop and is the tail expr of its // enclosing body suggest returning a value right after it - pub fn suggest_returning_value_after_loop( + pub(crate) fn suggest_returning_value_after_loop( &self, err: &mut Diag<'_>, expr: &hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index a9c929e76d5bf..62aa29e673def 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -38,7 +38,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) { + pub(crate) fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) { let tcx = self.tcx; let dl = &tcx.data_layout; let span = tcx.hir().span(hir_id); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 8ff4c11f24a83..8e6484f1e2934 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -8,6 +8,7 @@ #![feature(let_chains)] #![feature(never_type)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e0c0adac0767c..2c3cfcf3cbd63 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -42,13 +42,13 @@ impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> { } #[derive(Debug)] -pub struct ConfirmResult<'tcx> { +pub(crate) struct ConfirmResult<'tcx> { pub callee: MethodCallee<'tcx>, pub illegal_sized_bound: Option, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn confirm_method( + pub(crate) fn confirm_method( &self, span: Span, self_expr: &'tcx hir::Expr<'tcx>, @@ -66,7 +66,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { confirm_cx.confirm(unadjusted_self_ty, pick, segment) } - pub fn confirm_method_for_diagnostic( + pub(crate) fn confirm_method_for_diagnostic( &self, span: Span, self_expr: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index d6110ab94c15a..39307a29dad1f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -4,7 +4,7 @@ mod confirm; mod prelude_edition_lints; -pub mod probe; +pub(crate) mod probe; mod suggest; use rustc_errors::{Applicability, Diag, SubdiagMessage}; @@ -24,15 +24,15 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, NormalizeExt}; use self::probe::{IsSuggestion, ProbeScope}; -pub use self::MethodError::*; +pub(crate) use self::MethodError::*; use crate::FnCtxt; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { probe::provide(providers); } #[derive(Clone, Copy, Debug)] -pub struct MethodCallee<'tcx> { +pub(crate) struct MethodCallee<'tcx> { /// Impl method ID, for inherent methods, or trait method ID, otherwise. pub def_id: DefId, pub args: GenericArgsRef<'tcx>, @@ -44,7 +44,7 @@ pub struct MethodCallee<'tcx> { } #[derive(Debug)] -pub enum MethodError<'tcx> { +pub(crate) enum MethodError<'tcx> { // Did not find an applicable method, but we did find various near-misses that may work. NoMatch(NoMatchData<'tcx>), @@ -70,7 +70,7 @@ pub enum MethodError<'tcx> { // Contains a list of static methods that may apply, a list of unsatisfied trait predicates which // could lead to matches if satisfied, and a list of not-in-scope traits which may work. #[derive(Debug)] -pub struct NoMatchData<'tcx> { +pub(crate) struct NoMatchData<'tcx> { pub static_candidates: Vec, pub unsatisfied_predicates: Vec<(ty::Predicate<'tcx>, Option>, Option>)>, @@ -82,7 +82,7 @@ pub struct NoMatchData<'tcx> { // A pared down enum describing just the places from which a method // candidate can arise. Used for error reporting only. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum CandidateSource { +pub(crate) enum CandidateSource { Impl(DefId), Trait(DefId /* trait id */), } @@ -254,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(result.callee) } - pub fn lookup_method_for_diagnostic( + pub(crate) fn lookup_method_for_diagnostic( &self, self_ty: Ty<'tcx>, segment: &hir::PathSegment<'tcx>, @@ -296,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(pick) } - pub fn lookup_probe_for_diagnostic( + pub(crate) fn lookup_probe_for_diagnostic( &self, method_name: Ident, self_ty: Ty<'tcx>, @@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Finds item with name `item_name` defined in impl/trait `def_id` /// and return it, or `None`, if no such item was defined there. - pub fn associated_value(&self, def_id: DefId, item_name: Ident) -> Option { + fn associated_value(&self, def_id: DefId, item_name: Ident) -> Option { self.tcx .associated_items(def_id) .find_by_name_and_namespace(self.tcx, item_name, Namespace::ValueNS, def_id) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28f537c87c4ee..48e33c81b852b 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -38,14 +38,14 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt}; use smallvec::{smallvec, SmallVec}; use self::CandidateKind::*; -pub use self::PickKind::*; +pub(crate) use self::PickKind::*; use super::{suggest, CandidateSource, MethodError, NoMatchData}; use crate::FnCtxt; /// Boolean flag used to indicate if this search is for a suggestion /// or not. If true, we can allow ambiguity and so forth. #[derive(Clone, Copy, Debug)] -pub struct IsSuggestion(pub bool); +pub(crate) struct IsSuggestion(pub bool); pub(crate) struct ProbeContext<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, @@ -134,7 +134,7 @@ enum ProbeResult { /// (at most) one of these. Either the receiver has type `T` and we convert it to `&T` (or with /// `mut`), or it has type `*mut T` and we convert it to `*const T`. #[derive(Debug, PartialEq, Copy, Clone)] -pub enum AutorefOrPtrAdjustment { +pub(crate) enum AutorefOrPtrAdjustment { /// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it. /// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing. Autoref { @@ -158,7 +158,7 @@ impl AutorefOrPtrAdjustment { } #[derive(Debug, Clone)] -pub struct Pick<'tcx> { +pub(crate) struct Pick<'tcx> { pub item: ty::AssocItem, pub kind: PickKind<'tcx>, pub import_ids: SmallVec<[LocalDefId; 1]>, @@ -179,7 +179,7 @@ pub struct Pick<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq)] -pub enum PickKind<'tcx> { +pub(crate) enum PickKind<'tcx> { InherentImplPick, ObjectPick, TraitPick, @@ -189,10 +189,10 @@ pub enum PickKind<'tcx> { ), } -pub type PickResult<'tcx> = Result, MethodError<'tcx>>; +pub(crate) type PickResult<'tcx> = Result, MethodError<'tcx>>; #[derive(PartialEq, Eq, Copy, Clone, Debug)] -pub enum Mode { +pub(crate) enum Mode { // An expression of the form `receiver.method_name(...)`. // Autoderefs are performed on `receiver`, lookup is done based on the // `self` argument of the method, and static methods aren't considered. @@ -204,7 +204,7 @@ pub enum Mode { } #[derive(PartialEq, Eq, Copy, Clone, Debug)] -pub enum ProbeScope { +pub(crate) enum ProbeScope { // Single candidate coming from pre-resolved delegation method. Single(DefId), @@ -507,7 +507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { providers.method_autoderef_steps = method_autoderef_steps; } @@ -1288,7 +1288,7 @@ impl<'tcx> Pick<'tcx> { /// Checks whether two picks do not refer to the same trait item for the same `Self` type. /// Only useful for comparisons of picks in order to improve diagnostics. /// Do not use for type checking. - pub fn differs_from(&self, other: &Self) -> bool { + pub(crate) fn differs_from(&self, other: &Self) -> bool { let Self { item: AssocItem { @@ -1312,7 +1312,7 @@ impl<'tcx> Pick<'tcx> { } /// In case there were unstable name collisions, emit them as a lint. - pub fn maybe_emit_unstable_name_collision_hint( + pub(crate) fn maybe_emit_unstable_name_collision_hint( &self, tcx: TyCtxt<'tcx>, span: Span, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 8b8bb29dacdbd..b78bb8cb98db7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err } - pub fn suggest_use_shadowed_binding_with_method( + fn suggest_use_shadowed_binding_with_method( &self, self_source: SelfSource<'tcx>, method_name: Ident, @@ -4223,19 +4223,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[derive(Copy, Clone, Debug)] -pub enum SelfSource<'a> { +enum SelfSource<'a> { QPath(&'a hir::Ty<'a>), MethodCall(&'a hir::Expr<'a> /* rcvr */), } #[derive(Copy, Clone, PartialEq, Eq)] -pub struct TraitInfo { +pub(crate) struct TraitInfo { pub def_id: DefId, } /// Retrieves all traits in this crate and any dependent crates, /// and wraps them into `TraitInfo` for custom sorting. -pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { +pub(crate) fn all_traits(tcx: TyCtxt<'_>) -> Vec { tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect() } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index c54f6cfd0999a..fb0d30d5b0ef2 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -25,7 +25,7 @@ use crate::Expectation; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Checks a `a = b` - pub fn check_binop_assign( + pub(crate) fn check_binop_assign( &self, expr: &'tcx hir::Expr<'tcx>, op: hir::BinOp, @@ -84,7 +84,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Checks a potentially overloaded binary operator. - pub fn check_binop( + pub(crate) fn check_binop( &self, expr: &'tcx hir::Expr<'tcx>, op: hir::BinOp, @@ -770,7 +770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_user_unop( + pub(crate) fn check_user_unop( &self, ex: &'tcx hir::Expr<'tcx>, operand_ty: Ty<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index a8e5e09c8bbeb..206de455cd575 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -944,7 +944,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_dereferenceable( + fn check_dereferenceable( &self, span: Span, expected: Ty<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index ad04b6b8b1df5..bb22727258423 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -246,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// always know whether a place needs to be mutable or not in the first pass. /// This happens whether there is an implicit mutable reborrow, e.g. when the type /// is used as the receiver of a method call. - pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) { + pub(crate) fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) { // Gather up expressions we want to munge. let mut exprs = vec![expr]; diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs index f22a13d292e0f..fb0fe23be65fc 100644 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs @@ -65,7 +65,7 @@ fn record_rvalue_scope( } } -pub fn resolve_rvalue_scopes<'a, 'tcx>( +pub(crate) fn resolve_rvalue_scopes<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, scope_tree: &'a ScopeTree, def_id: DefId, diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index a43164589b5f3..e6b8da3e5d6ba 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -77,7 +77,7 @@ impl<'tcx> Deref for TypeckRootCtxt<'tcx> { } impl<'tcx> TypeckRootCtxt<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner; let infcx = tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(def_id).build(); @@ -124,7 +124,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> { infer_ok.value } - pub fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) { + fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) { let infer_var_info = &mut self.infer_var_info.borrow_mut(); // (*) binder skipped diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 55f002291f071..5350affb3bc48 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -74,7 +74,7 @@ enum PlaceAncestryRelation { type InferredCaptureInformation<'tcx> = Vec<(Place<'tcx>, ty::CaptureInfo)>; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) { + pub(crate) fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) { InferBorrowKindVisitor { fcx: self }.visit_body(body); // it's our job to process these. diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0327a3097eca2..0853ed9b05bfb 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -35,7 +35,7 @@ use crate::FnCtxt; // resolve_type_vars_in_body, which creates a new TypeTables which // doesn't contain any inference types. impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn resolve_type_vars_in_body( + pub(crate) fn resolve_type_vars_in_body( &self, body: &'tcx hir::Body<'tcx>, ) -> &'tcx ty::TypeckResults<'tcx> { From 969f9702dad51b288bc7b3b399ae96a6d0711cdb Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 27 Aug 2024 05:25:34 +0100 Subject: [PATCH 088/102] Fix typos in floating-point primitive type docs --- library/core/src/primitive_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 09ebef89fb0c2..70cfae3f7d991 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1130,7 +1130,7 @@ impl (T,) {} /// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008). /// /// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many -/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on +/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on /// half-precision values][wikipedia] for more information. /// /// Note that most common platforms will not support `f16` in hardware without enabling extra target @@ -1235,12 +1235,12 @@ mod prim_f64 {} /// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008). /// /// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice -/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on +/// as many bits as `f64`. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on /// quad-precision values][wikipedia] for more information. /// /// Note that no platforms have hardware support for `f128` without enabling target specific features, /// as for all instruction set architectures `f128` is considered an optional feature. -/// Only Power ISA ("PowerPC") and RISCV specify it, and only certain microarchitectures +/// Only Power ISA ("PowerPC") and RISC-V specify it, and only certain microarchitectures /// actually implement it. For x86-64 and AArch64, ISA support is not even specified, /// so it will always be a software implementation significantly slower than `f64`. /// From d0548359b5810c5c509e01de58fd47a1c3c6a385 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 27 Aug 2024 05:26:28 +0100 Subject: [PATCH 089/102] Reflow a couple of paragraphs in floating-point primitive docs --- library/core/src/primitive_docs.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 70cfae3f7d991..a08b0ff60175f 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1130,8 +1130,8 @@ impl (T,) {} /// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008). /// /// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many -/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on -/// half-precision values][wikipedia] for more information. +/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on half-precision +/// values][wikipedia] for more information. /// /// Note that most common platforms will not support `f16` in hardware without enabling extra target /// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors. @@ -1218,14 +1218,12 @@ mod prim_f32 {} #[doc(alias = "double")] /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008). /// -/// This type is very similar to [`f32`], but has increased -/// precision by using twice as many bits. Please see [the documentation for -/// `f32`][`f32`] or [Wikipedia on double precision +/// This type is very similar to [`prim@f32`], but has increased precision by using twice as many +/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on double-precision /// values][wikipedia] for more information. /// /// *[See also the `std::f64::consts` module](crate::f64::consts).* /// -/// [`f32`]: prim@f32 /// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format #[stable(feature = "rust1", since = "1.0.0")] mod prim_f64 {} From 37becf7bdcff5037cbb214277eb74ef17d8527f0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 14:30:20 +1000 Subject: [PATCH 090/102] Add `warn(unreachable_pub)` to `rustc_incremental`. --- .../rustc_incremental/src/assert_dep_graph.rs | 4 +- compiler/rustc_incremental/src/errors.rs | 82 +++++++++---------- compiler/rustc_incremental/src/lib.rs | 1 + .../rustc_incremental/src/persist/data.rs | 2 +- .../src/persist/dirty_clean.rs | 6 +- .../src/persist/file_format.rs | 2 +- compiler/rustc_incremental/src/persist/fs.rs | 2 +- 7 files changed, 50 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index b29ba59c9f351..46f30526d2a83 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -55,7 +55,7 @@ use {rustc_ast as ast, rustc_graphviz as dot, rustc_hir as hir}; use crate::errors; #[allow(missing_docs)] -pub fn assert_dep_graph(tcx: TyCtxt<'_>) { +pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.unstable_opts.dump_dep_graph { tcx.dep_graph.with_query(dump_graph); @@ -261,7 +261,7 @@ fn dump_graph(query: &DepGraphQuery) { } #[allow(missing_docs)] -pub struct GraphvizDepGraph(FxIndexSet, Vec<(DepKind, DepKind)>); +struct GraphvizDepGraph(FxIndexSet, Vec<(DepKind, DepKind)>); impl<'a> dot::GraphWalk<'a> for GraphvizDepGraph { type Node = DepKind; diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index c6f8b99bcd67b..cb21f9758789c 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(incremental_unrecognized_depnode)] -pub struct UnrecognizedDepNode { +pub(crate) struct UnrecognizedDepNode { #[primary_span] pub span: Span, pub name: Symbol, @@ -14,28 +14,28 @@ pub struct UnrecognizedDepNode { #[derive(Diagnostic)] #[diag(incremental_missing_depnode)] -pub struct MissingDepNode { +pub(crate) struct MissingDepNode { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_missing_if_this_changed)] -pub struct MissingIfThisChanged { +pub(crate) struct MissingIfThisChanged { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_ok)] -pub struct Ok { +pub(crate) struct Ok { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_no_path)] -pub struct NoPath { +pub(crate) struct NoPath { #[primary_span] pub span: Span, pub target: Symbol, @@ -44,7 +44,7 @@ pub struct NoPath { #[derive(Diagnostic)] #[diag(incremental_assertion_auto)] -pub struct AssertionAuto<'a> { +pub(crate) struct AssertionAuto<'a> { #[primary_span] pub span: Span, pub name: &'a str, @@ -53,7 +53,7 @@ pub struct AssertionAuto<'a> { #[derive(Diagnostic)] #[diag(incremental_undefined_clean_dirty_assertions_item)] -pub struct UndefinedCleanDirtyItem { +pub(crate) struct UndefinedCleanDirtyItem { #[primary_span] pub span: Span, pub kind: String, @@ -61,7 +61,7 @@ pub struct UndefinedCleanDirtyItem { #[derive(Diagnostic)] #[diag(incremental_undefined_clean_dirty_assertions)] -pub struct UndefinedCleanDirty { +pub(crate) struct UndefinedCleanDirty { #[primary_span] pub span: Span, pub kind: String, @@ -69,7 +69,7 @@ pub struct UndefinedCleanDirty { #[derive(Diagnostic)] #[diag(incremental_repeated_depnode_label)] -pub struct RepeatedDepNodeLabel<'a> { +pub(crate) struct RepeatedDepNodeLabel<'a> { #[primary_span] pub span: Span, pub label: &'a str, @@ -77,7 +77,7 @@ pub struct RepeatedDepNodeLabel<'a> { #[derive(Diagnostic)] #[diag(incremental_unrecognized_depnode_label)] -pub struct UnrecognizedDepNodeLabel<'a> { +pub(crate) struct UnrecognizedDepNodeLabel<'a> { #[primary_span] pub span: Span, pub label: &'a str, @@ -85,7 +85,7 @@ pub struct UnrecognizedDepNodeLabel<'a> { #[derive(Diagnostic)] #[diag(incremental_not_dirty)] -pub struct NotDirty<'a> { +pub(crate) struct NotDirty<'a> { #[primary_span] pub span: Span, pub dep_node_str: &'a str, @@ -93,7 +93,7 @@ pub struct NotDirty<'a> { #[derive(Diagnostic)] #[diag(incremental_not_clean)] -pub struct NotClean<'a> { +pub(crate) struct NotClean<'a> { #[primary_span] pub span: Span, pub dep_node_str: &'a str, @@ -101,7 +101,7 @@ pub struct NotClean<'a> { #[derive(Diagnostic)] #[diag(incremental_not_loaded)] -pub struct NotLoaded<'a> { +pub(crate) struct NotLoaded<'a> { #[primary_span] pub span: Span, pub dep_node_str: &'a str, @@ -109,7 +109,7 @@ pub struct NotLoaded<'a> { #[derive(Diagnostic)] #[diag(incremental_unknown_item)] -pub struct UnknownItem { +pub(crate) struct UnknownItem { #[primary_span] pub span: Span, pub name: Symbol, @@ -117,14 +117,14 @@ pub struct UnknownItem { #[derive(Diagnostic)] #[diag(incremental_no_cfg)] -pub struct NoCfg { +pub(crate) struct NoCfg { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_associated_value_expected_for)] -pub struct AssociatedValueExpectedFor { +pub(crate) struct AssociatedValueExpectedFor { #[primary_span] pub span: Span, pub ident: Ident, @@ -132,21 +132,21 @@ pub struct AssociatedValueExpectedFor { #[derive(Diagnostic)] #[diag(incremental_associated_value_expected)] -pub struct AssociatedValueExpected { +pub(crate) struct AssociatedValueExpected { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_unchecked_clean)] -pub struct UncheckedClean { +pub(crate) struct UncheckedClean { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(incremental_delete_old)] -pub struct DeleteOld<'a> { +pub(crate) struct DeleteOld<'a> { pub name: &'a str, pub path: PathBuf, pub err: std::io::Error, @@ -154,7 +154,7 @@ pub struct DeleteOld<'a> { #[derive(Diagnostic)] #[diag(incremental_create_new)] -pub struct CreateNew<'a> { +pub(crate) struct CreateNew<'a> { pub name: &'a str, pub path: PathBuf, pub err: std::io::Error, @@ -162,7 +162,7 @@ pub struct CreateNew<'a> { #[derive(Diagnostic)] #[diag(incremental_write_new)] -pub struct WriteNew<'a> { +pub(crate) struct WriteNew<'a> { pub name: &'a str, pub path: PathBuf, pub err: std::io::Error, @@ -170,14 +170,14 @@ pub struct WriteNew<'a> { #[derive(Diagnostic)] #[diag(incremental_canonicalize_path)] -pub struct CanonicalizePath { +pub(crate) struct CanonicalizePath { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_create_incr_comp_dir)] -pub struct CreateIncrCompDir<'a> { +pub(crate) struct CreateIncrCompDir<'a> { pub tag: &'a str, pub path: &'a Path, pub err: std::io::Error, @@ -185,7 +185,7 @@ pub struct CreateIncrCompDir<'a> { #[derive(Diagnostic)] #[diag(incremental_create_lock)] -pub struct CreateLock<'a> { +pub(crate) struct CreateLock<'a> { pub lock_err: std::io::Error, pub session_dir: &'a Path, #[note(incremental_lock_unsupported)] @@ -197,84 +197,84 @@ pub struct CreateLock<'a> { #[derive(Diagnostic)] #[diag(incremental_delete_lock)] -pub struct DeleteLock<'a> { +pub(crate) struct DeleteLock<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_hard_link_failed)] -pub struct HardLinkFailed<'a> { +pub(crate) struct HardLinkFailed<'a> { pub path: &'a Path, } #[derive(Diagnostic)] #[diag(incremental_delete_partial)] -pub struct DeletePartial<'a> { +pub(crate) struct DeletePartial<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_delete_full)] -pub struct DeleteFull<'a> { +pub(crate) struct DeleteFull<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_finalize)] -pub struct Finalize<'a> { +pub(crate) struct Finalize<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_invalid_gc_failed)] -pub struct InvalidGcFailed<'a> { +pub(crate) struct InvalidGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_finalized_gc_failed)] -pub struct FinalizedGcFailed<'a> { +pub(crate) struct FinalizedGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_session_gc_failed)] -pub struct SessionGcFailed<'a> { +pub(crate) struct SessionGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_assert_not_loaded)] -pub struct AssertNotLoaded; +pub(crate) struct AssertNotLoaded; #[derive(Diagnostic)] #[diag(incremental_assert_loaded)] -pub struct AssertLoaded; +pub(crate) struct AssertLoaded; #[derive(Diagnostic)] #[diag(incremental_delete_incompatible)] -pub struct DeleteIncompatible { +pub(crate) struct DeleteIncompatible { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_load_dep_graph)] -pub struct LoadDepGraph { +pub(crate) struct LoadDepGraph { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_move_dep_graph)] -pub struct MoveDepGraph<'a> { +pub(crate) struct MoveDepGraph<'a> { pub from: &'a Path, pub to: &'a Path, pub err: std::io::Error, @@ -282,14 +282,14 @@ pub struct MoveDepGraph<'a> { #[derive(Diagnostic)] #[diag(incremental_create_dep_graph)] -pub struct CreateDepGraph<'a> { +pub(crate) struct CreateDepGraph<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_copy_workproduct_to_cache)] -pub struct CopyWorkProductToCache<'a> { +pub(crate) struct CopyWorkProductToCache<'a> { pub from: &'a Path, pub to: &'a Path, pub err: std::io::Error, @@ -297,13 +297,13 @@ pub struct CopyWorkProductToCache<'a> { #[derive(Diagnostic)] #[diag(incremental_delete_workproduct)] -pub struct DeleteWorkProduct<'a> { +pub(crate) struct DeleteWorkProduct<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] #[diag(incremental_corrupt_file)] -pub struct CorruptFile<'a> { +pub(crate) struct CorruptFile<'a> { pub path: &'a Path, } diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index fcdcb08eed655..c79d108183c53 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -6,6 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod assert_dep_graph; diff --git a/compiler/rustc_incremental/src/persist/data.rs b/compiler/rustc_incremental/src/persist/data.rs index 81e5410978d5d..d962dc866f43b 100644 --- a/compiler/rustc_incremental/src/persist/data.rs +++ b/compiler/rustc_incremental/src/persist/data.rs @@ -4,7 +4,7 @@ use rustc_macros::{Decodable, Encodable}; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; #[derive(Debug, Encodable, Decodable)] -pub struct SerializedWorkProduct { +pub(crate) struct SerializedWorkProduct { /// node that produced the work-product pub id: WorkProductId, diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 1e02324f4048a..88cb82f0f37a8 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -133,7 +133,7 @@ struct Assertion { loaded_from_disk: Labels, } -pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { +pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { if !tcx.sess.opts.unstable_opts.query_dep_graph { return; } @@ -174,7 +174,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { }) } -pub struct DirtyCleanVisitor<'tcx> { +struct DirtyCleanVisitor<'tcx> { tcx: TyCtxt<'tcx>, checked_attrs: FxHashSet, } @@ -429,7 +429,7 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol { /// A visitor that collects all `#[rustc_clean]` attributes from /// the HIR. It is used to verify that we really ran checks for all annotated /// nodes. -pub struct FindAllAttrs<'tcx> { +struct FindAllAttrs<'tcx> { tcx: TyCtxt<'tcx>, found_attrs: Vec<&'tcx Attribute>, } diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 174414d0c85ef..f834c48cbf8fc 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -89,7 +89,7 @@ where /// incompatible version of the compiler. /// - Returns `Err(..)` if some kind of IO error occurred while reading the /// file. -pub fn read_file( +pub(crate) fn read_file( path: &Path, report_incremental_info: bool, is_nightly_build: bool, diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 0e87bc1e69211..feb25a9a89d0d 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -157,7 +157,7 @@ pub(crate) fn work_products_path(sess: &Session) -> PathBuf { } /// Returns the path to a session's query cache. -pub fn query_cache_path(sess: &Session) -> PathBuf { +pub(crate) fn query_cache_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, QUERY_CACHE_FILENAME) } From 46fe09f3f3dd724a9a9f1af50f3408a4f8dea25a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 14:33:24 +1000 Subject: [PATCH 091/102] Add `warn(unreachable_pub)` to `rustc_index`. --- compiler/rustc_index/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index b9d2a43206b1e..eb47ac3c68e90 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -3,6 +3,7 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] +#![warn(unreachable_pub)] // tidy-alphabetical-end pub mod bit_set; From 688792715bb1e3c420e896b62ee3e825dce4c174 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 14:47:56 +1000 Subject: [PATCH 092/102] Add `warn(unreachable_pub)` to `rustc_infer`. --- compiler/rustc_infer/src/errors/mod.rs | 2 +- compiler/rustc_infer/src/infer/free_regions.rs | 6 +++--- .../rustc_infer/src/infer/lexical_region_resolve/mod.rs | 2 +- compiler/rustc_infer/src/infer/relate/generalize.rs | 2 +- compiler/rustc_infer/src/infer/relate/lattice.rs | 2 +- compiler/rustc_infer/src/infer/snapshot/fudge.rs | 2 +- compiler/rustc_infer/src/infer/snapshot/undo_log.rs | 2 +- compiler/rustc_infer/src/lib.rs | 1 + compiler/rustc_infer/src/traits/mod.rs | 2 +- compiler/rustc_infer/src/traits/project.rs | 2 +- 10 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 1a5c013721971..76ea9c3433d39 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -3,7 +3,7 @@ use rustc_span::Span; #[derive(Diagnostic)] #[diag(infer_opaque_hidden_type)] -pub struct OpaqueHiddenTypeDiag { +pub(crate) struct OpaqueHiddenTypeDiag { #[primary_span] #[label] pub span: Span, diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index 0dde3082d48dc..9a5674369daba 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -18,11 +18,11 @@ pub(crate) struct RegionRelations<'a, 'tcx> { } impl<'a, 'tcx> RegionRelations<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, free_regions: &'a FreeRegionMap<'tcx>) -> Self { + pub(crate) fn new(tcx: TyCtxt<'tcx>, free_regions: &'a FreeRegionMap<'tcx>) -> Self { Self { tcx, free_regions } } - pub fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { + pub(crate) fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { self.free_regions.lub_param_regions(self.tcx, r_a, r_b) } } @@ -80,7 +80,7 @@ impl<'tcx> FreeRegionMap<'tcx> { /// cases, this is more conservative than necessary, in order to /// avoid making arbitrary choices. See /// `TransitiveRelation::postdom_upper_bound` for more details. - pub fn lub_param_regions( + pub(crate) fn lub_param_regions( &self, tcx: TyCtxt<'tcx>, r_a: Region<'tcx>, diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index c2c0c7a41feac..e5533213400c6 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -43,7 +43,7 @@ pub(crate) fn resolve<'tcx>( /// Contains the result of lexical region resolution. Offers methods /// to lookup up the final value of a region variable. #[derive(Clone)] -pub struct LexicalRegionResolutions<'tcx> { +pub(crate) struct LexicalRegionResolutions<'tcx> { pub(crate) values: IndexVec>, } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 542104fa10ba0..6fa10a95313c9 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -705,7 +705,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { /// not only the generalized type, but also a bool flag /// indicating whether further WF checks are needed. #[derive(Debug)] -pub struct Generalization { +struct Generalization { /// When generalizing `::Assoc` or /// `::Assoc>>::Assoc` /// for `?0` generalization returns an inference diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index f555fedbb5bcd..1eafbb9acb330 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -29,7 +29,7 @@ use crate::traits::ObligationCause; /// /// GLB moves "down" the lattice (to smaller values); LUB moves /// "up" the lattice (to bigger values). -pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation> { +pub(crate) trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation> { fn infcx(&self) -> &'f InferCtxt<'tcx>; fn cause(&self) -> &ObligationCause<'tcx>; diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index bc954054ea281..fdf55447f7983 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -170,7 +170,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -pub struct InferenceFudger<'a, 'tcx> { +struct InferenceFudger<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, type_vars: (Range, Vec), int_vars: Range, diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 50a0d3bf21407..366af913ddc1c 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -158,7 +158,7 @@ impl<'tcx> InferCtxtInner<'tcx> { } impl<'tcx> InferCtxtUndoLogs<'tcx> { - pub fn start_snapshot(&mut self) -> Snapshot<'tcx> { + pub(crate) fn start_snapshot(&mut self) -> Snapshot<'tcx> { self.num_open_snapshots += 1; Snapshot { undo_len: self.logs.len(), _marker: PhantomData } } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 30dc666128cb1..94aa2ddd92fcc 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -28,6 +28,7 @@ #![feature(let_chains)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc +#![warn(unreachable_pub)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 4f34c1395451b..3a05b576a9744 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -22,7 +22,7 @@ pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine}; pub(crate) use self::project::UndoLog; pub use self::project::{ MismatchedProjectionTypes, Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry, - ProjectionCacheKey, ProjectionCacheStorage, Reveal, + ProjectionCacheKey, ProjectionCacheStorage, }; pub use self::ImplSource::*; pub use self::SelectionError::*; diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 9ed557ec40bc3..3d4ec9e51db23 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -2,7 +2,7 @@ use rustc_data_structures::snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage}; use rustc_data_structures::undo_log::Rollback; -pub use rustc_middle::traits::{EvaluationResult, Reveal}; +use rustc_middle::traits::EvaluationResult; use rustc_middle::ty; use super::PredicateObligation; From a941a4be77dbf2953d23bf89947d58abfca0a824 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 15:11:54 +1000 Subject: [PATCH 093/102] Add `warn(unreachable_pub)` to `rustc_interface`. --- compiler/rustc_interface/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 3492df69b8d32..3b6c2acaf3083 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -2,6 +2,7 @@ #![feature(decl_macro)] #![feature(let_chains)] #![feature(try_blocks)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod callbacks; From 6c84c55c9f279b9ea1f77c7cac3a63f0c89ab90a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 15:12:46 +1000 Subject: [PATCH 094/102] Add `warn(unreachable_pub)` to `rustc_lexer`. --- compiler/rustc_lexer/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 2116ba6c079ac..31fdd2d7cec70 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -23,6 +23,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod cursor; From f10284162ff1cebaab7b2d7b2d5f952f4e52a5bc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 15:24:11 +1000 Subject: [PATCH 095/102] Add `warn(unreachable_pub)` to `rustc_lint`. --- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_lint/src/errors.rs | 18 +- compiler/rustc_lint/src/late.rs | 2 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/lints.rs | 494 +++++++++--------- compiler/rustc_lint/src/non_local_def.rs | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 4 +- compiler/rustc_lint/src/shadowed_into_iter.rs | 2 +- compiler/rustc_lint/src/types.rs | 6 +- compiler/rustc_lint/src/unused.rs | 4 +- 11 files changed, 269 insertions(+), 268 deletions(-) diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 6fb0a6246442e..0ee9dda1fefa2 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -413,7 +413,7 @@ pub fn check_ast_node<'a>( } } -pub fn check_ast_node_inner<'a, T: EarlyLintPass>( +fn check_ast_node_inner<'a, T: EarlyLintPass>( sess: &Session, check_node: impl EarlyCheckNode<'a>, context: EarlyContext<'_>, diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 85ee18aba8f47..d109a5c90305e 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -8,7 +8,7 @@ use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(lint_overruled_attribute, code = E0453)] -pub struct OverruledAttribute<'a> { +pub(crate) struct OverruledAttribute<'a> { #[primary_span] pub span: Span, #[label] @@ -19,7 +19,7 @@ pub struct OverruledAttribute<'a> { pub sub: OverruledAttributeSub, } -pub enum OverruledAttributeSub { +pub(crate) enum OverruledAttributeSub { DefaultSource { id: String }, NodeSource { span: Span, reason: Option }, CommandLineSource, @@ -52,7 +52,7 @@ impl Subdiagnostic for OverruledAttributeSub { #[derive(Diagnostic)] #[diag(lint_malformed_attribute, code = E0452)] -pub struct MalformedAttribute { +pub(crate) struct MalformedAttribute { #[primary_span] pub span: Span, #[subdiagnostic] @@ -60,7 +60,7 @@ pub struct MalformedAttribute { } #[derive(Subdiagnostic)] -pub enum MalformedAttributeSub { +pub(crate) enum MalformedAttributeSub { #[label(lint_bad_attribute_argument)] BadAttributeArgument(#[primary_span] Span), #[label(lint_reason_must_be_string_literal)] @@ -71,7 +71,7 @@ pub enum MalformedAttributeSub { #[derive(Diagnostic)] #[diag(lint_unknown_tool_in_scoped_lint, code = E0710)] -pub struct UnknownToolInScopedLint { +pub(crate) struct UnknownToolInScopedLint { #[primary_span] pub span: Option, pub tool_name: Symbol, @@ -82,7 +82,7 @@ pub struct UnknownToolInScopedLint { #[derive(Diagnostic)] #[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = E0783)] -pub struct BuiltinEllipsisInclusiveRangePatterns { +pub(crate) struct BuiltinEllipsisInclusiveRangePatterns { #[primary_span] pub span: Span, #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] @@ -92,20 +92,20 @@ pub struct BuiltinEllipsisInclusiveRangePatterns { #[derive(Subdiagnostic)] #[note(lint_requested_level)] -pub struct RequestedLevel<'a> { +pub(crate) struct RequestedLevel<'a> { pub level: Level, pub lint_name: &'a str, } #[derive(Diagnostic)] #[diag(lint_unsupported_group, code = E0602)] -pub struct UnsupportedGroup { +pub(crate) struct UnsupportedGroup { pub lint_group: String, } #[derive(Diagnostic)] #[diag(lint_check_name_unknown_tool, code = E0602)] -pub struct CheckNameUnknownTool<'a> { +pub(crate) struct CheckNameUnknownTool<'a> { pub tool_name: Symbol, #[subdiagnostic] pub sub: RequestedLevel<'a>, diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 638b623510e74..cb369d99a8450 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -47,7 +47,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ /// Implements the AST traversal for late lint passes. `T` provides the /// `check_*` methods. -pub struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> { +struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> { context: LateContext<'tcx>, pass: T, } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 91d4f95df8054..07ac63ec96cf1 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1103,7 +1103,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers }; } -pub fn parse_lint_and_tool_name(lint_name: &str) -> (Option, &str) { +pub(crate) fn parse_lint_and_tool_name(lint_name: &str) -> (Option, &str) { match lint_name.split_once("::") { Some((tool_name, lint_name)) => { let tool_name = Symbol::intern(tool_name); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a6e7d288f0827..c5a5c5b30afef 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -39,6 +39,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(trait_upcasting)] +#![warn(unreachable_pub)] // tidy-alphabetical-end mod async_closures; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c12c5427997f9..c6bcb1f3e8334 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -26,7 +26,7 @@ use crate::{fluent_generated as fluent, LateContext}; // array_into_iter.rs #[derive(LintDiagnostic)] #[diag(lint_shadowed_into_iter)] -pub struct ShadowedIntoIterDiag { +pub(crate) struct ShadowedIntoIterDiag { pub target: &'static str, pub edition: &'static str, #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] @@ -36,7 +36,7 @@ pub struct ShadowedIntoIterDiag { } #[derive(Subdiagnostic)] -pub enum ShadowedIntoIterDiagSub { +pub(crate) enum ShadowedIntoIterDiagSub { #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")] RemoveIntoIter { #[primary_span] @@ -57,7 +57,7 @@ pub enum ShadowedIntoIterDiagSub { // builtin.rs #[derive(LintDiagnostic)] #[diag(lint_builtin_while_true)] -pub struct BuiltinWhileTrue { +pub(crate) struct BuiltinWhileTrue { #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] pub suggestion: Span, pub replace: String, @@ -65,7 +65,7 @@ pub struct BuiltinWhileTrue { #[derive(LintDiagnostic)] #[diag(lint_builtin_non_shorthand_field_patterns)] -pub struct BuiltinNonShorthandFieldPatterns { +pub(crate) struct BuiltinNonShorthandFieldPatterns { pub ident: Ident, #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")] pub suggestion: Span, @@ -73,7 +73,7 @@ pub struct BuiltinNonShorthandFieldPatterns { } #[derive(LintDiagnostic)] -pub enum BuiltinUnsafe { +pub(crate) enum BuiltinUnsafe { #[diag(lint_builtin_allow_internal_unsafe)] AllowInternalUnsafe, #[diag(lint_builtin_unsafe_block)] @@ -121,16 +121,16 @@ pub enum BuiltinUnsafe { #[derive(LintDiagnostic)] #[diag(lint_builtin_missing_doc)] -pub struct BuiltinMissingDoc<'a> { +pub(crate) struct BuiltinMissingDoc<'a> { pub article: &'a str, pub desc: &'a str, } #[derive(LintDiagnostic)] #[diag(lint_builtin_missing_copy_impl)] -pub struct BuiltinMissingCopyImpl; +pub(crate) struct BuiltinMissingCopyImpl; -pub struct BuiltinMissingDebugImpl<'a> { +pub(crate) struct BuiltinMissingDebugImpl<'a> { pub tcx: TyCtxt<'a>, pub def_id: DefId, } @@ -145,7 +145,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { #[derive(LintDiagnostic)] #[diag(lint_builtin_anonymous_params)] -pub struct BuiltinAnonymousParams<'a> { +pub(crate) struct BuiltinAnonymousParams<'a> { #[suggestion(code = "_: {ty_snip}")] pub suggestion: (Span, Applicability), pub ty_snip: &'a str, @@ -154,7 +154,7 @@ pub struct BuiltinAnonymousParams<'a> { // FIXME(davidtwco) translatable deprecated attr #[derive(LintDiagnostic)] #[diag(lint_builtin_deprecated_attr_link)] -pub struct BuiltinDeprecatedAttrLink<'a> { +pub(crate) struct BuiltinDeprecatedAttrLink<'a> { pub name: Symbol, pub reason: &'a str, pub link: &'a str, @@ -163,7 +163,7 @@ pub struct BuiltinDeprecatedAttrLink<'a> { } #[derive(Subdiagnostic)] -pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> { +pub(crate) enum BuiltinDeprecatedAttrLinkSuggestion<'a> { #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")] Msg { #[primary_span] @@ -179,7 +179,7 @@ pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> { #[derive(LintDiagnostic)] #[diag(lint_builtin_deprecated_attr_used)] -pub struct BuiltinDeprecatedAttrUsed { +pub(crate) struct BuiltinDeprecatedAttrUsed { pub name: String, #[suggestion( lint_builtin_deprecated_attr_default_suggestion, @@ -192,7 +192,7 @@ pub struct BuiltinDeprecatedAttrUsed { #[derive(LintDiagnostic)] #[diag(lint_builtin_unused_doc_comment)] -pub struct BuiltinUnusedDocComment<'a> { +pub(crate) struct BuiltinUnusedDocComment<'a> { pub kind: &'a str, #[label] pub label: Span, @@ -201,7 +201,7 @@ pub struct BuiltinUnusedDocComment<'a> { } #[derive(Subdiagnostic)] -pub enum BuiltinUnusedDocCommentSub { +pub(crate) enum BuiltinUnusedDocCommentSub { #[help(lint_plain_help)] PlainHelp, #[help(lint_block_help)] @@ -210,7 +210,7 @@ pub enum BuiltinUnusedDocCommentSub { #[derive(LintDiagnostic)] #[diag(lint_builtin_no_mangle_generic)] -pub struct BuiltinNoMangleGeneric { +pub(crate) struct BuiltinNoMangleGeneric { // Use of `#[no_mangle]` suggests FFI intent; correct // fix may be to monomorphize source by hand #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")] @@ -219,21 +219,21 @@ pub struct BuiltinNoMangleGeneric { #[derive(LintDiagnostic)] #[diag(lint_builtin_const_no_mangle)] -pub struct BuiltinConstNoMangle { +pub(crate) struct BuiltinConstNoMangle { #[suggestion(code = "pub static", applicability = "machine-applicable")] pub suggestion: Span, } #[derive(LintDiagnostic)] #[diag(lint_builtin_mutable_transmutes)] -pub struct BuiltinMutablesTransmutes; +pub(crate) struct BuiltinMutablesTransmutes; #[derive(LintDiagnostic)] #[diag(lint_builtin_unstable_features)] -pub struct BuiltinUnstableFeatures; +pub(crate) struct BuiltinUnstableFeatures; // lint_ungated_async_fn_track_caller -pub struct BuiltinUngatedAsyncFnTrackCaller<'a> { +pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> { pub label: Span, pub session: &'a Session, } @@ -252,7 +252,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { #[derive(LintDiagnostic)] #[diag(lint_builtin_unreachable_pub)] -pub struct BuiltinUnreachablePub<'a> { +pub(crate) struct BuiltinUnreachablePub<'a> { pub what: &'a str, #[suggestion(code = "pub(crate)")] pub suggestion: (Span, Applicability), @@ -262,12 +262,12 @@ pub struct BuiltinUnreachablePub<'a> { #[derive(LintDiagnostic)] #[diag(lint_macro_expr_fragment_specifier_2024_migration)] -pub struct MacroExprFragment2024 { +pub(crate) struct MacroExprFragment2024 { #[suggestion(code = "expr_2021", applicability = "machine-applicable")] pub suggestion: Span, } -pub struct BuiltinTypeAliasBounds<'a, 'hir> { +pub(crate) struct BuiltinTypeAliasBounds<'a, 'hir> { pub in_where_clause: bool, pub label: Span, pub enable_feat_help: bool, @@ -338,13 +338,13 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_, '_> { #[derive(LintDiagnostic)] #[diag(lint_builtin_trivial_bounds)] -pub struct BuiltinTrivialBounds<'a> { +pub(crate) struct BuiltinTrivialBounds<'a> { pub predicate_kind_name: &'a str, pub predicate: Clause<'a>, } #[derive(LintDiagnostic)] -pub enum BuiltinEllipsisInclusiveRangePatternsLint { +pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint { #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] Parenthesise { #[suggestion(code = "{replace}", applicability = "machine-applicable")] @@ -360,7 +360,7 @@ pub enum BuiltinEllipsisInclusiveRangePatternsLint { #[derive(LintDiagnostic)] #[diag(lint_builtin_keyword_idents)] -pub struct BuiltinKeywordIdents { +pub(crate) struct BuiltinKeywordIdents { pub kw: Ident, pub next: Edition, #[suggestion(code = "r#{kw}", applicability = "machine-applicable")] @@ -369,7 +369,7 @@ pub struct BuiltinKeywordIdents { #[derive(LintDiagnostic)] #[diag(lint_builtin_explicit_outlives)] -pub struct BuiltinExplicitOutlives { +pub(crate) struct BuiltinExplicitOutlives { pub count: usize, #[subdiagnostic] pub suggestion: BuiltinExplicitOutlivesSuggestion, @@ -377,7 +377,7 @@ pub struct BuiltinExplicitOutlives { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion)] -pub struct BuiltinExplicitOutlivesSuggestion { +pub(crate) struct BuiltinExplicitOutlivesSuggestion { #[suggestion_part(code = "")] pub spans: Vec, #[applicability] @@ -386,7 +386,7 @@ pub struct BuiltinExplicitOutlivesSuggestion { #[derive(LintDiagnostic)] #[diag(lint_builtin_incomplete_features)] -pub struct BuiltinIncompleteFeatures { +pub(crate) struct BuiltinIncompleteFeatures { pub name: Symbol, #[subdiagnostic] pub note: Option, @@ -397,21 +397,21 @@ pub struct BuiltinIncompleteFeatures { #[derive(LintDiagnostic)] #[diag(lint_builtin_internal_features)] #[note] -pub struct BuiltinInternalFeatures { +pub(crate) struct BuiltinInternalFeatures { pub name: Symbol, } #[derive(Subdiagnostic)] #[help(lint_help)] -pub struct BuiltinIncompleteFeaturesHelp; +pub(crate) struct BuiltinIncompleteFeaturesHelp; #[derive(Subdiagnostic)] #[note(lint_note)] -pub struct BuiltinFeatureIssueNote { +pub(crate) struct BuiltinFeatureIssueNote { pub n: NonZero, } -pub struct BuiltinUnpermittedTypeInit<'a> { +pub(crate) struct BuiltinUnpermittedTypeInit<'a> { pub msg: DiagMessage, pub ty: Ty<'a>, pub label: Span, @@ -436,7 +436,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { } // FIXME(davidtwco): make translatable -pub struct BuiltinUnpermittedTypeInitSub { +pub(crate) struct BuiltinUnpermittedTypeInitSub { pub err: InitError, } @@ -463,7 +463,7 @@ impl Subdiagnostic for BuiltinUnpermittedTypeInitSub { } #[derive(LintDiagnostic)] -pub enum BuiltinClashingExtern<'a> { +pub(crate) enum BuiltinClashingExtern<'a> { #[diag(lint_builtin_clashing_extern_same_name)] SameName { this: Symbol, @@ -489,7 +489,7 @@ pub enum BuiltinClashingExtern<'a> { } // FIXME(davidtwco): translatable expected/found -pub struct BuiltinClashingExternSub<'a> { +pub(crate) struct BuiltinClashingExternSub<'a> { pub tcx: TyCtxt<'a>, pub expected: Ty<'a>, pub found: Ty<'a>, @@ -511,7 +511,7 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> { #[derive(LintDiagnostic)] #[diag(lint_builtin_deref_nullptr)] -pub struct BuiltinDerefNullptr { +pub(crate) struct BuiltinDerefNullptr { #[label] pub label: Span, } @@ -519,7 +519,7 @@ pub struct BuiltinDerefNullptr { // FIXME: migrate fluent::lint::builtin_asm_labels #[derive(LintDiagnostic)] -pub enum BuiltinSpecialModuleNameUsed { +pub(crate) enum BuiltinSpecialModuleNameUsed { #[diag(lint_builtin_special_module_name_used_lib)] #[note] #[help] @@ -532,7 +532,7 @@ pub enum BuiltinSpecialModuleNameUsed { // deref_into_dyn_supertrait.rs #[derive(LintDiagnostic)] #[diag(lint_supertrait_as_deref_target)] -pub struct SupertraitAsDerefTarget<'a> { +pub(crate) struct SupertraitAsDerefTarget<'a> { pub self_ty: Ty<'a>, pub supertrait_principal: PolyExistentialTraitRef<'a>, pub target_principal: PolyExistentialTraitRef<'a>, @@ -544,7 +544,7 @@ pub struct SupertraitAsDerefTarget<'a> { #[derive(Subdiagnostic)] #[label(lint_label2)] -pub struct SupertraitAsDerefTargetLabel { +pub(crate) struct SupertraitAsDerefTargetLabel { #[primary_span] pub label: Span, } @@ -552,7 +552,7 @@ pub struct SupertraitAsDerefTargetLabel { // enum_intrinsics_non_enums.rs #[derive(LintDiagnostic)] #[diag(lint_enum_intrinsics_mem_discriminant)] -pub struct EnumIntrinsicsMemDiscriminate<'a> { +pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> { pub ty_param: Ty<'a>, #[note] pub note: Span, @@ -561,14 +561,14 @@ pub struct EnumIntrinsicsMemDiscriminate<'a> { #[derive(LintDiagnostic)] #[diag(lint_enum_intrinsics_mem_variant)] #[note] -pub struct EnumIntrinsicsMemVariant<'a> { +pub(crate) struct EnumIntrinsicsMemVariant<'a> { pub ty_param: Ty<'a>, } // expect.rs #[derive(LintDiagnostic)] #[diag(lint_expectation)] -pub struct Expectation { +pub(crate) struct Expectation { #[subdiagnostic] pub rationale: Option, #[note] @@ -577,13 +577,13 @@ pub struct Expectation { #[derive(Subdiagnostic)] #[note(lint_rationale)] -pub struct ExpectationNote { +pub(crate) struct ExpectationNote { pub rationale: Symbol, } // ptr_nulls.rs #[derive(LintDiagnostic)] -pub enum PtrNullChecksDiag<'a> { +pub(crate) enum PtrNullChecksDiag<'a> { #[diag(lint_ptr_null_checks_fn_ptr)] #[help(lint_help)] FnPtr { @@ -604,7 +604,7 @@ pub enum PtrNullChecksDiag<'a> { // for_loops_over_fallibles.rs #[derive(LintDiagnostic)] #[diag(lint_for_loops_over_fallibles)] -pub struct ForLoopsOverFalliblesDiag<'a> { +pub(crate) struct ForLoopsOverFalliblesDiag<'a> { pub article: &'static str, pub ref_prefix: &'static str, pub ty: &'static str, @@ -617,7 +617,7 @@ pub struct ForLoopsOverFalliblesDiag<'a> { } #[derive(Subdiagnostic)] -pub enum ForLoopsOverFalliblesLoopSub<'a> { +pub(crate) enum ForLoopsOverFalliblesLoopSub<'a> { #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")] RemoveNext { #[primary_span] @@ -636,14 +636,14 @@ pub enum ForLoopsOverFalliblesLoopSub<'a> { #[derive(Subdiagnostic)] #[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")] -pub struct ForLoopsOverFalliblesQuestionMark { +pub(crate) struct ForLoopsOverFalliblesQuestionMark { #[primary_span] pub suggestion: Span, } #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] -pub struct ForLoopsOverFalliblesSuggestion<'a> { +pub(crate) struct ForLoopsOverFalliblesSuggestion<'a> { pub var: &'a str, #[suggestion_part(code = "if let {var}(")] pub start_span: Span, @@ -652,7 +652,7 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { } #[derive(Subdiagnostic)] -pub enum UseLetUnderscoreIgnoreSuggestion { +pub(crate) enum UseLetUnderscoreIgnoreSuggestion { #[note(lint_use_let_underscore_ignore_suggestion)] Note, #[multipart_suggestion( @@ -671,7 +671,7 @@ pub enum UseLetUnderscoreIgnoreSuggestion { // drop_forget_useless.rs #[derive(LintDiagnostic)] #[diag(lint_dropping_references)] -pub struct DropRefDiag<'a> { +pub(crate) struct DropRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -681,7 +681,7 @@ pub struct DropRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_dropping_copy_types)] -pub struct DropCopyDiag<'a> { +pub(crate) struct DropCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -691,7 +691,7 @@ pub struct DropCopyDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forgetting_references)] -pub struct ForgetRefDiag<'a> { +pub(crate) struct ForgetRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -701,7 +701,7 @@ pub struct ForgetRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forgetting_copy_types)] -pub struct ForgetCopyDiag<'a> { +pub(crate) struct ForgetCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -711,7 +711,7 @@ pub struct ForgetCopyDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_undropped_manually_drops)] -pub struct UndroppedManuallyDropsDiag<'a> { +pub(crate) struct UndroppedManuallyDropsDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -721,7 +721,7 @@ pub struct UndroppedManuallyDropsDiag<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] -pub struct UndroppedManuallyDropsSuggestion { +pub(crate) struct UndroppedManuallyDropsSuggestion { #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")] pub start_span: Span, #[suggestion_part(code = ")")] @@ -730,7 +730,7 @@ pub struct UndroppedManuallyDropsSuggestion { // invalid_from_utf8.rs #[derive(LintDiagnostic)] -pub enum InvalidFromUtf8Diag { +pub(crate) enum InvalidFromUtf8Diag { #[diag(lint_invalid_from_utf8_unchecked)] Unchecked { method: String, @@ -749,7 +749,7 @@ pub enum InvalidFromUtf8Diag { // reference_casting.rs #[derive(LintDiagnostic)] -pub enum InvalidReferenceCastingDiag<'tcx> { +pub(crate) enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_invalid_reference_casting_borrow_as_mut)] #[note(lint_invalid_reference_casting_note_book)] BorrowAsMut { @@ -784,7 +784,7 @@ pub enum InvalidReferenceCastingDiag<'tcx> { #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] #[note] -pub struct HiddenUnicodeCodepointsDiag<'a> { +pub(crate) struct HiddenUnicodeCodepointsDiag<'a> { pub label: &'a str, pub count: usize, #[label] @@ -795,7 +795,7 @@ pub struct HiddenUnicodeCodepointsDiag<'a> { pub sub: HiddenUnicodeCodepointsDiagSub, } -pub struct HiddenUnicodeCodepointsDiagLabels { +pub(crate) struct HiddenUnicodeCodepointsDiagLabels { pub spans: Vec<(char, Span)>, } @@ -811,7 +811,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels { } } -pub enum HiddenUnicodeCodepointsDiagSub { +pub(crate) enum HiddenUnicodeCodepointsDiagSub { Escape { spans: Vec<(char, Span)> }, NoEscape { spans: Vec<(char, Span)> }, } @@ -866,7 +866,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { #[derive(LintDiagnostic)] #[diag(lint_map_unit_fn)] #[note] -pub struct MappingToUnit { +pub(crate) struct MappingToUnit { #[label(lint_function_label)] pub function_label: Span, #[label(lint_argument_label)] @@ -882,7 +882,7 @@ pub struct MappingToUnit { #[derive(LintDiagnostic)] #[diag(lint_default_hash_types)] #[note] -pub struct DefaultHashTypesDiag<'a> { +pub(crate) struct DefaultHashTypesDiag<'a> { pub preferred: &'a str, pub used: Symbol, } @@ -890,17 +890,17 @@ pub struct DefaultHashTypesDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_query_instability)] #[note] -pub struct QueryInstability { +pub(crate) struct QueryInstability { pub query: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_span_use_eq_ctxt)] -pub struct SpanUseEqCtxtDiag; +pub(crate) struct SpanUseEqCtxtDiag; #[derive(LintDiagnostic)] #[diag(lint_tykind_kind)] -pub struct TykindKind { +pub(crate) struct TykindKind { #[suggestion(code = "ty", applicability = "maybe-incorrect")] pub suggestion: Span, } @@ -908,11 +908,11 @@ pub struct TykindKind { #[derive(LintDiagnostic)] #[diag(lint_tykind)] #[help] -pub struct TykindDiag; +pub(crate) struct TykindDiag; #[derive(LintDiagnostic)] #[diag(lint_ty_qualified)] -pub struct TyQualified { +pub(crate) struct TyQualified { pub ty: String, #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] pub suggestion: Span, @@ -920,7 +920,7 @@ pub struct TyQualified { #[derive(LintDiagnostic)] #[diag(lint_non_glob_import_type_ir_inherent)] -pub struct NonGlobImportTypeIrInherent { +pub(crate) struct NonGlobImportTypeIrInherent { #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")] pub suggestion: Option, pub snippet: &'static str, @@ -929,32 +929,32 @@ pub struct NonGlobImportTypeIrInherent { #[derive(LintDiagnostic)] #[diag(lint_lintpass_by_hand)] #[help] -pub struct LintPassByHand; +pub(crate) struct LintPassByHand; #[derive(LintDiagnostic)] #[diag(lint_non_existent_doc_keyword)] #[help] -pub struct NonExistentDocKeyword { +pub(crate) struct NonExistentDocKeyword { pub keyword: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_diag_out_of_impl)] -pub struct DiagOutOfImpl; +pub(crate) struct DiagOutOfImpl; #[derive(LintDiagnostic)] #[diag(lint_untranslatable_diag)] -pub struct UntranslatableDiag; +pub(crate) struct UntranslatableDiag; #[derive(LintDiagnostic)] #[diag(lint_bad_opt_access)] -pub struct BadOptAccessDiag<'a> { +pub(crate) struct BadOptAccessDiag<'a> { pub msg: &'a str, } // let_underscore.rs #[derive(LintDiagnostic)] -pub enum NonBindingLet { +pub(crate) enum NonBindingLet { #[diag(lint_non_binding_let_on_sync_lock)] SyncLock { #[label] @@ -969,7 +969,7 @@ pub enum NonBindingLet { }, } -pub struct NonBindingLetSub { +pub(crate) struct NonBindingLetSub { pub suggestion: Span, pub drop_fn_start_end: Option<(Span, Span)>, pub is_assign_desugar: bool, @@ -1012,7 +1012,7 @@ impl Subdiagnostic for NonBindingLetSub { // levels.rs #[derive(LintDiagnostic)] #[diag(lint_overruled_attribute)] -pub struct OverruledAttributeLint<'a> { +pub(crate) struct OverruledAttributeLint<'a> { #[label] pub overruled: Span, pub lint_level: &'a str, @@ -1023,7 +1023,7 @@ pub struct OverruledAttributeLint<'a> { #[derive(LintDiagnostic)] #[diag(lint_deprecated_lint_name)] -pub struct DeprecatedLintName<'a> { +pub(crate) struct DeprecatedLintName<'a> { pub name: String, #[suggestion(code = "{replace}", applicability = "machine-applicable")] pub suggestion: Span, @@ -1033,7 +1033,7 @@ pub struct DeprecatedLintName<'a> { #[derive(LintDiagnostic)] #[diag(lint_deprecated_lint_name)] #[help] -pub struct DeprecatedLintNameFromCommandLine<'a> { +pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { pub name: String, pub replace: &'a str, #[subdiagnostic] @@ -1042,14 +1042,14 @@ pub struct DeprecatedLintNameFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_renamed_lint)] -pub struct RenamedLint<'a> { +pub(crate) struct RenamedLint<'a> { pub name: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, } #[derive(Subdiagnostic)] -pub enum RenamedLintSuggestion<'a> { +pub(crate) enum RenamedLintSuggestion<'a> { #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")] WithSpan { #[primary_span] @@ -1062,7 +1062,7 @@ pub enum RenamedLintSuggestion<'a> { #[derive(LintDiagnostic)] #[diag(lint_renamed_lint)] -pub struct RenamedLintFromCommandLine<'a> { +pub(crate) struct RenamedLintFromCommandLine<'a> { pub name: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, @@ -1072,14 +1072,14 @@ pub struct RenamedLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_removed_lint)] -pub struct RemovedLint<'a> { +pub(crate) struct RemovedLint<'a> { pub name: &'a str, pub reason: &'a str, } #[derive(LintDiagnostic)] #[diag(lint_removed_lint)] -pub struct RemovedLintFromCommandLine<'a> { +pub(crate) struct RemovedLintFromCommandLine<'a> { pub name: &'a str, pub reason: &'a str, #[subdiagnostic] @@ -1088,14 +1088,14 @@ pub struct RemovedLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_unknown_lint)] -pub struct UnknownLint { +pub(crate) struct UnknownLint { pub name: String, #[subdiagnostic] pub suggestion: Option, } #[derive(Subdiagnostic)] -pub enum UnknownLintSuggestion { +pub(crate) enum UnknownLintSuggestion { #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] WithSpan { #[primary_span] @@ -1109,7 +1109,7 @@ pub enum UnknownLintSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unknown_lint, code = E0602)] -pub struct UnknownLintFromCommandLine<'a> { +pub(crate) struct UnknownLintFromCommandLine<'a> { pub name: String, #[subdiagnostic] pub suggestion: Option, @@ -1119,7 +1119,7 @@ pub struct UnknownLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_ignored_unless_crate_specified)] -pub struct IgnoredUnlessCrateSpecified<'a> { +pub(crate) struct IgnoredUnlessCrateSpecified<'a> { pub level: &'a str, pub name: Symbol, } @@ -1129,7 +1129,7 @@ pub struct IgnoredUnlessCrateSpecified<'a> { #[diag(lint_cstring_ptr)] #[note] #[help] -pub struct CStringPtr { +pub(crate) struct CStringPtr { #[label(lint_as_ptr_label)] pub as_ptr: Span, #[label(lint_unwrap_label)] @@ -1139,19 +1139,19 @@ pub struct CStringPtr { // multiple_supertrait_upcastable.rs #[derive(LintDiagnostic)] #[diag(lint_multiple_supertrait_upcastable)] -pub struct MultipleSupertraitUpcastable { +pub(crate) struct MultipleSupertraitUpcastable { pub ident: Ident, } // non_ascii_idents.rs #[derive(LintDiagnostic)] #[diag(lint_identifier_non_ascii_char)] -pub struct IdentifierNonAsciiChar; +pub(crate) struct IdentifierNonAsciiChar; #[derive(LintDiagnostic)] #[diag(lint_identifier_uncommon_codepoints)] #[note] -pub struct IdentifierUncommonCodepoints { +pub(crate) struct IdentifierUncommonCodepoints { pub codepoints: Vec, pub codepoints_len: usize, pub identifier_type: &'static str, @@ -1159,7 +1159,7 @@ pub struct IdentifierUncommonCodepoints { #[derive(LintDiagnostic)] #[diag(lint_confusable_identifier_pair)] -pub struct ConfusableIdentifierPair { +pub(crate) struct ConfusableIdentifierPair { pub existing_sym: Symbol, pub sym: Symbol, #[label(lint_other_use)] @@ -1172,13 +1172,13 @@ pub struct ConfusableIdentifierPair { #[diag(lint_mixed_script_confusables)] #[note(lint_includes_note)] #[note] -pub struct MixedScriptConfusables { +pub(crate) struct MixedScriptConfusables { pub set: String, pub includes: String, } // non_fmt_panic.rs -pub struct NonFmtPanicUnused { +pub(crate) struct NonFmtPanicUnused { pub count: usize, pub suggestion: Option, } @@ -1209,7 +1209,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { #[derive(LintDiagnostic)] #[diag(lint_non_fmt_panic_braces)] #[note] -pub struct NonFmtPanicBraces { +pub(crate) struct NonFmtPanicBraces { pub count: usize, #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")] pub suggestion: Option, @@ -1218,7 +1218,7 @@ pub struct NonFmtPanicBraces { // nonstandard_style.rs #[derive(LintDiagnostic)] #[diag(lint_non_camel_case_type)] -pub struct NonCamelCaseType<'a> { +pub(crate) struct NonCamelCaseType<'a> { pub sort: &'a str, pub name: &'a str, #[subdiagnostic] @@ -1226,7 +1226,7 @@ pub struct NonCamelCaseType<'a> { } #[derive(Subdiagnostic)] -pub enum NonCamelCaseTypeSub { +pub(crate) enum NonCamelCaseTypeSub { #[label(lint_label)] Label { #[primary_span] @@ -1242,7 +1242,7 @@ pub enum NonCamelCaseTypeSub { #[derive(LintDiagnostic)] #[diag(lint_non_snake_case)] -pub struct NonSnakeCaseDiag<'a> { +pub(crate) struct NonSnakeCaseDiag<'a> { pub sort: &'a str, pub name: &'a str, pub sc: String, @@ -1250,7 +1250,7 @@ pub struct NonSnakeCaseDiag<'a> { pub sub: NonSnakeCaseDiagSub, } -pub enum NonSnakeCaseDiagSub { +pub(crate) enum NonSnakeCaseDiagSub { Label { span: Span }, Help, RenameOrConvertSuggestion { span: Span, suggestion: Ident }, @@ -1302,7 +1302,7 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { #[derive(LintDiagnostic)] #[diag(lint_non_upper_case_global)] -pub struct NonUpperCaseGlobal<'a> { +pub(crate) struct NonUpperCaseGlobal<'a> { pub sort: &'a str, pub name: &'a str, #[subdiagnostic] @@ -1310,7 +1310,7 @@ pub struct NonUpperCaseGlobal<'a> { } #[derive(Subdiagnostic)] -pub enum NonUpperCaseGlobalSub { +pub(crate) enum NonUpperCaseGlobalSub { #[label(lint_label)] Label { #[primary_span] @@ -1328,7 +1328,7 @@ pub enum NonUpperCaseGlobalSub { #[derive(LintDiagnostic)] #[diag(lint_noop_method_call)] #[note] -pub struct NoopMethodCallDiag<'a> { +pub(crate) struct NoopMethodCallDiag<'a> { pub method: Symbol, pub orig_ty: Ty<'a>, pub trait_: Symbol, @@ -1344,18 +1344,18 @@ pub struct NoopMethodCallDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_suspicious_double_ref_deref)] -pub struct SuspiciousDoubleRefDerefDiag<'a> { +pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> { pub ty: Ty<'a>, } #[derive(LintDiagnostic)] #[diag(lint_suspicious_double_ref_clone)] -pub struct SuspiciousDoubleRefCloneDiag<'a> { +pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> { pub ty: Ty<'a>, } // non_local_defs.rs -pub enum NonLocalDefinitionsDiag { +pub(crate) enum NonLocalDefinitionsDiag { Impl { depth: u32, body_kind_descr: &'static str, @@ -1487,7 +1487,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { #[derive(Subdiagnostic)] #[note(lint_non_local_definitions_cargo_update)] -pub struct NonLocalDefinitionsCargoUpdateNote { +pub(crate) struct NonLocalDefinitionsCargoUpdateNote { pub macro_kind: &'static str, pub macro_name: Symbol, pub crate_name: Symbol, @@ -1497,7 +1497,7 @@ pub struct NonLocalDefinitionsCargoUpdateNote { #[derive(LintDiagnostic)] #[diag(lint_ambiguous_negative_literals)] #[note(lint_example)] -pub struct AmbiguousNegativeLiteralsDiag { +pub(crate) struct AmbiguousNegativeLiteralsDiag { #[subdiagnostic] pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion, #[subdiagnostic] @@ -1506,7 +1506,7 @@ pub struct AmbiguousNegativeLiteralsDiag { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")] -pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion { +pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion { #[suggestion_part(code = "(")] pub start_span: Span, #[suggestion_part(code = ")")] @@ -1515,7 +1515,7 @@ pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")] -pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { +pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { #[suggestion_part(code = "(")] pub start_span: Span, #[suggestion_part(code = ")")] @@ -1525,7 +1525,7 @@ pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { // pass_by_value.rs #[derive(LintDiagnostic)] #[diag(lint_pass_by_value)] -pub struct PassByValueDiag { +pub(crate) struct PassByValueDiag { pub ty: String, #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] pub suggestion: Span, @@ -1534,14 +1534,14 @@ pub struct PassByValueDiag { // redundant_semicolon.rs #[derive(LintDiagnostic)] #[diag(lint_redundant_semicolons)] -pub struct RedundantSemicolonsDiag { +pub(crate) struct RedundantSemicolonsDiag { pub multiple: bool, #[suggestion(code = "", applicability = "maybe-incorrect")] pub suggestion: Span, } // traits.rs -pub struct DropTraitConstraintsDiag<'a> { +pub(crate) struct DropTraitConstraintsDiag<'a> { pub predicate: Clause<'a>, pub tcx: TyCtxt<'a>, pub def_id: DefId, @@ -1556,7 +1556,7 @@ impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { } } -pub struct DropGlue<'a> { +pub(crate) struct DropGlue<'a> { pub tcx: TyCtxt<'a>, pub def_id: DefId, } @@ -1572,14 +1572,14 @@ impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { // types.rs #[derive(LintDiagnostic)] #[diag(lint_range_endpoint_out_of_range)] -pub struct RangeEndpointOutOfRange<'a> { +pub(crate) struct RangeEndpointOutOfRange<'a> { pub ty: &'a str, #[subdiagnostic] pub sub: UseInclusiveRange<'a>, } #[derive(Subdiagnostic)] -pub enum UseInclusiveRange<'a> { +pub(crate) enum UseInclusiveRange<'a> { #[suggestion( lint_range_use_inclusive_range, code = "{start}..={literal}{suffix}", @@ -1605,7 +1605,7 @@ pub enum UseInclusiveRange<'a> { #[derive(LintDiagnostic)] #[diag(lint_overflowing_bin_hex)] -pub struct OverflowingBinHex<'a> { +pub(crate) struct OverflowingBinHex<'a> { pub ty: &'a str, pub lit: String, pub dec: u128, @@ -1618,7 +1618,7 @@ pub struct OverflowingBinHex<'a> { pub sign_bit_sub: Option>, } -pub enum OverflowingBinHexSign { +pub(crate) enum OverflowingBinHexSign { Positive, Negative, } @@ -1642,7 +1642,7 @@ impl Subdiagnostic for OverflowingBinHexSign { } #[derive(Subdiagnostic)] -pub enum OverflowingBinHexSub<'a> { +pub(crate) enum OverflowingBinHexSub<'a> { #[suggestion( lint_suggestion, code = "{sans_suffix}{suggestion_ty}", @@ -1664,7 +1664,7 @@ pub enum OverflowingBinHexSub<'a> { code = "{lit_no_suffix}{uint_ty} as {int_ty}", applicability = "maybe-incorrect" )] -pub struct OverflowingBinHexSignBitSub<'a> { +pub(crate) struct OverflowingBinHexSignBitSub<'a> { #[primary_span] pub span: Span, pub lit_no_suffix: &'a str, @@ -1676,7 +1676,7 @@ pub struct OverflowingBinHexSignBitSub<'a> { #[derive(LintDiagnostic)] #[diag(lint_overflowing_int)] #[note] -pub struct OverflowingInt<'a> { +pub(crate) struct OverflowingInt<'a> { pub ty: &'a str, pub lit: String, pub min: i128, @@ -1687,13 +1687,13 @@ pub struct OverflowingInt<'a> { #[derive(Subdiagnostic)] #[help(lint_help)] -pub struct OverflowingIntHelp<'a> { +pub(crate) struct OverflowingIntHelp<'a> { pub suggestion_ty: &'a str, } #[derive(LintDiagnostic)] #[diag(lint_only_cast_u8_to_char)] -pub struct OnlyCastu8ToChar { +pub(crate) struct OnlyCastu8ToChar { #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")] pub span: Span, pub literal: u128, @@ -1702,7 +1702,7 @@ pub struct OnlyCastu8ToChar { #[derive(LintDiagnostic)] #[diag(lint_overflowing_uint)] #[note] -pub struct OverflowingUInt<'a> { +pub(crate) struct OverflowingUInt<'a> { pub ty: &'a str, pub lit: String, pub min: u128, @@ -1712,17 +1712,17 @@ pub struct OverflowingUInt<'a> { #[derive(LintDiagnostic)] #[diag(lint_overflowing_literal)] #[note] -pub struct OverflowingLiteral<'a> { +pub(crate) struct OverflowingLiteral<'a> { pub ty: &'a str, pub lit: String, } #[derive(LintDiagnostic)] #[diag(lint_unused_comparisons)] -pub struct UnusedComparisons; +pub(crate) struct UnusedComparisons; #[derive(LintDiagnostic)] -pub enum InvalidNanComparisons { +pub(crate) enum InvalidNanComparisons { #[diag(lint_invalid_nan_comparisons_eq_ne)] EqNe { #[subdiagnostic] @@ -1733,7 +1733,7 @@ pub enum InvalidNanComparisons { } #[derive(Subdiagnostic)] -pub enum InvalidNanComparisonsSuggestion { +pub(crate) enum InvalidNanComparisonsSuggestion { #[multipart_suggestion( lint_suggestion, style = "verbose", @@ -1752,7 +1752,7 @@ pub enum InvalidNanComparisonsSuggestion { } #[derive(LintDiagnostic)] -pub enum AmbiguousWidePointerComparisons<'a> { +pub(crate) enum AmbiguousWidePointerComparisons<'a> { #[diag(lint_ambiguous_wide_pointer_comparisons)] Spanful { #[subdiagnostic] @@ -1773,7 +1773,7 @@ pub enum AmbiguousWidePointerComparisons<'a> { // FIXME(#53934): make machine-applicable again applicability = "maybe-incorrect" )] -pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> { +pub(crate) struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> { pub ne: &'a str, pub deref_left: &'a str, pub deref_right: &'a str, @@ -1788,7 +1788,7 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> { } #[derive(Subdiagnostic)] -pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { +pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { #[multipart_suggestion( lint_addr_suggestion, style = "verbose", @@ -1832,7 +1832,7 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { }, } -pub struct ImproperCTypes<'a> { +pub(crate) struct ImproperCTypes<'a> { pub ty: Ty<'a>, pub desc: &'a str, pub label: Span, @@ -1860,29 +1860,29 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { #[derive(LintDiagnostic)] #[diag(lint_variant_size_differences)] -pub struct VariantSizeDifferencesDiag { +pub(crate) struct VariantSizeDifferencesDiag { pub largest: u64, } #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_load)] #[help] -pub struct AtomicOrderingLoad; +pub(crate) struct AtomicOrderingLoad; #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_store)] #[help] -pub struct AtomicOrderingStore; +pub(crate) struct AtomicOrderingStore; #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_fence)] #[help] -pub struct AtomicOrderingFence; +pub(crate) struct AtomicOrderingFence; #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_invalid)] #[help] -pub struct InvalidAtomicOrderingDiag { +pub(crate) struct InvalidAtomicOrderingDiag { pub method: Symbol, #[label] pub fail_order_arg_span: Span, @@ -1891,7 +1891,7 @@ pub struct InvalidAtomicOrderingDiag { // unused.rs #[derive(LintDiagnostic)] #[diag(lint_unused_op)] -pub struct UnusedOp<'a> { +pub(crate) struct UnusedOp<'a> { pub op: &'a str, #[label] pub label: Span, @@ -1900,7 +1900,7 @@ pub struct UnusedOp<'a> { } #[derive(Subdiagnostic)] -pub enum UnusedOpSuggestion { +pub(crate) enum UnusedOpSuggestion { #[suggestion( lint_suggestion, style = "verbose", @@ -1922,7 +1922,7 @@ pub enum UnusedOpSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unused_result)] -pub struct UnusedResult<'a> { +pub(crate) struct UnusedResult<'a> { pub ty: Ty<'a>, } @@ -1931,7 +1931,7 @@ pub struct UnusedResult<'a> { #[derive(LintDiagnostic)] #[diag(lint_unused_closure)] #[note] -pub struct UnusedClosure<'a> { +pub(crate) struct UnusedClosure<'a> { pub count: usize, pub pre: &'a str, pub post: &'a str, @@ -1942,7 +1942,7 @@ pub struct UnusedClosure<'a> { #[derive(LintDiagnostic)] #[diag(lint_unused_coroutine)] #[note] -pub struct UnusedCoroutine<'a> { +pub(crate) struct UnusedCoroutine<'a> { pub count: usize, pub pre: &'a str, pub post: &'a str, @@ -1950,7 +1950,7 @@ pub struct UnusedCoroutine<'a> { // FIXME(davidtwco): this isn't properly translatable because of the pre/post // strings -pub struct UnusedDef<'a, 'b> { +pub(crate) struct UnusedDef<'a, 'b> { pub pre: &'a str, pub post: &'a str, pub cx: &'a LateContext<'b>, @@ -1961,7 +1961,7 @@ pub struct UnusedDef<'a, 'b> { #[derive(Subdiagnostic)] -pub enum UnusedDefSuggestion { +pub(crate) enum UnusedDefSuggestion { #[suggestion( lint_suggestion, style = "verbose", @@ -2000,13 +2000,13 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { #[derive(LintDiagnostic)] #[diag(lint_path_statement_drop)] -pub struct PathStatementDrop { +pub(crate) struct PathStatementDrop { #[subdiagnostic] pub sub: PathStatementDropSub, } #[derive(Subdiagnostic)] -pub enum PathStatementDropSub { +pub(crate) enum PathStatementDropSub { #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")] Suggestion { #[primary_span] @@ -2022,11 +2022,11 @@ pub enum PathStatementDropSub { #[derive(LintDiagnostic)] #[diag(lint_path_statement_no_effect)] -pub struct PathStatementNoEffect; +pub(crate) struct PathStatementNoEffect; #[derive(LintDiagnostic)] #[diag(lint_unused_delim)] -pub struct UnusedDelim<'a> { +pub(crate) struct UnusedDelim<'a> { pub delim: &'static str, pub item: &'a str, #[subdiagnostic] @@ -2035,7 +2035,7 @@ pub struct UnusedDelim<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] -pub struct UnusedDelimSuggestion { +pub(crate) struct UnusedDelimSuggestion { #[suggestion_part(code = "{start_replace}")] pub start_span: Span, pub start_replace: &'static str, @@ -2046,19 +2046,19 @@ pub struct UnusedDelimSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unused_import_braces)] -pub struct UnusedImportBracesDiag { +pub(crate) struct UnusedImportBracesDiag { pub node: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_unused_allocation)] -pub struct UnusedAllocationDiag; +pub(crate) struct UnusedAllocationDiag; #[derive(LintDiagnostic)] #[diag(lint_unused_allocation_mut)] -pub struct UnusedAllocationMutDiag; +pub(crate) struct UnusedAllocationMutDiag; -pub struct AsyncFnInTraitDiag { +pub(crate) struct AsyncFnInTraitDiag { pub sugg: Option>, } @@ -2074,13 +2074,13 @@ impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { #[derive(LintDiagnostic)] #[diag(lint_unit_bindings)] -pub struct UnitBindingsDiag { +pub(crate) struct UnitBindingsDiag { #[label] pub label: Span, } #[derive(LintDiagnostic)] -pub enum InvalidAsmLabel { +pub(crate) enum InvalidAsmLabel { #[diag(lint_invalid_asm_label_named)] #[help] #[note] @@ -2110,7 +2110,7 @@ pub enum InvalidAsmLabel { } #[derive(Subdiagnostic)] -pub enum UnexpectedCfgCargoHelp { +pub(crate) enum UnexpectedCfgCargoHelp { #[help(lint_unexpected_cfg_add_cargo_feature)] #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] LintCfg { cargo_toml_lint_cfg: String }, @@ -2127,13 +2127,13 @@ impl UnexpectedCfgCargoHelp { ) } - pub fn lint_cfg(unescaped: &str) -> Self { + pub(crate) fn lint_cfg(unescaped: &str) -> Self { UnexpectedCfgCargoHelp::LintCfg { cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped), } } - pub fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self { + pub(crate) fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self { UnexpectedCfgCargoHelp::LintCfgAndBuildRs { cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped), build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"), @@ -2143,19 +2143,19 @@ impl UnexpectedCfgCargoHelp { #[derive(Subdiagnostic)] #[help(lint_unexpected_cfg_add_cmdline_arg)] -pub struct UnexpectedCfgRustcHelp { +pub(crate) struct UnexpectedCfgRustcHelp { pub cmdline_arg: String, } impl UnexpectedCfgRustcHelp { - pub fn new(unescaped: &str) -> Self { + pub(crate) fn new(unescaped: &str) -> Self { Self { cmdline_arg: format!("--check-cfg={unescaped}") } } } #[derive(LintDiagnostic)] #[diag(lint_unexpected_cfg_name)] -pub struct UnexpectedCfgName { +pub(crate) struct UnexpectedCfgName { #[subdiagnostic] pub code_sugg: unexpected_cfg_name::CodeSuggestion, #[subdiagnostic] @@ -2164,13 +2164,13 @@ pub struct UnexpectedCfgName { pub name: Symbol, } -pub mod unexpected_cfg_name { +pub(crate) mod unexpected_cfg_name { use rustc_errors::DiagSymbolList; use rustc_macros::Subdiagnostic; use rustc_span::{Span, Symbol}; #[derive(Subdiagnostic)] - pub enum CodeSuggestion { + pub(crate) enum CodeSuggestion { #[help(lint_unexpected_cfg_define_features)] DefineFeatures, #[suggestion( @@ -2227,7 +2227,7 @@ pub mod unexpected_cfg_name { #[derive(Subdiagnostic)] #[help(lint_unexpected_cfg_name_expected_values)] - pub struct ExpectedValues { + pub(crate) struct ExpectedValues { pub best_match: Symbol, pub possibilities: DiagSymbolList, } @@ -2238,7 +2238,7 @@ pub mod unexpected_cfg_name { applicability = "maybe-incorrect", code = "{code}" )] - pub struct FoundWithSimilarValue { + pub(crate) struct FoundWithSimilarValue { #[primary_span] pub span: Span, pub code: String, @@ -2246,13 +2246,13 @@ pub mod unexpected_cfg_name { #[derive(Subdiagnostic)] #[help_once(lint_unexpected_cfg_name_expected_names)] - pub struct ExpectedNames { + pub(crate) struct ExpectedNames { pub possibilities: DiagSymbolList, pub and_more: usize, } #[derive(Subdiagnostic)] - pub enum InvocationHelp { + pub(crate) enum InvocationHelp { #[note(lint_unexpected_cfg_doc_cargo)] Cargo { #[subdiagnostic] @@ -2265,7 +2265,7 @@ pub mod unexpected_cfg_name { #[derive(LintDiagnostic)] #[diag(lint_unexpected_cfg_value)] -pub struct UnexpectedCfgValue { +pub(crate) struct UnexpectedCfgValue { #[subdiagnostic] pub code_sugg: unexpected_cfg_value::CodeSuggestion, #[subdiagnostic] @@ -2275,13 +2275,13 @@ pub struct UnexpectedCfgValue { pub value: String, } -pub mod unexpected_cfg_value { +pub(crate) mod unexpected_cfg_value { use rustc_errors::DiagSymbolList; use rustc_macros::Subdiagnostic; use rustc_span::{Span, Symbol}; #[derive(Subdiagnostic)] - pub enum CodeSuggestion { + pub(crate) enum CodeSuggestion { ChangeValue { #[subdiagnostic] expected_values: ExpectedValues, @@ -2305,7 +2305,7 @@ pub mod unexpected_cfg_value { } #[derive(Subdiagnostic)] - pub enum ChangeValueSuggestion { + pub(crate) enum ChangeValueSuggestion { #[suggestion( lint_unexpected_cfg_value_similar_name, code = r#""{best_match}""#, @@ -2334,7 +2334,7 @@ pub mod unexpected_cfg_value { code = "", applicability = "maybe-incorrect" )] - pub struct RemoveValueSuggestion { + pub(crate) struct RemoveValueSuggestion { #[primary_span] pub span: Span, } @@ -2345,14 +2345,14 @@ pub mod unexpected_cfg_value { code = "", applicability = "maybe-incorrect" )] - pub struct RemoveConditionSuggestion { + pub(crate) struct RemoveConditionSuggestion { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] #[note(lint_unexpected_cfg_value_expected_values)] - pub struct ExpectedValues { + pub(crate) struct ExpectedValues { pub name: Symbol, pub have_none_possibility: bool, pub possibilities: DiagSymbolList, @@ -2360,7 +2360,7 @@ pub mod unexpected_cfg_value { } #[derive(Subdiagnostic)] - pub enum InvocationHelp { + pub(crate) enum InvocationHelp { #[note(lint_unexpected_cfg_doc_cargo)] Cargo(#[subdiagnostic] Option), #[note(lint_unexpected_cfg_doc_rustc)] @@ -2368,7 +2368,7 @@ pub mod unexpected_cfg_value { } #[derive(Subdiagnostic)] - pub enum CargoHelp { + pub(crate) enum CargoHelp { #[help(lint_unexpected_cfg_value_add_feature)] AddFeature { value: Symbol, @@ -2383,7 +2383,7 @@ pub mod unexpected_cfg_value { #[diag(lint_unexpected_builtin_cfg)] #[note(lint_controlled_by)] #[note(lint_incoherent)] -pub struct UnexpectedBuiltinCfg { +pub(crate) struct UnexpectedBuiltinCfg { pub(crate) cfg: String, pub(crate) cfg_name: Symbol, pub(crate) controlled_by: &'static str, @@ -2392,15 +2392,15 @@ pub struct UnexpectedBuiltinCfg { #[derive(LintDiagnostic)] #[diag(lint_macro_use_deprecated)] #[help] -pub struct MacroUseDeprecated; +pub(crate) struct MacroUseDeprecated; #[derive(LintDiagnostic)] #[diag(lint_unused_macro_use)] -pub struct UnusedMacroUse; +pub(crate) struct UnusedMacroUse; #[derive(LintDiagnostic)] #[diag(lint_private_extern_crate_reexport, code = E0365)] -pub struct PrivateExternCrateReexport { +pub(crate) struct PrivateExternCrateReexport { pub ident: Ident, #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")] pub sugg: Span, @@ -2408,28 +2408,28 @@ pub struct PrivateExternCrateReexport { #[derive(LintDiagnostic)] #[diag(lint_unused_label)] -pub struct UnusedLabel; +pub(crate) struct UnusedLabel; #[derive(LintDiagnostic)] #[diag(lint_macro_is_private)] -pub struct MacroIsPrivate { +pub(crate) struct MacroIsPrivate { pub ident: Ident, } #[derive(LintDiagnostic)] #[diag(lint_unused_macro_definition)] -pub struct UnusedMacroDefinition { +pub(crate) struct UnusedMacroDefinition { pub name: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_macro_rule_never_used)] -pub struct MacroRuleNeverUsed { +pub(crate) struct MacroRuleNeverUsed { pub n: usize, pub name: Symbol, } -pub struct UnstableFeature { +pub(crate) struct UnstableFeature { pub msg: DiagMessage, } @@ -2441,81 +2441,81 @@ impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { #[derive(LintDiagnostic)] #[diag(lint_avoid_intel_syntax)] -pub struct AvoidIntelSyntax; +pub(crate) struct AvoidIntelSyntax; #[derive(LintDiagnostic)] #[diag(lint_avoid_att_syntax)] -pub struct AvoidAttSyntax; +pub(crate) struct AvoidAttSyntax; #[derive(LintDiagnostic)] #[diag(lint_incomplete_include)] -pub struct IncompleteInclude; +pub(crate) struct IncompleteInclude; #[derive(LintDiagnostic)] #[diag(lint_unnameable_test_items)] -pub struct UnnameableTestItems; +pub(crate) struct UnnameableTestItems; #[derive(LintDiagnostic)] #[diag(lint_duplicate_macro_attribute)] -pub struct DuplicateMacroAttribute; +pub(crate) struct DuplicateMacroAttribute; #[derive(LintDiagnostic)] #[diag(lint_cfg_attr_no_attributes)] -pub struct CfgAttrNoAttributes; +pub(crate) struct CfgAttrNoAttributes; #[derive(LintDiagnostic)] #[diag(lint_crate_type_in_cfg_attr_deprecated)] -pub struct CrateTypeInCfgAttr; +pub(crate) struct CrateTypeInCfgAttr; #[derive(LintDiagnostic)] #[diag(lint_crate_name_in_cfg_attr_deprecated)] -pub struct CrateNameInCfgAttr; +pub(crate) struct CrateNameInCfgAttr; #[derive(LintDiagnostic)] #[diag(lint_missing_fragment_specifier)] -pub struct MissingFragmentSpecifier; +pub(crate) struct MissingFragmentSpecifier; #[derive(LintDiagnostic)] #[diag(lint_metavariable_still_repeating)] -pub struct MetaVariableStillRepeating { +pub(crate) struct MetaVariableStillRepeating { pub name: MacroRulesNormalizedIdent, } #[derive(LintDiagnostic)] #[diag(lint_metavariable_wrong_operator)] -pub struct MetaVariableWrongOperator; +pub(crate) struct MetaVariableWrongOperator; #[derive(LintDiagnostic)] #[diag(lint_duplicate_matcher_binding)] -pub struct DuplicateMatcherBinding; +pub(crate) struct DuplicateMatcherBinding; #[derive(LintDiagnostic)] #[diag(lint_unknown_macro_variable)] -pub struct UnknownMacroVariable { +pub(crate) struct UnknownMacroVariable { pub name: MacroRulesNormalizedIdent, } #[derive(LintDiagnostic)] #[diag(lint_unused_crate_dependency)] #[help] -pub struct UnusedCrateDependency { +pub(crate) struct UnusedCrateDependency { pub extern_crate: Symbol, pub local_crate: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_wasm_c_abi)] -pub struct WasmCAbi; +pub(crate) struct WasmCAbi; #[derive(LintDiagnostic)] #[diag(lint_ill_formed_attribute_input)] -pub struct IllFormedAttributeInput { +pub(crate) struct IllFormedAttributeInput { pub num_suggestions: usize, pub suggestions: DiagArgValue, } #[derive(LintDiagnostic)] -pub enum InnerAttributeUnstable { +pub(crate) enum InnerAttributeUnstable { #[diag(lint_inner_macro_attribute_unstable)] InnerMacroAttribute, #[diag(lint_custom_inner_attribute_unstable)] @@ -2524,7 +2524,7 @@ pub enum InnerAttributeUnstable { #[derive(LintDiagnostic)] #[diag(lint_unknown_diagnostic_attribute)] -pub struct UnknownDiagnosticAttribute { +pub(crate) struct UnknownDiagnosticAttribute { #[subdiagnostic] pub typo: Option, } @@ -2536,7 +2536,7 @@ pub struct UnknownDiagnosticAttribute { code = "{typo_name}", applicability = "machine-applicable" )] -pub struct UnknownDiagnosticAttributeTypoSugg { +pub(crate) struct UnknownDiagnosticAttributeTypoSugg { #[primary_span] pub span: Span, pub typo_name: Symbol, @@ -2545,7 +2545,7 @@ pub struct UnknownDiagnosticAttributeTypoSugg { #[derive(LintDiagnostic)] #[diag(lint_unicode_text_flow)] #[note] -pub struct UnicodeTextFlow { +pub(crate) struct UnicodeTextFlow { #[label] pub comment_span: Span, #[subdiagnostic] @@ -2558,7 +2558,7 @@ pub struct UnicodeTextFlow { #[derive(Subdiagnostic)] #[label(lint_label_comment_char)] -pub struct UnicodeCharNoteSub { +pub(crate) struct UnicodeCharNoteSub { #[primary_span] pub span: Span, pub c_debug: String, @@ -2566,21 +2566,21 @@ pub struct UnicodeCharNoteSub { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable", style = "hidden")] -pub struct UnicodeTextFlowSuggestion { +pub(crate) struct UnicodeTextFlowSuggestion { #[suggestion_part(code = "")] pub spans: Vec, } #[derive(LintDiagnostic)] #[diag(lint_abs_path_with_module)] -pub struct AbsPathWithModule { +pub(crate) struct AbsPathWithModule { #[subdiagnostic] pub sugg: AbsPathWithModuleSugg, } #[derive(Subdiagnostic)] #[suggestion(lint_suggestion, code = "{replacement}")] -pub struct AbsPathWithModuleSugg { +pub(crate) struct AbsPathWithModuleSugg { #[primary_span] pub span: Span, #[applicability] @@ -2590,7 +2590,7 @@ pub struct AbsPathWithModuleSugg { #[derive(LintDiagnostic)] #[diag(lint_proc_macro_derive_resolution_fallback)] -pub struct ProcMacroDeriveResolutionFallback { +pub(crate) struct ProcMacroDeriveResolutionFallback { #[label] pub span: Span, pub ns: Namespace, @@ -2599,28 +2599,28 @@ pub struct ProcMacroDeriveResolutionFallback { #[derive(LintDiagnostic)] #[diag(lint_macro_expanded_macro_exports_accessed_by_absolute_paths)] -pub struct MacroExpandedMacroExportsAccessedByAbsolutePaths { +pub(crate) struct MacroExpandedMacroExportsAccessedByAbsolutePaths { #[note] pub definition: Span, } #[derive(LintDiagnostic)] #[diag(lint_hidden_lifetime_parameters)] -pub struct ElidedLifetimesInPaths { +pub(crate) struct ElidedLifetimesInPaths { #[subdiagnostic] pub subdiag: ElidedLifetimeInPathSubdiag, } #[derive(LintDiagnostic)] #[diag(lint_invalid_crate_type_value)] -pub struct UnknownCrateTypes { +pub(crate) struct UnknownCrateTypes { #[subdiagnostic] pub sugg: Option, } #[derive(Subdiagnostic)] #[suggestion(lint_suggestion, code = r#""{candidate}""#, applicability = "maybe-incorrect")] -pub struct UnknownCrateTypesSub { +pub(crate) struct UnknownCrateTypesSub { #[primary_span] pub span: Span, pub candidate: Symbol, @@ -2628,7 +2628,7 @@ pub struct UnknownCrateTypesSub { #[derive(LintDiagnostic)] #[diag(lint_unused_imports)] -pub struct UnusedImports { +pub(crate) struct UnusedImports { #[subdiagnostic] pub sugg: UnusedImportsSugg, #[help] @@ -2639,7 +2639,7 @@ pub struct UnusedImports { } #[derive(Subdiagnostic)] -pub enum UnusedImportsSugg { +pub(crate) enum UnusedImportsSugg { #[suggestion( lint_suggestion_remove_whole_use, applicability = "machine-applicable", @@ -2664,7 +2664,7 @@ pub enum UnusedImportsSugg { #[derive(LintDiagnostic)] #[diag(lint_redundant_import)] -pub struct RedundantImport { +pub(crate) struct RedundantImport { #[subdiagnostic] pub subs: Vec, @@ -2672,7 +2672,7 @@ pub struct RedundantImport { } #[derive(Subdiagnostic)] -pub enum RedundantImportSub { +pub(crate) enum RedundantImportSub { #[label(lint_label_imported_here)] ImportedHere(#[primary_span] Span), #[label(lint_label_defined_here)] @@ -2686,13 +2686,13 @@ pub enum RedundantImportSub { #[derive(LintDiagnostic)] #[diag(lint_unused_doc_comment)] #[help] -pub struct UnusedDocComment { +pub(crate) struct UnusedDocComment { #[label] pub span: Span, } #[derive(LintDiagnostic)] -pub enum PatternsInFnsWithoutBody { +pub(crate) enum PatternsInFnsWithoutBody { #[diag(lint_pattern_in_foreign)] Foreign { #[subdiagnostic] @@ -2707,7 +2707,7 @@ pub enum PatternsInFnsWithoutBody { #[derive(Subdiagnostic)] #[suggestion(lint_remove_mut_from_pattern, code = "{ident}", applicability = "machine-applicable")] -pub struct PatternsInFnsWithoutBodySub { +pub(crate) struct PatternsInFnsWithoutBodySub { #[primary_span] pub span: Span, @@ -2717,7 +2717,7 @@ pub struct PatternsInFnsWithoutBodySub { #[derive(LintDiagnostic)] #[diag(lint_extern_without_abi)] #[help] -pub struct MissingAbi { +pub(crate) struct MissingAbi { #[label] pub span: Span, @@ -2726,14 +2726,14 @@ pub struct MissingAbi { #[derive(LintDiagnostic)] #[diag(lint_legacy_derive_helpers)] -pub struct LegacyDeriveHelpers { +pub(crate) struct LegacyDeriveHelpers { #[label] pub span: Span, } #[derive(LintDiagnostic)] #[diag(lint_or_patterns_back_compat)] -pub struct OrPatternsBackCompat { +pub(crate) struct OrPatternsBackCompat { #[suggestion(code = "{suggestion}", applicability = "machine-applicable")] pub span: Span, pub suggestion: String, @@ -2741,7 +2741,7 @@ pub struct OrPatternsBackCompat { #[derive(LintDiagnostic)] #[diag(lint_reserved_prefix)] -pub struct ReservedPrefix { +pub(crate) struct ReservedPrefix { #[label] pub label: Span, #[suggestion(code = " ", applicability = "machine-applicable")] @@ -2752,7 +2752,7 @@ pub struct ReservedPrefix { #[derive(LintDiagnostic)] #[diag(lint_unused_builtin_attribute)] -pub struct UnusedBuiltinAttribute { +pub(crate) struct UnusedBuiltinAttribute { #[note] pub invoc_span: Span, @@ -2762,7 +2762,7 @@ pub struct UnusedBuiltinAttribute { #[derive(LintDiagnostic)] #[diag(lint_trailing_semi_macro)] -pub struct TrailingMacro { +pub(crate) struct TrailingMacro { #[note(lint_note1)] #[note(lint_note2)] pub is_trailing: bool, @@ -2772,14 +2772,14 @@ pub struct TrailingMacro { #[derive(LintDiagnostic)] #[diag(lint_break_with_label_and_loop)] -pub struct BreakWithLabelAndLoop { +pub(crate) struct BreakWithLabelAndLoop { #[subdiagnostic] pub sub: BreakWithLabelAndLoopSub, } #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] -pub struct BreakWithLabelAndLoopSub { +pub(crate) struct BreakWithLabelAndLoopSub { #[suggestion_part(code = "(")] pub left: Span, #[suggestion_part(code = ")")] @@ -2789,13 +2789,13 @@ pub struct BreakWithLabelAndLoopSub { #[derive(LintDiagnostic)] #[diag(lint_deprecated_where_clause_location)] #[note] -pub struct DeprecatedWhereClauseLocation { +pub(crate) struct DeprecatedWhereClauseLocation { #[subdiagnostic] pub suggestion: DeprecatedWhereClauseLocationSugg, } #[derive(Subdiagnostic)] -pub enum DeprecatedWhereClauseLocationSugg { +pub(crate) enum DeprecatedWhereClauseLocationSugg { #[multipart_suggestion(lint_suggestion_move_to_end, applicability = "machine-applicable")] MoveToEnd { #[suggestion_part(code = "")] @@ -2814,14 +2814,14 @@ pub enum DeprecatedWhereClauseLocationSugg { #[derive(LintDiagnostic)] #[diag(lint_missing_unsafe_on_extern)] -pub struct MissingUnsafeOnExtern { +pub(crate) struct MissingUnsafeOnExtern { #[suggestion(code = "unsafe ", applicability = "machine-applicable")] pub suggestion: Span, } #[derive(LintDiagnostic)] #[diag(lint_single_use_lifetime)] -pub struct SingleUseLifetime { +pub(crate) struct SingleUseLifetime { #[label(lint_label_param)] pub param_span: Span, #[label(lint_label_use)] @@ -2834,7 +2834,7 @@ pub struct SingleUseLifetime { #[derive(Subdiagnostic)] #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] -pub struct SingleUseLifetimeSugg { +pub(crate) struct SingleUseLifetimeSugg { #[suggestion_part(code = "")] pub deletion_span: Option, #[suggestion_part(code = "{replace_lt}")] @@ -2845,7 +2845,7 @@ pub struct SingleUseLifetimeSugg { #[derive(LintDiagnostic)] #[diag(lint_unused_lifetime)] -pub struct UnusedLifetime { +pub(crate) struct UnusedLifetime { #[suggestion(code = "", applicability = "machine-applicable")] pub deletion_span: Option, @@ -2854,7 +2854,7 @@ pub struct UnusedLifetime { #[derive(LintDiagnostic)] #[diag(lint_named_argument_used_positionally)] -pub struct NamedArgumentUsedPositionally { +pub(crate) struct NamedArgumentUsedPositionally { #[label(lint_label_named_arg)] pub named_arg_sp: Span, #[label(lint_label_position_arg)] @@ -2869,21 +2869,21 @@ pub struct NamedArgumentUsedPositionally { #[derive(LintDiagnostic)] #[diag(lint_byte_slice_in_packed_struct_with_derive)] #[help] -pub struct ByteSliceInPackedStructWithDerive { +pub(crate) struct ByteSliceInPackedStructWithDerive { // FIXME: make this translatable pub ty: String, } #[derive(LintDiagnostic)] #[diag(lint_unused_extern_crate)] -pub struct UnusedExternCrate { +pub(crate) struct UnusedExternCrate { #[suggestion(code = "", applicability = "machine-applicable")] pub removal_span: Span, } #[derive(LintDiagnostic)] #[diag(lint_extern_crate_not_idiomatic)] -pub struct ExternCrateNotIdiomatic { +pub(crate) struct ExternCrateNotIdiomatic { #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")] pub span: Span, @@ -2891,7 +2891,7 @@ pub struct ExternCrateNotIdiomatic { } // FIXME: make this translatable -pub struct AmbiguousGlobImports { +pub(crate) struct AmbiguousGlobImports { pub ambiguity: AmbiguityErrorDiag, } @@ -2904,7 +2904,7 @@ impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { #[derive(LintDiagnostic)] #[diag(lint_ambiguous_glob_reexport)] -pub struct AmbiguousGlobReexports { +pub(crate) struct AmbiguousGlobReexports { #[label(lint_label_first_reexport)] pub first_reexport: Span, #[label(lint_label_duplicate_reexport)] @@ -2917,7 +2917,7 @@ pub struct AmbiguousGlobReexports { #[derive(LintDiagnostic)] #[diag(lint_hidden_glob_reexport)] -pub struct HiddenGlobReexports { +pub(crate) struct HiddenGlobReexports { #[note(lint_note_glob_reexport)] pub glob_reexport: Span, #[note(lint_note_private_item)] @@ -2930,14 +2930,14 @@ pub struct HiddenGlobReexports { #[derive(LintDiagnostic)] #[diag(lint_unnecessary_qualification)] -pub struct UnusedQualifications { +pub(crate) struct UnusedQualifications { #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")] pub removal_span: Span, } #[derive(LintDiagnostic)] #[diag(lint_associated_const_elided_lifetime)] -pub struct AssociatedConstElidedLifetime { +pub(crate) struct AssociatedConstElidedLifetime { #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")] pub span: Span, @@ -2949,7 +2949,7 @@ pub struct AssociatedConstElidedLifetime { #[derive(LintDiagnostic)] #[diag(lint_redundant_import_visibility)] -pub struct RedundantImportVisibility { +pub(crate) struct RedundantImportVisibility { #[note] pub span: Span, #[help] @@ -2961,7 +2961,7 @@ pub struct RedundantImportVisibility { #[derive(LintDiagnostic)] #[diag(lint_unsafe_attr_outside_unsafe)] -pub struct UnsafeAttrOutsideUnsafe { +pub(crate) struct UnsafeAttrOutsideUnsafe { #[label] pub span: Span, #[subdiagnostic] @@ -2973,7 +2973,7 @@ pub struct UnsafeAttrOutsideUnsafe { lint_unsafe_attr_outside_unsafe_suggestion, applicability = "machine-applicable" )] -pub struct UnsafeAttrOutsideUnsafeSuggestion { +pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[suggestion_part(code = "unsafe(")] pub left: Span, #[suggestion_part(code = ")")] @@ -2983,6 +2983,6 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion { #[derive(LintDiagnostic)] #[diag(lint_out_of_scope_macro_calls)] #[help] -pub struct OutOfScopeMacroCalls { +pub(crate) struct OutOfScopeMacroCalls { pub path: String, } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 5ad677995da1c..13a3c741fe39b 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -55,7 +55,7 @@ declare_lint! { } #[derive(Default)] -pub struct NonLocalDefinitions { +pub(crate) struct NonLocalDefinitions { body_depth: u32, } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index d7fd41c0ad7a3..d81052b5e2466 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -17,13 +17,13 @@ use crate::lints::{ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; #[derive(PartialEq)] -pub enum MethodLateContext { +pub(crate) enum MethodLateContext { TraitAutoImpl, TraitImpl, PlainImpl, } -pub fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext { +pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext { let item = cx.tcx.associated_item(id); match item.container { ty::TraitContainer => MethodLateContext::TraitAutoImpl, diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index 4fe35a6a0a3bc..bb9c7d85c2efc 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -65,7 +65,7 @@ declare_lint! { } #[derive(Copy, Clone)] -pub struct ShadowedIntoIter; +pub(crate) struct ShadowedIntoIter; impl_lint_pass!(ShadowedIntoIter => [ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER]); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f1da14bb1f382..f2f7c0eaa4df8 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -165,7 +165,7 @@ declare_lint! { } #[derive(Copy, Clone)] -pub struct TypeLimits { +pub(crate) struct TypeLimits { /// Id of the last visited negated expression negated_expr_id: Option, /// Span of the last visited negated expression @@ -180,7 +180,7 @@ impl_lint_pass!(TypeLimits => [ ]); impl TypeLimits { - pub fn new() -> TypeLimits { + pub(crate) fn new() -> TypeLimits { TypeLimits { negated_expr_id: None, negated_expr_span: None } } } @@ -1008,7 +1008,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>( /// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that /// field. -pub fn transparent_newtype_field<'a, 'tcx>( +pub(crate) fn transparent_newtype_field<'a, 'tcx>( tcx: TyCtxt<'tcx>, variant: &'a ty::VariantDef, ) -> Option<&'a ty::FieldDef> { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 553d9db12c572..c3b80e01c3624 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1019,7 +1019,7 @@ declare_lint! { "`if`, `match`, `while` and `return` do not need parentheses" } -pub struct UnusedParens { +pub(crate) struct UnusedParens { with_self_ty_parens: bool, /// `1 as (i32) < 2` parses to ExprKind::Lt /// `1 as i32 < 2` parses to i32::<2[missing angle bracket] @@ -1027,7 +1027,7 @@ pub struct UnusedParens { } impl UnusedParens { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() } } } From e7f1922abdca0a155effacb26d9d16dd283a2062 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 15:25:49 +1000 Subject: [PATCH 096/102] Add `warn(unreachable_pub)` to `rustc_lint_defs`. --- compiler/rustc_lint_defs/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 0f07de43e80ed..c17b85db3b044 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,3 +1,7 @@ +// tidy-alphabetical-start +#![warn(unreachable_pub)] +// tidy-alphabetical-end + use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; From 22cdd632f1a98830ead8f03cf7f227cc72d814a8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 27 Aug 2024 15:28:26 +1000 Subject: [PATCH 097/102] Add `warn(unreachable_pub)` to `rustc_llvm`. --- compiler/rustc_llvm/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 939e5e4dbd4ff..29442655eb0ab 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -3,6 +3,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![warn(unreachable_pub)] // tidy-alphabetical-end // NOTE: This crate only exists to allow linking on mingw targets. From ab7b03e3f4126c94864bd2548660143d6bbd3d3a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2024 09:04:59 +0200 Subject: [PATCH 098/102] ABI compat check: detect unadjusted ABI mismatches --- compiler/rustc_abi/src/lib.rs | 4 +++- compiler/rustc_target/src/abi/call/mod.rs | 19 +++++++++++++++++-- compiler/rustc_target/src/spec/abi/mod.rs | 2 ++ tests/ui/abi/compatibility.rs | 7 ++++--- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ea634d7485ef7..df29b3d54f0fb 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1700,7 +1700,9 @@ impl LayoutS { /// Checks if these two `Layout` are equal enough to be considered "the same for all function /// call ABIs". Note however that real ABIs depend on more details that are not reflected in the - /// `Layout`; the `PassMode` need to be compared as well. + /// `Layout`; the `PassMode` need to be compared as well. Also note that we assume + /// aggregates are passed via `PassMode::Indirect` or `PassMode::Cast`; more strict + /// checks would otherwise be required. pub fn eq_abi(&self, other: &Self) -> bool { // The one thing that we are not capturing here is that for unsized types, the metadata must // also have the same ABI, and moreover that the same metadata leads to the same size. The diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index c1ddfcb2f9090..082c169b210f8 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -745,10 +745,25 @@ impl<'a, Ty> ArgAbi<'a, Ty> { /// Checks if these two `ArgAbi` are equal enough to be considered "the same for all /// function call ABIs". - pub fn eq_abi(&self, other: &Self) -> bool { + pub fn eq_abi(&self, other: &Self) -> bool + where + Ty: PartialEq, + { // Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look // at the type. - self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode) + self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode) && { + // `fn_arg_sanity_check` accepts `PassMode::Direct` for some aggregates. + // That elevates any type difference to an ABI difference since we just use the + // full Rust type as the LLVM argument/return type. + if matches!(self.mode, PassMode::Direct(..)) + && matches!(self.layout.abi, Abi::Aggregate { .. }) + { + // For aggregates in `Direct` mode to be compatible, the types need to be equal. + self.layout.ty == other.layout.ty + } else { + true + } + } } } diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs index 0d61345a70e41..cc383f88fbc5b 100644 --- a/compiler/rustc_target/src/spec/abi/mod.rs +++ b/compiler/rustc_target/src/spec/abi/mod.rs @@ -53,6 +53,8 @@ pub enum Abi { }, RustIntrinsic, RustCall, + /// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even + /// normally ABI-compatible Rust types can become ABI-incompatible with this ABI! Unadjusted, /// For things unlikely to be called, where reducing register pressure in /// `extern "Rust"` callers is worth paying extra cost in the callee. diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index ca78604edd866..d37e793d9892d 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -40,9 +40,10 @@ //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch //@[loongarch64] min-llvm-version: 18 -//@ revisions: wasm -//@[wasm] compile-flags: --target wasm32-unknown-unknown -//@[wasm] needs-llvm-components: webassembly +//FIXME: wasm is disabled due to . +//FIXME @ revisions: wasm +//FIXME @[wasm] compile-flags: --target wasm32-unknown-unknown +//FIXME @[wasm] needs-llvm-components: webassembly //@ revisions: wasip1 //@[wasip1] compile-flags: --target wasm32-wasip1 //@[wasip1] needs-llvm-components: webassembly From d456814842e65a153a1de67960b892897a02ed14 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 23 Jul 2024 16:10:08 +0200 Subject: [PATCH 099/102] std: move allocators to `sys` --- .../{pal/hermit/alloc.rs => alloc/hermit.rs} | 1 - .../sys/{pal/common/alloc.rs => alloc/mod.rs} | 67 ++++++++++++++----- .../sys/{pal/sgx/alloc.rs => alloc/sgx.rs} | 7 +- .../{pal/solid/alloc.rs => alloc/solid.rs} | 2 +- .../sys/{pal/uefi/alloc.rs => alloc/uefi.rs} | 2 +- .../sys/{pal/unix/alloc.rs => alloc/unix.rs} | 20 +++--- .../sys/{pal/wasm/alloc.rs => alloc/wasm.rs} | 0 .../windows/alloc.rs => alloc/windows.rs} | 15 ++--- .../windows/alloc => alloc/windows}/tests.rs | 0 .../sys/{pal/xous/alloc.rs => alloc/xous.rs} | 0 .../sys/{pal/zkvm/alloc.rs => alloc/zkvm.rs} | 2 +- library/std/src/sys/mod.rs | 1 + library/std/src/sys/pal/common/mod.rs | 1 - library/std/src/sys/pal/hermit/mod.rs | 1 - library/std/src/sys/pal/sgx/mod.rs | 1 - library/std/src/sys/pal/solid/mod.rs | 1 - library/std/src/sys/pal/teeos/alloc.rs | 57 ---------------- library/std/src/sys/pal/teeos/mod.rs | 1 - library/std/src/sys/pal/uefi/mod.rs | 4 +- library/std/src/sys/pal/unix/mod.rs | 1 - library/std/src/sys/pal/unsupported/alloc.rs | 23 ------- library/std/src/sys/pal/unsupported/mod.rs | 1 - library/std/src/sys/pal/wasi/mod.rs | 2 - library/std/src/sys/pal/wasip2/mod.rs | 2 - library/std/src/sys/pal/wasm/mod.rs | 1 - library/std/src/sys/pal/windows/mod.rs | 1 - library/std/src/sys/pal/xous/mod.rs | 1 - library/std/src/sys/pal/zkvm/mod.rs | 9 +-- 28 files changed, 78 insertions(+), 146 deletions(-) rename library/std/src/sys/{pal/hermit/alloc.rs => alloc/hermit.rs} (97%) rename library/std/src/sys/{pal/common/alloc.rs => alloc/mod.rs} (55%) rename library/std/src/sys/{pal/sgx/alloc.rs => alloc/sgx.rs} (95%) rename library/std/src/sys/{pal/solid/alloc.rs => alloc/solid.rs} (94%) rename library/std/src/sys/{pal/uefi/alloc.rs => alloc/uefi.rs} (98%) rename library/std/src/sys/{pal/unix/alloc.rs => alloc/unix.rs} (83%) rename library/std/src/sys/{pal/wasm/alloc.rs => alloc/wasm.rs} (100%) rename library/std/src/sys/{pal/windows/alloc.rs => alloc/windows.rs} (97%) rename library/std/src/sys/{pal/windows/alloc => alloc/windows}/tests.rs (100%) rename library/std/src/sys/{pal/xous/alloc.rs => alloc/xous.rs} (100%) rename library/std/src/sys/{pal/zkvm/alloc.rs => alloc/zkvm.rs} (94%) delete mode 100644 library/std/src/sys/pal/teeos/alloc.rs delete mode 100644 library/std/src/sys/pal/unsupported/alloc.rs diff --git a/library/std/src/sys/pal/hermit/alloc.rs b/library/std/src/sys/alloc/hermit.rs similarity index 97% rename from library/std/src/sys/pal/hermit/alloc.rs rename to library/std/src/sys/alloc/hermit.rs index f10d5f9227e63..77f8200a70a64 100644 --- a/library/std/src/sys/pal/hermit/alloc.rs +++ b/library/std/src/sys/alloc/hermit.rs @@ -1,4 +1,3 @@ -use super::hermit_abi; use crate::alloc::{GlobalAlloc, Layout, System}; #[stable(feature = "alloc_system_type", since = "1.28.0")] diff --git a/library/std/src/sys/pal/common/alloc.rs b/library/std/src/sys/alloc/mod.rs similarity index 55% rename from library/std/src/sys/pal/common/alloc.rs rename to library/std/src/sys/alloc/mod.rs index 1b465f95d1bc3..2c0b533a5703f 100644 --- a/library/std/src/sys/pal/common/alloc.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -1,10 +1,18 @@ #![forbid(unsafe_op_in_unsafe_fn)] + use crate::alloc::{GlobalAlloc, Layout, System}; -use crate::{cmp, ptr}; +use crate::ptr; // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. -#[cfg(any( +#[allow(dead_code)] +const MIN_ALIGN: usize = if cfg!(any( + all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")), + all(target_arch = "xtensa", target_os = "espidf"), +)) { + // The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment. + 4 +} else if cfg!(any( target_arch = "x86", target_arch = "arm", target_arch = "m68k", @@ -16,11 +24,11 @@ use crate::{cmp, ptr}; target_arch = "sparc", target_arch = "wasm32", target_arch = "hexagon", - all(target_arch = "riscv32", not(any(target_os = "espidf", target_os = "zkvm"))), - all(target_arch = "xtensa", not(target_os = "espidf")), -))] -pub const MIN_ALIGN: usize = 8; -#[cfg(any( + target_arch = "riscv32", + target_arch = "xtensa", +)) { + 8 +} else if cfg!(any( target_arch = "x86_64", target_arch = "aarch64", target_arch = "arm64ec", @@ -31,16 +39,14 @@ pub const MIN_ALIGN: usize = 8; target_arch = "sparc64", target_arch = "riscv64", target_arch = "wasm64", -))] -pub const MIN_ALIGN: usize = 16; -// The allocator on the esp-idf and zkvm platforms guarantee 4 byte alignment. -#[cfg(all(any( - all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")), - all(target_arch = "xtensa", target_os = "espidf"), -)))] -pub const MIN_ALIGN: usize = 4; +)) { + 16 +} else { + panic!("add a value for MIN_ALIGN") +}; -pub unsafe fn realloc_fallback( +#[allow(dead_code)] +unsafe fn realloc_fallback( alloc: &System, ptr: *mut u8, old_layout: Layout, @@ -52,10 +58,37 @@ pub unsafe fn realloc_fallback( let new_ptr = GlobalAlloc::alloc(alloc, new_layout); if !new_ptr.is_null() { - let size = cmp::min(old_layout.size(), new_size); + let size = usize::min(old_layout.size(), new_size); ptr::copy_nonoverlapping(ptr, new_ptr, size); GlobalAlloc::dealloc(alloc, ptr, old_layout); } + new_ptr } } + +cfg_if::cfg_if! { + if #[cfg(any( + target_family = "unix", + target_os = "wasi", + target_os = "teeos", + ))] { + mod unix; + } else if #[cfg(target_os = "windows")] { + mod windows; + } else if #[cfg(target_os = "hermit")] { + mod hermit; + } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + mod sgx; + } else if #[cfg(target_os = "solid_asp3")] { + mod solid; + } else if #[cfg(target_os = "uefi")] { + mod uefi; + } else if #[cfg(target_family = "wasm")] { + mod wasm; + } else if #[cfg(target_os = "xous")] { + mod xous; + } else if #[cfg(target_os = "zkvm")] { + mod zkvm; + } +} diff --git a/library/std/src/sys/pal/sgx/alloc.rs b/library/std/src/sys/alloc/sgx.rs similarity index 95% rename from library/std/src/sys/pal/sgx/alloc.rs rename to library/std/src/sys/alloc/sgx.rs index f68ede9fcf012..fca9d087e5bfc 100644 --- a/library/std/src/sys/pal/sgx/alloc.rs +++ b/library/std/src/sys/alloc/sgx.rs @@ -1,9 +1,8 @@ -use core::sync::atomic::{AtomicBool, Ordering}; - -use super::abi::mem as sgx_mem; -use super::waitqueue::SpinMutex; use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; +use crate::sync::atomic::{AtomicBool, Ordering}; +use crate::sys::pal::abi::mem as sgx_mem; +use crate::sys::pal::waitqueue::SpinMutex; // Using a SpinMutex because we never want to exit the enclave waiting for the // allocator. diff --git a/library/std/src/sys/pal/solid/alloc.rs b/library/std/src/sys/alloc/solid.rs similarity index 94% rename from library/std/src/sys/pal/solid/alloc.rs rename to library/std/src/sys/alloc/solid.rs index 4cf60ac9b2e23..abb534a1c5cf4 100644 --- a/library/std/src/sys/pal/solid/alloc.rs +++ b/library/std/src/sys/alloc/solid.rs @@ -1,5 +1,5 @@ +use super::{realloc_fallback, MIN_ALIGN}; use crate::alloc::{GlobalAlloc, Layout, System}; -use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { diff --git a/library/std/src/sys/pal/uefi/alloc.rs b/library/std/src/sys/alloc/uefi.rs similarity index 98% rename from library/std/src/sys/pal/uefi/alloc.rs rename to library/std/src/sys/alloc/uefi.rs index 15404ac3ea696..5221876e90866 100644 --- a/library/std/src/sys/pal/uefi/alloc.rs +++ b/library/std/src/sys/alloc/uefi.rs @@ -3,9 +3,9 @@ use r_efi::protocols::loaded_image; -use super::helpers; use crate::alloc::{GlobalAlloc, Layout, System}; use crate::sync::OnceLock; +use crate::sys::pal::helpers; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/alloc/unix.rs similarity index 83% rename from library/std/src/sys/pal/unix/alloc.rs rename to library/std/src/sys/alloc/unix.rs index 625ba5247f111..46ed7de7162f8 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/alloc/unix.rs @@ -1,6 +1,6 @@ +use super::{realloc_fallback, MIN_ALIGN}; use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; -use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { @@ -11,7 +11,7 @@ unsafe impl GlobalAlloc for System { // Also see and // . if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 + unsafe { libc::malloc(layout.size()) as *mut u8 } } else { // `posix_memalign` returns a non-aligned value if supplied a very // large alignment on older versions of Apple's platforms (unknown @@ -25,7 +25,7 @@ unsafe impl GlobalAlloc for System { return ptr::null_mut(); } } - aligned_malloc(&layout) + unsafe { aligned_malloc(&layout) } } } @@ -33,11 +33,11 @@ unsafe impl GlobalAlloc for System { unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { // See the comment above in `alloc` for why this check looks the way it does. if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut u8 + unsafe { libc::calloc(layout.size(), 1) as *mut u8 } } else { - let ptr = self.alloc(layout); + let ptr = unsafe { self.alloc(layout) }; if !ptr.is_null() { - ptr::write_bytes(ptr, 0, layout.size()); + unsafe { ptr::write_bytes(ptr, 0, layout.size()) }; } ptr } @@ -45,15 +45,15 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - libc::free(ptr as *mut libc::c_void) + unsafe { libc::free(ptr as *mut libc::c_void) } } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } } else { - realloc_fallback(self, ptr, layout, new_size) + unsafe { realloc_fallback(self, ptr, layout, new_size) } } } } @@ -81,7 +81,7 @@ cfg_if::cfg_if! { // posix_memalign only has one, clear requirement: that the alignment be a multiple of // `sizeof(void*)`. Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::()); - let ret = libc::posix_memalign(&mut out, align, layout.size()); + let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; if ret != 0 { ptr::null_mut() } else { out as *mut u8 } } } diff --git a/library/std/src/sys/pal/wasm/alloc.rs b/library/std/src/sys/alloc/wasm.rs similarity index 100% rename from library/std/src/sys/pal/wasm/alloc.rs rename to library/std/src/sys/alloc/wasm.rs diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/alloc/windows.rs similarity index 97% rename from library/std/src/sys/pal/windows/alloc.rs rename to library/std/src/sys/alloc/windows.rs index 2205885687dea..e91956966aa73 100644 --- a/library/std/src/sys/pal/windows/alloc.rs +++ b/library/std/src/sys/alloc/windows.rs @@ -1,11 +1,10 @@ -use core::mem::MaybeUninit; - +use super::{realloc_fallback, MIN_ALIGN}; use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ffi::c_void; +use crate::mem::MaybeUninit; use crate::ptr; use crate::sync::atomic::{AtomicPtr, Ordering}; use crate::sys::c; -use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; #[cfg(test)] mod tests; @@ -113,28 +112,28 @@ fn init_or_get_process_heap() -> c::HANDLE { extern "C" fn process_heap_init_and_alloc( _heap: MaybeUninit, // We pass this argument to match the ABI of `HeapAlloc` flags: u32, - dwBytes: usize, + bytes: usize, ) -> *mut c_void { let heap = init_or_get_process_heap(); if core::intrinsics::unlikely(heap.is_null()) { return ptr::null_mut(); } // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. - unsafe { HeapAlloc(heap, flags, dwBytes) } + unsafe { HeapAlloc(heap, flags, bytes) } } #[inline(never)] fn process_heap_alloc( _heap: MaybeUninit, // We pass this argument to match the ABI of `HeapAlloc`, flags: u32, - dwBytes: usize, + bytes: usize, ) -> *mut c_void { let heap = HEAP.load(Ordering::Relaxed); if core::intrinsics::likely(!heap.is_null()) { // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. - unsafe { HeapAlloc(heap, flags, dwBytes) } + unsafe { HeapAlloc(heap, flags, bytes) } } else { - process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes) + process_heap_init_and_alloc(MaybeUninit::uninit(), flags, bytes) } } diff --git a/library/std/src/sys/pal/windows/alloc/tests.rs b/library/std/src/sys/alloc/windows/tests.rs similarity index 100% rename from library/std/src/sys/pal/windows/alloc/tests.rs rename to library/std/src/sys/alloc/windows/tests.rs diff --git a/library/std/src/sys/pal/xous/alloc.rs b/library/std/src/sys/alloc/xous.rs similarity index 100% rename from library/std/src/sys/pal/xous/alloc.rs rename to library/std/src/sys/alloc/xous.rs diff --git a/library/std/src/sys/pal/zkvm/alloc.rs b/library/std/src/sys/alloc/zkvm.rs similarity index 94% rename from library/std/src/sys/pal/zkvm/alloc.rs rename to library/std/src/sys/alloc/zkvm.rs index 2fdca22352470..a600cfa2220dd 100644 --- a/library/std/src/sys/pal/zkvm/alloc.rs +++ b/library/std/src/sys/alloc/zkvm.rs @@ -1,5 +1,5 @@ -use super::abi; use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::sys::pal::abi; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index a86b3628f249a..1ef17dd530fd2 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -5,6 +5,7 @@ /// descriptors. mod pal; +mod alloc; mod personality; pub mod anonymous_pipe; diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs index 29fc0835d7666..9af4dee401cf3 100644 --- a/library/std/src/sys/pal/common/mod.rs +++ b/library/std/src/sys/pal/common/mod.rs @@ -10,7 +10,6 @@ #![allow(dead_code)] -pub mod alloc; pub mod small_c_string; #[cfg(test)] diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index ef406b9ec7f0d..1f2e5d9469f5c 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -18,7 +18,6 @@ use crate::os::raw::c_char; -pub mod alloc; pub mod args; pub mod env; pub mod fd; diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 851ab9b9f9767..8d29b2ec6193e 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -9,7 +9,6 @@ use crate::io::ErrorKind; use crate::sync::atomic::{AtomicBool, Ordering}; pub mod abi; -pub mod alloc; pub mod args; pub mod env; pub mod fd; diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index cbf34286878fe..6ebcf5b7c48c8 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -16,7 +16,6 @@ pub mod itron { use super::unsupported; } -pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; pub mod env; diff --git a/library/std/src/sys/pal/teeos/alloc.rs b/library/std/src/sys/pal/teeos/alloc.rs deleted file mode 100644 index b280d1dd76f7a..0000000000000 --- a/library/std/src/sys/pal/teeos/alloc.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::alloc::{GlobalAlloc, Layout, System}; -use crate::ptr; -use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; - -#[stable(feature = "alloc_system_type", since = "1.28.0")] -unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - // jemalloc provides alignment less than MIN_ALIGN for small allocations. - // So only rely on MIN_ALIGN if size >= align. - // Also see and - // . - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - unsafe { libc::malloc(layout.size()) as *mut u8 } - } else { - unsafe { aligned_malloc(&layout) } - } - } - - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - // See the comment above in `alloc` for why this check looks the way it does. - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - unsafe { libc::calloc(layout.size(), 1) as *mut u8 } - } else { - let ptr = unsafe { self.alloc(layout) }; - if !ptr.is_null() { - unsafe { ptr::write_bytes(ptr, 0, layout.size()) }; - } - ptr - } - } - - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - unsafe { libc::free(ptr as *mut libc::c_void) } - } - - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } - } else { - unsafe { realloc_fallback(self, ptr, layout, new_size) } - } - } -} - -#[inline] -unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - let mut out = ptr::null_mut(); - // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. - // Since these are all powers of 2, we can just use max. - let align = layout.align().max(crate::mem::size_of::()); - let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; - if ret != 0 { ptr::null_mut() } else { out as *mut u8 } -} diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index adefd1bb42c8d..00e3860424006 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -8,7 +8,6 @@ pub use self::rand::hashmap_random_keys; -pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; #[path = "../unsupported/env.rs"] diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 851bcea4c1e43..ac22f4ded8855 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -13,11 +13,11 @@ //! [`OsString`]: crate::ffi::OsString #![forbid(unsafe_op_in_unsafe_fn)] -pub mod alloc; pub mod args; pub mod env; #[path = "../unsupported/fs.rs"] pub mod fs; +pub mod helpers; #[path = "../unsupported/io.rs"] pub mod io; #[path = "../unsupported/net.rs"] @@ -30,8 +30,6 @@ pub mod stdio; pub mod thread; pub mod time; -mod helpers; - #[cfg(test)] mod tests; diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 10df3306f9251..ba2f58f9c10bd 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -7,7 +7,6 @@ use crate::io::ErrorKind; #[macro_use] pub mod weak; -pub mod alloc; pub mod args; pub mod env; pub mod fd; diff --git a/library/std/src/sys/pal/unsupported/alloc.rs b/library/std/src/sys/pal/unsupported/alloc.rs deleted file mode 100644 index d715ae45401e6..0000000000000 --- a/library/std/src/sys/pal/unsupported/alloc.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::alloc::{GlobalAlloc, Layout, System}; -use crate::ptr::null_mut; - -#[stable(feature = "alloc_system_type", since = "1.28.0")] -unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { - null_mut() - } - - #[inline] - unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 { - null_mut() - } - - #[inline] - unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} - - #[inline] - unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 { - null_mut() - } -} diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index 442e6042ad561..01d516f7568bf 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -1,6 +1,5 @@ #![deny(unsafe_op_in_unsafe_fn)] -pub mod alloc; pub mod args; pub mod env; pub mod fs; diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index f4dc3ebd4140b..8051021a58897 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -14,8 +14,6 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -#[path = "../unix/alloc.rs"] -pub mod alloc; pub mod args; pub mod env; pub mod fd; diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index f20630e10cff9..546fadbe5011c 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -6,8 +6,6 @@ //! To begin with, this target mirrors the wasi target 1 to 1, but over //! time this will change significantly. -#[path = "../unix/alloc.rs"] -pub mod alloc; #[path = "../wasi/args.rs"] pub mod args; #[path = "../wasi/env.rs"] diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 4c34859e918bb..8141bfac49aad 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -16,7 +16,6 @@ #![deny(unsafe_op_in_unsafe_fn)] -pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; pub mod env; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 6ed77fbc3d445..272fadd915005 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -15,7 +15,6 @@ pub mod compat; mod api; -pub mod alloc; pub mod args; pub mod c; pub mod env; diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 961d45c5e834f..b211e94db65d6 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -1,6 +1,5 @@ #![forbid(unsafe_op_in_unsafe_fn)] -pub mod alloc; #[path = "../unsupported/args.rs"] pub mod args; #[path = "../unsupported/env.rs"] diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 651f25d66236b..20fdb7468a40d 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -10,7 +10,7 @@ const WORD_SIZE: usize = core::mem::size_of::(); -pub mod alloc; +pub mod abi; #[path = "../zkvm/args.rs"] pub mod args; pub mod env; @@ -26,13 +26,10 @@ pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; pub mod stdio; -#[path = "../unsupported/time.rs"] -pub mod time; - #[path = "../unsupported/thread.rs"] pub mod thread; - -mod abi; +#[path = "../unsupported/time.rs"] +pub mod time; use crate::io as std_io; From e9566ce9e92df5fbdf87260cef7f3aa8d096e1bd Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 24 Jul 2024 15:36:26 +0200 Subject: [PATCH 100/102] bless miri test --- src/tools/miri/tests/fail/alloc/global_system_mixup.rs | 4 +++- src/tools/miri/tests/fail/alloc/global_system_mixup.stderr | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs index 804aa13660b99..bbf069b7a2def 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs @@ -4,7 +4,9 @@ //@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation" //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^}]*\};" -> "FREE();" +//@normalize-stderr-test: "unsafe \{ libc::free\([^()]*\) \}|unsafe \{ HeapFree\([^}]*\};" -> "FREE();" +//@normalize-stderr-test: "alloc::[A-Za-z]+::" -> "alloc::PLATFORM::" +//@normalize-stderr-test: "alloc/[A-Za-z]+.rs" -> "alloc/PLATFORM.rs" #![feature(allocator_api, slice_ptr_get)] diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr index 7790956414961..287a1f1a3e396 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation - --> RUSTLIB/std/src/sys/pal/PLATFORM/alloc.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC | LL | FREE(); | ^ deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation @@ -7,7 +7,7 @@ LL | FREE(); = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::alloc::::dealloc` at RUSTLIB/std/src/sys/pal/PLATFORM/alloc.rs:LL:CC + = note: inside `std::sys::alloc::PLATFORM::::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC = note: inside `::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC note: inside `main` --> $DIR/global_system_mixup.rs:LL:CC From ab4a743a38d4f466d16d97fde14604b242a37020 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 27 Aug 2024 11:08:09 +0200 Subject: [PATCH 101/102] fix Pointer to reference conversion docs --- library/core/src/ptr/mod.rs | 38 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 859fad9e069ca..d7ed4edcc0041 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -57,50 +57,42 @@ //! [`NonNull::dangling`] in such cases. //! //! ## Pointer to reference conversion -//! When converting a pointer to a reference `&T` using `&*`, +//! +//! When converting a pointer to a reference (e.g. via `&*ptr` or `&mut *ptr`), //! there are several rules that must be followed: //! //! * The pointer must be properly aligned. //! -// some microprocessors may use address 0 for an interrupt vector. -// users of these microprocessors must always read/write address 0 through -// a raw pointer, not a reference. //! * It must be non-null. //! //! * It must be "dereferenceable" in the sense defined above. //! -//! * The pointer must point to a valid value of type `T`. -//! This means that the created reference can only refer to -//! uninitialized memory through careful use of `MaybeUninit`, -//! or if the uninitialized memory is entirely contained within -//! padding bytes, since -//! [padding has the same validity invariant as `MaybeUninit`][ucg-pad]. -//! -//! * You must enforce Rust's aliasing rules, since the lifetime of the -//! created reference is arbitrarily chosen, -//! and does not necessarily reflect the actual lifetime of the data. -//! In particular, while this reference exists, -//! the memory the pointer points to must -//! not get accessed (read or written) through any raw pointer, -//! except for data inside an `UnsafeCell`. -//! Note that aliased writes are always UB for mutable references, -//! even if they only modify `UnsafeCell` data. +//! * The pointer must point to a [valid value] of type `T`. +//! +//! * You must enforce Rust's aliasing rules. The exact aliasing rules are not decided yet, so we +//! only give a rough overview here. The rules also depend on whether a mutable or a shared +//! reference is being created. +//! * When creating a mutable reference, then while this reference exists, the memory it points to +//! must not get accessed (read or written) through any other pointer or reference not derived +//! from this reference. +//! * When creating a shared reference, then while this reference exists, the memory it points to +//! must not get mutated (except inside `UnsafeCell`). //! //! If a pointer follows all of these rules, it is said to be -//! *convertible to a reference*. +//! *convertible to a (mutable or shared) reference*. // ^ we use this term instead of saying that the produced reference must // be valid, as the validity of a reference is easily confused for the // validity of the thing it refers to, and while the two concepts are // closly related, they are not identical. //! -//! These apply even if the result is unused! +//! These rules apply even if the result is unused! //! (The part about being initialized is not yet fully decided, but until //! it is, the only safe approach is to ensure that they are indeed initialized.) //! //! An example of the implications of the above rules is that an expression such //! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior. //! -//! [ucgpad]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#padding +//! [valid value]: ../../reference/behavior-considered-undefined.html#invalid-values //! //! ## Allocated object //! From 0589dc75d314152de3ddf095ff2fc774c4a2d9c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Aug 2024 12:06:28 +0200 Subject: [PATCH 102/102] copysign with sign being a NaN is non-portable --- library/std/src/f128.rs | 11 ++++++++--- library/std/src/f16.rs | 11 ++++++++--- library/std/src/f32.rs | 11 ++++++++--- library/std/src/f64.rs | 11 ++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 506d708d0d2eb..b436fe9929c36 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -250,9 +250,14 @@ impl f128 { /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations - /// is not generally guaranteed. See [specification of NaN bit - /// patterns](primitive@f32#nan-bit-patterns) for more info. + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. /// /// # Examples /// diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index 033a3d4500932..b2cd5fae9d04a 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -249,9 +249,14 @@ impl f16 { /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations - /// is not generally guaranteed. See [specification of NaN bit - /// patterns](primitive@f32#nan-bit-patterns) for more info. + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. /// /// # Examples /// diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 35c2a77b5338d..cafbe9761da19 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -228,9 +228,14 @@ impl f32 { /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations - /// is not generally guaranteed. See [specification of NaN bit - /// patterns](primitive@f32#nan-bit-patterns) for more info. + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. /// /// # Examples /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index c177f74a97e15..fba283e3a44bc 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -228,9 +228,14 @@ impl f64 { /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations - /// is not generally guaranteed. See [specification of NaN bit - /// patterns](primitive@f32#nan-bit-patterns) for more info. + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. /// /// # Examples ///