From 6360287fd91c5d02597b45ef65c34388af348638 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 11 Aug 2024 09:07:52 +0100 Subject: [PATCH 01/24] Fix #128930: Print documentation of CLI options missing their arg --- compiler/rustc_driver_impl/src/lib.rs | 17 +++++++++++++++-- compiler/rustc_session/src/config.rs | 2 +- .../invalid-compile-flags/print-without-arg.rs | 1 + .../print-without-arg.stderr | 5 +++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/ui/invalid-compile-flags/print-without-arg.rs create mode 100644 tests/ui/invalid-compile-flags/print-without-arg.stderr diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 627a0ebb4e5e3..fa1b8e7c83497 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1221,17 +1221,30 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option = match e { getopts::Fail::UnrecognizedOption(ref opt) => CG_OPTIONS .iter() .map(|&(name, ..)| ('C', name)) .chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name))) .find(|&(_, name)| *opt == name.replace('_', "-")) .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")), + getopts::Fail::ArgumentMissing(ref opt) => { + optgroups.iter().find(|option| option.name == opt).map(|option| { + // Print the help just for the option in question. + let mut options = getopts::Options::new(); + (option.apply)(&mut options); + // getopt requires us to pass a function for joining an iterator of + // strings, even though in this case we expect exactly one string. + options.usage_with_format(|it| { + it.fold(format!("{e}\nUsage:"), |a, b| a + "\n" + &b) + }) + }) + } _ => None, }; early_dcx.early_fatal(msg.unwrap_or_else(|| e.to_string())); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f58a991a616da..6699fd8332ba0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1349,7 +1349,7 @@ enum OptionStability { pub struct RustcOptGroup { pub apply: Box &mut getopts::Options>, - name: &'static str, + pub name: &'static str, stability: OptionStability, } diff --git a/tests/ui/invalid-compile-flags/print-without-arg.rs b/tests/ui/invalid-compile-flags/print-without-arg.rs new file mode 100644 index 0000000000000..a762cb22275ee --- /dev/null +++ b/tests/ui/invalid-compile-flags/print-without-arg.rs @@ -0,0 +1 @@ +//@ compile-flags: --print diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr new file mode 100644 index 0000000000000..a18d2779cade9 --- /dev/null +++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr @@ -0,0 +1,5 @@ +error: Argument to option 'print' missing + Usage: + --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target] + Compiler information to print on stdout + From ae75a9b33aef4bdd03f33bc75bdf44fe3a48356d Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 11 Aug 2024 09:58:11 +0100 Subject: [PATCH 02/24] Update expectations --- tests/ui/compiletest-self-test/compile-flags-last.stderr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui/compiletest-self-test/compile-flags-last.stderr b/tests/ui/compiletest-self-test/compile-flags-last.stderr index d8d40a7d9f112..72d92206e2bb4 100644 --- a/tests/ui/compiletest-self-test/compile-flags-last.stderr +++ b/tests/ui/compiletest-self-test/compile-flags-last.stderr @@ -1,2 +1,5 @@ error: Argument to option 'cap-lints' missing + Usage: + --cap-lints LEVEL Set the most restrictive lint level. More restrictive + lints are capped at this level From 13e36cf8870a88ab0ac5651d9513b13085baa8cc Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Tue, 27 Aug 2024 18:06:00 -0700 Subject: [PATCH 03/24] add new_cyclic_in for rc --- library/alloc/src/rc.rs | 60 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f153aa6d3be9a..151eec532613c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -687,6 +687,54 @@ impl Rc { } } + /// TODO: document + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc + where + F: FnOnce(&Weak) -> T, + { + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let uninit_ptr: NonNull<_> = Box::leak( + Box::new_in(RcBox { + strong: Cell::new(0), + weak: Cell::new(1), + value: mem::MaybeUninit::::uninit(), + }), + alloc, + ) + .into(); + + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc: Global }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + let strong = unsafe { + let inner = init_ptr.as_ptr(); + ptr::write(ptr::addr_of_mut!((*inner).value), data); + + let prev_value = (*inner).strong.get(); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + (*inner).strong.set(1); + + Rc::from_inner(init_ptr) + }; + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + mem::forget(weak); + strong + } + /// Constructs a new `Rc` with uninitialized contents in the provided allocator. /// /// # Examples @@ -1662,7 +1710,11 @@ impl Rc { #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { - if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None } + if Rc::is_unique(this) { + unsafe { Some(Rc::get_mut_unchecked(this)) } + } else { + None + } } /// Returns a mutable reference into the given `Rc`, @@ -3239,7 +3291,11 @@ impl Weak { #[must_use] #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { inner.strong() } else { 0 } + if let Some(inner) = self.inner() { + inner.strong() + } else { + 0 + } } /// Gets the number of `Weak` pointers pointing to this allocation. From 21cb84763cf942dc2fa70d582cf2b8ba50163750 Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Thu, 29 Aug 2024 12:32:33 -0700 Subject: [PATCH 04/24] fix fmt --- library/alloc/src/rc.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 151eec532613c..0afb138db8ada 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1710,11 +1710,7 @@ impl Rc { #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { - if Rc::is_unique(this) { - unsafe { Some(Rc::get_mut_unchecked(this)) } - } else { - None - } + if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None } } /// Returns a mutable reference into the given `Rc`, @@ -3291,11 +3287,7 @@ impl Weak { #[must_use] #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { - inner.strong() - } else { - 0 - } + if let Some(inner) = self.inner() { inner.strong() } else { 0 } } /// Gets the number of `Weak` pointers pointing to this allocation. From 4abb8e2d0d1821a98e77109dae4001a613229074 Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Thu, 29 Aug 2024 13:26:39 -0700 Subject: [PATCH 05/24] fix new_cyclic_in for rc --- library/alloc/src/rc.rs | 127 +++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 48 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0afb138db8ada..726c0f2de9f25 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -687,54 +687,6 @@ impl Rc { } } - /// TODO: document - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_api", issue = "32838")] - pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc - where - F: FnOnce(&Weak) -> T, - { - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let uninit_ptr: NonNull<_> = Box::leak( - Box::new_in(RcBox { - strong: Cell::new(0), - weak: Cell::new(1), - value: mem::MaybeUninit::::uninit(), - }), - alloc, - ) - .into(); - - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc: Global }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - let strong = unsafe { - let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).value), data); - - let prev_value = (*inner).strong.get(); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - (*inner).strong.set(1); - - Rc::from_inner(init_ptr) - }; - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - mem::forget(weak); - strong - } - /// Constructs a new `Rc` with uninitialized contents in the provided allocator. /// /// # Examples @@ -2312,6 +2264,85 @@ impl Clone for Rc { } } +impl Rc { + /// Constructs a new `Rc` in the given allocator while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Rc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic` first allocates the managed allocation for the `Rc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Rc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Rc` is not fully-constructed until `Rc::new_cyclic` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Examples + /// See [`new_cyclic`]. + /// + /// [`new_cyclic`]: Rc::new_cyclic + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc + where + F: FnOnce(&Weak) -> T, + { + // Note: comments and implementation are copied from Rc::new_cyclic. + + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let uninit_ptr: NonNull<_> = Box::leak(Box::new_in( + RcBox { + strong: Cell::new(0), + weak: Cell::new(1), + value: mem::MaybeUninit::::uninit(), + }, + alloc.clone(), + )) + .into(); + + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc: alloc.clone() }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + let strong = unsafe { + let inner = init_ptr.as_ptr(); + ptr::write(ptr::addr_of_mut!((*inner).value), data); + + let prev_value = (*inner).strong.get(); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + (*inner).strong.set(1); + + Rc::from_inner_in(init_ptr, alloc) + }; + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + mem::forget(weak); + strong + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Rc { From 2383cc991020b9dd678074072fcd3ed4f459eb6c Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Thu, 29 Aug 2024 13:41:37 -0700 Subject: [PATCH 06/24] improve comments --- library/alloc/src/rc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 726c0f2de9f25..f6d4174f5ebb5 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2279,7 +2279,7 @@ impl Rc { /// and only afterwards completes the construction of the `Rc` by placing /// the `T` returned from your closure into the allocation. /// - /// Since the new `Rc` is not fully-constructed until `Rc::new_cyclic` + /// Since the new `Rc` is not fully-constructed until `Rc::new_cyclic_in` /// returns, calling [`upgrade`] on the weak reference inside your closure will /// fail and result in a `None` value. /// @@ -2289,6 +2289,7 @@ impl Rc { /// temporary [`Weak`] is dropped normally. /// /// # Examples + /// /// See [`new_cyclic`]. /// /// [`new_cyclic`]: Rc::new_cyclic From 68169d3103dca63330b7e3e0e03f41b43b3b0490 Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Thu, 29 Aug 2024 13:41:57 -0700 Subject: [PATCH 07/24] add new_cyclic_in for Arc --- library/alloc/src/sync.rs | 93 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4a3522f1a641b..f808f3313297b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1322,6 +1322,99 @@ impl Arc<[mem::MaybeUninit], A> { } } +impl Arc { + /// Constructs a new `Arc` in the given allocator while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Arc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic` first allocates the managed allocation for the `Arc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Arc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic_in` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Example + /// + /// See [`new_cyclic`] + /// + /// [`new_cyclic`]: Arc::new_cyclic + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "arc_new_cyclic", since = "1.60.0")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc + where + F: FnOnce(&Weak) -> T, + { + // Note: these comments and much of the implementation is copied from Arc::new_cyclic. + + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let uninit_ptr: NonNull<_> = Box::leak(Box::new_in( + ArcInner { + strong: atomic::AtomicUsize::new(0), + weak: atomic::AtomicUsize::new(1), + data: mem::MaybeUninit::::uninit(), + }, + alloc.clone(), + )) + .into(); + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc: alloc.clone() }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + // Now we can properly initialize the inner value and turn our weak + // reference into a strong reference. + let strong = unsafe { + let inner = init_ptr.as_ptr(); + ptr::write(ptr::addr_of_mut!((*inner).data), data); + + // The above write to the data field must be visible to any threads which + // observe a non-zero strong count. Therefore we need at least "Release" ordering + // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. + // + // "Acquire" ordering is not required. When considering the possible behaviours + // of `data_fn` we only need to look at what it could do with a reference to a + // non-upgradeable `Weak`: + // - It can *clone* the `Weak`, increasing the weak reference count. + // - It can drop those clones, decreasing the weak reference count (but never to zero). + // + // These side effects do not impact us in any way, and no other side effects are + // possible with safe code alone. + let prev_value = (*inner).strong.fetch_add(1, Release); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + + Arc::from_inner_in(init_ptr, alloc) + }; + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + mem::forget(weak); + strong + } +} + impl Arc { /// Constructs an `Arc` from a raw pointer. /// From 97df334d5fd97725ffc2836c80a9bfae501085d1 Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Fri, 6 Sep 2024 14:24:25 -0700 Subject: [PATCH 08/24] remove the Clone requirement --- library/alloc/src/rc.rs | 158 ++++++++++++++++---------------- library/alloc/src/sync.rs | 185 +++++++++++++++++++------------------- 2 files changed, 170 insertions(+), 173 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f6d4174f5ebb5..664bc5ffc3441 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -766,6 +766,84 @@ impl Rc { } } + /// Constructs a new `Rc` in the given allocator while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Rc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic_in` first allocates the managed allocation for the `Rc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Rc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Rc` is not fully-constructed until `Rc::new_cyclic_in` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Examples + /// + /// See [`new_cyclic`]. + /// + /// [`new_cyclic`]: Rc::new_cyclic + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc + where + F: FnOnce(&Weak) -> T, + { + // Note: comments and implementation are copied from Rc::new_cyclic. + + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in( + RcBox { + strong: Cell::new(0), + weak: Cell::new(1), + value: mem::MaybeUninit::::uninit(), + }, + alloc, + )); + let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc: alloc }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + let strong = unsafe { + let inner = init_ptr.as_ptr(); + ptr::write(ptr::addr_of_mut!((*inner).value), data); + + let prev_value = (*inner).strong.get(); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + (*inner).strong.set(1); + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + let alloc = weak.into_raw_with_allocator().1; + + Rc::from_inner_in(init_ptr, alloc) + }; + + strong + } + /// Constructs a new `Rc` in the provided allocator, returning an error if the allocation /// fails /// @@ -2264,86 +2342,6 @@ impl Clone for Rc { } } -impl Rc { - /// Constructs a new `Rc` in the given allocator while giving you a `Weak` to the allocation, - /// to allow you to construct a `T` which holds a weak pointer to itself. - /// - /// Generally, a structure circularly referencing itself, either directly or - /// indirectly, should not hold a strong reference to itself to prevent a memory leak. - /// Using this function, you get access to the weak pointer during the - /// initialization of `T`, before the `Rc` is created, such that you can - /// clone and store it inside the `T`. - /// - /// `new_cyclic` first allocates the managed allocation for the `Rc`, - /// then calls your closure, giving it a `Weak` to this allocation, - /// and only afterwards completes the construction of the `Rc` by placing - /// the `T` returned from your closure into the allocation. - /// - /// Since the new `Rc` is not fully-constructed until `Rc::new_cyclic_in` - /// returns, calling [`upgrade`] on the weak reference inside your closure will - /// fail and result in a `None` value. - /// - /// # Panics - /// - /// If `data_fn` panics, the panic is propagated to the caller, and the - /// temporary [`Weak`] is dropped normally. - /// - /// # Examples - /// - /// See [`new_cyclic`]. - /// - /// [`new_cyclic`]: Rc::new_cyclic - /// [`upgrade`]: Weak::upgrade - #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_api", issue = "32838")] - pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc - where - F: FnOnce(&Weak) -> T, - { - // Note: comments and implementation are copied from Rc::new_cyclic. - - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let uninit_ptr: NonNull<_> = Box::leak(Box::new_in( - RcBox { - strong: Cell::new(0), - weak: Cell::new(1), - value: mem::MaybeUninit::::uninit(), - }, - alloc.clone(), - )) - .into(); - - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc: alloc.clone() }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - let strong = unsafe { - let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).value), data); - - let prev_value = (*inner).strong.get(); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - (*inner).strong.set(1); - - Rc::from_inner_in(init_ptr, alloc) - }; - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - mem::forget(weak); - strong - } -} - #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Rc { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index f808f3313297b..4f8039fd1f8b8 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -785,6 +785,98 @@ impl Arc { } } + /// Constructs a new `Arc` in the given allocator while giving you a `Weak` to the allocation, + /// to allow you to construct a `T` which holds a weak pointer to itself. + /// + /// Generally, a structure circularly referencing itself, either directly or + /// indirectly, should not hold a strong reference to itself to prevent a memory leak. + /// Using this function, you get access to the weak pointer during the + /// initialization of `T`, before the `Arc` is created, such that you can + /// clone and store it inside the `T`. + /// + /// `new_cyclic_in` first allocates the managed allocation for the `Arc`, + /// then calls your closure, giving it a `Weak` to this allocation, + /// and only afterwards completes the construction of the `Arc` by placing + /// the `T` returned from your closure into the allocation. + /// + /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic_in` + /// returns, calling [`upgrade`] on the weak reference inside your closure will + /// fail and result in a `None` value. + /// + /// # Panics + /// + /// If `data_fn` panics, the panic is propagated to the caller, and the + /// temporary [`Weak`] is dropped normally. + /// + /// # Example + /// + /// See [`new_cyclic`] + /// + /// [`new_cyclic`]: Arc::new_cyclic + /// [`upgrade`]: Weak::upgrade + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "arc_new_cyclic", since = "1.60.0")] + pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc + where + F: FnOnce(&Weak) -> T, + { + // Note: these comments and much of the implementation is copied from Arc::new_cyclic. + + // Construct the inner in the "uninitialized" state with a single + // weak reference. + let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in( + ArcInner { + strong: atomic::AtomicUsize::new(0), + weak: atomic::AtomicUsize::new(1), + data: mem::MaybeUninit::::uninit(), + }, + alloc, + )); + let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); + let init_ptr: NonNull> = uninit_ptr.cast(); + + let weak = Weak { ptr: init_ptr, alloc: alloc }; + + // It's important we don't give up ownership of the weak pointer, or + // else the memory might be freed by the time `data_fn` returns. If + // we really wanted to pass ownership, we could create an additional + // weak pointer for ourselves, but this would result in additional + // updates to the weak reference count which might not be necessary + // otherwise. + let data = data_fn(&weak); + + // Now we can properly initialize the inner value and turn our weak + // reference into a strong reference. + let strong = unsafe { + let inner = init_ptr.as_ptr(); + ptr::write(ptr::addr_of_mut!((*inner).data), data); + + // The above write to the data field must be visible to any threads which + // observe a non-zero strong count. Therefore we need at least "Release" ordering + // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. + // + // "Acquire" ordering is not required. When considering the possible behaviours + // of `data_fn` we only need to look at what it could do with a reference to a + // non-upgradeable `Weak`: + // - It can *clone* the `Weak`, increasing the weak reference count. + // - It can drop those clones, decreasing the weak reference count (but never to zero). + // + // These side effects do not impact us in any way, and no other side effects are + // possible with safe code alone. + let prev_value = (*inner).strong.fetch_add(1, Release); + debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); + + // Strong references should collectively own a shared weak reference, + // so don't run the destructor for our old weak reference. + let alloc = weak.into_raw_with_allocator().1; + + Arc::from_inner_in(init_ptr, alloc) + }; + + strong + } + /// Constructs a new `Pin>` in the provided allocator. If `T` does not implement `Unpin`, /// then `data` will be pinned in memory and unable to be moved. #[cfg(not(no_global_oom_handling))] @@ -1322,99 +1414,6 @@ impl Arc<[mem::MaybeUninit], A> { } } -impl Arc { - /// Constructs a new `Arc` in the given allocator while giving you a `Weak` to the allocation, - /// to allow you to construct a `T` which holds a weak pointer to itself. - /// - /// Generally, a structure circularly referencing itself, either directly or - /// indirectly, should not hold a strong reference to itself to prevent a memory leak. - /// Using this function, you get access to the weak pointer during the - /// initialization of `T`, before the `Arc` is created, such that you can - /// clone and store it inside the `T`. - /// - /// `new_cyclic` first allocates the managed allocation for the `Arc`, - /// then calls your closure, giving it a `Weak` to this allocation, - /// and only afterwards completes the construction of the `Arc` by placing - /// the `T` returned from your closure into the allocation. - /// - /// Since the new `Arc` is not fully-constructed until `Arc::new_cyclic_in` - /// returns, calling [`upgrade`] on the weak reference inside your closure will - /// fail and result in a `None` value. - /// - /// # Panics - /// - /// If `data_fn` panics, the panic is propagated to the caller, and the - /// temporary [`Weak`] is dropped normally. - /// - /// # Example - /// - /// See [`new_cyclic`] - /// - /// [`new_cyclic`]: Arc::new_cyclic - /// [`upgrade`]: Weak::upgrade - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "arc_new_cyclic", since = "1.60.0")] - pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc - where - F: FnOnce(&Weak) -> T, - { - // Note: these comments and much of the implementation is copied from Arc::new_cyclic. - - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let uninit_ptr: NonNull<_> = Box::leak(Box::new_in( - ArcInner { - strong: atomic::AtomicUsize::new(0), - weak: atomic::AtomicUsize::new(1), - data: mem::MaybeUninit::::uninit(), - }, - alloc.clone(), - )) - .into(); - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc: alloc.clone() }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - // Now we can properly initialize the inner value and turn our weak - // reference into a strong reference. - let strong = unsafe { - let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).data), data); - - // The above write to the data field must be visible to any threads which - // observe a non-zero strong count. Therefore we need at least "Release" ordering - // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. - // - // "Acquire" ordering is not required. When considering the possible behaviours - // of `data_fn` we only need to look at what it could do with a reference to a - // non-upgradeable `Weak`: - // - It can *clone* the `Weak`, increasing the weak reference count. - // - It can drop those clones, decreasing the weak reference count (but never to zero). - // - // These side effects do not impact us in any way, and no other side effects are - // possible with safe code alone. - let prev_value = (*inner).strong.fetch_add(1, Release); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - - Arc::from_inner_in(init_ptr, alloc) - }; - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - mem::forget(weak); - strong - } -} - impl Arc { /// Constructs an `Arc` from a raw pointer. /// From 550e55fec5cf3a11cf5b7372fda45465e4e6b4d0 Mon Sep 17 00:00:00 2001 From: Matthew Giordano Date: Fri, 6 Sep 2024 15:20:41 -0700 Subject: [PATCH 09/24] Remove duplicate impl --- library/alloc/src/rc.rs | 41 +++--------------------------- library/alloc/src/sync.rs | 53 +++------------------------------------ 2 files changed, 6 insertions(+), 88 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 664bc5ffc3441..719f154141b56 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -460,42 +460,7 @@ impl Rc { where F: FnOnce(&Weak) -> T, { - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let uninit_ptr: NonNull<_> = Box::leak(Box::new(RcBox { - strong: Cell::new(0), - weak: Cell::new(1), - value: mem::MaybeUninit::::uninit(), - })) - .into(); - - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc: Global }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - let strong = unsafe { - let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).value), data); - - let prev_value = (*inner).strong.get(); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - (*inner).strong.set(1); - - Rc::from_inner(init_ptr) - }; - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - mem::forget(weak); - strong + Self::new_cyclic_in(data_fn, Global) } /// Constructs a new `Rc` with uninitialized contents. @@ -801,8 +766,6 @@ impl Rc { where F: FnOnce(&Weak) -> T, { - // Note: comments and implementation are copied from Rc::new_cyclic. - // Construct the inner in the "uninitialized" state with a single // weak reference. let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in( @@ -836,6 +799,8 @@ impl Rc { // Strong references should collectively own a shared weak reference, // so don't run the destructor for our old weak reference. + // Calling into_raw_with_allocator has the double effect of giving us back the allocator, + // and forgetting the weak reference. let alloc = weak.into_raw_with_allocator().1; Rc::from_inner_in(init_ptr, alloc) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4f8039fd1f8b8..496865e303b40 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -450,54 +450,7 @@ impl Arc { where F: FnOnce(&Weak) -> T, { - // Construct the inner in the "uninitialized" state with a single - // weak reference. - let uninit_ptr: NonNull<_> = Box::leak(Box::new(ArcInner { - strong: atomic::AtomicUsize::new(0), - weak: atomic::AtomicUsize::new(1), - data: mem::MaybeUninit::::uninit(), - })) - .into(); - let init_ptr: NonNull> = uninit_ptr.cast(); - - let weak = Weak { ptr: init_ptr, alloc: Global }; - - // It's important we don't give up ownership of the weak pointer, or - // else the memory might be freed by the time `data_fn` returns. If - // we really wanted to pass ownership, we could create an additional - // weak pointer for ourselves, but this would result in additional - // updates to the weak reference count which might not be necessary - // otherwise. - let data = data_fn(&weak); - - // Now we can properly initialize the inner value and turn our weak - // reference into a strong reference. - let strong = unsafe { - let inner = init_ptr.as_ptr(); - ptr::write(ptr::addr_of_mut!((*inner).data), data); - - // The above write to the data field must be visible to any threads which - // observe a non-zero strong count. Therefore we need at least "Release" ordering - // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`. - // - // "Acquire" ordering is not required. When considering the possible behaviours - // of `data_fn` we only need to look at what it could do with a reference to a - // non-upgradeable `Weak`: - // - It can *clone* the `Weak`, increasing the weak reference count. - // - It can drop those clones, decreasing the weak reference count (but never to zero). - // - // These side effects do not impact us in any way, and no other side effects are - // possible with safe code alone. - let prev_value = (*inner).strong.fetch_add(1, Release); - debug_assert_eq!(prev_value, 0, "No prior strong references should exist"); - - Arc::from_inner(init_ptr) - }; - - // Strong references should collectively own a shared weak reference, - // so don't run the destructor for our old weak reference. - mem::forget(weak); - strong + Self::new_cyclic_in(data_fn, Global) } /// Constructs a new `Arc` with uninitialized contents. @@ -821,8 +774,6 @@ impl Arc { where F: FnOnce(&Weak) -> T, { - // Note: these comments and much of the implementation is copied from Arc::new_cyclic. - // Construct the inner in the "uninitialized" state with a single // weak reference. let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in( @@ -869,6 +820,8 @@ impl Arc { // Strong references should collectively own a shared weak reference, // so don't run the destructor for our old weak reference. + // Calling into_raw_with_allocator has the double effect of giving us back the allocator, + // and forgetting the weak reference. let alloc = weak.into_raw_with_allocator().1; Arc::from_inner_in(init_ptr, alloc) From 9d5d03b7dec8a87c81528e9a1310313fa3f0111e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 12 Sep 2024 09:07:44 -0400 Subject: [PATCH 10/24] Don't call extern_crate when local crate name is the same as a dependency and we have a trait error --- .../traits/fulfillment_errors.rs | 1 + .../foreign_struct_trait_unimplemented.rs | 1 + .../foreign_struct_trait_unimplemented.rs | 15 ++++++++++++ .../foreign_struct_trait_unimplemented.stderr | 23 +++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs create mode 100644 tests/ui/typeck/foreign_struct_trait_unimplemented.rs create mode 100644 tests/ui/typeck/foreign_struct_trait_unimplemented.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 5918686213a78..85a6ef5caab47 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1669,6 +1669,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let name = self.tcx.crate_name(trait_def_id.krate); let spans: Vec<_> = [trait_def_id, found_type] .into_iter() + .filter(|def_id| def_id.krate != LOCAL_CRATE) .filter_map(|def_id| self.tcx.extern_crate(def_id.krate)) .map(|data| { let dependency = if data.dependency_of == LOCAL_CRATE { diff --git a/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs b/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs new file mode 100644 index 0000000000000..097a269e8ee6b --- /dev/null +++ b/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs @@ -0,0 +1 @@ +pub struct B; diff --git a/tests/ui/typeck/foreign_struct_trait_unimplemented.rs b/tests/ui/typeck/foreign_struct_trait_unimplemented.rs new file mode 100644 index 0000000000000..8ac56bac9b0a6 --- /dev/null +++ b/tests/ui/typeck/foreign_struct_trait_unimplemented.rs @@ -0,0 +1,15 @@ +//@ aux-build:foreign_struct_trait_unimplemented.rs + +extern crate foreign_struct_trait_unimplemented; + +pub trait Test {} + +struct A; +impl Test for A {} + +fn needs_test(_: impl Test) {} + +fn main() { + needs_test(foreign_struct_trait_unimplemented::B); + //~^ ERROR the trait bound `B: Test` is not satisfied +} diff --git a/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr b/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr new file mode 100644 index 0000000000000..b9bb97548f67c --- /dev/null +++ b/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `B: Test` is not satisfied + --> $DIR/foreign_struct_trait_unimplemented.rs:13:16 + | +LL | needs_test(foreign_struct_trait_unimplemented::B); + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `B` + | | + | required by a bound introduced by this call + | +help: there are multiple different versions of crate `foreign_struct_trait_unimplemented` in the dependency graph + --> $DIR/foreign_struct_trait_unimplemented.rs:3:1 + | +LL | extern crate foreign_struct_trait_unimplemented; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `foreign_struct_trait_unimplemented` is used here, as a direct dependency of the current crate + = help: you can use `cargo tree` to explore your dependency tree +note: required by a bound in `needs_test` + --> $DIR/foreign_struct_trait_unimplemented.rs:10:23 + | +LL | fn needs_test(_: impl Test) {} + | ^^^^ required by this bound in `needs_test` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 05483d5602d1460ef5b77cae67db82118c00475c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 13 Aug 2024 22:17:01 -0400 Subject: [PATCH 11/24] Relate receiver invariantly in method probe for Mode::Path --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_hir_typeck/src/method/probe.rs | 26 ++++++++-- ...rojection-self-ty-invalid-bivariant-arg.rs | 1 + ...ction-self-ty-invalid-bivariant-arg.stderr | 17 +++++- ...ojection-self-ty-invalid-bivariant-arg2.rs | 1 + ...tion-self-ty-invalid-bivariant-arg2.stderr | 17 +++++- ...erce-issue-49593-box-never.fallback.stderr | 11 ---- .../coercion/coerce-issue-49593-box-never.rs | 8 +-- .../generic_arg_infer/issue-91614.stderr | 4 +- tests/ui/impl-trait/issues/issue-62742.rs | 3 +- tests/ui/impl-trait/issues/issue-62742.stderr | 52 +++++++++++++++---- .../need_type_info/type-alias-indirect.stderr | 2 +- .../need_type_info/type-alias.stderr | 6 +-- tests/ui/methods/receiver-equality.rs | 16 ++++++ tests/ui/methods/receiver-equality.stderr | 12 +++++ .../suggestions/mut-borrow-needed-by-trait.rs | 1 - .../mut-borrow-needed-by-trait.stderr | 16 ++---- 17 files changed, 141 insertions(+), 56 deletions(-) delete mode 100644 tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr create mode 100644 tests/ui/methods/receiver-equality.rs create mode 100644 tests/ui/methods/receiver-equality.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7318d02d24c49..61898b06476fd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1388,10 +1388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This also occurs for an enum variant on a type alias. let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, self_ty); - match self.at(&self.misc(span), self.param_env).sub( + match self.at(&self.misc(span), self.param_env).eq( DefineOpaqueTypes::Yes, - self_ty, impl_ty, + self_ty, ) { Ok(ok) => self.register_infer_ok_obligations(ok), Err(_) => { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3ba3429cbb331..c9749944176cd 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -621,6 +621,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.unsatisfied_predicates.borrow_mut().clear(); } + /// When we're looking up a method by path (UFCS), we relate the receiver + /// types invariantly. When we are looking up a method by the `.` operator, + /// we relate them covariantly. + fn variance(&self) -> ty::Variance { + match self.mode { + Mode::MethodCall => ty::Covariant, + Mode::Path => ty::Invariant, + } + } + /////////////////////////////////////////////////////////////////////////// // CANDIDATE ASSEMBLY @@ -1443,7 +1453,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, impl_ty, impl_args); xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); - match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) + { Ok(()) => {} Err(err) => { debug!("--> cannot relate self-types {:?}", err); @@ -1514,7 +1525,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { { return ProbeResult::NoMatch; } - _ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + _ => match ocx.relate( + cause, + self.param_env, + self.variance(), + self_ty, + xform_self_ty, + ) { Ok(()) => {} Err(err) => { debug!("--> cannot relate self-types {:?}", err); @@ -1560,7 +1577,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); - match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) + { Ok(()) => {} Err(err) => { debug!("--> cannot relate self-types {:?}", err); @@ -1603,7 +1621,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty); - match ocx.sup(cause, self.param_env, return_ty, xform_ret_ty) { + match ocx.relate(cause, self.param_env, self.variance(), xform_ret_ty, return_ty) { Ok(()) => {} Err(_) => { result = ProbeResult::BadReturnType; diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs index e2fc2961a448d..a33d4928f0145 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs @@ -7,4 +7,5 @@ impl Fail { fn main() { Fail::<()>::C + //~^ ERROR no associated item named `C` found for struct `Fail<()>` in the current scope } diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr index f0a6ccf243a9e..c581639310711 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr @@ -7,6 +7,19 @@ LL | struct Fail; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error: aborting due to 1 previous error +error[E0599]: no associated item named `C` found for struct `Fail<()>` in the current scope + --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:9:17 + | +LL | struct Fail; + | -------------- associated item `C` not found for this struct +... +LL | Fail::<()>::C + | ^ associated item not found in `Fail<()>` + | + = note: the associated item was found for + - `Fail` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0392, E0599. +For more information about an error, try `rustc --explain E0392`. diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs index cb53d902ba18a..d891b7bd62b4a 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs @@ -14,4 +14,5 @@ impl Fail { fn main() { Fail::::C //~^ ERROR: type mismatch + //~| ERROR no associated item named `C` found for struct `Fail` in the current scope } diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr index 0d63b7f5b2934..18d458aea809b 100644 --- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr +++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr @@ -1,3 +1,15 @@ +error[E0599]: no associated item named `C` found for struct `Fail` in the current scope + --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23 + | +LL | struct Fail, U>(T); + | ---------------------------------- associated item `C` not found for this struct +... +LL | Fail::::C + | ^ associated item not found in `Fail` + | + = note: the associated item was found for + - `Fail` + error[E0271]: type mismatch resolving `::Assoc == u32` --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5 | @@ -15,6 +27,7 @@ note: required by a bound in `Fail` LL | struct Fail, U>(T); | ^^^^^^^^^ required by this bound in `Fail` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0271, E0599. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr deleted file mode 100644 index ef5633f71348a..0000000000000 --- a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `(): std::error::Error` is not satisfied - --> $DIR/coerce-issue-49593-box-never.rs:18:5 - | -LL | Box::<_ /* ! */>::new(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` - | - = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.rs b/tests/ui/coercion/coerce-issue-49593-box-never.rs index 53071be47dcbe..e556959204590 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.rs +++ b/tests/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,5 +1,5 @@ //@ revisions: nofallback fallback -//@check-fail +//@[fallback] check-pass #![feature(never_type)] #![cfg_attr(fallback, feature(never_type_fallback))] @@ -13,10 +13,10 @@ fn raw_ptr_box(t: T) -> *mut T { } fn foo(x: !) -> Box { - // Subtyping during method resolution will generate new inference vars and - // subtype them. Thus fallback will not fall back to `!`, but `()` instead. + // Method resolution will generate new inference vars and relate them. + // Thus fallback will not fall back to `!`, but `()` instead. Box::<_ /* ! */>::new(x) - //~^ ERROR trait bound `(): std::error::Error` is not satisfied + //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied } fn foo_raw_ptr(x: !) -> *mut dyn Error { diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 217f609459eed..b88fe966b77ce 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -8,7 +8,7 @@ note: required by a const generic parameter in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | -LL | let y: Mask = Mask::<_, _>::splat(false); +LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); | ++++++++++++ error[E0284]: type annotations needed for `Mask<_, _>` @@ -21,7 +21,7 @@ note: required by a const generic parameter in `Mask` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | -LL | let y: Mask = Mask::<_, _>::splat(false); +LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); | ++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/issues/issue-62742.rs b/tests/ui/impl-trait/issues/issue-62742.rs index 56c63a1daa867..c64278c2c5bec 100644 --- a/tests/ui/impl-trait/issues/issue-62742.rs +++ b/tests/ui/impl-trait/issues/issue-62742.rs @@ -2,7 +2,8 @@ use std::marker::PhantomData; fn a() { WrongImpl::foo(0i32); - //~^ ERROR overflow assigning `_` to `[_]` + //~^ ERROR the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied + //~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied } fn b() { diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 7a1bcfc70d54f..94822e41ccd67 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -1,11 +1,43 @@ -error[E0275]: overflow assigning `_` to `[_]` +error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied --> $DIR/issue-62742.rs:4:16 | LL | WrongImpl::foo(0i32); - | ^^^ + | ^^^ function or associated item cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds +... +LL | pub struct RawImpl(PhantomData); + | --------------------- doesn't satisfy `RawImpl<_>: Raw<_>` +... +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ----------------------------------------- function or associated item `foo` not found for this struct + | +note: trait bound `RawImpl<_>: Raw<_>` was not satisfied + --> $DIR/issue-62742.rs:35:20 + | +LL | impl> SafeImpl { + | ^^^^^^ -------------- + | | + | unsatisfied trait bound introduced here +note: the trait `Raw` must be implemented + --> $DIR/issue-62742.rs:19:1 + | +LL | pub trait Raw { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied + --> $DIR/issue-62742.rs:4:5 + | +LL | WrongImpl::foo(0i32); + | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` + | + = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:33:35 + | +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ^^^^^^ required by this bound in `SafeImpl` error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied - --> $DIR/issue-62742.rs:9:22 + --> $DIR/issue-62742.rs:10:22 | LL | WrongImpl::<()>::foo(0i32); | ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds @@ -17,20 +49,20 @@ LL | pub struct SafeImpl>(PhantomData<(A, T)>); | ----------------------------------------- function or associated item `foo` not found for this struct | note: trait bound `RawImpl<()>: Raw<()>` was not satisfied - --> $DIR/issue-62742.rs:34:20 + --> $DIR/issue-62742.rs:35:20 | LL | impl> SafeImpl { | ^^^^^^ -------------- | | | unsatisfied trait bound introduced here note: the trait `Raw` must be implemented - --> $DIR/issue-62742.rs:18:1 + --> $DIR/issue-62742.rs:19:1 | LL | pub trait Raw { | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied - --> $DIR/issue-62742.rs:9:5 + --> $DIR/issue-62742.rs:10:5 | LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` @@ -38,12 +70,12 @@ LL | WrongImpl::<()>::foo(0i32); = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` = help: for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` - --> $DIR/issue-62742.rs:32:35 + --> $DIR/issue-62742.rs:33:35 | LL | pub struct SafeImpl>(PhantomData<(A, T)>); | ^^^^^^ required by this bound in `SafeImpl` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0275, E0277, E0599. -For more information about an error, try `rustc --explain E0275`. +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.stderr b/tests/ui/inference/need_type_info/type-alias-indirect.stderr index 5c5b4c149c170..535c0044aec03 100644 --- a/tests/ui/inference/need_type_info/type-alias-indirect.stderr +++ b/tests/ui/inference/need_type_info/type-alias-indirect.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/type-alias-indirect.rs:14:5 | LL | IndirectAlias::new(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` + | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` error: aborting due to 1 previous error diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr index fd9bcf2fe3f39..2c39a3f56466f 100644 --- a/tests/ui/inference/need_type_info/type-alias.stderr +++ b/tests/ui/inference/need_type_info/type-alias.stderr @@ -2,19 +2,19 @@ error[E0282]: type annotations needed --> $DIR/type-alias.rs:12:5 | LL | DirectAlias::new() - | ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias` + | ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` error[E0282]: type annotations needed --> $DIR/type-alias.rs:18:5 | LL | IndirectAlias::new(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` + | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` error[E0282]: type annotations needed --> $DIR/type-alias.rs:32:5 | LL | DirectButWithDefaultAlias::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` error: aborting due to 3 previous errors diff --git a/tests/ui/methods/receiver-equality.rs b/tests/ui/methods/receiver-equality.rs new file mode 100644 index 0000000000000..891435a425eb9 --- /dev/null +++ b/tests/ui/methods/receiver-equality.rs @@ -0,0 +1,16 @@ +// Tests that we probe receivers invariantly when using path-based method lookup. + +struct B(T); + +impl B { + fn method(self) { + println!("hey"); + } +} + +fn foo(y: B) { + B:: fn(&'a ())>::method(y); + //~^ ERROR no function or associated item named `method` found +} + +fn main() {} diff --git a/tests/ui/methods/receiver-equality.stderr b/tests/ui/methods/receiver-equality.stderr new file mode 100644 index 0000000000000..cea3340e386dc --- /dev/null +++ b/tests/ui/methods/receiver-equality.stderr @@ -0,0 +1,12 @@ +error[E0599]: no function or associated item named `method` found for struct `B fn(&'a ())>` in the current scope + --> $DIR/receiver-equality.rs:12:30 + | +LL | struct B(T); + | ----------- function or associated item `method` not found for this struct +... +LL | B:: fn(&'a ())>::method(y); + | ^^^^^^ function or associated item not found in `B` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs index 924bfd82eb832..66e1e77c905e0 100644 --- a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs +++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs @@ -17,7 +17,6 @@ fn main() { let fp = BufWriter::new(fp); //~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied writeln!(fp, "hello world").unwrap(); //~ ERROR the method } diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr index b2f9150142fe4..09a9b1d3b3482 100644 --- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -10,16 +10,6 @@ LL | let fp = BufWriter::new(fp); note: required by a bound in `BufWriter::::new` --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL -error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:17:14 - | -LL | let fp = BufWriter::new(fp); - | ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` - | - = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` -note: required by a bound in `BufWriter` - --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL - error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | @@ -31,13 +21,13 @@ note: required by a bound in `BufWriter` --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:22:14 + --> $DIR/mut-borrow-needed-by-trait.rs:21:14 | LL | writeln!(fp, "hello world").unwrap(); | ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds | note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method - --> $DIR/mut-borrow-needed-by-trait.rs:22:14 + --> $DIR/mut-borrow-needed-by-trait.rs:21:14 | LL | writeln!(fp, "hello world").unwrap(); | ^^ @@ -45,7 +35,7 @@ LL | writeln!(fp, "hello world").unwrap(); `&dyn std::io::Write: std::io::Write` which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. From 6e982f59ab6919005ce9aa0301fba8d183415939 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 16 Sep 2024 12:35:42 -0400 Subject: [PATCH 12/24] Don't ICE in opaque_hidden_inferred_bound lint for RPITIT in trait with no default method body --- .../src/opaque_hidden_inferred_bound.rs | 12 ++++++++++++ .../impl-trait/opaque-hidden-inferred-rpitit.rs | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index e0ba6a912f120..c9ca1ea5e7a79 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -72,6 +72,18 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { let hir::ItemKind::OpaqueTy(opaque) = &item.kind else { return; }; + + // If this is an RPITIT from a trait method with no body, then skip. + // That's because although we may have an opaque type on the function, + // it won't have a hidden type, so proving predicates about it is + // not really meaningful. + if let hir::OpaqueTyOrigin::FnReturn(method_def_id) = opaque.origin + && let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id) + && !trait_item.defaultness.has_value() + { + return; + } + let def_id = item.owner_id.def_id.to_def_id(); let infcx = &cx.tcx.infer_ctxt().build(); // For every projection predicate in the opaque type's explicit bounds, diff --git a/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs b/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs new file mode 100644 index 0000000000000..1582cca5cd258 --- /dev/null +++ b/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs @@ -0,0 +1,16 @@ +//@ check-pass + +// Make sure that the `opaque_hidden_inferred_bound` lint doesn't fire on +// RPITITs with no hidden type. + +trait T0 {} + +trait T1 { + type A: Send; +} + +trait T2 { + fn foo() -> impl T1; +} + +fn main() {} From 062ff4dfdae35e1cf54af7ab11f615a095171803 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 10 Sep 2024 11:39:46 -0400 Subject: [PATCH 13/24] Encode coroutine_by_move_body_def_id in crate metadata --- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 11 ++++++++++- compiler/rustc_metadata/src/rmeta/mod.rs | 1 + tests/ui/async-await/async-closures/foreign.rs | 5 +++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 53da07aeaa695..b9d287730fa6e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -290,6 +290,7 @@ provide! { tcx, def_id, other, cdata, fn_arg_names => { table } coroutine_kind => { table_direct } coroutine_for_closure => { table } + coroutine_by_move_body_def_id => { table } eval_static_initializer => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b617d5236b980..46dc0696638cc 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1488,9 +1488,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() { + let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id); self.tables .coroutine_for_closure - .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into()); + .set_some(def_id.index, coroutine_for_closure.into()); + + // If this async closure has a by-move body, record it too. + if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) { + self.tables.coroutine_by_move_body_def_id.set_some( + coroutine_for_closure.index, + self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure).into(), + ); + } } if let DefKind::Static { .. } = def_kind { if !self.tcx.is_foreign_item(def_id) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8180a507a514d..c791a1f541c52 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -446,6 +446,7 @@ define_tables! { fn_arg_names: Table>, coroutine_kind: Table, coroutine_for_closure: Table, + coroutine_by_move_body_def_id: Table, eval_static_initializer: Table>>, trait_def: Table>, trait_item_def_id: Table, diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs index 50bef9cf11d5f..ab6fe06a3f4bd 100644 --- a/tests/ui/async-await/async-closures/foreign.rs +++ b/tests/ui/async-await/async-closures/foreign.rs @@ -12,8 +12,13 @@ extern crate foreign; struct NoCopy; +async fn call_once(f: impl async FnOnce()) { + f().await; +} + fn main() { block_on::block_on(async { foreign::closure()().await; + call_once(foreign::closure()).await; }); } From af1ca7794ab9ff62ab60d42de948248602cfd8cd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 10 Sep 2024 11:40:11 -0400 Subject: [PATCH 14/24] Record synthetic MIR bodies in mir_keys --- compiler/rustc_mir_transform/src/lib.rs | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 424e7008326bf..0868f4b3d882a 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -21,9 +21,8 @@ use rustc_const_eval::util; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::steal::Steal; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::intravisit::{self, Visitor}; use rustc_index::IndexVec; use rustc_middle::mir::{ AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl, @@ -224,26 +223,31 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// MIR associated with them. fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. - let set: FxIndexSet<_> = tcx.hir().body_owners().collect(); + let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect(); - // Additionally, tuple struct/variant constructors have MIR, but - // they don't have a BodyId, so we need to build them separately. - struct GatherCtors { - set: FxIndexSet, + // Coroutine-closures (e.g. async closures) have an additional by-move MIR + // body that isn't in the HIR. + for body_owner in tcx.hir().body_owners() { + if let DefKind::Closure = tcx.def_kind(body_owner) + && tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id()) + { + set.insert(tcx.coroutine_by_move_body_def_id(body_owner).expect_local()); + } } - impl<'tcx> Visitor<'tcx> for GatherCtors { - fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) { - if let hir::VariantData::Tuple(_, _, def_id) = *v { - self.set.insert(def_id); + + // tuple struct/variant constructors have MIR, but they don't have a BodyId, + // so we need to build them separately. + for item in tcx.hir_crate_items(()).free_items() { + if let DefKind::Struct | DefKind::Enum = tcx.def_kind(item.owner_id) { + for variant in tcx.adt_def(item.owner_id).variants() { + if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { + set.insert(ctor_def_id.expect_local()); + } } - intravisit::walk_struct_def(self, v) } } - let mut gather_ctors = GatherCtors { set }; - tcx.hir().visit_all_item_likes_in_crate(&mut gather_ctors); - - gather_ctors.set + set } fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { From 6750f042ca571407c8050693412d929ea1097b3f Mon Sep 17 00:00:00 2001 From: matthewpipie Date: Mon, 16 Sep 2024 20:05:15 -0500 Subject: [PATCH 15/24] Update library/alloc/src/sync.rs Co-authored-by: David Tolnay --- library/alloc/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 496865e303b40..63e4af34a578c 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -769,7 +769,7 @@ impl Arc { /// [`upgrade`]: Weak::upgrade #[cfg(not(no_global_oom_handling))] #[inline] - #[stable(feature = "arc_new_cyclic", since = "1.60.0")] + #[unstable(feature = "allocator_api", issue = "32838")] pub fn new_cyclic_in(data_fn: F, alloc: A) -> Arc where F: FnOnce(&Weak) -> T, From 978f10d8a94ee9dde3c0e33f41f86acc6cae4ba7 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Mon, 16 Sep 2024 20:46:46 -0400 Subject: [PATCH 16/24] tests: allow trunc/select instructions to be missing On LLVM 20, these instructions already get eliminated, which at least partially satisfies a TODO. I'm not talented enough at using FileCheck to try and constrain this further, but if we really want to we could copy an LLVM 20 specific version of this test that would restore it to being CHECK-NEXT: insertvalue ... @rustbot label: +llvm-main --- tests/codegen/try_question_mark_nop.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 321067d1b904c..15e51d33a92c3 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -1,7 +1,10 @@ //@ compile-flags: -O -Z merge-functions=disabled --edition=2021 //@ only-x86_64 // FIXME: Remove the `min-llvm-version`. -//@ min-llvm-version: 19 +//@ revisions: NINETEEN TWENTY +//@[NINETEEN] min-llvm-version: 19 +//@[NINETEEN] ignore-llvm-version: 20-99 +//@[TWENTY] min-llvm-version: 20 #![crate_type = "lib"] #![feature(try_blocks)] @@ -9,14 +12,13 @@ use std::ops::ControlFlow::{self, Break, Continue}; use std::ptr::NonNull; -// FIXME: The `trunc` and `select` instructions can be eliminated. // CHECK-LABEL: @option_nop_match_32 #[no_mangle] pub fn option_nop_match_32(x: Option) -> Option { // CHECK: start: - // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 - // CHECK-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0 - // CHECK-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]] + // NINETEEN-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 + // NINETEEN-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0 + // CHECK-NEXT: insertvalue { i32, i32 } poison, i32 %0, 0 // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } match x { From 4beb1cf9e53102ad32793127316f0045a9c004f3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 16 Sep 2024 21:40:14 -0400 Subject: [PATCH 17/24] Fix a couple more DefKind discrepancies between DefKind::Closure and DefKind::SyntheticCoroutineBody --- compiler/rustc_hir/src/def.rs | 5 ++- .../src/cross_crate_inline.rs | 2 +- compiler/rustc_symbol_mangling/src/lib.rs | 6 +++- .../async-await/async-closures/inline-body.rs | 34 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tests/ui/async-await/async-closures/inline-body.rs diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index bd55617d84ea2..9b4174013a6a3 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -287,7 +287,10 @@ impl DefKind { #[inline] pub fn is_fn_like(self) -> bool { - matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) + matches!( + self, + DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody + ) } /// Whether `query get_codegen_attrs` should be used with this definition. diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index ce109ef7674f0..42cbece32d8c9 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -24,7 +24,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // This just reproduces the logic from Instance::requires_inline. match tcx.def_kind(def_id) { - DefKind::Ctor(..) | DefKind::Closure => return true, + DefKind::Ctor(..) | DefKind::Closure | DefKind::SyntheticCoroutineBody => return true, DefKind::Fn | DefKind::AssocFn => {} _ => return false, } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 0c97cda81c8af..78e6b9ec6e850 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -227,7 +227,11 @@ fn compute_symbol_name<'tcx>( // and we want to be sure to avoid any symbol conflicts here. let is_globally_shared_function = matches!( tcx.def_kind(instance.def_id()), - DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Ctor(..) + DefKind::Fn + | DefKind::AssocFn + | DefKind::Closure + | DefKind::SyntheticCoroutineBody + | DefKind::Ctor(..) ) && matches!( MonoItem::Fn(instance).instantiation_mode(tcx), InstantiationMode::GloballyShared { may_conflict: true } diff --git a/tests/ui/async-await/async-closures/inline-body.rs b/tests/ui/async-await/async-closures/inline-body.rs new file mode 100644 index 0000000000000..a842d98d1de4c --- /dev/null +++ b/tests/ui/async-await/async-closures/inline-body.rs @@ -0,0 +1,34 @@ +//@ edition: 2021 +//@ compile-flags: -Zinline-mir +//@ build-pass + +// Ensure that we don't hit a Steal ICE because we forgot to ensure +// `mir_inliner_callees` for the synthetic by-move coroutine body since +// its def-id wasn't previously being considered. + +#![feature(async_closure, noop_waker)] + +use std::future::Future; +use std::pin::pin; +use std::task::*; + +pub fn block_on(fut: impl Future) -> T { + let mut fut = pin!(fut); + let ctx = &mut Context::from_waker(Waker::noop()); + + loop { + match fut.as_mut().poll(ctx) { + Poll::Pending => {} + Poll::Ready(t) => break t, + } + } +} + +async fn call_once(f: impl async FnOnce() -> T) -> T { + f().await +} + +fn main() { + let c = async || {}; + block_on(call_once(c)); +} From bdacdfe95f17188f5b047e0330e3e47f993a2016 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Sep 2024 15:16:55 +1000 Subject: [PATCH 18/24] Minimize visibilities. This makes it much clearer which things are used outside the crate. --- .../rustc_codegen_ssa/src/back/archive.rs | 2 +- .../rustc_codegen_ssa/src/back/command.rs | 26 ++-- compiler/rustc_codegen_ssa/src/back/linker.rs | 54 ++++---- .../rustc_codegen_ssa/src/back/metadata.rs | 6 +- compiler/rustc_codegen_ssa/src/back/mod.rs | 6 +- compiler/rustc_codegen_ssa/src/back/rpath.rs | 4 +- .../src/back/symbol_export.rs | 10 +- compiler/rustc_codegen_ssa/src/back/write.rs | 36 ++--- compiler/rustc_codegen_ssa/src/base.rs | 20 +-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_codegen_ssa/src/common.rs | 4 +- .../rustc_codegen_ssa/src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 127 +++++++++--------- compiler/rustc_codegen_ssa/src/lib.rs | 2 +- compiler/rustc_codegen_ssa/src/meth.rs | 12 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 6 +- .../rustc_codegen_ssa/src/mir/constant.rs | 4 +- .../rustc_codegen_ssa/src/mir/coverageinfo.rs | 2 +- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 6 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 12 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 14 +- .../rustc_codegen_ssa/src/mir/statement.rs | 2 +- .../rustc_codegen_ssa/src/target_features.rs | 4 +- 24 files changed, 188 insertions(+), 179 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 76a94de54339c..a665f5c93060d 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -157,7 +157,7 @@ pub trait ArchiveBuilderBuilder { } } -pub fn create_mingw_dll_import_lib( +fn create_mingw_dll_import_lib( sess: &Session, lib_name: &str, import_name_and_ordinal_vector: Vec<(String, Option)>, diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 95c4af2e59ea9..b3c5b86ccf430 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -8,7 +8,7 @@ use std::{fmt, io, mem}; use rustc_target::spec::LldFlavor; #[derive(Clone)] -pub struct Command { +pub(crate) struct Command { program: Program, args: Vec, env: Vec<(OsString, OsString)>, @@ -23,15 +23,15 @@ enum Program { } impl Command { - pub fn new>(program: P) -> Command { + pub(crate) fn new>(program: P) -> Command { Command::_new(Program::Normal(program.as_ref().to_owned())) } - pub fn bat_script>(program: P) -> Command { + pub(crate) fn bat_script>(program: P) -> Command { Command::_new(Program::CmdBatScript(program.as_ref().to_owned())) } - pub fn lld>(program: P, flavor: LldFlavor) -> Command { + pub(crate) fn lld>(program: P, flavor: LldFlavor) -> Command { Command::_new(Program::Lld(program.as_ref().to_owned(), flavor)) } @@ -39,12 +39,12 @@ impl Command { Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() } } - pub fn arg>(&mut self, arg: P) -> &mut Command { + pub(crate) fn arg>(&mut self, arg: P) -> &mut Command { self._arg(arg.as_ref()); self } - pub fn args(&mut self, args: I) -> &mut Command + pub(crate) fn args(&mut self, args: I) -> &mut Command where I: IntoIterator>, { @@ -58,7 +58,7 @@ impl Command { self.args.push(arg.to_owned()); } - pub fn env(&mut self, key: K, value: V) -> &mut Command + pub(crate) fn env(&mut self, key: K, value: V) -> &mut Command where K: AsRef, V: AsRef, @@ -71,7 +71,7 @@ impl Command { self.env.push((key.to_owned(), value.to_owned())); } - pub fn env_remove(&mut self, key: K) -> &mut Command + pub(crate) fn env_remove(&mut self, key: K) -> &mut Command where K: AsRef, { @@ -83,11 +83,11 @@ impl Command { self.env_remove.push(key.to_owned()); } - pub fn output(&mut self) -> io::Result { + pub(crate) fn output(&mut self) -> io::Result { self.command().output() } - pub fn command(&self) -> process::Command { + pub(crate) fn command(&self) -> process::Command { let mut ret = match self.program { Program::Normal(ref p) => process::Command::new(p), Program::CmdBatScript(ref p) => { @@ -111,17 +111,17 @@ impl Command { // extensions - pub fn get_args(&self) -> &[OsString] { + pub(crate) fn get_args(&self) -> &[OsString] { &self.args } - pub fn take_args(&mut self) -> Vec { + pub(crate) fn take_args(&mut self) -> Vec { mem::take(&mut self.args) } /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, /// or `false` if we should attempt to spawn and see what the OS says. - pub fn very_likely_to_exceed_some_spawn_limit(&self) -> bool { + pub(crate) fn very_likely_to_exceed_some_spawn_limit(&self) -> bool { // We mostly only care about Windows in this method, on Unix the limits // can be gargantuan anyway so we're pretty unlikely to hit them if cfg!(unix) { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 7f5f9f0386809..61476e0a25b10 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -28,7 +28,7 @@ use crate::errors; /// and prevent inspection of linker output in case of errors, which we occasionally do. /// This should be acceptable because other messages from rustc are in English anyway, /// and may also be desirable to improve searchability of the linker diagnostics. -pub fn disable_localization(linker: &mut Command) { +pub(crate) fn disable_localization(linker: &mut Command) { // No harm in setting both env vars simultaneously. // Unix-style linkers. linker.env("LC_ALL", "C"); @@ -39,7 +39,7 @@ pub fn disable_localization(linker: &mut Command) { /// The third parameter is for env vars, used on windows to set up the /// path for MSVC to find its DLLs, and gcc to find its bundled /// toolchain -pub fn get_linker<'a>( +pub(crate) fn get_linker<'a>( sess: &'a Session, linker: &Path, flavor: LinkerFlavor, @@ -213,28 +213,36 @@ fn link_or_cc_args( macro_rules! generate_arg_methods { ($($ty:ty)*) => { $( impl $ty { - pub fn verbatim_args(&mut self, args: impl IntoIterator>) -> &mut Self { + #[allow(unused)] + pub(crate) fn verbatim_args(&mut self, args: impl IntoIterator>) -> &mut Self { verbatim_args(self, args) } - pub fn verbatim_arg(&mut self, arg: impl AsRef) -> &mut Self { + #[allow(unused)] + pub(crate) fn verbatim_arg(&mut self, arg: impl AsRef) -> &mut Self { verbatim_args(self, iter::once(arg)) } - pub fn link_args(&mut self, args: impl IntoIterator, IntoIter: ExactSizeIterator>) -> &mut Self { + #[allow(unused)] + pub(crate) fn link_args(&mut self, args: impl IntoIterator, IntoIter: ExactSizeIterator>) -> &mut Self { link_args(self, args) } - pub fn link_arg(&mut self, arg: impl AsRef) -> &mut Self { + #[allow(unused)] + pub(crate) fn link_arg(&mut self, arg: impl AsRef) -> &mut Self { link_args(self, iter::once(arg)) } - pub fn cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + #[allow(unused)] + pub(crate) fn cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { cc_args(self, args) } - pub fn cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + #[allow(unused)] + pub(crate) fn cc_arg(&mut self, arg: impl AsRef) -> &mut Self { cc_args(self, iter::once(arg)) } - pub fn link_or_cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + #[allow(unused)] + pub(crate) fn link_or_cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { link_or_cc_args(self, args) } - pub fn link_or_cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + #[allow(unused)] + pub(crate) fn link_or_cc_arg(&mut self, arg: impl AsRef) -> &mut Self { link_or_cc_args(self, iter::once(arg)) } } @@ -261,7 +269,7 @@ generate_arg_methods! { /// represents the meaning of each option being passed down. This trait is then /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an /// MSVC linker (e.g., `link.exe`) is being used. -pub trait Linker { +pub(crate) trait Linker { fn cmd(&mut self) -> &mut Command; fn is_cc(&self) -> bool { false @@ -312,12 +320,12 @@ pub trait Linker { } impl dyn Linker + '_ { - pub fn take_cmd(&mut self) -> Command { + pub(crate) fn take_cmd(&mut self) -> Command { mem::replace(self.cmd(), Command::new("")) } } -pub struct GccLinker<'a> { +struct GccLinker<'a> { cmd: Command, sess: &'a Session, target_cpu: &'a str, @@ -847,7 +855,7 @@ impl<'a> Linker for GccLinker<'a> { } } -pub struct MsvcLinker<'a> { +struct MsvcLinker<'a> { cmd: Command, sess: &'a Session, } @@ -1095,7 +1103,7 @@ impl<'a> Linker for MsvcLinker<'a> { } } -pub struct EmLinker<'a> { +struct EmLinker<'a> { cmd: Command, sess: &'a Session, } @@ -1212,7 +1220,7 @@ impl<'a> Linker for EmLinker<'a> { } } -pub struct WasmLd<'a> { +struct WasmLd<'a> { cmd: Command, sess: &'a Session, } @@ -1396,7 +1404,7 @@ impl<'a> WasmLd<'a> { } /// Linker shepherd script for L4Re (Fiasco) -pub struct L4Bender<'a> { +struct L4Bender<'a> { cmd: Command, sess: &'a Session, hinted_static: bool, @@ -1502,7 +1510,7 @@ impl<'a> Linker for L4Bender<'a> { } impl<'a> L4Bender<'a> { - pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> { + fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> { L4Bender { cmd, sess, hinted_static: false } } @@ -1515,14 +1523,14 @@ impl<'a> L4Bender<'a> { } /// Linker for AIX. -pub struct AixLinker<'a> { +struct AixLinker<'a> { cmd: Command, sess: &'a Session, hinted_static: Option, } impl<'a> AixLinker<'a> { - pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> { + fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> { AixLinker { cmd, sess, hinted_static: None } } @@ -1750,7 +1758,7 @@ pub(crate) fn linked_symbols( /// Much simplified and explicit CLI for the NVPTX linker. The linker operates /// with bitcode and uses LLVM backend to generate a PTX assembly. -pub struct PtxLinker<'a> { +struct PtxLinker<'a> { cmd: Command, sess: &'a Session, } @@ -1816,7 +1824,7 @@ impl<'a> Linker for PtxLinker<'a> { } /// The `self-contained` LLVM bitcode linker -pub struct LlbcLinker<'a> { +struct LlbcLinker<'a> { cmd: Command, sess: &'a Session, } @@ -1887,7 +1895,7 @@ impl<'a> Linker for LlbcLinker<'a> { fn linker_plugin_lto(&mut self) {} } -pub struct BpfLinker<'a> { +struct BpfLinker<'a> { cmd: Command, sess: &'a Session, } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 6215616e51000..ff87f7f1ea45f 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -32,7 +32,7 @@ use rustc_target::spec::{ef_avr_arch, RelocModel, Target}; ///
The metadata can be found in the `.rustc` section of the shared library.
/// #[derive(Debug)] -pub struct DefaultMetadataLoader; +pub(crate) struct DefaultMetadataLoader; static AIX_METADATA_SYMBOL_NAME: &'static str = "__aix_rust_metadata"; @@ -416,7 +416,7 @@ fn macho_is_arm64e(target: &Target) -> bool { target.llvm_target.starts_with("arm64e") } -pub enum MetadataPosition { +pub(crate) enum MetadataPosition { First, Last, } @@ -452,7 +452,7 @@ pub enum MetadataPosition { /// * ELF - All other targets are similar to Windows in that there's a /// `SHF_EXCLUDE` flag we can set on sections in an object file to get /// automatically removed from the final output. -pub fn create_wrapper_file( +pub(crate) fn create_wrapper_file( sess: &Session, section_name: String, data: &[u8], diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs index d11ed54eb209f..2b3a2e3a369bb 100644 --- a/compiler/rustc_codegen_ssa/src/back/mod.rs +++ b/compiler/rustc_codegen_ssa/src/back/mod.rs @@ -1,9 +1,9 @@ pub mod archive; -pub mod command; +pub(crate) mod command; pub mod link; -pub mod linker; +pub(crate) mod linker; pub mod lto; pub mod metadata; -pub mod rpath; +pub(crate) mod rpath; pub mod symbol_export; pub mod write; diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs index 42f8c3114ff50..56a808df6b0bd 100644 --- a/compiler/rustc_codegen_ssa/src/back/rpath.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs @@ -6,14 +6,14 @@ use rustc_data_structures::fx::FxHashSet; use rustc_fs_util::try_canonicalize; use tracing::debug; -pub struct RPathConfig<'a> { +pub(super) struct RPathConfig<'a> { pub libs: &'a [&'a Path], pub out_filename: PathBuf, pub is_like_osx: bool, pub linker_is_gnu: bool, } -pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec { +pub(super) fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec { debug!("preparing the RPATH!"); let rpaths = get_rpaths(config); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d2f11d48140c9..257e2dfac006a 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -18,7 +18,7 @@ use tracing::debug; use crate::base::allocator_kind_for_codegen; -pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { +fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(tcx.crate_types()) } @@ -484,7 +484,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) !tcx.reachable_set(()).contains(&def_id) } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { providers.reachable_non_generics = reachable_non_generics_provider; providers.is_reachable_non_generic = is_reachable_non_generic_provider_local; providers.exported_symbols = exported_symbols_provider_local; @@ -525,7 +525,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel } /// This is the symbol name of the given instance instantiated in a specific crate. -pub fn symbol_name_for_instance_in_crate<'tcx>( +pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, instantiating_crate: CrateNum, @@ -582,7 +582,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>( /// This is the symbol name of the given instance as seen by the linker. /// /// On 32-bit Windows symbols are decorated according to their calling conventions. -pub fn linking_symbol_name_for_instance_in_crate<'tcx>( +pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, instantiating_crate: CrateNum, @@ -661,7 +661,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>( format!("{prefix}{undecorated}{suffix}{args_in_bytes}") } -pub fn exporting_symbol_name_for_instance_in_crate<'tcx>( +pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, cnum: CrateNum, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index feb27c148a188..d83cb799b57be 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -335,7 +335,7 @@ pub type TargetMachineFactoryFn = Arc< + Sync, >; -pub type ExportedSymbols = FxHashMap>>; +type ExportedSymbols = FxHashMap>>; /// Additional resources used by optimize_and_codegen (not module specific) #[derive(Clone)] @@ -437,9 +437,9 @@ fn generate_lto_work( } } -pub struct CompiledModules { - pub modules: Vec, - pub allocator_module: Option, +struct CompiledModules { + modules: Vec, + allocator_module: Option, } fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool { @@ -462,7 +462,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { } } -pub fn start_async_codegen( +pub(crate) fn start_async_codegen( backend: B, tcx: TyCtxt<'_>, target_cpu: String, @@ -836,13 +836,13 @@ pub enum FatLtoInput { } /// Actual LTO type we end up choosing based on multiple factors. -pub enum ComputedLtoType { +pub(crate) enum ComputedLtoType { No, Thin, Fat, } -pub fn compute_per_cgu_lto_type( +pub(crate) fn compute_per_cgu_lto_type( sess_lto: &Lto, opts: &config::Options, sess_crate_types: &[CrateType], @@ -1087,7 +1087,7 @@ struct Diagnostic { // A cut-down version of `rustc_errors::Subdiag` that impls `Send`. It's // missing the following fields from `rustc_errors::Subdiag`. // - `span`: it doesn't impl `Send`. -pub struct Subdiagnostic { +pub(crate) struct Subdiagnostic { level: Level, messages: Vec<(DiagMessage, Style)>, } @@ -1779,7 +1779,7 @@ fn start_executing_work( /// `FatalError` is explicitly not `Send`. #[must_use] -pub struct WorkerFatalError; +pub(crate) struct WorkerFatalError; fn spawn_work<'a, B: ExtraBackendMethods>( cgcx: &'a CodegenContext, @@ -1867,7 +1867,7 @@ pub struct SharedEmitterMain { } impl SharedEmitter { - pub fn new() -> (SharedEmitter, SharedEmitterMain) { + fn new() -> (SharedEmitter, SharedEmitterMain) { let (sender, receiver) = channel(); (SharedEmitter { sender }, SharedEmitterMain { receiver }) @@ -1883,7 +1883,7 @@ impl SharedEmitter { drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source))); } - pub fn fatal(&self, msg: &str) { + fn fatal(&self, msg: &str) { drop(self.sender.send(SharedEmitterMessage::Fatal(msg.to_string()))); } } @@ -1930,7 +1930,7 @@ impl Emitter for SharedEmitter { } impl SharedEmitterMain { - pub fn check(&self, sess: &Session, blocking: bool) { + fn check(&self, sess: &Session, blocking: bool) { loop { let message = if blocking { match self.receiver.recv() { @@ -2087,17 +2087,17 @@ impl OngoingCodegen { ) } - pub fn codegen_finished(&self, tcx: TyCtxt<'_>) { + pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { self.wait_for_signal_to_codegen_item(); self.check_for_errors(tcx.sess); drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::))); } - pub fn check_for_errors(&self, sess: &Session) { + pub(crate) fn check_for_errors(&self, sess: &Session) { self.shared_emitter_main.check(sess, false); } - pub fn wait_for_signal_to_codegen_item(&self) { + pub(crate) fn wait_for_signal_to_codegen_item(&self) { match self.codegen_worker_receive.recv() { Ok(CguMessage) => { // Ok to proceed. @@ -2110,7 +2110,7 @@ impl OngoingCodegen { } } -pub fn submit_codegened_module_to_llvm( +pub(crate) fn submit_codegened_module_to_llvm( _backend: &B, tx_to_llvm_workers: &Sender>, module: ModuleCodegen, @@ -2120,7 +2120,7 @@ pub fn submit_codegened_module_to_llvm( drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost }))); } -pub fn submit_post_lto_module_to_llvm( +pub(crate) fn submit_post_lto_module_to_llvm( _backend: &B, tx_to_llvm_workers: &Sender>, module: CachedModuleCodegen, @@ -2129,7 +2129,7 @@ pub fn submit_post_lto_module_to_llvm( drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost: 0 }))); } -pub fn submit_pre_lto_module_to_llvm( +pub(crate) fn submit_pre_lto_module_to_llvm( _backend: &B, tcx: TyCtxt<'_>, tx_to_llvm_workers: &Sender>, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f1e7f87f56767..62f47c39b7b95 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -44,7 +44,7 @@ use crate::{ errors, meth, mir, CachedModuleCodegen, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, }; -pub fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { +pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { match op { BinOp::Eq => IntPredicate::IntEQ, BinOp::Ne => IntPredicate::IntNE, @@ -84,7 +84,7 @@ pub fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { } } -pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate { +pub(crate) fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate { match op { BinOp::Eq => RealPredicate::RealOEQ, BinOp::Ne => RealPredicate::RealUNE, @@ -135,7 +135,7 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( /// /// The `old_info` argument is a bit odd. It is intended for use in an upcast, /// where the new vtable for an object will be derived from the old one. -pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, source: Ty<'tcx>, target: Ty<'tcx>, @@ -182,7 +182,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } /// Coerces `src` to `dst_ty`. `src_ty` must be a pointer. -pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, src: Bx::Value, src_ty: Ty<'tcx>, @@ -227,7 +227,7 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } /// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type. -pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, src: Bx::Value, src_ty_and_layout: TyAndLayout<'tcx>, @@ -250,7 +250,7 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( /// Coerces `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty`, and stores the result in `dst`. -pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, src: PlaceRef<'tcx, Bx::Value>, dst: PlaceRef<'tcx, Bx::Value>, @@ -305,7 +305,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( /// /// If `is_unchecked` is true, this does no masking, and adds sufficient `assume` /// calls or operation flags to preserve as much freedom to optimize as possible. -pub fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, lhs: Bx::Value, mut rhs: Bx::Value, @@ -369,11 +369,11 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { /// Returns `true` if this session's target requires the new exception /// handling LLVM IR instructions (catchpad / cleanuppad / ... instead /// of landingpad) -pub fn wants_new_eh_instructions(sess: &Session) -> bool { +pub(crate) fn wants_new_eh_instructions(sess: &Session) -> bool { wants_wasm_eh(sess) || wants_msvc_seh(sess) } -pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, instance: Instance<'tcx>, ) { @@ -999,7 +999,7 @@ impl CrateInfo { } } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { providers.backend_optimization_level = |tcx, cratenum| { let for_speed = match tcx.sess.opts.optimize { // If globally no optimisation is done, #[optimize] has no effect. diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9149c60229668..f8a1398db8599 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -755,6 +755,6 @@ fn check_link_name_xor_ordinal( } } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers }; } diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index bfb1d217eae8a..eb61d5cc96332 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -118,7 +118,7 @@ mod temp_stable_hash_impls { } } -pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &Bx, span: Option, li: LangItem, @@ -129,7 +129,7 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance), instance) } -pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, llty: Bx::Type, mask_llty: Bx::Type, diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs index 0918660e6be88..0867c43eb7f75 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs @@ -54,7 +54,7 @@ pub fn tag_base_type<'tcx>(tcx: TyCtxt<'tcx>, enum_type_and_layout: TyAndLayout< }) } -pub fn tag_base_type_opt<'tcx>( +fn tag_base_type_opt<'tcx>( tcx: TyCtxt<'tcx>, enum_type_and_layout: TyAndLayout<'tcx>, ) -> Option> { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 573a8cf7cbe42..58877379e2686 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -21,7 +21,7 @@ use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(codegen_ssa_incorrect_cgu_reuse_type)] -pub struct IncorrectCguReuseType<'a> { +pub(crate) struct IncorrectCguReuseType<'a> { #[primary_span] pub span: Span, pub cgu_user_name: &'a str, @@ -32,14 +32,14 @@ pub struct IncorrectCguReuseType<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_cgu_not_recorded)] -pub struct CguNotRecorded<'a> { +pub(crate) struct CguNotRecorded<'a> { pub cgu_user_name: &'a str, pub cgu_name: &'a str, } #[derive(Diagnostic)] #[diag(codegen_ssa_unknown_reuse_kind)] -pub struct UnknownReuseKind { +pub(crate) struct UnknownReuseKind { #[primary_span] pub span: Span, pub kind: Symbol, @@ -47,14 +47,14 @@ pub struct UnknownReuseKind { #[derive(Diagnostic)] #[diag(codegen_ssa_missing_query_depgraph)] -pub struct MissingQueryDepGraph { +pub(crate) struct MissingQueryDepGraph { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(codegen_ssa_malformed_cgu_name)] -pub struct MalformedCguName { +pub(crate) struct MalformedCguName { #[primary_span] pub span: Span, pub user_path: String, @@ -63,7 +63,7 @@ pub struct MalformedCguName { #[derive(Diagnostic)] #[diag(codegen_ssa_no_module_named)] -pub struct NoModuleNamed<'a> { +pub(crate) struct NoModuleNamed<'a> { #[primary_span] pub span: Span, pub user_path: &'a str, @@ -73,7 +73,7 @@ pub struct NoModuleNamed<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_field_associated_value_expected)] -pub struct FieldAssociatedValueExpected { +pub(crate) struct FieldAssociatedValueExpected { #[primary_span] pub span: Span, pub name: Symbol, @@ -81,7 +81,7 @@ pub struct FieldAssociatedValueExpected { #[derive(Diagnostic)] #[diag(codegen_ssa_no_field)] -pub struct NoField { +pub(crate) struct NoField { #[primary_span] pub span: Span, pub name: Symbol, @@ -89,49 +89,49 @@ pub struct NoField { #[derive(Diagnostic)] #[diag(codegen_ssa_lib_def_write_failure)] -pub struct LibDefWriteFailure { +pub(crate) struct LibDefWriteFailure { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_version_script_write_failure)] -pub struct VersionScriptWriteFailure { +pub(crate) struct VersionScriptWriteFailure { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_symbol_file_write_failure)] -pub struct SymbolFileWriteFailure { +pub(crate) struct SymbolFileWriteFailure { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_ld64_unimplemented_modifier)] -pub struct Ld64UnimplementedModifier; +pub(crate) struct Ld64UnimplementedModifier; #[derive(Diagnostic)] #[diag(codegen_ssa_linker_unsupported_modifier)] -pub struct LinkerUnsupportedModifier; +pub(crate) struct LinkerUnsupportedModifier; #[derive(Diagnostic)] #[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)] -pub struct L4BenderExportingSymbolsUnimplemented; +pub(crate) struct L4BenderExportingSymbolsUnimplemented; #[derive(Diagnostic)] #[diag(codegen_ssa_no_natvis_directory)] -pub struct NoNatvisDirectory { +pub(crate) struct NoNatvisDirectory { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_no_saved_object_file)] -pub struct NoSavedObjectFile<'a> { +pub(crate) struct NoSavedObjectFile<'a> { pub cgu_name: &'a str, } #[derive(Diagnostic)] #[diag(codegen_ssa_copy_path_buf)] -pub struct CopyPathBuf { +pub(crate) struct CopyPathBuf { pub source_file: PathBuf, pub output_path: PathBuf, pub error: Error, @@ -180,20 +180,20 @@ pub struct IgnoringOutput { #[derive(Diagnostic)] #[diag(codegen_ssa_create_temp_dir)] -pub struct CreateTempDir { +pub(crate) struct CreateTempDir { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_add_native_library)] -pub struct AddNativeLibrary { +pub(crate) struct AddNativeLibrary { pub library_path: PathBuf, pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_multiple_external_func_decl)] -pub struct MultipleExternalFuncDecl<'a> { +pub(crate) struct MultipleExternalFuncDecl<'a> { #[primary_span] pub span: Span, pub function: Symbol, @@ -215,7 +215,7 @@ pub enum LinkRlibError { IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String }, } -pub struct ThorinErrorWrapper(pub thorin::Error); +pub(crate) struct ThorinErrorWrapper(pub thorin::Error); impl Diagnostic<'_, G> for ThorinErrorWrapper { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { @@ -343,7 +343,7 @@ impl Diagnostic<'_, G> for ThorinErrorWrapper { } } -pub struct LinkingFailed<'a> { +pub(crate) struct LinkingFailed<'a> { pub linker_path: &'a PathBuf, pub exit_status: ExitStatus, pub command: &'a Command, @@ -376,28 +376,28 @@ impl Diagnostic<'_, G> for LinkingFailed<'_> { #[derive(Diagnostic)] #[diag(codegen_ssa_link_exe_unexpected_error)] -pub struct LinkExeUnexpectedError; +pub(crate) struct LinkExeUnexpectedError; #[derive(Diagnostic)] #[diag(codegen_ssa_repair_vs_build_tools)] -pub struct RepairVSBuildTools; +pub(crate) struct RepairVSBuildTools; #[derive(Diagnostic)] #[diag(codegen_ssa_missing_cpp_build_tool_component)] -pub struct MissingCppBuildToolComponent; +pub(crate) struct MissingCppBuildToolComponent; #[derive(Diagnostic)] #[diag(codegen_ssa_select_cpp_build_tool_workload)] -pub struct SelectCppBuildToolWorkload; +pub(crate) struct SelectCppBuildToolWorkload; #[derive(Diagnostic)] #[diag(codegen_ssa_visual_studio_not_installed)] -pub struct VisualStudioNotInstalled; +pub(crate) struct VisualStudioNotInstalled; #[derive(Diagnostic)] #[diag(codegen_ssa_linker_not_found)] #[note] -pub struct LinkerNotFound { +pub(crate) struct LinkerNotFound { pub linker_path: PathBuf, pub error: Error, } @@ -406,7 +406,7 @@ pub struct LinkerNotFound { #[diag(codegen_ssa_unable_to_exe_linker)] #[note] #[note(codegen_ssa_command_note)] -pub struct UnableToExeLinker { +pub(crate) struct UnableToExeLinker { pub linker_path: PathBuf, pub error: Error, pub command_formatted: String, @@ -414,38 +414,38 @@ pub struct UnableToExeLinker { #[derive(Diagnostic)] #[diag(codegen_ssa_msvc_missing_linker)] -pub struct MsvcMissingLinker; +pub(crate) struct MsvcMissingLinker; #[derive(Diagnostic)] #[diag(codegen_ssa_self_contained_linker_missing)] -pub struct SelfContainedLinkerMissing; +pub(crate) struct SelfContainedLinkerMissing; #[derive(Diagnostic)] #[diag(codegen_ssa_check_installed_visual_studio)] -pub struct CheckInstalledVisualStudio; +pub(crate) struct CheckInstalledVisualStudio; #[derive(Diagnostic)] #[diag(codegen_ssa_insufficient_vs_code_product)] -pub struct InsufficientVSCodeProduct; +pub(crate) struct InsufficientVSCodeProduct; #[derive(Diagnostic)] #[diag(codegen_ssa_processing_dymutil_failed)] #[note] -pub struct ProcessingDymutilFailed { +pub(crate) struct ProcessingDymutilFailed { pub status: ExitStatus, pub output: String, } #[derive(Diagnostic)] #[diag(codegen_ssa_unable_to_run_dsymutil)] -pub struct UnableToRunDsymutil { +pub(crate) struct UnableToRunDsymutil { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_stripping_debug_info_failed)] #[note] -pub struct StrippingDebugInfoFailed<'a> { +pub(crate) struct StrippingDebugInfoFailed<'a> { pub util: &'a str, pub status: ExitStatus, pub output: String, @@ -453,58 +453,59 @@ pub struct StrippingDebugInfoFailed<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_unable_to_run)] -pub struct UnableToRun<'a> { +pub(crate) struct UnableToRun<'a> { pub util: &'a str, pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_linker_file_stem)] -pub struct LinkerFileStem; +pub(crate) struct LinkerFileStem; #[derive(Diagnostic)] #[diag(codegen_ssa_static_library_native_artifacts)] -pub struct StaticLibraryNativeArtifacts; +pub(crate) struct StaticLibraryNativeArtifacts; #[derive(Diagnostic)] #[diag(codegen_ssa_static_library_native_artifacts_to_file)] -pub struct StaticLibraryNativeArtifactsToFile<'a> { +pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> { pub path: &'a Path, } #[derive(Diagnostic)] #[diag(codegen_ssa_link_script_unavailable)] -pub struct LinkScriptUnavailable; +pub(crate) struct LinkScriptUnavailable; #[derive(Diagnostic)] #[diag(codegen_ssa_link_script_write_failure)] -pub struct LinkScriptWriteFailure { +pub(crate) struct LinkScriptWriteFailure { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_failed_to_write)] -pub struct FailedToWrite { +pub(crate) struct FailedToWrite { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_unable_to_write_debugger_visualizer)] -pub struct UnableToWriteDebuggerVisualizer { +pub(crate) struct UnableToWriteDebuggerVisualizer { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_rlib_archive_build_failure)] -pub struct RlibArchiveBuildFailure { +pub(crate) struct RlibArchiveBuildFailure { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] +// Public for rustc_codegen_llvm::back::archive pub enum ExtractBundledLibsError<'a> { #[diag(codegen_ssa_extract_bundled_libs_open_file)] OpenFile { rlib: &'a Path, error: Box }, @@ -533,26 +534,26 @@ pub enum ExtractBundledLibsError<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_unsupported_arch)] -pub struct UnsupportedArch<'a> { +pub(crate) struct UnsupportedArch<'a> { pub arch: &'a str, pub os: &'a str, } #[derive(Diagnostic)] -pub enum AppleSdkRootError<'a> { +pub(crate) enum AppleSdkRootError<'a> { #[diag(codegen_ssa_apple_sdk_error_sdk_path)] SdkPath { sdk_name: &'a str, error: Error }, } #[derive(Diagnostic)] #[diag(codegen_ssa_read_file)] -pub struct ReadFileError { +pub(crate) struct ReadFileError { pub message: std::io::Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_unsupported_link_self_contained)] -pub struct UnsupportedLinkSelfContained; +pub(crate) struct UnsupportedLinkSelfContained; #[derive(Diagnostic)] #[diag(codegen_ssa_archive_build_failure)] @@ -571,7 +572,7 @@ pub struct UnknownArchiveKind<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_expected_used_symbol)] -pub struct ExpectedUsedSymbol { +pub(crate) struct ExpectedUsedSymbol { #[primary_span] pub span: Span, } @@ -579,45 +580,45 @@ pub struct ExpectedUsedSymbol { #[derive(Diagnostic)] #[diag(codegen_ssa_multiple_main_functions)] #[help] -pub struct MultipleMainFunctions { +pub(crate) struct MultipleMainFunctions { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(codegen_ssa_metadata_object_file_write)] -pub struct MetadataObjectFileWrite { +pub(crate) struct MetadataObjectFileWrite { pub error: Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_invalid_windows_subsystem)] -pub struct InvalidWindowsSubsystem { +pub(crate) struct InvalidWindowsSubsystem { pub subsystem: Symbol, } #[derive(Diagnostic)] #[diag(codegen_ssa_shuffle_indices_evaluation)] -pub struct ShuffleIndicesEvaluation { +pub(crate) struct ShuffleIndicesEvaluation { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(codegen_ssa_missing_memory_ordering)] -pub struct MissingMemoryOrdering; +pub(crate) struct MissingMemoryOrdering; #[derive(Diagnostic)] #[diag(codegen_ssa_unknown_atomic_ordering)] -pub struct UnknownAtomicOrdering; +pub(crate) struct UnknownAtomicOrdering; #[derive(Diagnostic)] #[diag(codegen_ssa_atomic_compare_exchange)] -pub struct AtomicCompareExchange; +pub(crate) struct AtomicCompareExchange; #[derive(Diagnostic)] #[diag(codegen_ssa_unknown_atomic_operation)] -pub struct UnknownAtomicOperation; +pub(crate) struct UnknownAtomicOperation; #[derive(Diagnostic)] pub enum InvalidMonomorphization<'tcx> { @@ -986,7 +987,7 @@ impl IntoDiagArg for ExpectedPointerMutability { #[derive(Diagnostic)] #[diag(codegen_ssa_invalid_no_sanitize)] #[note] -pub struct InvalidNoSanitize { +pub(crate) struct InvalidNoSanitize { #[primary_span] pub span: Span, } @@ -994,7 +995,7 @@ pub struct InvalidNoSanitize { #[derive(Diagnostic)] #[diag(codegen_ssa_invalid_link_ordinal_nargs)] #[note] -pub struct InvalidLinkOrdinalNargs { +pub(crate) struct InvalidLinkOrdinalNargs { #[primary_span] pub span: Span, } @@ -1002,14 +1003,14 @@ pub struct InvalidLinkOrdinalNargs { #[derive(Diagnostic)] #[diag(codegen_ssa_illegal_link_ordinal_format)] #[note] -pub struct InvalidLinkOrdinalFormat { +pub(crate) struct InvalidLinkOrdinalFormat { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(codegen_ssa_target_feature_safe_trait)] -pub struct TargetFeatureSafeTrait { +pub(crate) struct TargetFeatureSafeTrait { #[primary_span] #[label] pub span: Span, @@ -1050,7 +1051,7 @@ pub(crate) struct ErrorCallingDllTool<'a> { #[derive(Diagnostic)] #[diag(codegen_ssa_error_creating_remark_dir)] -pub struct ErrorCreatingRemarkDir { +pub(crate) struct ErrorCreatingRemarkDir { pub error: std::io::Error, } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c89bfca668789..f6570532b97fb 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -128,7 +128,7 @@ impl CompiledModule { } } -pub struct CachedModuleCodegen { +pub(crate) struct CachedModuleCodegen { pub name: String, pub source: WorkProduct, } diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index c9602d9cdae1e..ecc3b2b24f1cf 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -8,10 +8,10 @@ use tracing::{debug, instrument}; use crate::traits::*; #[derive(Copy, Clone, Debug)] -pub struct VirtualIndex(u64); +pub(crate) struct VirtualIndex(u64); impl<'a, 'tcx> VirtualIndex { - pub fn from_index(index: usize) -> Self { + pub(crate) fn from_index(index: usize) -> Self { VirtualIndex(index as u64) } @@ -51,7 +51,7 @@ impl<'a, 'tcx> VirtualIndex { } } - pub fn get_optional_fn>( + pub(crate) fn get_optional_fn>( self, bx: &mut Bx, llvtable: Bx::Value, @@ -61,7 +61,7 @@ impl<'a, 'tcx> VirtualIndex { self.get_fn_inner(bx, llvtable, ty, fn_abi, false) } - pub fn get_fn>( + pub(crate) fn get_fn>( self, bx: &mut Bx, llvtable: Bx::Value, @@ -71,7 +71,7 @@ impl<'a, 'tcx> VirtualIndex { self.get_fn_inner(bx, llvtable, ty, fn_abi, true) } - pub fn get_usize>( + pub(crate) fn get_usize>( self, bx: &mut Bx, llvtable: Bx::Value, @@ -115,7 +115,7 @@ fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { /// making an object `Foo` from a value of type `Foo`, then /// `trait_ref` would map `T: Trait`. #[instrument(level = "debug", skip(cx))] -pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( +pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( cx: &Cx, ty: Ty<'tcx>, trait_ref: Option>, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 8f96c46224098..e27d53baf0f48 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1215,7 +1215,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn codegen_block(&mut self, mut bb: mir::BasicBlock) { + pub(crate) fn codegen_block(&mut self, mut bb: mir::BasicBlock) { let llbb = match self.try_llbb(bb) { Some(llbb) => llbb, None => return, @@ -1255,7 +1255,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) { + pub(crate) fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) { let llbb = match self.try_llbb(bb) { Some(llbb) => llbb, None => return, @@ -1740,7 +1740,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } /// Like `llbb`, but may fail if the basic block should be skipped. - pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option { + pub(crate) fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option { match self.cached_llbbs[bb] { CachedLlbb::None => { let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}")); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 8254fb3d8661e..3f8ddfe1fe7a7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -10,7 +10,7 @@ use crate::mir::operand::OperandRef; use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn eval_mir_constant_to_operand( + pub(crate) fn eval_mir_constant_to_operand( &self, bx: &mut Bx, constant: &mir::ConstOperand<'tcx>, @@ -33,7 +33,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip. /// /// Note that this function is cursed, since usually MIR consts should not be evaluated to valtrees! - pub fn eval_unevaluated_mir_constant_to_valtree( + fn eval_unevaluated_mir_constant_to_valtree( &self, constant: &mir::ConstOperand<'tcx>, ) -> Result, Ty<'tcx>>, ErrorHandled> { diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index 67f1ef5d9449c..52e749f4fb75f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -5,7 +5,7 @@ use super::FunctionCx; use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) { + pub(crate) fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) { // Determine the instance that coverage data was originally generated for. let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) { self.monomorphize(inlined) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index ab08ef72a697b..cfffc09ecbc0b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Apply debuginfo and/or name, after creating the `alloca` for a local, /// or initializing the local with an operand (whichever applies). - pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { + pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; let vars = match &self.per_local_var_debug_info { @@ -426,7 +426,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn debug_introduce_locals(&self, bx: &mut Bx) { + pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) { if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() { for local in self.locals.indices() { self.debug_introduce_local(bx, local); @@ -435,7 +435,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`. - pub fn compute_per_local_var_debug_info( + pub(crate) fn compute_per_local_var_debug_info( &self, bx: &mut Bx, ) -> Option>>> { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index de94d87bcea7a..61e9b9bd774e8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -15,8 +15,8 @@ use crate::traits::*; mod analyze; mod block; -pub mod constant; -pub mod coverageinfo; +mod constant; +mod coverageinfo; pub mod debuginfo; mod intrinsic; mod locals; diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 1891de8c0eb37..f0f93f8c6cb63 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -64,7 +64,7 @@ impl OperandValue { /// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values. /// If this is Ref, return the place. #[inline] - pub fn immediates_or_place(self) -> Either, PlaceValue> { + pub(crate) fn immediates_or_place(self) -> Either, PlaceValue> { match self { OperandValue::ZeroSized => Either::Left(ArrayVec::new()), OperandValue::Immediate(a) => Either::Left(ArrayVec::from_iter([a])), @@ -75,7 +75,7 @@ impl OperandValue { /// Given an array of 0/1/2 immediate values, return ZeroSized/Immediate/Pair. #[inline] - pub fn from_immediates(immediates: ArrayVec) -> Self { + pub(crate) fn from_immediates(immediates: ArrayVec) -> Self { let mut it = immediates.into_iter(); let Some(a) = it.next() else { return OperandValue::ZeroSized; @@ -90,7 +90,7 @@ impl OperandValue { /// optional metadata as backend values. /// /// If you're making a place, use [`Self::deref`] instead. - pub fn pointer_parts(self) -> (V, Option) { + pub(crate) fn pointer_parts(self) -> (V, Option) { match self { OperandValue::Immediate(llptr) => (llptr, None), OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), @@ -105,7 +105,7 @@ impl OperandValue { /// alignment, then maybe you want [`OperandRef::deref`] instead. /// /// This is the inverse of [`PlaceValue::address`]. - pub fn deref(self, align: Align) -> PlaceValue { + pub(crate) fn deref(self, align: Align) -> PlaceValue { let (llval, llextra) = self.pointer_parts(); PlaceValue { llval, llextra, align } } @@ -153,7 +153,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { OperandRef { val: OperandValue::ZeroSized, layout } } - pub fn from_const>( + pub(crate) fn from_const>( bx: &mut Bx, val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, @@ -334,7 +334,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { OperandRef { val, layout } } - pub fn extract_field>( + pub(crate) fn extract_field>( &self, bx: &mut Bx, i: usize, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 91fd9905f63cc..863af730ae717 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -19,7 +19,7 @@ use crate::{base, MemFlags}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] - pub fn codegen_rvalue( + pub(crate) fn codegen_rvalue( &mut self, bx: &mut Bx, dest: PlaceRef<'tcx, Bx::Value>, @@ -419,7 +419,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn codegen_rvalue_unsized( + pub(crate) fn codegen_rvalue_unsized( &mut self, bx: &mut Bx, indirect_dest: PlaceRef<'tcx, Bx::Value>, @@ -440,7 +440,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn codegen_rvalue_operand( + pub(crate) fn codegen_rvalue_operand( &mut self, bx: &mut Bx, rvalue: &mir::Rvalue<'tcx>, @@ -836,7 +836,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) } } - pub fn codegen_scalar_binop( + fn codegen_scalar_binop( &mut self, bx: &mut Bx, op: mir::BinOp, @@ -981,7 +981,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn codegen_fat_ptr_binop( + fn codegen_fat_ptr_binop( &mut self, bx: &mut Bx, op: mir::BinOp, @@ -1023,7 +1023,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub fn codegen_scalar_checked_binop( + fn codegen_scalar_checked_binop( &mut self, bx: &mut Bx, op: mir::BinOp, @@ -1050,7 +1050,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { + pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => { let operand_ty = operand.ty(self.mir, self.cx.tcx()); diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 73283cafb4947..6338d16c897f6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -7,7 +7,7 @@ use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "debug", skip(self, bx))] - pub fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) { + pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) { self.set_debug_loc(bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(box (ref place, ref rvalue)) => { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index cf8f7fa25d856..0349d5817b451 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -15,7 +15,7 @@ use rustc_span::Span; use crate::errors; -pub fn from_target_feature( +pub(crate) fn from_target_feature( tcx: TyCtxt<'_>, attr: &ast::Attribute, supported_target_features: &UnordMap>, @@ -146,7 +146,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet { /// Checks the function annotated with `#[target_feature]` is not a safe /// trait method implementation, reporting an error if it is. -pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) { +pub(crate) fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) { if let DefKind::AssocFn = tcx.def_kind(id) { let parent_id = tcx.local_parent(id); if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) { From cd3da000c0ea2e1ce77a18587a7acdb01bf7fd23 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Sep 2024 09:59:50 +1000 Subject: [PATCH 19/24] Clean up formatting. Reflow overly long comments, plus some minor whitespace improvements. --- compiler/rustc_codegen_ssa/src/base.rs | 6 ++-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 29 ++++++++++--------- compiler/rustc_codegen_ssa/src/common.rs | 3 +- .../rustc_codegen_ssa/src/debuginfo/mod.rs | 6 ++-- .../src/debuginfo/type_names.rs | 3 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 12 ++++---- .../rustc_codegen_ssa/src/mir/constant.rs | 21 +++++++------- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 1 + compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 +-- compiler/rustc_codegen_ssa/src/size_of_val.rs | 25 ++++++++++------ .../rustc_codegen_ssa/src/traits/backend.rs | 7 +++++ compiler/rustc_codegen_ssa/src/traits/misc.rs | 3 +- 12 files changed, 72 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 62f47c39b7b95..d0379e1097538 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -154,7 +154,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); if data_a.principal_def_id() == data_b.principal_def_id() { - // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables. + // A NOP cast that doesn't actually change anything, should be allowed even with + // invalid vtables. return old_info; } @@ -985,7 +986,8 @@ impl CrateInfo { false } CrateType::Staticlib | CrateType::Rlib => { - // We don't invoke the linker for these, so we don't need to collect the NatVis for them. + // We don't invoke the linker for these, so we don't need to collect the NatVis for + // them. false } }); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index f8a1398db8599..137e481f08ccb 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -317,9 +317,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { "extern mutable statics are not allowed with `#[linkage]`", ); diag.note( - "marking the extern static mutable would allow changing which symbol \ - the static references rather than make the target of the symbol \ - mutable", + "marking the extern static mutable would allow changing which \ + symbol the static references rather than make the target of the \ + symbol mutable", ); diag.emit(); } @@ -711,18 +711,19 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option { if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list { - // According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, - // the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined - // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information - // to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t. + // According to the table at + // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the + // ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined + // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import + // information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t. // - // FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for this: - // both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies - // a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library - // for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import - // library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I don't know yet - // if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment - // about LINK.EXE failing.) + // FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for + // this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that + // specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import + // library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an + // import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I + // don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL -- + // see earlier comment about LINK.EXE failing.) if *ordinal <= u16::MAX as u128 { Some(ordinal.get() as u16) } else { diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index eb61d5cc96332..582a2a87e4867 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -200,7 +200,8 @@ pub fn i686_decorated_name( let mut decorated_name = String::with_capacity(name.len() + 6); if disable_name_mangling { - // LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled. + // LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be + // disabled. decorated_name.push('\x01'); } diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs index 0867c43eb7f75..bfd1b94c7903f 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs @@ -76,9 +76,9 @@ fn tag_base_type_opt<'tcx>( Primitive::Float(f) => Integer::from_size(f.size()).unwrap(), // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => { - // If the niche is the NULL value of a reference, then `discr_enum_ty` will be - // a RawPtr. CodeView doesn't know what to do with enums whose base type is a - // pointer so we fix this up to just be `usize`. + // If the niche is the NULL value of a reference, then `discr_enum_ty` will + // be a RawPtr. CodeView doesn't know what to do with enums whose base type + // is a pointer so we fix this up to just be `usize`. // DWARF might be able to deal with this but with an integer type we are on // the safe side there too. tcx.data_layout.ptr_sized_integer() diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index e34fbfe3f7614..101e2c824c52f 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -95,7 +95,8 @@ fn push_debuginfo_type_name<'tcx>( } Err(e) => { // Computing the layout can still fail here, e.g. if the target architecture - // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961. + // cannot represent the type. See + // https://github.com/rust-lang/rust/issues/94961. tcx.dcx().emit_fatal(e.into_diagnostic()); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e27d53baf0f48..fc7b2aba5ee61 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -996,7 +996,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // To get a `*mut RcBox`, we just keep unwrapping newtypes until // we get a value of a built-in pointer type. // - // This is also relevant for `Pin<&mut Self>`, where we need to peel the `Pin`. + // This is also relevant for `Pin<&mut Self>`, where we need to peel the + // `Pin`. while !op.layout.ty.is_unsafe_ptr() && !op.layout.ty.is_ref() { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", @@ -1004,9 +1005,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { op = op.extract_field(bx, idx); } - // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its + // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its // data pointer and vtable. Look up the method in the vtable, and pass - // the data pointer as the first argument + // the data pointer as the first argument. llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( bx, meta, @@ -1440,8 +1441,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (mut llval, align, by_ref) = match op.val { Immediate(_) | Pair(..) => match arg.mode { PassMode::Indirect { attrs, .. } => { - // Indirect argument may have higher alignment requirements than the type's alignment. - // This can happen, e.g. when passing types with <4 byte alignment on the stack on x86. + // Indirect argument may have higher alignment requirements than the type's + // alignment. This can happen, e.g. when passing types with <4 byte alignment + // on the stack on x86. let required_align = match attrs.pointee_align { Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi), None => arg.layout.align.abi, diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 3f8ddfe1fe7a7..15f45b226f5e4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -32,7 +32,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// that the given `constant` is an `Const::Unevaluated` and must be convertible to /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip. /// - /// Note that this function is cursed, since usually MIR consts should not be evaluated to valtrees! + /// Note that this function is cursed, since usually MIR consts should not be evaluated to + /// valtrees! fn eval_unevaluated_mir_constant_to_valtree( &self, constant: &mir::ConstOperand<'tcx>, @@ -40,19 +41,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let uv = match self.monomorphize(constant.const_) { mir::Const::Unevaluated(uv, _) => uv.shrink(), mir::Const::Ty(_, c) => match c.kind() { - // A constant that came from a const generic but was then used as an argument to old-style - // simd_shuffle (passing as argument instead of as a generic param). + // A constant that came from a const generic but was then used as an argument to + // old-style simd_shuffle (passing as argument instead of as a generic param). rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)), other => span_bug!(constant.span, "{other:#?}"), }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate - // a constant and write that value back into `Operand`s. This could happen, but is unlikely. - // Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care - // around intrinsics. For an issue to happen here, it would require a macro expanding to a - // `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but - // the user pass through arbitrary expressions. - // FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a real - // const generic, and get rid of this entire function. + // a constant and write that value back into `Operand`s. This could happen, but is + // unlikely. Also: all users of `simd_shuffle` are on unstable and already need to take + // a lot of care around intrinsics. For an issue to happen here, it would require a + // macro expanding to a `simd_shuffle` call without wrapping the constant argument in a + // `const {}` block, but the user pass through arbitrary expressions. + // FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a + // real const generic, and get rid of this entire function. other => span_bug!(constant.span, "{other:#?}"), }; let uv = self.monomorphize(uv); diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index cfffc09ecbc0b..5b36a11aa2546 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -24,6 +24,7 @@ pub struct FunctionDebugContext<'tcx, S, L> { /// Maps from an inlined function to its debug info declaration. pub inlined_function_scopes: FxHashMap, S>, } + #[derive(Copy, Clone)] pub enum VariableKind { ArgumentVariable(usize /*index*/), diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index f0f93f8c6cb63..8afd5e867b5c3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -478,8 +478,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); match self { OperandValue::ZeroSized => { - // Avoid generating stores of zero-sized values, because the only way to have a zero-sized - // value is through `undef`/`poison`, and the store itself is useless. + // Avoid generating stores of zero-sized values, because the only way to have a + // zero-sized value is through `undef`/`poison`, and the store itself is useless. } OperandValue::Ref(val) => { assert!(dest.layout.is_sized(), "cannot directly store unsized values"); diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index 933904f984505..3f3ae21035d5a 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -45,11 +45,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // The info in this case is the length of the str, so the size is that // times the unit size. ( - // All slice sizes must fit into `isize`, so this multiplication cannot (signed) wrap. + // All slice sizes must fit into `isize`, so this multiplication cannot (signed) + // wrap. // NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul` // (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication - // cannot signed wrap, and that both operands are non-negative. But at the time of writing, - // the `LLVM-C` binding can't do this, and it doesn't seem to enable any further optimizations. + // cannot signed wrap, and that both operands are non-negative. But at the time of + // writing, the `LLVM-C` binding can't do this, and it doesn't seem to enable any + // further optimizations. bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())), bx.const_usize(unit.align.abi.bytes()), ) @@ -67,9 +69,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let (fn_abi, llfn, _instance) = common::build_langcall(bx, None, LangItem::PanicNounwind); - // Generate the call. - // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`. - // (But we are in good company, this code is duplicated plenty of times.) + // Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we + // can't create a `TerminationCodegenHelper`. (But we are in good company, this code is + // duplicated plenty of times.) let fn_ty = bx.fn_decl_backend_type(fn_abi); bx.call( @@ -148,9 +150,14 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // The full formula for the size would be: // let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align); // let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align); - // However, `unsized_size` is a multiple of `unsized_align`. - // Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`: - // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align); + // However, `unsized_size` is a multiple of `unsized_align`. Therefore, we can + // equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`: + // + // let full_size = + // (unsized_offset_unadjusted + unsized_size) + // .align_to(unsized_align) + // .align_to(full_align); + // // Furthermore, `align >= unsized_align`, and therefore we only need to do: // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index c5e2d55be833d..4fc44e9c0fcec 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -59,11 +59,15 @@ pub trait CodegenBackend { fn locale_resource(&self) -> &'static str; fn init(&self, _sess: &Session) {} + fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {} + fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { vec![] } + fn print_passes(&self) {} + fn print_version(&self) {} /// The metadata loader used to load rlib and dylib metadata. @@ -75,6 +79,7 @@ pub trait CodegenBackend { } fn provide(&self, _providers: &mut Providers) {} + fn codegen_crate<'tcx>( &self, tcx: TyCtxt<'tcx>, @@ -120,6 +125,7 @@ pub trait ExtraBackendMethods: kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module; + /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. fn compile_codegen_unit( @@ -127,6 +133,7 @@ pub trait ExtraBackendMethods: tcx: TyCtxt<'_>, cgu_name: Symbol, ) -> (ModuleCodegen, u64); + fn target_machine_factory( &self, sess: &Session, diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 40a49b3e1b578..bf1b7eabe236a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -25,6 +25,7 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>; fn set_frame_pointer_type(&self, llfn: Self::Function); fn apply_target_cpu_attr(&self, llfn: Self::Function); - /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists. + /// Declares the extern "C" main function for the entry point. Returns None if the symbol + /// already exists. fn declare_c_main(&self, fn_type: Self::Type) -> Option; } From 52c5de00dc63a0df8c79a681a775e0b5795e0679 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Sep 2024 09:55:04 +1000 Subject: [PATCH 20/24] Streamline `bin_op_to_[if]cmp_predicate`. --- compiler/rustc_codegen_ssa/src/base.rs | 56 ++++++-------------------- 1 file changed, 13 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index d0379e1097538..15edf7e73058a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -45,42 +45,18 @@ use crate::{ }; pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { - match op { - BinOp::Eq => IntPredicate::IntEQ, - BinOp::Ne => IntPredicate::IntNE, - BinOp::Lt => { - if signed { - IntPredicate::IntSLT - } else { - IntPredicate::IntULT - } - } - BinOp::Le => { - if signed { - IntPredicate::IntSLE - } else { - IntPredicate::IntULE - } - } - BinOp::Gt => { - if signed { - IntPredicate::IntSGT - } else { - IntPredicate::IntUGT - } - } - BinOp::Ge => { - if signed { - IntPredicate::IntSGE - } else { - IntPredicate::IntUGE - } - } - op => bug!( - "comparison_op_to_icmp_predicate: expected comparison operator, \ - found {:?}", - op - ), + match (op, signed) { + (BinOp::Eq, _) => IntPredicate::IntEQ, + (BinOp::Ne, _) => IntPredicate::IntNE, + (BinOp::Lt, true) => IntPredicate::IntSLT, + (BinOp::Lt, false) => IntPredicate::IntULT, + (BinOp::Le, true) => IntPredicate::IntSLE, + (BinOp::Le, false) => IntPredicate::IntULE, + (BinOp::Gt, true) => IntPredicate::IntSGT, + (BinOp::Gt, false) => IntPredicate::IntUGT, + (BinOp::Ge, true) => IntPredicate::IntSGE, + (BinOp::Ge, false) => IntPredicate::IntUGE, + op => bug!("bin_op_to_icmp_predicate: expected comparison operator, found {:?}", op), } } @@ -92,13 +68,7 @@ pub(crate) fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate { BinOp::Le => RealPredicate::RealOLE, BinOp::Gt => RealPredicate::RealOGT, BinOp::Ge => RealPredicate::RealOGE, - op => { - bug!( - "comparison_op_to_fcmp_predicate: expected comparison operator, \ - found {:?}", - op - ); - } + op => bug!("bin_op_to_fcmp_predicate: expected comparison operator, found {:?}", op), } } From b3b56d805fb0d431a37d56c453602916653dfddc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Sep 2024 10:22:06 +1000 Subject: [PATCH 21/24] Remove unnecessary `cx` argument. Because `bx` contains a `cx`. --- compiler/rustc_codegen_ssa/src/base.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 15edf7e73058a..f6b45eb4466fb 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -425,7 +425,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let isize_ty = cx.type_isize(); let ptr_ty = cx.type_ptr(); - let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx); + let (arg_argc, arg_argv) = get_argc_argv(&mut bx); let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type { @@ -468,33 +468,30 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } /// Obtain the `argc` and `argv` values to pass to the rust start function. -fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - cx: &'a Bx::CodegenCx, - bx: &mut Bx, -) -> (Bx::Value, Bx::Value) { - if cx.sess().target.os.contains("uefi") { +fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) { + if bx.cx().sess().target.os.contains("uefi") { // Params for UEFI let param_handle = bx.get_param(0); let param_system_table = bx.get_param(1); let ptr_size = bx.tcx().data_layout.pointer_size; let ptr_align = bx.tcx().data_layout.pointer_align.abi; - let arg_argc = bx.const_int(cx.type_isize(), 2); + let arg_argc = bx.const_int(bx.cx().type_isize(), 2); let arg_argv = bx.alloca(2 * ptr_size, ptr_align); bx.store(param_handle, arg_argv, ptr_align); let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes())); bx.store(param_system_table, arg_argv_el1, ptr_align); (arg_argc, arg_argv) - } else if cx.sess().target.main_needs_argc_argv { + } else if bx.cx().sess().target.main_needs_argc_argv { // Params from native `main()` used as args for rust start function let param_argc = bx.get_param(0); let param_argv = bx.get_param(1); - let arg_argc = bx.intcast(param_argc, cx.type_isize(), true); + let arg_argc = bx.intcast(param_argc, bx.cx().type_isize(), true); let arg_argv = param_argv; (arg_argc, arg_argv) } else { // The Rust start function doesn't need `argc` and `argv`, so just pass zeros. - let arg_argc = bx.const_int(cx.type_int(), 0); - let arg_argv = bx.const_null(cx.type_ptr()); + let arg_argc = bx.const_int(bx.cx().type_int(), 0); + let arg_argv = bx.const_null(bx.cx().type_ptr()); (arg_argc, arg_argv) } } From ae1f092307986627ac18887ebf169ce35ef3046e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Sep 2024 16:31:59 +1000 Subject: [PATCH 22/24] Streamline `coroutine_kind_label`. --- .../src/debuginfo/type_names.rs | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 101e2c824c52f..55a71db9baebd 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -576,33 +576,20 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: & } fn coroutine_kind_label(coroutine_kind: Option) -> &'static str { + use CoroutineDesugaring::*; + use CoroutineKind::*; + use CoroutineSource::*; match coroutine_kind { - Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Block)) => { - "gen_block" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Closure)) => { - "gen_closure" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Fn)) => "gen_fn", - Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) => { - "async_block" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)) => { - "async_closure" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Fn)) => { - "async_fn" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Block)) => { - "async_gen_block" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Closure)) => { - "async_gen_closure" - } - Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => { - "async_gen_fn" - } - Some(CoroutineKind::Coroutine(_)) => "coroutine", + Some(Desugared(Gen, Block)) => "gen_block", + Some(Desugared(Gen, Closure)) => "gen_closure", + Some(Desugared(Gen, Fn)) => "gen_fn", + Some(Desugared(Async, Block)) => "async_block", + Some(Desugared(Async, Closure)) => "async_closure", + Some(Desugared(Async, Fn)) => "async_fn", + Some(Desugared(AsyncGen, Block)) => "async_gen_block", + Some(Desugared(AsyncGen, Closure)) => "async_gen_closure", + Some(Desugared(AsyncGen, Fn)) => "async_gen_fn", + Some(Coroutine(_)) => "coroutine", None => "closure", } } From 3ec2f121cc92879bdfc6aa80c29841b7e3a779e1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 Sep 2024 17:06:44 +1000 Subject: [PATCH 23/24] Rename some lifetimes. `'mir` is not a good lifetime name in `LocalAnalyzer`, because it's used on two unrelated fields. `'a` is more standard for a situation like this (e.g. #130022). --- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 386e1f91e7f0c..f13c46e8befdd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -69,13 +69,13 @@ enum LocalKind { SSA(DefLocation), } -struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { - fx: &'mir FunctionCx<'a, 'tcx, Bx>, - dominators: &'mir Dominators, +struct LocalAnalyzer<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> { + fx: &'a FunctionCx<'b, 'tcx, Bx>, + dominators: &'a Dominators, locals: IndexVec, } -impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { +impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> { fn define(&mut self, local: mir::Local, location: DefLocation) { let kind = &mut self.locals[local]; match *kind { @@ -152,9 +152,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, } } -impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> - for LocalAnalyzer<'mir, 'a, 'tcx, Bx> -{ +impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer<'a, 'b, 'tcx, Bx> { fn visit_assign( &mut self, place: &mir::Place<'tcx>, From c629538dadd4b33554125d1e10df4252e0f070c4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 13 Sep 2024 15:01:06 +1000 Subject: [PATCH 24/24] Merge some impl blocks. --- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 -- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index fc7b2aba5ee61..f23ae7abafdb3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1213,9 +1213,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mergeable_succ, ) } -} -impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub(crate) fn codegen_block(&mut self, mut bb: mir::BasicBlock) { let llbb = match self.try_llbb(bb) { Some(llbb) => llbb, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 863af730ae717..37474d85b11b6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1047,9 +1047,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Pair(val, of) } -} -impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => {