From 4913ab8f779582dc9da099a148a4670ede0e15aa Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Tue, 20 Feb 2024 20:55:13 -0700 Subject: [PATCH 001/101] Stabilize `LazyCell` and `LazyLock` (`lazy_cell`) --- .../rustc_const_eval/src/check_consts/ops.rs | 2 +- compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_error_messages/src/lib.rs | 1 - compiler/rustc_feature/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_interface/src/lib.rs | 1 - compiler/rustc_lint_defs/src/builtin.rs | 10 ++--- compiler/rustc_session/src/lib.rs | 1 - library/core/src/cell.rs | 2 +- library/core/src/cell/lazy.rs | 20 ++++----- library/core/tests/lib.rs | 1 - library/std/src/lib.rs | 1 - library/std/src/sync/lazy_lock.rs | 41 +++++++++++-------- library/std/src/sync/mod.rs | 2 +- src/librustdoc/lib.rs | 1 - src/tools/clippy/clippy_dev/src/lib.rs | 1 - src/tools/clippy/src/driver.rs | 1 - src/tools/clippy/tests/compile-test.rs | 1 - src/tools/clippy/tests/dogfood.rs | 1 - .../clippy/tests/lint_message_convention.rs | 1 - src/tools/clippy/tests/workspace.rs | 2 - tests/ui/borrowck/issue-64453.stderr | 2 +- tests/ui/consts/issue-16538.stderr | 2 +- tests/ui/consts/issue-32829-2.stderr | 4 +- tests/ui/consts/mir_check_nonconst.stderr | 2 +- tests/ui/issues/issue-25901.stderr | 2 +- tests/ui/issues/issue-7364.stderr | 2 +- tests/ui/lint/suspicious-double-ref-op.rs | 1 - tests/ui/lint/suspicious-double-ref-op.stderr | 10 ++--- .../issue-35813-postfix-after-cast.stderr | 2 +- .../nested-closure.rs | 2 +- .../ui/static/static-mut-not-constant.stderr | 2 +- .../static-vec-repeat-not-constant.stderr | 2 +- .../statics/check-values-constraints.stderr | 16 ++++---- 34 files changed, 60 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 8406e0f48762..90b622cae656 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -309,7 +309,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } if let ConstContext::Static(_) = ccx.const_kind() { - err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell"); + err.note("consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`"); } err diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 85b5a3cdb7c3..9781aae22eb3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -24,7 +24,6 @@ #![feature(extend_one)] #![feature(hash_raw_entry)] #![feature(hasher_prefixfree_extras)] -#![feature(lazy_cell)] #![feature(lint_reasons)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2a8f42220640..08388c5a58ed 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,6 +1,5 @@ #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] #![allow(internal_features)] diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 36ef8fe7816f..9cbf836ec76f 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -14,7 +14,6 @@ #![allow(internal_features)] #![feature(rustdoc_internals)] #![doc(rust_logo)] -#![feature(lazy_cell)] mod accepted; mod builtin_attrs; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index d1e50e13894a..8fe81851f932 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -68,7 +68,6 @@ This API is completely unstable and subject to change. #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] -#![feature(lazy_cell)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index c1d460ddd086..8b1d9b706cac 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,5 +1,4 @@ #![feature(decl_macro)] -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(thread_spawn_unchecked)] #![feature(try_blocks)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 617fe99ef6a7..747b7292a199 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1316,10 +1316,8 @@ declare_lint! { /// * If you are trying to perform a one-time initialization of a global: /// * If the value can be computed at compile-time, consider using /// const-compatible values (see [Constant Evaluation]). - /// * For more complex single-initialization cases, consider using a - /// third-party crate, such as [`lazy_static`] or [`once_cell`]. - /// * If you are using the [nightly channel], consider the new - /// [`lazy`] module in the standard library. + /// * For more complex single-initialization cases, consider using + /// [`std::sync::LazyLock`]. /// * If you truly need a mutable global, consider using a [`static`], /// which has a variety of options: /// * Simple data types can be directly defined and mutated with an @@ -1334,9 +1332,7 @@ declare_lint! { /// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html /// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html /// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics - /// [`lazy`]: https://doc.rust-lang.org/nightly/std/lazy/index.html - /// [`lazy_static`]: https://crates.io/crates/lazy_static - /// [`once_cell`]: https://crates.io/crates/once_cell + /// [`std::sync::LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html /// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html /// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html pub CONST_ITEM_MUTATION, diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index ce866906e1e6..cb02fbdfee9e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,5 +1,4 @@ #![feature(let_chains)] -#![feature(lazy_cell)] #![feature(option_get_or_insert_default)] #![feature(rustc_attrs)] #![feature(map_many_mut)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 4b491ffdafa7..ac026de95da1 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -245,7 +245,7 @@ use crate::ptr::{self, NonNull}; mod lazy; mod once; -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub use lazy::LazyCell; #[stable(feature = "once_cell", since = "1.70.0")] pub use once::OnceCell; diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 1b213f6a2941..47eab6fd0163 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -18,8 +18,6 @@ enum State { /// # Examples /// /// ``` -/// #![feature(lazy_cell)] -/// /// use std::cell::LazyCell; /// /// let lazy: LazyCell = LazyCell::new(|| { @@ -36,7 +34,7 @@ enum State { /// // 92 /// // 92 /// ``` -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub struct LazyCell T> { state: UnsafeCell>, } @@ -47,8 +45,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::cell::LazyCell; /// /// let hello = "Hello, World!".to_string(); @@ -58,7 +54,8 @@ impl T> LazyCell { /// assert_eq!(&*lazy, "HELLO, WORLD!"); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new(f: F) -> LazyCell { LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } @@ -70,7 +67,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] /// #![feature(lazy_cell_consume)] /// /// use std::cell::LazyCell; @@ -99,8 +95,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::cell::LazyCell; /// /// let lazy = LazyCell::new(|| 92); @@ -109,7 +103,7 @@ impl T> LazyCell { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub fn force(this: &LazyCell) -> &T { // SAFETY: // This invalidates any mutable references to the data. The resulting @@ -173,7 +167,7 @@ impl LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl T> Deref for LazyCell { type Target = T; #[inline] @@ -182,7 +176,7 @@ impl T> Deref for LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Default for LazyCell { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -191,7 +185,7 @@ impl Default for LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for LazyCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyCell"); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 797108a8425d..e6828f6cb4ea 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -96,7 +96,6 @@ #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_metadata)] -#![feature(lazy_cell)] #![feature(unsized_tuple_coercion)] #![feature(const_option)] #![feature(const_option_ext)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4a18db3d5a3f..9d6576fa8411 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -395,7 +395,6 @@ #![feature(edition_panic)] #![feature(format_args_nl)] #![feature(get_many_mut)] -#![feature(lazy_cell)] #![feature(log_syntax)] #![feature(test)] #![feature(trace_macros)] diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 27b59cfc8c24..16d5dc30552f 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -31,8 +31,6 @@ union Data { /// Initialize static variables with `LazyLock`. /// /// ``` -/// #![feature(lazy_cell)] -/// /// use std::collections::HashMap; /// /// use std::sync::LazyLock; @@ -61,8 +59,6 @@ union Data { /// ``` /// Initialize fields with `LazyLock`. /// ``` -/// #![feature(lazy_cell)] -/// /// use std::sync::LazyLock; /// /// #[derive(Debug)] @@ -76,8 +72,7 @@ union Data { /// println!("{}", *data.number); /// } /// ``` - -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub struct LazyLock T> { once: Once, data: UnsafeCell>, @@ -85,8 +80,21 @@ pub struct LazyLock T> { impl T> LazyLock { /// Creates a new lazy value with the given initializing function. + /// + /// # Examples + /// + /// ``` + /// use std::sync::LazyLock; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = LazyLock::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new(f: F) -> LazyLock { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } @@ -107,7 +115,6 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] /// #![feature(lazy_cell_consume)] /// /// use std::sync::LazyLock; @@ -145,8 +152,6 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::sync::LazyLock; /// /// let lazy = LazyLock::new(|| 92); @@ -155,7 +160,7 @@ impl T> LazyLock { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub fn force(this: &LazyLock) -> &T { this.once.call_once(|| { // SAFETY: `call_once` only runs this closure once, ever. @@ -191,7 +196,7 @@ impl LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { @@ -204,7 +209,7 @@ impl Drop for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl T> Deref for LazyLock { type Target = T; @@ -219,7 +224,7 @@ impl T> Deref for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Default for LazyLock { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -228,7 +233,7 @@ impl Default for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for LazyLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyLock"); @@ -242,13 +247,13 @@ impl fmt::Debug for LazyLock { // We never create a `&F` from a `&LazyLock` so it is fine // to not impl `Sync` for `F`. -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] unsafe impl Sync for LazyLock {} // auto-derived `Send` impl is OK. -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl RefUnwindSafe for LazyLock {} -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl UnwindSafe for LazyLock {} #[cfg(test)] diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index e8c35bd48a70..fb7d601b0947 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -179,7 +179,7 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub use self::lazy_lock::LazyLock; #[stable(feature = "once_cell", since = "1.70.0")] pub use self::once_lock::OnceLock; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0650afb90c7e..55346c768b66 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(never_type)] #![feature(round_char_boundary)] diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index 385191e0361b..3aa43dbe23ed 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(rustc_private)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 9e42abbc9aa9..f79da26964f3 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -2,7 +2,6 @@ #![allow(rustc::untranslatable_diagnostic)] #![feature(rustc_private)] #![feature(let_chains)] -#![feature(lazy_cell)] #![feature(lint_reasons)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index b06a11702ec8..333a2ab58575 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![feature(is_sorted)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index 3f16c180ea78..36a7a651c4d2 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -3,7 +3,6 @@ //! //! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context -#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs index 98019c755276..6ce7e44474d8 100644 --- a/src/tools/clippy/tests/lint_message_convention.rs +++ b/src/tools/clippy/tests/lint_message_convention.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs index 699ab2be199a..19ccc7ae9607 100644 --- a/src/tools/clippy/tests/workspace.rs +++ b/src/tools/clippy/tests/workspace.rs @@ -1,5 +1,3 @@ -#![feature(lazy_cell)] - use std::path::PathBuf; use std::process::Command; use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE}; diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 0e4a8d42f6e8..e671817633be 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -14,7 +14,7 @@ LL | static settings_dir: String = format!(""); | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `settings_dir` diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index 3981b4ada491..c4f5364b4d78 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -5,7 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block --> $DIR/issue-16538.rs:11:22 diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr index 0fec3581873e..bd0b8c15b558 100644 --- a/tests/ui/consts/issue-32829-2.stderr +++ b/tests/ui/consts/issue-32829-2.stderr @@ -13,7 +13,7 @@ LL | invalid(); | ^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0015]: cannot call non-const fn `invalid` in statics --> $DIR/issue-32829-2.rs:54:9 @@ -22,7 +22,7 @@ LL | invalid(); | ^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr index ea6a8b8ee4a5..95d64622ad7a 100644 --- a/tests/ui/consts/mir_check_nonconst.stderr +++ b/tests/ui/consts/mir_check_nonconst.stderr @@ -5,7 +5,7 @@ LL | static foo: Foo = bar(); | ^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index 5c19abffa029..3fedfd964170 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -16,7 +16,7 @@ note: impl defined here, but it is not `const` LL | impl Deref for A { | ^^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index 3bf59a6d7114..d5b6dde1f10e 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -18,7 +18,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/suspicious-double-ref-op.rs b/tests/ui/lint/suspicious-double-ref-op.rs index bc8c23c7b895..5aeb81dbd65a 100644 --- a/tests/ui/lint/suspicious-double-ref-op.rs +++ b/tests/ui/lint/suspicious-double-ref-op.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![deny(suspicious_double_ref_op, noop_method_call)] use std::borrow::Borrow; diff --git a/tests/ui/lint/suspicious-double-ref-op.stderr b/tests/ui/lint/suspicious-double-ref-op.stderr index f5a71d40fc13..c956843c5078 100644 --- a/tests/ui/lint/suspicious-double-ref-op.stderr +++ b/tests/ui/lint/suspicious-double-ref-op.stderr @@ -1,29 +1,29 @@ error: using `.clone()` on a double reference, which returns `&Vec` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:15:23 + --> $DIR/suspicious-double-ref-op.rs:14:23 | LL | let z: &Vec<_> = y.clone(); | ^^^^^^^^ | note: the lint level is defined here - --> $DIR/suspicious-double-ref-op.rs:2:9 + --> $DIR/suspicious-double-ref-op.rs:1:9 | LL | #![deny(suspicious_double_ref_op, noop_method_call)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: using `.clone()` on a double reference, which returns `&CloneType` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:33:63 + --> $DIR/suspicious-double-ref-op.rs:32:63 | LL | let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); | ^^^^^^^^ error: using `.deref()` on a double reference, which returns `&PlainType` instead of dereferencing the inner type - --> $DIR/suspicious-double-ref-op.rs:37:63 + --> $DIR/suspicious-double-ref-op.rs:36:63 | LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); | ^^^^^^^^ error: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:41:44 + --> $DIR/suspicious-double-ref-op.rs:40:44 | LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead | ^^^^^^^^ diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr index 7b896ce14266..66b57c772d54 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -352,7 +352,7 @@ LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); | ^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs index d43fabcedec5..7bd372c16952 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(const_trait_impl, lazy_cell)] +#![feature(const_trait_impl)] use std::sync::LazyLock; diff --git a/tests/ui/static/static-mut-not-constant.stderr b/tests/ui/static/static-mut-not-constant.stderr index d125bec59435..46dc175cb298 100644 --- a/tests/ui/static/static-mut-not-constant.stderr +++ b/tests/ui/static/static-mut-not-constant.stderr @@ -5,7 +5,7 @@ LL | static mut a: Box = Box::new(3); | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr index db0c7eb8d35f..a3b930323d5b 100644 --- a/tests/ui/static/static-vec-repeat-not-constant.stderr +++ b/tests/ui/static/static-vec-repeat-not-constant.stderr @@ -5,7 +5,7 @@ LL | static a: [isize; 2] = [foo(); 2]; | ^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index 45a699f575fb..24763c175fc8 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -26,7 +26,7 @@ LL | static STATIC11: Vec = vec![MyOwned]; | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const fn `::to_string` in statics @@ -36,7 +36,7 @@ LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] @@ -57,7 +57,7 @@ LL | vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -75,7 +75,7 @@ LL | vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -93,7 +93,7 @@ LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -111,7 +111,7 @@ LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -129,7 +129,7 @@ LL | static STATIC19: Vec = vec![3]; | ^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -147,7 +147,7 @@ LL | static x: Vec = vec![3]; | ^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `x` From 214c49837a56c402ab28f7dd5eff08c7ae709c09 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 6 Mar 2024 12:42:32 +0100 Subject: [PATCH 002/101] Less syscalls for the `copy_file_range` probe If it's obvious from the actual syscall results themselves that the syscall is supported or unsupported, don't do an extra syscall with an invalid file descriptor. CC #122052 --- library/std/src/sys/pal/unix/kernel_copy.rs | 71 ++++++++++++++------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index 18acd5ecccd5..60f4e55755d7 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -560,6 +560,12 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> // We store the availability in a global to avoid unnecessary syscalls static HAS_COPY_FILE_RANGE: AtomicU8 = AtomicU8::new(NOT_PROBED); + let mut have_probed = match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) { + NOT_PROBED => false, + UNAVAILABLE => return CopyResult::Fallback(0), + _ => true, + }; + syscall! { fn copy_file_range( fd_in: libc::c_int, @@ -571,26 +577,6 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> ) -> libc::ssize_t } - match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) { - NOT_PROBED => { - // EPERM can indicate seccomp filters or an immutable file. - // To distinguish these cases we probe with invalid file descriptors which should result in EBADF if the syscall is supported - // and some other error (ENOSYS or EPERM) if it's not available - let result = unsafe { - cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0)) - }; - - if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF))) { - HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); - } else { - HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); - return CopyResult::Fallback(0); - } - } - UNAVAILABLE => return CopyResult::Fallback(0), - _ => {} - }; - let mut written = 0u64; while written < max_len { let bytes_to_copy = cmp::min(max_len - written, usize::MAX as u64); @@ -604,6 +590,11 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> cvt(copy_file_range(reader, ptr::null_mut(), writer, ptr::null_mut(), bytes_to_copy, 0)) }; + if !have_probed && copy_result.is_ok() { + have_probed = true; + HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); + } + match copy_result { Ok(0) if written == 0 => { // fallback to work around several kernel bugs where copy_file_range will fail to @@ -616,10 +607,44 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> Ok(0) => return CopyResult::Ended(written), // reached EOF Ok(ret) => written += ret as u64, Err(err) => { - return match err.raw_os_error() { + let raw_os_error = match err.raw_os_error() { + Some(raw) => raw, + _ => return CopyResult::Error(err, written), + }; + return match raw_os_error { // when file offset + max_length > u64::MAX - Some(EOVERFLOW) => CopyResult::Fallback(written), - Some(ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF) if written == 0 => { + EOVERFLOW => CopyResult::Fallback(written), + ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF if written == 0 => { + if !have_probed { + if raw_os_error == ENOSYS { + HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); + } else { + // EPERM can indicate seccomp filters or an + // immutable file. To distinguish these cases + // we probe with invalid file descriptors which + // should result in EBADF if the syscall is + // supported and some other error (ENOSYS or + // EPERM) if it's not available. + let result = unsafe { + cvt(copy_file_range( + INVALID_FD, + ptr::null_mut(), + INVALID_FD, + ptr::null_mut(), + 1, + 0, + )) + }; + + if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF))) + { + HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); + } else { + HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); + } + } + } + // Try fallback io::copy if either: // - Kernel version is < 4.5 (ENOSYS¹) // - Files are mounted on different fs (EXDEV) From 5073475b0e5477c3d02c219a4c2e7075891240a7 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 6 Mar 2024 14:37:25 +0100 Subject: [PATCH 003/101] Be stricter with `copy_file_range` probe results --- library/std/src/sys/pal/unix/kernel_copy.rs | 68 +++++++++++---------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index 60f4e55755d7..1db86bdb180f 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -607,42 +607,44 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> Ok(0) => return CopyResult::Ended(written), // reached EOF Ok(ret) => written += ret as u64, Err(err) => { - let raw_os_error = match err.raw_os_error() { - Some(raw) => raw, - _ => return CopyResult::Error(err, written), - }; - return match raw_os_error { + return match err.raw_os_error() { // when file offset + max_length > u64::MAX - EOVERFLOW => CopyResult::Fallback(written), - ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF if written == 0 => { + Some(EOVERFLOW) => CopyResult::Fallback(written), + Some(raw_os_error @ (ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF)) + if written == 0 => + { if !have_probed { - if raw_os_error == ENOSYS { - HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); - } else { - // EPERM can indicate seccomp filters or an - // immutable file. To distinguish these cases - // we probe with invalid file descriptors which - // should result in EBADF if the syscall is - // supported and some other error (ENOSYS or - // EPERM) if it's not available. - let result = unsafe { - cvt(copy_file_range( - INVALID_FD, - ptr::null_mut(), - INVALID_FD, - ptr::null_mut(), - 1, - 0, - )) - }; - - if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF))) - { - HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); - } else { - HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); + let available = match raw_os_error { + EPERM => { + // EPERM can indicate seccomp filters or an + // immutable file. To distinguish these + // cases we probe with invalid file + // descriptors which should result in EBADF + // if the syscall is supported and EPERM or + // ENOSYS if it's not available. + match unsafe { + cvt(copy_file_range( + INVALID_FD, + ptr::null_mut(), + INVALID_FD, + ptr::null_mut(), + 1, + 0, + )) + .map_err(|e| e.raw_os_error()) + } { + Err(Some(EPERM | ENOSYS)) => UNAVAILABLE, + Err(Some(EBADF)) => AVAILABLE, + Ok(_) => panic!("unexpected copy_file_range probe success"), + // Treat other errors as the syscall + // being unavailable. + Err(_) => UNAVAILABLE, + } } - } + ENOSYS => UNAVAILABLE, + _ => AVAILABLE, + }; + HAS_COPY_FILE_RANGE.store(available, Ordering::Relaxed); } // Try fallback io::copy if either: From 62a104df983522de8fe06ff866a47b3938fbd561 Mon Sep 17 00:00:00 2001 From: Veera Date: Tue, 16 Apr 2024 18:15:37 -0400 Subject: [PATCH 004/101] Update Tests --- .../c-variadic/variadic-ffi-no-fixed-args.rs | 5 +- .../variadic-ffi-no-fixed-args.stderr | 8 -- .../variadic-ffi-semantic-restrictions.rs | 8 -- .../variadic-ffi-semantic-restrictions.stderr | 114 ++++++------------ 4 files changed, 40 insertions(+), 95 deletions(-) delete mode 100644 tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs index 588c15a18297..b8841e88c4f4 100644 --- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs +++ b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs @@ -1,6 +1,9 @@ +//@ build-pass + +// Supported since C23 +// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf extern "C" { fn foo(...); -//~^ ERROR C-variadic function must be declared with at least one named argument } fn main() {} diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr deleted file mode 100644 index e268ef3fa681..000000000000 --- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-no-fixed-args.rs:2:12 - | -LL | fn foo(...); - | ^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index a2d2388ff508..11126dbc65d2 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -8,14 +8,12 @@ fn f1_1(x: isize, ...) {} fn f1_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f2_1(x: isize, ...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic extern "C" fn f2_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f2_3(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic @@ -26,7 +24,6 @@ extern "C" fn f3_1(x: isize, ...) {} extern "C" fn f3_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f3_3(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic @@ -47,8 +44,6 @@ const extern "C" fn f4_3(..., x: isize, ...) {} //~| ERROR `...` must be the last argument of a C-variadic function extern "C" { - fn e_f1(...); - //~^ ERROR C-variadic function must be declared with at least one named argument fn e_f2(..., x: isize); //~^ ERROR `...` must be the last argument of a C-variadic function } @@ -60,7 +55,6 @@ impl X { //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic fn i_f2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn i_f3(..., x: isize, ...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic //~| ERROR `...` must be the last argument of a C-variadic function @@ -80,10 +74,8 @@ trait T { //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic fn t_f3(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn t_f4(...); //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn t_f5(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic //~| ERROR `...` must be the last argument of a C-variadic function diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 6a65ed79d4fb..f71e3863440f 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -4,12 +4,6 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic LL | fn f1_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 - | -LL | fn f1_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | @@ -17,91 +11,79 @@ LL | fn f1_2(...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:13:30 + --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | LL | extern "C" fn f2_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 - | -LL | extern "C" fn f2_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20 | LL | extern "C" fn f2_2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 + --> $DIR/variadic-ffi-semantic-restrictions.rs:22:30 | LL | extern "C" fn f3_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 - | -LL | extern "C" fn f3_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:25:20 | LL | extern "C" fn f3_2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:35:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:32:1 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:1 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:1 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^^^ ^^^ ^^^ C-variadic because of this @@ -110,67 +92,55 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {} | `const` because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13 - | -LL | fn e_f1(...); - | ^^^ - error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:52:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13 | LL | fn e_f2(..., x: isize); | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:59:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:54:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 - | -LL | fn i_f2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13 | LL | fn i_f2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:5 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:5 | LL | const fn i_f5(x: isize, ...) {} | ^^^^^ ^^^ C-variadic because of this @@ -178,73 +148,61 @@ LL | const fn i_f5(x: isize, ...) {} | `const` because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:77:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:79:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23 | LL | fn t_f2(x: isize, ...); | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13 | LL | fn t_f3(...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 - | -LL | fn t_f3(...) {} - | ^^^ - -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 - | -LL | fn t_f4(...); - | ^^^ - -error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 | LL | fn t_f4(...); | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize); | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize); | ^^^ error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:35:43 + --> $DIR/variadic-ffi-semantic-restrictions.rs:32:43 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^ - value is dropped here @@ -252,7 +210,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ - value is dropped here @@ -260,13 +218,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 43 previous errors +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0493`. From f005b451c2eeb018e3c2c6e6653636981cfa7f1a Mon Sep 17 00:00:00 2001 From: Veera Date: Tue, 16 Apr 2024 18:53:05 -0400 Subject: [PATCH 005/101] Support C23's Variadics Without a Named Parameter This PR removes the static check that disallowed extern functions with ellipsis (varargs) as the only parameter since this is now valid in C23. Also, adds a doc comment for `check_decl_cvariadic_pos()` and fixes the name of the function (`varadic` -> `variadic`). --- compiler/rustc_ast_passes/messages.ftl | 3 --- compiler/rustc_ast_passes/src/ast_validation.rs | 12 +++++------- compiler/rustc_ast_passes/src/errors.rs | 7 ------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index a3731e94276b..f578165f369c 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -97,9 +97,6 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block ast_passes_fn_param_c_var_args_not_last = `...` must be the last argument of a C-variadic function -ast_passes_fn_param_c_var_args_only = - C-variadic function must be declared with at least one named argument - ast_passes_fn_param_doc_comment = documentation comments cannot be applied to function parameters .label = doc comments are not allowed here diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 495e90e967b9..63aed6493dc4 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -365,7 +365,7 @@ impl<'a> AstValidator<'a> { fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { self.check_decl_num_args(fn_decl); - self.check_decl_cvaradic_pos(fn_decl); + self.check_decl_cvariadic_pos(fn_decl); self.check_decl_attrs(fn_decl); self.check_decl_self_param(fn_decl, self_semantic); } @@ -380,13 +380,11 @@ impl<'a> AstValidator<'a> { } } - fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) { + /// Emits an error if a function declaration has a variadic parameter in the + /// beginning or middle of parameter list. + /// Example: `fn foo(..., x: i32)` will emit an error. + fn check_decl_cvariadic_pos(&self, fn_decl: &FnDecl) { match &*fn_decl.inputs { - [Param { ty, span, .. }] => { - if let TyKind::CVarArgs = ty.kind { - self.dcx().emit_err(errors::FnParamCVarArgsOnly { span: *span }); - } - } [ps @ .., _] => { for Param { ty, span, .. } in ps { if let TyKind::CVarArgs = ty.kind { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index f397c949e048..0e4599f55ba5 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -92,13 +92,6 @@ pub struct FnParamTooMany { pub max_num_args: usize, } -#[derive(Diagnostic)] -#[diag(ast_passes_fn_param_c_var_args_only)] -pub struct FnParamCVarArgsOnly { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(ast_passes_fn_param_c_var_args_not_last)] pub struct FnParamCVarArgsNotLast { From 7d67ee5aba849939f64ed821a757518f211620a7 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 27 Apr 2024 18:44:30 +0200 Subject: [PATCH 006/101] Lift the probe code of `copy_file_range` into a function --- library/std/src/sys/pal/unix/kernel_copy.rs | 60 +++++++++++---------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index 1db86bdb180f..cd38b7c07e2b 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -577,6 +577,23 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> ) -> libc::ssize_t } + fn probe_copy_file_range_support() -> u8 { + // In some cases, we cannot determine availability from the first + // `copy_file_range` call. In this case, we probe with an invalid file + // descriptor so that the results are easily interpretable. + match unsafe { + cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0)) + .map_err(|e| e.raw_os_error()) + } { + Err(Some(EPERM | ENOSYS)) => UNAVAILABLE, + Err(Some(EBADF)) => AVAILABLE, + Ok(_) => panic!("unexpected copy_file_range probe success"), + // Treat other errors as the syscall + // being unavailable. + Err(_) => UNAVAILABLE, + } + } + let mut written = 0u64; while written < max_len { let bytes_to_copy = cmp::min(max_len - written, usize::MAX as u64); @@ -614,35 +631,20 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> if written == 0 => { if !have_probed { - let available = match raw_os_error { - EPERM => { - // EPERM can indicate seccomp filters or an - // immutable file. To distinguish these - // cases we probe with invalid file - // descriptors which should result in EBADF - // if the syscall is supported and EPERM or - // ENOSYS if it's not available. - match unsafe { - cvt(copy_file_range( - INVALID_FD, - ptr::null_mut(), - INVALID_FD, - ptr::null_mut(), - 1, - 0, - )) - .map_err(|e| e.raw_os_error()) - } { - Err(Some(EPERM | ENOSYS)) => UNAVAILABLE, - Err(Some(EBADF)) => AVAILABLE, - Ok(_) => panic!("unexpected copy_file_range probe success"), - // Treat other errors as the syscall - // being unavailable. - Err(_) => UNAVAILABLE, - } - } - ENOSYS => UNAVAILABLE, - _ => AVAILABLE, + let available = if matches!(raw_os_error, ENOSYS | EOPNOTSUPP | EPERM) { + // EPERM can indicate seccomp filters or an + // immutable file. To distinguish these + // cases we probe with invalid file + // descriptors which should result in EBADF + // if the syscall is supported and EPERM or + // ENOSYS if it's not available. + // + // For EOPNOTSUPP, see below. In the case of + // ENOSYS, we try to cover for faulty FUSE + // drivers. + probe_copy_file_range_support() + } else { + AVAILABLE }; HAS_COPY_FILE_RANGE.store(available, Ordering::Relaxed); } From 39a653f632a4d5a2d3da54496b221e66923625ce Mon Sep 17 00:00:00 2001 From: morine0122 Date: Fri, 26 Apr 2024 22:02:58 +0900 Subject: [PATCH 007/101] Fix coercion of async block --- .../crates/hir-ty/src/infer/expr.rs | 17 +++++++++++- .../crates/ide/src/inlay_hints/bind_pat.rs | 26 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 38076fce8f8f..bccad751fc20 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -933,8 +933,23 @@ impl InferenceContext<'_> { let prev_ret_coercion = mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone()))); + let expected = &Expectation::has_type(ret_ty); let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { - this.infer_block(tgt_expr, *id, statements, *tail, None, &Expectation::has_type(ret_ty)) + let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected); + if let Some(target) = expected.only_has_type(&mut this.table) { + match this.coerce(Some(tgt_expr), &ty, &target) { + Ok(res) => res, + Err(_) => { + this.result.type_mismatches.insert( + tgt_expr.into(), + TypeMismatch { expected: target.clone(), actual: ty.clone() }, + ); + target + } + } + } else { + ty + } }); self.diverges = prev_diverges; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 0cb8c485b2f2..3311bb48ad65 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -1120,4 +1120,30 @@ fn test() { "#, ); } + + #[test] + fn type_hints_async_block() { + check_types( + r#" +//- minicore: future +async fn main() { + let _x = async { 8_i32 }; + //^^ impl Future +}"#, + ); + } + + #[test] + fn type_hints_async_block_with_tail_return_exp() { + check_types( + r#" +//- minicore: future +async fn main() { + let _x = async { + //^^ impl Future + return 8_i32; + }; +}"#, + ); + } } From dd16cbcb4e633841e32694a822b498f7ea76fb87 Mon Sep 17 00:00:00 2001 From: Harry Sarson Date: Thu, 25 Apr 2024 15:16:52 +0100 Subject: [PATCH 008/101] braces around {self} in UseTree are not unnecessary Before this commit `UseTree::remove_unnecessary_braces` removed the braces around `{self}` in `use x::y::{self};` but `use x::y::self;` is not valid rust. --- .../src/handlers/remove_unused_imports.rs | 34 +++++++++++++++++++ .../crates/syntax/src/ast/node_ext.rs | 21 ++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs index 0f0f13bbc80b..b653f3b6650e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -776,6 +776,40 @@ mod z { ); } + #[test] + fn remove_unused_fixes_nested_self() { + check_assist( + remove_unused_imports, + r#" +mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self, X}$0; + + fn f() { + let y = inner::Y(); + } +} +"#, + r#"mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self}; + + fn f() { + let y = inner::Y(); + } +} +"#, + ); + } + #[test] fn dont_remove_used_glob() { check_assist_not_applicable( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index c3d6f50e6b08..b0fbe7101c11 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -378,9 +378,26 @@ impl ast::UseTreeList { /// Remove the unnecessary braces in current `UseTreeList` pub fn remove_unnecessary_braces(mut self) { + // Returns true iff there is a single subtree and it is not the self keyword. The braces in + // `use x::{self};` are necessary and so we should not remove them. + let has_single_subtree_that_is_not_self = |u: &ast::UseTreeList| { + if let Some((single_subtree,)) = u.use_trees().collect_tuple() { + // We have a single subtree, check whether it is self. + + let is_self = single_subtree.path().as_ref().map_or(false, |path| { + path.segment().and_then(|seg| seg.self_token()).is_some() + && path.qualifier().is_none() + }); + + !is_self + } else { + // Not a single subtree + false + } + }; + let remove_brace_in_use_tree_list = |u: &ast::UseTreeList| { - let use_tree_count = u.use_trees().count(); - if use_tree_count == 1 { + if has_single_subtree_that_is_not_self(u) { if let Some(a) = u.l_curly_token() { ted::remove(a) } From 179a6a08b127c7670ec648c245d8c31c6ac2419c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 15:24:53 +0200 Subject: [PATCH 009/101] remove IndirectStructuralMatch lint, emit the usual hard error instead --- compiler/rustc_lint/src/lib.rs | 5 ++ compiler/rustc_lint_defs/src/builtin.rs | 47 ------------ compiler/rustc_mir_build/messages.ftl | 6 -- compiler/rustc_mir_build/src/errors.rs | 16 ---- .../src/thir/pattern/const_to_pat.rs | 76 +------------------ .../const_in_pattern/accept_structural.rs | 1 - .../const_in_pattern/cross-crate-fail.rs | 2 - .../const_in_pattern/cross-crate-fail.stderr | 4 +- .../const_in_pattern/cross-crate-pass.rs | 2 - .../const_in_pattern/custom-eq-branch-pass.rs | 2 - .../const_in_pattern/no-eq-branch-fail.rs | 2 - .../const_in_pattern/no-eq-branch-fail.stderr | 2 +- .../const_in_pattern/reject_non_structural.rs | 6 +- .../reject_non_structural.stderr | 48 +++--------- tests/ui/consts/issue-89088.rs | 5 +- tests/ui/consts/issue-89088.stderr | 9 +-- tests/ui/nll/issue-55511.rs | 1 - tests/ui/nll/issue-55511.stderr | 2 +- .../const-partial_eq-fallback-ice.stderr | 12 --- .../cant-hide-behind-direct-struct-param.rs | 1 - ...ant-hide-behind-direct-struct-param.stderr | 2 +- ...nt-hide-behind-doubly-indirect-embedded.rs | 5 +- ...ide-behind-doubly-indirect-embedded.stderr | 30 +------- .../cant-hide-behind-doubly-indirect-param.rs | 5 +- ...t-hide-behind-doubly-indirect-param.stderr | 30 +------- ...nt-hide-behind-indirect-struct-embedded.rs | 5 +- ...ide-behind-indirect-struct-embedded.stderr | 30 +------- .../cant-hide-behind-indirect-struct-param.rs | 5 +- ...t-hide-behind-indirect-struct-param.stderr | 30 +------- ...2307-match-ref-ref-forbidden-without-eq.rs | 8 +- ...-match-ref-ref-forbidden-without-eq.stderr | 53 ++----------- 31 files changed, 54 insertions(+), 398 deletions(-) diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a78b410f500c..b3a7f50e8ea2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -539,6 +539,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ for more information", ); + store.register_removed( + "indirect_structural_match", + "converted into hard error, see RFC #3535 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c7996c27c2f0..6da6b39bac10 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -50,7 +50,6 @@ declare_lint_pass! { HIDDEN_GLOB_REEXPORTS, ILL_FORMED_ATTRIBUTE_INPUT, INCOMPLETE_INCLUDE, - INDIRECT_STRUCTURAL_MATCH, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, INLINE_NO_SANITIZE, INVALID_DOC_ATTRIBUTES, @@ -2355,52 +2354,6 @@ declare_lint! { "outlives requirements can be inferred" } -declare_lint! { - /// The `indirect_structural_match` lint detects a `const` in a pattern - /// that manually implements [`PartialEq`] and [`Eq`]. - /// - /// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html - /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(indirect_structural_match)] - /// - /// struct NoDerive(i32); - /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - /// impl Eq for NoDerive { } - /// #[derive(PartialEq, Eq)] - /// struct WrapParam(T); - /// const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); - /// fn main() { - /// match WRAP_INDIRECT_PARAM { - /// WRAP_INDIRECT_PARAM => { } - /// _ => { } - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The compiler unintentionally accepted this form in the past. This is a - /// [future-incompatible] lint to transition this to a hard error in the - /// future. See [issue #62411] for a complete description of the problem, - /// and some possible solutions. - /// - /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub INDIRECT_STRUCTURAL_MATCH, - Warn, - "constant used in pattern contains value of non-structural-match type in a field or a variant", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #120362 ", - }; -} - declare_lint! { /// The `deprecated_in_future` lint is internal to rustc and should not be /// used by user code. diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 34440c60cf37..c1d340fa2d1f 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -109,9 +109,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .label = use of extern static -mir_build_indirect_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant mir_build_initializing_type_with_requires_unsafe = @@ -257,9 +254,6 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type mir_build_non_partial_eq_match = to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq` -mir_build_nontrivial_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_pattern_not_covered = refutable pattern in {$origin} .pattern_ty = the matched value is of type `{$pattern_ty}` diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f67113afd6d9..1d52c2723aab 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -802,22 +802,6 @@ pub struct NonEmptyNeverPattern<'tcx> { pub ty: Ty<'tcx>, } -#[derive(LintDiagnostic)] -#[diag(mir_build_indirect_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct IndirectStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - -#[derive(LintDiagnostic)] -#[diag(mir_build_nontrivial_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct NontrivialStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - #[derive(Diagnostic)] #[diag(mir_build_exceeds_mcdc_condition_num_limit)] pub(crate) struct MCDCExceedsConditionNumLimit { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 65c53be8ddd9..6d2e740af408 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -16,8 +16,8 @@ use std::cell::Cell; use super::PatCtxt; use crate::errors::{ - IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, - TypeNotStructural, UnionPattern, UnsizedPattern, + InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, + UnsizedPattern, }; impl<'a, 'tcx> PatCtxt<'a, 'tcx> { @@ -49,15 +49,6 @@ struct ConstToPat<'tcx> { // value. saw_const_match_error: Cell>, - // This tracks if we emitted some diagnostic for a given const value, so that - // we will not subsequently issue an irrelevant lint for the same const - // value. - saw_const_match_lint: Cell, - - // For backcompat we need to keep allowing non-structurally-eq types behind references. - // See also all the `cant-hide-behind` tests. - behind_reference: Cell, - // inference context used for checking `T: Structural` bounds. infcx: InferCtxt<'tcx>, @@ -84,8 +75,6 @@ impl<'tcx> ConstToPat<'tcx> { infcx, param_env: pat_ctxt.param_env, saw_const_match_error: Cell::new(None), - saw_const_match_lint: Cell::new(false), - behind_reference: Cell::new(false), treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice @@ -197,7 +186,7 @@ impl<'tcx> ConstToPat<'tcx> { // complained about structural match violations there, so we don't // have to check anything any more. } - } else if !have_valtree && !self.saw_const_match_lint.get() { + } else if !have_valtree { // The only way valtree construction can fail without the structural match // checker finding a violation is if there is a pointer somewhere. self.tcx().emit_node_span_lint( @@ -274,36 +263,11 @@ impl<'tcx> ConstToPat<'tcx> { cv: ValTree<'tcx>, ty: Ty<'tcx>, ) -> Result>, FallbackToOpaqueConst> { - let id = self.id; let span = self.span; let tcx = self.tcx(); let param_env = self.param_env; let kind = match ty.kind() { - // If the type is not structurally comparable, just emit the constant directly, - // causing the pattern match code to treat it opaquely. - // FIXME: This code doesn't emit errors itself, the caller emits the errors. - // So instead of specific errors, you just get blanket errors about the whole - // const type. See - // https://github.com/rust-lang/rust/pull/70743#discussion_r404701963 for - // details. - // Backwards compatibility hack because we can't cause hard errors on these - // types, so we compare them via `PartialEq::eq` at runtime. - ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => { - if self.saw_const_match_error.get().is_none() && !self.saw_const_match_lint.get() { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - id, - span, - IndirectStructuralMatch { non_sm_ty: ty }, - ); - } - // Since we are behind a reference, we can just bubble the error up so we get a - // constant at reference type, making it easy to let the fallback call - // `PartialEq::eq` on it. - return Err(FallbackToOpaqueConst); - } ty::FnDef(..) => { let e = tcx.dcx().emit_err(InvalidPattern { span, non_sm_ty: ty }); self.saw_const_match_error.set(Some(e)); @@ -377,38 +341,6 @@ impl<'tcx> ConstToPat<'tcx> { ty::Str => { PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } - // Backwards compatibility hack: support references to non-structural types, - // but hard error if we aren't behind a double reference. We could just use - // the fallback code path below, but that would allow *more* of this fishy - // code to compile, as then it only goes through the future incompat lint - // instead of a hard error. - ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { - if self.behind_reference.get() { - if self.saw_const_match_error.get().is_none() - && !self.saw_const_match_lint.get() - { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - self.id, - span, - IndirectStructuralMatch { non_sm_ty: *pointee_ty }, - ); - } - return Err(FallbackToOpaqueConst); - } else { - if let Some(e) = self.saw_const_match_error.get() { - // We already errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } else { - let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; - let e = tcx.dcx().emit_err(err); - self.saw_const_match_error.set(Some(e)); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } - } - } // All other references are converted into deref patterns and then recursively // convert the dereferenced constant to a pattern that is the sub-pattern of the // deref pattern. @@ -419,7 +351,6 @@ impl<'tcx> ConstToPat<'tcx> { // We errored. Signal that in the pattern, so that follow up errors can be silenced. PatKind::Error(e) } else { - let old = self.behind_reference.replace(true); // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. // The typechecker has a special case for byte string literals, by treating them @@ -434,7 +365,6 @@ impl<'tcx> ConstToPat<'tcx> { }; // References have the same valtree representation as their pointee. let subpattern = self.recur(cv, pointee_ty)?; - self.behind_reference.set(old); PatKind::Deref { subpattern } } } diff --git a/tests/ui/consts/const_in_pattern/accept_structural.rs b/tests/ui/consts/const_in_pattern/accept_structural.rs index 31d3b6e73312..78d92abd88b4 100644 --- a/tests/ui/consts/const_in_pattern/accept_structural.rs +++ b/tests/ui/consts/const_in_pattern/accept_structural.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_local_definitions)] -#![warn(indirect_structural_match)] // This test is checking our logic for structural match checking by enumerating // the different kinds of const expressions. This test is collecting cases where diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs index d8df2847c440..163a47f43336 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs @@ -1,7 +1,5 @@ //@ aux-build:consts.rs -#![warn(indirect_structural_match)] - extern crate consts; struct Defaulted; diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index 067f2b6e6747..e0f97a9abd21 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:13:9 + --> $DIR/cross-crate-fail.rs:11:9 | LL | consts::SOME => panic!(), | ^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | consts::SOME => panic!(), = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:20:9 + --> $DIR/cross-crate-fail.rs:18:9 | LL | ::SOME => panic!(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const_in_pattern/cross-crate-pass.rs b/tests/ui/consts/const_in_pattern/cross-crate-pass.rs index c18a30b3495b..2a121a23dfc8 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-pass.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-pass.rs @@ -1,8 +1,6 @@ //@ run-pass //@ aux-build:consts.rs -#![warn(indirect_structural_match)] - extern crate consts; use consts::CustomEq; diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs index 605f4e760cd2..2e7061e7c4b4 100644 --- a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs +++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs @@ -1,7 +1,5 @@ //@ run-pass -#![warn(indirect_structural_match)] - struct CustomEq; impl Eq for CustomEq {} diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs index 141d87d9b703..cf013c1a7906 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs @@ -1,5 +1,3 @@ -#![warn(indirect_structural_match)] - struct NoEq; enum Foo { diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index b29f959de972..7766c6ce683d 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` - --> $DIR/no-eq-branch-fail.rs:21:9 + --> $DIR/no-eq-branch-fail.rs:19:9 | LL | BAR_BAZ => panic!(), | ^^^^^^^ diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index a9b0aa5507e3..e3dcecec960a 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -11,8 +11,6 @@ // See also RFC 1445 #![feature(type_ascription)] -#![warn(indirect_structural_match)] -//~^ NOTE lint level is defined here #[derive(Copy, Clone, Debug)] struct NoPartialEq; @@ -96,9 +94,7 @@ fn main() { const ADDR_OF: &OND = &Some(NoDerive); match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - //~^ WARN must be annotated with `#[derive(PartialEq)]` + //~^ ERROR must be annotated with `#[derive(PartialEq)]` //~| NOTE the traits must be derived //~| NOTE StructuralPartialEq.html for details - //~| WARN previously accepted by the compiler but is being phased out - //~| NOTE for more information, see } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index 2c7aaf89aa78..c068db42e4d9 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:42:36 + --> $DIR/reject_non_structural.rs:40:36 | LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; | ^^^^ @@ -8,7 +8,7 @@ LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops" = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:48:28 + --> $DIR/reject_non_structural.rs:46:28 | LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; | ^^^^^ @@ -17,7 +17,7 @@ LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:55:27 + --> $DIR/reject_non_structural.rs:53:27 | LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; | ^^^^^^^^ @@ -26,7 +26,7 @@ LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops") = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:61:36 + --> $DIR/reject_non_structural.rs:59:36 | LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; | ^^^^^ @@ -35,7 +35,7 @@ LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:67:28 + --> $DIR/reject_non_structural.rs:65:28 | LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:73:36 + --> $DIR/reject_non_structural.rs:71:36 | LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; | ^^^^^ @@ -53,7 +53,7 @@ LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:79:33 + --> $DIR/reject_non_structural.rs:77:33 | LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; | ^^^^^^ @@ -62,7 +62,7 @@ LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:86:28 + --> $DIR/reject_non_structural.rs:84:28 | LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:92:28 + --> $DIR/reject_non_structural.rs:90:28 | LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; | ^^^^^ @@ -79,38 +79,14 @@ LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:98:29 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/reject_non_structural.rs:96:29 | LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; | ^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/reject_non_structural.rs:14:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors; 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:98:29 - | -LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/reject_non_structural.rs:14:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 10 previous errors diff --git a/tests/ui/consts/issue-89088.rs b/tests/ui/consts/issue-89088.rs index d0782963dfc8..02a786e74651 100644 --- a/tests/ui/consts/issue-89088.rs +++ b/tests/ui/consts/issue-89088.rs @@ -1,8 +1,5 @@ // Regression test for the ICE described in #89088. -//@ check-pass - -#![allow(indirect_structural_match)] use std::borrow::Cow; const FOO: &A = &A::Field(Cow::Borrowed("foo")); @@ -16,7 +13,7 @@ fn main() { let var = A::Field(Cow::Borrowed("bar")); match &var { - FOO => todo!(), + FOO => todo!(), //~ERROR derive(PartialEq) _ => todo!() } } diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index 7cb85d5279d0..362c63a2a456 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr @@ -1,12 +1,11 @@ -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-89088.rs:19:9 +error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-89088.rs:16:9 | LL | FOO => todo!(), | ^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +error: aborting due to 1 previous error + diff --git a/tests/ui/nll/issue-55511.rs b/tests/ui/nll/issue-55511.rs index 7dfa9c7bcdff..78ca89b624a9 100644 --- a/tests/ui/nll/issue-55511.rs +++ b/tests/ui/nll/issue-55511.rs @@ -1,4 +1,3 @@ -#![warn(indirect_structural_match)] use std::cell::Cell; trait Foo<'a> { const C: Option>; diff --git a/tests/ui/nll/issue-55511.stderr b/tests/ui/nll/issue-55511.stderr index ac7cd54df71f..726630307bb2 100644 --- a/tests/ui/nll/issue-55511.stderr +++ b/tests/ui/nll/issue-55511.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/issue-55511.rs:13:28 + --> $DIR/issue-55511.rs:12:28 | LL | let a = 22; | - binding `a` declared here diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 2a1cd3a7aa4b..0b4d99727581 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -9,15 +9,3 @@ LL | if let CONSTANT = &&MyType { error: aborting due to 1 previous error -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]` - --> $DIR/const-partial_eq-fallback-ice.rs:14:12 - | -LL | if let CONSTANT = &&MyType { - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs index 112021c783fc..f840b4040b65 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs @@ -4,7 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] struct NoDerive(i32); // This impl makes NoDerive irreflexive. diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index 8bca7d9889cd..3d00ef2dfbf6 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-direct-struct-param.rs:22:9 + --> $DIR/cant-hide-behind-direct-struct-param.rs:21:9 | LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs index b64fbd9d49a1..898acefc83cc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0) fn main() { match WRAP_DOUBLY_INDIRECT_INLINE { WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 9945041113d7..3636307e16c6 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9 | LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9 - | -LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs index be37217a7d45..7cbaada88a30 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDe fn main() { match WRAP_DOUBLY_INDIRECT_PARAM { WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index 6ac261ae8143..40fd31762b2f 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9 | LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9 - | -LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs index e26234bd4553..ac868efed6fd 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); fn main() { match WRAP_INDIRECT_INLINE { WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index 41616fb90fe9..dbf1848326aa 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9 | LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9 - | -LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs index 729f411a0215..cbfabec6819e 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); fn main() { match WRAP_INDIRECT_PARAM { WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index 99dea5171d1b..58acc11a7449 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9 | LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9 - | -LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs index 81618b3b791e..0fa2370c95bf 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -10,8 +10,6 @@ // Issue 62307 pointed out a case where the structural-match checking // was too shallow. -#![warn(indirect_structural_match)] -//@ run-pass #[derive(Debug)] struct B(i32); @@ -29,15 +27,13 @@ fn main() { match RR_B0 { RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { } } match RR_B1 { RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index d4ab1ce3ba2a..e79b05fdf9dc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -1,63 +1,20 @@ -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9 +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9 | LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 | LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9 - | -LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 - | -LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors From cbd682beeb0a7b54f4cc9e5dee3be3e6d728b9c4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 May 2024 15:49:10 +0200 Subject: [PATCH 010/101] turn pointer_structural_match into a hard error --- compiler/rustc_lint/src/lib.rs | 5 + compiler/rustc_lint_defs/src/builtin.rs | 40 ---- compiler/rustc_mir_build/src/errors.rs | 7 +- .../src/thir/pattern/const_to_pat.rs | 10 +- .../match/match-edge-cases_1.rs | 6 +- .../match/match-edge-cases_1.stderr | 23 -- .../issue-34784-match-on-non-int-raw-ptr.rs | 5 - ...ssue-34784-match-on-non-int-raw-ptr.stderr | 85 +------- .../ui/consts/const_in_pattern/issue-44333.rs | 10 +- .../const_in_pattern/issue-44333.stderr | 51 +---- tests/ui/pattern/usefulness/consts-opaque.rs | 25 +-- .../pattern/usefulness/consts-opaque.stderr | 163 ++------------ .../const-eval-compare-ice-105047.rs | 15 -- .../const-eval-compare-ice-105047.stderr | 31 --- ...-hide-behind-direct-unsafe-ptr-embedded.rs | 26 --- ...low-hide-behind-direct-unsafe-ptr-param.rs | 26 --- ...ide-behind-indirect-unsafe-ptr-embedded.rs | 26 --- ...w-hide-behind-indirect-unsafe-ptr-param.rs | 26 --- ...> fn-ptr-is-not-structurally-matchable.rs} | 36 ++-- ...n-ptr-is-not-structurally-matchable.stderr | 62 ++++++ .../fn-ptr-is-structurally-matchable.stderr | 203 ------------------ .../issue-63479-match-fnptr.rs | 10 +- .../issue-63479-match-fnptr.stderr | 51 +---- 23 files changed, 131 insertions(+), 811 deletions(-) delete mode 100644 tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr delete mode 100644 tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs delete mode 100644 tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr delete mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs delete mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs delete mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs delete mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs rename tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/{fn-ptr-is-structurally-matchable.rs => fn-ptr-is-not-structurally-matchable.rs} (76%) create mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr delete mode 100644 tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b3a7f50e8ea2..04f15167bd93 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -544,6 +544,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ for more information", ); + store.register_removed( + "pointer_structural_match", + "converted into hard error, see RFC #3535 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 6da6b39bac10..1a437eb55c77 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -74,7 +74,6 @@ declare_lint_pass! { ORDER_DEPENDENT_TRAIT_OBJECTS, OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, - POINTER_STRUCTURAL_MATCH, PRIVATE_BOUNDS, PRIVATE_INTERFACES, PROC_MACRO_BACK_COMPAT, @@ -2371,45 +2370,6 @@ declare_lint! { report_in_external_macro } -declare_lint! { - /// The `pointer_structural_match` lint detects pointers used in patterns whose behaviour - /// cannot be relied upon across compiler versions and optimization levels. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(pointer_structural_match)] - /// fn foo(a: usize, b: usize) -> usize { a + b } - /// const FOO: fn(usize, usize) -> usize = foo; - /// fn main() { - /// match FOO { - /// FOO => {}, - /// _ => {}, - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Previous versions of Rust allowed function pointers and all raw pointers in patterns. - /// While these work in many cases as expected by users, it is possible that due to - /// optimizations pointers are "not equal to themselves" or pointers to different functions - /// compare as equal during runtime. This is because LLVM optimizations can deduplicate - /// functions if their bodies are the same, thus also making pointers to these functions point - /// to the same location. Additionally functions may get duplicated if they are instantiated - /// in different crates and not deduplicated again via LTO. Pointer identity for memory - /// created by `const` is similarly unreliable. - pub POINTER_STRUCTURAL_MATCH, - Warn, - "pointers are not structural-match", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #120362 ", - }; -} - declare_lint! { /// The `ambiguous_associated_items` lint detects ambiguity between /// [associated items] and [enum variants]. diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 1d52c2723aab..51dd774b638d 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -788,9 +788,12 @@ pub struct NaNPattern { pub span: Span, } -#[derive(LintDiagnostic)] +#[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] -pub struct PointerPattern; +pub struct PointerPattern { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(mir_build_non_empty_never_pattern)] diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 6d2e740af408..84162433fa9d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -6,7 +6,6 @@ use rustc_infer::traits::Obligation; use rustc_middle::mir; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; -use rustc_session::lint; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -189,12 +188,9 @@ impl<'tcx> ConstToPat<'tcx> { } else if !have_valtree { // The only way valtree construction can fail without the structural match // checker finding a violation is if there is a pointer somewhere. - self.tcx().emit_node_span_lint( - lint::builtin::POINTER_STRUCTURAL_MATCH, - self.id, - self.span, - PointerPattern, - ); + let e = self.tcx().dcx().emit_err(PointerPattern { span: self.span }); + let kind = PatKind::Error(e); + return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); } // Always check for `PartialEq` if we had no other errors yet. diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs index 840eda0513f8..a0e8e614d8ee 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs @@ -2,8 +2,7 @@ //@ edition:2021 const PATTERN_REF: &str = "Hello World"; -const NUMBER: i32 = 30; -const NUMBER_POINTER: *const i32 = &NUMBER; +const NUMBER_POINTER: *const i32 = 30 as *const i32; pub fn edge_case_ref(event: &str) { let _ = || { @@ -26,8 +25,7 @@ pub fn edge_case_str(event: String) { pub fn edge_case_raw_ptr(event: *const i32) { let _ = || { match event { - NUMBER_POINTER => (), //~WARN behave unpredictably - //~| previously accepted + NUMBER_POINTER => (), _ => (), }; }; diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr deleted file mode 100644 index 8a2aaade6650..000000000000 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr +++ /dev/null @@ -1,23 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/match-edge-cases_1.rs:29:13 - | -LL | NUMBER_POINTER => (), - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/match-edge-cases_1.rs:29:13 - | -LL | NUMBER_POINTER => (), - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs index 6285427f59cb..e7c6101a3e06 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs @@ -1,4 +1,3 @@ -#![deny(pointer_structural_match)] #![allow(dead_code)] const C: *const u8 = &0; @@ -8,7 +7,6 @@ const C_INNER: (*const u8, u8) = (C, 0); fn foo(x: *const u8) { match x { C => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } @@ -16,7 +14,6 @@ fn foo(x: *const u8) { fn foo2(x: *const u8) { match (x, 1) { C_INNER => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } @@ -28,13 +25,11 @@ const STR: *const str = "abcd"; fn main() { match D { D => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } match STR { STR => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr index bc1015c17342..aa208341c131 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr @@ -1,103 +1,26 @@ error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9 | LL | C => {} | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9 | LL | C_INNER => {} | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9 | LL | D => {} | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9 | LL | STR => {} | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: aborting due to 4 previous errors -Future incompatibility report: Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9 - | -LL | C => {} - | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9 - | -LL | C_INNER => {} - | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9 - | -LL | D => {} - | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9 - | -LL | STR => {} - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - diff --git a/tests/ui/consts/const_in_pattern/issue-44333.rs b/tests/ui/consts/const_in_pattern/issue-44333.rs index 9adf02cbfcef..8a70aae1d509 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.rs +++ b/tests/ui/consts/const_in_pattern/issue-44333.rs @@ -1,7 +1,3 @@ -//@ run-pass - -#![warn(pointer_structural_match)] - type Func = fn(usize, usize) -> usize; fn foo(a: usize, b: usize) -> usize { a + b } @@ -16,10 +12,8 @@ const BAR: Func = bar; fn main() { match test(std::env::consts::ARCH.len()) { - FOO => println!("foo"), //~ WARN behave unpredictably - //~^ WARN will become a hard error - BAR => println!("bar"), //~ WARN behave unpredictably - //~^ WARN will become a hard error + FOO => println!("foo"), //~ ERROR behave unpredictably + BAR => println!("bar"), //~ ERROR behave unpredictably _ => unreachable!(), } } diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr index f5931f0cad08..d377bfd95f9c 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.stderr +++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr @@ -1,55 +1,14 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:19:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-44333.rs:15:9 | LL | FOO => println!("foo"), | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:21:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-44333.rs:16:9 | LL | BAR => println!("bar"), | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:19:9 - | -LL | FOO => println!("foo"), - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:21:9 - | -LL | BAR => println!("bar"), - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs index 3e4617851823..a5743c633085 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.rs +++ b/tests/ui/pattern/usefulness/consts-opaque.rs @@ -93,10 +93,8 @@ fn main() { const QUUX: Quux = quux; match QUUX { - QUUX => {} //~WARN behave unpredictably - //~| previously accepted - QUUX => {} //~WARN behave unpredictably - //~| previously accepted + QUUX => {} //~ERROR behave unpredictably + QUUX => {} //~ERROR behave unpredictably _ => {} } @@ -105,17 +103,14 @@ fn main() { const WRAPQUUX: Wrap = Wrap(quux); match WRAPQUUX { - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably + WRAPQUUX => {} //~ERROR behave unpredictably Wrap(_) => {} } match WRAPQUUX { Wrap(_) => {} - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably } match WRAPQUUX { @@ -123,9 +118,7 @@ fn main() { } match WRAPQUUX { - //~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably } #[derive(PartialEq, Eq)] @@ -136,11 +129,9 @@ fn main() { const WHOKNOWSQUUX: WhoKnows = WhoKnows::Yay(quux); match WHOKNOWSQUUX { - WHOKNOWSQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WHOKNOWSQUUX => {} //~ERROR behave unpredictably WhoKnows::Yay(_) => {} - WHOKNOWSQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WHOKNOWSQUUX => {} //~ERROR behave unpredictably WhoKnows::Nope => {} } } diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 6a5bd185e39b..d057309e4206 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,75 +1,50 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. --> $DIR/consts-opaque.rs:96:9 | LL | QUUX => {} | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:98:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:97:9 | LL | QUUX => {} | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:108:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:106:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:110:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:107:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:117:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:113:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:127:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:121:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:139:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:132:9 | LL | WHOKNOWSQUUX => {} | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:142:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:134:9 | LL | WHOKNOWSQUUX => {} | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: unreachable pattern --> $DIR/consts-opaque.rs:48:9 @@ -146,111 +121,5 @@ error: unreachable pattern LL | _ => {} // should not be emitting unreachable warning | ^ -error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered - --> $DIR/consts-opaque.rs:125:11 - | -LL | match WRAPQUUX { - | ^^^^^^^^ pattern `Wrap(_)` not covered - | -note: `Wrap usize>` defined here - --> $DIR/consts-opaque.rs:104:12 - | -LL | struct Wrap(T); - | ^^^^ - = note: the matched value is of type `Wrap usize>` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL | WRAPQUUX => {}, Wrap(_) => todo!() - | ++++++++++++++++++++ - -error: aborting due to 10 previous errors; 8 warnings emitted - -For more information about this error, try `rustc --explain E0004`. -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:96:9 - | -LL | QUUX => {} - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:98:9 - | -LL | QUUX => {} - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:108:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:110:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:117:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:127:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:139:9 - | -LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:142:9 - | -LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default +error: aborting due to 17 previous errors diff --git a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs b/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs deleted file mode 100644 index 87ce4f1e14d9..000000000000 --- a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs +++ /dev/null @@ -1,15 +0,0 @@ -// issue: rust-lang/rust#105047 -// ICE raw ptr comparison should already be caught in the trait systems - -#![feature(raw_ref_op)] - -const RCZ: *const i32 = &raw const *&0; - -const fn f() { - if let RCZ = &raw const *&0 { } - //~^ WARN function pointers and raw pointers not derived from integers in patterns - //~| ERROR pointers cannot be reliably compared during const eval - //~| WARN this was previously accepted by the compiler but is being phased out -} - -fn main() {} diff --git a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr b/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr deleted file mode 100644 index 9c472cda2442..000000000000 --- a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr +++ /dev/null @@ -1,31 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -error: pointers cannot be reliably compared during const eval - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = note: see issue #53020 for more information - -error: aborting due to 1 previous error; 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs deleted file mode 100644 index 22ea6f7534a7..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapEmbedded(*const NoDerive); - -const WRAP_UNSAFE_EMBEDDED: WrapEmbedded = WrapEmbedded(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_EMBEDDED { - WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs deleted file mode 100644 index cd513d2aff4d..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapParam(*const X); - -const WRAP_UNSAFE_PARAM: WrapParam = WrapParam(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_PARAM { - WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs deleted file mode 100644 index 9595d00876bc..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapEmbedded(*const NoDerive); - -const WRAP_UNSAFE_EMBEDDED: & &WrapEmbedded = & &WrapEmbedded(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_EMBEDDED { - WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs deleted file mode 100644 index 9dce827a57cb..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapParam(*const X); - -const WRAP_UNSAFE_PARAM: & &WrapParam = & &WrapParam(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_PARAM { - WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs similarity index 76% rename from tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs rename to tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs index 25434e0050f0..d572d12c5b1c 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs @@ -1,7 +1,5 @@ -//@ run-pass - -// This file checks that fn ptrs are considered structurally matchable. -// See also rust-lang/rust#63479. +// This file checks that fn ptrs are *not* considered structurally matchable. +// See also rust-lang/rust#63479 and RFC 3535. fn main() { let mut count = 0; @@ -40,8 +38,7 @@ fn main() { const CFN1: Wrap = Wrap(trivial); let input: Wrap = Wrap(trivial); match Wrap(input) { - Wrap(CFN1) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN1) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -49,8 +46,7 @@ fn main() { const CFN2: Wrap = Wrap(sm_to); let input: Wrap = Wrap(sm_to); match Wrap(input) { - Wrap(CFN2) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN2) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -58,8 +54,7 @@ fn main() { const CFN3: Wrap SM> = Wrap(to_sm); let input: Wrap SM> = Wrap(to_sm); match Wrap(input) { - Wrap(CFN3) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN3) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -67,8 +62,7 @@ fn main() { const CFN4: Wrap = Wrap(not_sm_to); let input: Wrap = Wrap(not_sm_to); match Wrap(input) { - Wrap(CFN4) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN4) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -76,8 +70,7 @@ fn main() { const CFN5: Wrap NotSM> = Wrap(to_not_sm); let input: Wrap NotSM> = Wrap(to_not_sm); match Wrap(input) { - Wrap(CFN5) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN5) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -85,8 +78,7 @@ fn main() { const CFN6: Wrap = Wrap(r_sm_to); let input: Wrap = Wrap(r_sm_to); match Wrap(input) { - Wrap(CFN6) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN6) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -94,8 +86,7 @@ fn main() { const CFN7: Wrap &SM> = Wrap(r_to_r_sm); let input: Wrap &SM> = Wrap(r_to_r_sm); match Wrap(input) { - Wrap(CFN7) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN7) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -103,8 +94,7 @@ fn main() { const CFN8: Wrap = Wrap(r_not_sm_to); let input: Wrap = Wrap(r_not_sm_to); match Wrap(input) { - Wrap(CFN8) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN8) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -112,8 +102,7 @@ fn main() { const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); let input: Wrap &NotSM> = Wrap(r_to_r_not_sm); match Wrap(input) { - Wrap(CFN9) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN9) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -135,8 +124,7 @@ fn main() { let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm }; match input { - CFOO => count += 1, //~WARN behave unpredictably - //~| previously accepted + CFOO => count += 1, //~ERROR behave unpredictably Foo { .. } => {} }; diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr new file mode 100644 index 000000000000..0bc1e7fc89b5 --- /dev/null +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr @@ -0,0 +1,62 @@ +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14 + | +LL | Wrap(CFN1) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14 + | +LL | Wrap(CFN2) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14 + | +LL | Wrap(CFN3) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14 + | +LL | Wrap(CFN4) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14 + | +LL | Wrap(CFN5) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14 + | +LL | Wrap(CFN6) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14 + | +LL | Wrap(CFN7) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14 + | +LL | Wrap(CFN8) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14 + | +LL | Wrap(CFN9) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9 + | +LL | CFOO => count += 1, + | ^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr deleted file mode 100644 index 11163ba70ec6..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr +++ /dev/null @@ -1,203 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:43:14 - | -LL | Wrap(CFN1) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:52:14 - | -LL | Wrap(CFN2) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14 - | -LL | Wrap(CFN3) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14 - | -LL | Wrap(CFN4) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14 - | -LL | Wrap(CFN5) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14 - | -LL | Wrap(CFN6) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14 - | -LL | Wrap(CFN7) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14 - | -LL | Wrap(CFN8) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14 - | -LL | Wrap(CFN9) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9 - | -LL | CFOO => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: 10 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:43:14 - | -LL | Wrap(CFN1) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:52:14 - | -LL | Wrap(CFN2) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14 - | -LL | Wrap(CFN3) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14 - | -LL | Wrap(CFN4) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14 - | -LL | Wrap(CFN5) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14 - | -LL | Wrap(CFN6) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14 - | -LL | Wrap(CFN7) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14 - | -LL | Wrap(CFN8) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14 - | -LL | Wrap(CFN9) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9 - | -LL | CFOO => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs index 634aaf8115f2..9ceb72b68721 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs @@ -1,12 +1,8 @@ -//@ run-pass - // The actual regression test from #63479. (Including this because my // first draft at fn-ptr-is-structurally-matchable.rs failed to actually // cover the case this hit; I've since expanded it accordingly, but the // experience left me wary of leaving this regression test out.) -#![warn(pointer_structural_match)] - #[derive(Eq)] struct A { a: i64 @@ -34,14 +30,12 @@ fn main() { let s = B(my_fn); match s { B(TEST) => println!("matched"), - //~^ WARN behave unpredictably - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR behave unpredictably _ => panic!("didn't match") }; match (s.0, 0) { TEST2 => println!("matched"), - //~^ WARN behave unpredictably - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR behave unpredictably _ => panic!("didn't match") } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr index 0edcf44c4d79..7b1832ed0fa5 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr @@ -1,55 +1,14 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:36:7 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-63479-match-fnptr.rs:32:7 | LL | B(TEST) => println!("matched"), | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:42:5 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-63479-match-fnptr.rs:37:5 | LL | TEST2 => println!("matched"), | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:36:7 - | -LL | B(TEST) => println!("matched"), - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:42:5 - | -LL | TEST2 => println!("matched"), - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors From 1f1653c3283deca450ee84a01562ef9a914e4478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 3 May 2024 17:31:55 +0300 Subject: [PATCH 011/101] Stabilize `div_duration` --- library/core/src/time.rs | 6 ++---- library/core/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 78494b866b10..e2cf0cb62159 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1062,14 +1062,13 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` - #[unstable(feature = "div_duration", issue = "63139")] + #[stable(feature = "div_duration", since = "1.80.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1082,14 +1081,13 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` - #[unstable(feature = "div_duration", issue = "63139")] + #[stable(feature = "div_duration", since = "1.80.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 797108a8425d..b7fcf6bbf4b4 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -29,7 +29,6 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] -#![feature(div_duration)] #![feature(duration_abs_diff)] #![feature(duration_consts_float)] #![feature(duration_constants)] From 6d223bb6a1f54eacd57e14d5fc323f97f12e5005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 3 May 2024 17:42:34 +0300 Subject: [PATCH 012/101] Use `CURRENT_RUSTC_VERSION` --- library/core/src/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index e2cf0cb62159..a4de3d099b3e 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1068,7 +1068,7 @@ impl Duration { /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` - #[stable(feature = "div_duration", since = "1.80.0")] + #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1087,7 +1087,7 @@ impl Duration { /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` - #[stable(feature = "div_duration", since = "1.80.0")] + #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From ffe8510e3d989f35163ac5406af82e1c9dd8f769 Mon Sep 17 00:00:00 2001 From: Markus Everling Date: Thu, 11 Apr 2024 15:31:10 +0000 Subject: [PATCH 013/101] Fix `VecDeque::shrink_to` UB when `handle_alloc_error` unwinds. Luckily it's comparatively simple to just restore the `VecDeque` into a valid state on unwinds. --- .../alloc/src/collections/vec_deque/mod.rs | 66 ++++++++++++++++++- .../alloc/src/collections/vec_deque/tests.rs | 55 +++++++++++++++- library/alloc/src/lib.rs | 1 + 3 files changed, 120 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4643a6bbe2ec..61d05afccfd1 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -982,6 +982,8 @@ impl VecDeque { // `head` and `len` are at most `isize::MAX` and `target_cap < self.capacity()`, so nothing can // overflow. let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); + // Used in the drop guard below. + let old_head = self.head; if self.len == 0 { self.head = 0; @@ -1034,12 +1036,74 @@ impl VecDeque { } self.head = new_head; } - self.buf.shrink_to_fit(target_cap); + + struct Guard<'a, T, A: Allocator> { + deque: &'a mut VecDeque, + old_head: usize, + target_cap: usize, + } + + impl Drop for Guard<'_, T, A> { + #[cold] + fn drop(&mut self) { + unsafe { + // SAFETY: This is only called if `buf.shrink_to_fit` unwinds, + // which is the only time it's safe to call `abort_shrink`. + self.deque.abort_shrink(self.old_head, self.target_cap) + } + } + } + + let guard = Guard { deque: self, old_head, target_cap }; + + guard.deque.buf.shrink_to_fit(target_cap); + + // Don't drop the guard if we didn't unwind. + mem::forget(guard); debug_assert!(self.head < self.capacity() || self.capacity() == 0); debug_assert!(self.len <= self.capacity()); } + /// Reverts the deque back into a consistent state in case `shrink_to` failed. + /// This is necessary to prevent UB if the backing allocator returns an error + /// from `shrink` and `handle_alloc_error` subsequently unwinds (see #123369). + /// + /// `old_head` refers to the head index before `shrink_to` was called. `target_cap` + /// is the capacity that it was trying to shrink to. + unsafe fn abort_shrink(&mut self, old_head: usize, target_cap: usize) { + // Moral equivalent of self.head + self.len <= target_cap. Won't overflow + // because `self.len <= target_cap`. + if self.head <= target_cap - self.len { + // The deque's buffer is contiguous, so no need to copy anything around. + return; + } + + // `shrink_to` already copied the head to fit into the new capacity, so this won't overflow. + let head_len = target_cap - self.head; + // `self.head > target_cap - self.len` => `self.len > target_cap - self.head =: head_len` so this must be positive. + let tail_len = self.len - head_len; + + if tail_len <= cmp::min(head_len, self.capacity() - target_cap) { + // There's enough spare capacity to copy the tail to the back (because `tail_len < self.capacity() - target_cap`), + // and copying the tail should be cheaper than copying the head (because `tail_len <= head_len`). + + unsafe { + // The old tail and the new tail can't overlap because the head slice lies between them. The + // head slice ends at `target_cap`, so that's where we copy to. + self.copy_nonoverlapping(0, target_cap, tail_len); + } + } else { + // Either there's not enough spare capacity to make the deque contiguous, or the head is shorter than the tail + // (and therefore hopefully cheaper to copy). + unsafe { + // The old and the new head slice can overlap, so we can't use `copy_nonoverlapping` here. + self.copy(self.head, old_head, head_len); + self.head = old_head; + } + } + } + /// Shortens the deque, keeping the first `len` elements and dropping /// the rest. /// diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index f8ce4ca97884..5329ad1aed5c 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -1,4 +1,11 @@ -use core::iter::TrustedLen; +#![feature(alloc_error_hook)] + +use crate::alloc::{AllocError, Layout}; +use core::{iter::TrustedLen, ptr::NonNull}; +use std::{ + alloc::{set_alloc_error_hook, take_alloc_error_hook, System}, + panic::{catch_unwind, AssertUnwindSafe}, +}; use super::*; @@ -790,6 +797,52 @@ fn test_shrink_to() { } } +#[test] +fn test_shrink_to_unwind() { + // This tests that `shrink_to` leaves the deque in a consistent state when + // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369 + // but changed to hopefully not have any UB even if the test fails. + + struct BadAlloc; + + unsafe impl Allocator for BadAlloc { + fn allocate(&self, l: Layout) -> Result, AllocError> { + // We allocate zeroed here so that the whole buffer of the deque + // is always initialized. That way, even if the deque is left in + // an inconsistent state, no uninitialized memory should be accessed. + System.allocate_zeroed(l) + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + unsafe { System.deallocate(ptr, layout) } + } + + unsafe fn shrink( + &self, + _ptr: NonNull, + _old_layout: Layout, + _new_layout: Layout, + ) -> Result, AllocError> { + Err(AllocError) + } + } + + // preserve the old error hook just in case. + let old_error_hook = take_alloc_error_hook(); + set_alloc_error_hook(|_| panic!("alloc error")); + + let mut v = VecDeque::with_capacity_in(15, BadAlloc); + v.push_back(1); + v.push_front(2); + // This should unwind because it calls `BadAlloc::shrink` and then `handle_alloc_error` which unwinds. + assert!(catch_unwind(AssertUnwindSafe(|| v.shrink_to_fit())).is_err()); + // This should only pass if the deque is left in a consistent state. + assert_eq!(v, [2, 1]); + + // restore the old error hook. + set_alloc_error_hook(old_error_hook); +} + #[test] fn test_shrink_to_fit() { // This test checks that every single combination of head and tail position, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 91b83cfe011f..d607926f8d49 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -92,6 +92,7 @@ // tidy-alphabetical-start #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] #![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))] +#![cfg_attr(test, feature(alloc_error_hook))] #![cfg_attr(test, feature(is_sorted))] #![cfg_attr(test, feature(new_uninit))] #![feature(alloc_layout_extra)] From 5cb53bc34d462a59629e5430cf2e29fe6820c550 Mon Sep 17 00:00:00 2001 From: Markus Everling Date: Tue, 7 May 2024 19:43:54 +0000 Subject: [PATCH 014/101] Move `test_shrink_to_unwind` to its own file. This way, no other test can be tripped up by `test_shrink_to_unwind` changing the alloc error hook. --- library/alloc/Cargo.toml | 4 ++ .../alloc/src/collections/vec_deque/tests.rs | 55 +------------------ library/alloc/src/lib.rs | 1 - library/alloc/tests/vec_deque_alloc_error.rs | 49 +++++++++++++++++ 4 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 library/alloc/tests/vec_deque_alloc_error.rs diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index e8afed6b35a8..7bc0bddcafc6 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -20,6 +20,10 @@ rand_xorshift = "0.3.0" name = "alloctests" path = "tests/lib.rs" +[[test]] +name = "vec_deque_alloc_error" +path = "tests/vec_deque_alloc_error.rs" + [[bench]] name = "allocbenches" path = "benches/lib.rs" diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 5329ad1aed5c..f8ce4ca97884 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -1,11 +1,4 @@ -#![feature(alloc_error_hook)] - -use crate::alloc::{AllocError, Layout}; -use core::{iter::TrustedLen, ptr::NonNull}; -use std::{ - alloc::{set_alloc_error_hook, take_alloc_error_hook, System}, - panic::{catch_unwind, AssertUnwindSafe}, -}; +use core::iter::TrustedLen; use super::*; @@ -797,52 +790,6 @@ fn test_shrink_to() { } } -#[test] -fn test_shrink_to_unwind() { - // This tests that `shrink_to` leaves the deque in a consistent state when - // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369 - // but changed to hopefully not have any UB even if the test fails. - - struct BadAlloc; - - unsafe impl Allocator for BadAlloc { - fn allocate(&self, l: Layout) -> Result, AllocError> { - // We allocate zeroed here so that the whole buffer of the deque - // is always initialized. That way, even if the deque is left in - // an inconsistent state, no uninitialized memory should be accessed. - System.allocate_zeroed(l) - } - - unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - unsafe { System.deallocate(ptr, layout) } - } - - unsafe fn shrink( - &self, - _ptr: NonNull, - _old_layout: Layout, - _new_layout: Layout, - ) -> Result, AllocError> { - Err(AllocError) - } - } - - // preserve the old error hook just in case. - let old_error_hook = take_alloc_error_hook(); - set_alloc_error_hook(|_| panic!("alloc error")); - - let mut v = VecDeque::with_capacity_in(15, BadAlloc); - v.push_back(1); - v.push_front(2); - // This should unwind because it calls `BadAlloc::shrink` and then `handle_alloc_error` which unwinds. - assert!(catch_unwind(AssertUnwindSafe(|| v.shrink_to_fit())).is_err()); - // This should only pass if the deque is left in a consistent state. - assert_eq!(v, [2, 1]); - - // restore the old error hook. - set_alloc_error_hook(old_error_hook); -} - #[test] fn test_shrink_to_fit() { // This test checks that every single combination of head and tail position, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index d607926f8d49..91b83cfe011f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -92,7 +92,6 @@ // tidy-alphabetical-start #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] #![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))] -#![cfg_attr(test, feature(alloc_error_hook))] #![cfg_attr(test, feature(is_sorted))] #![cfg_attr(test, feature(new_uninit))] #![feature(alloc_layout_extra)] diff --git a/library/alloc/tests/vec_deque_alloc_error.rs b/library/alloc/tests/vec_deque_alloc_error.rs new file mode 100644 index 000000000000..c11f4556da9a --- /dev/null +++ b/library/alloc/tests/vec_deque_alloc_error.rs @@ -0,0 +1,49 @@ +#![feature(alloc_error_hook, allocator_api)] + +use std::{ + alloc::{set_alloc_error_hook, AllocError, Allocator, Layout, System}, + collections::VecDeque, + panic::{catch_unwind, AssertUnwindSafe}, + ptr::NonNull, +}; + +#[test] +fn test_shrink_to_unwind() { + // This tests that `shrink_to` leaves the deque in a consistent state when + // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369 + // but changed to hopefully not have any UB even if the test fails. + + struct BadAlloc; + + unsafe impl Allocator for BadAlloc { + fn allocate(&self, l: Layout) -> Result, AllocError> { + // We allocate zeroed here so that the whole buffer of the deque + // is always initialized. That way, even if the deque is left in + // an inconsistent state, no uninitialized memory should be accessed. + System.allocate_zeroed(l) + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + unsafe { System.deallocate(ptr, layout) } + } + + unsafe fn shrink( + &self, + _ptr: NonNull, + _old_layout: Layout, + _new_layout: Layout, + ) -> Result, AllocError> { + Err(AllocError) + } + } + + set_alloc_error_hook(|_| panic!("alloc error")); + + let mut v = VecDeque::with_capacity_in(15, BadAlloc); + v.push_back(1); + v.push_front(2); + // This should unwind because it calls `BadAlloc::shrink` and then `handle_alloc_error` which unwinds. + assert!(catch_unwind(AssertUnwindSafe(|| v.shrink_to_fit())).is_err()); + // This should only pass if the deque is left in a consistent state. + assert_eq!(v, [2, 1]); +} From 700b3ea61ba2a37876af0a5d2d2f991aba5c7000 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 13 May 2024 14:22:45 +0200 Subject: [PATCH 015/101] Panic if `PathBuf::set_extension` would add a path separator This is likely never intended and potentially a security vulnerability if it happens. I'd guess that it's mostly literal strings that are passed to this function in practice, so I'm guessing this doesn't break anyone. CC #125060 --- library/std/src/path.rs | 13 +++++++++++++ library/std/src/path/tests.rs | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 79d800ff0729..acf23d976177 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1425,6 +1425,11 @@ impl PathBuf { /// If `extension` is the empty string, [`self.extension`] will be [`None`] /// afterwards, not `Some("")`. /// + /// # Panics + /// + /// Panics if the passed extension contains a path separator (see + /// [`is_separator`]). + /// /// # Caveats /// /// The new `extension` may contain dots and will be used in its entirety, @@ -1470,6 +1475,14 @@ impl PathBuf { } fn _set_extension(&mut self, extension: &OsStr) -> bool { + for &b in extension.as_encoded_bytes() { + if b < 128 { + if is_separator(b as char) { + panic!("extension cannot contain path separators: {:?}", extension); + } + } + } + let file_stem = match self.file_stem() { None => return false, Some(f) => f.as_encoded_bytes(), diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index fde6ed4f0c05..2d8e50d1f88e 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1803,6 +1803,29 @@ fn test_windows_absolute() { assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str()); } +#[test] +#[should_panic = "path separator"] +fn test_extension_path_sep() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d/../../../../../etc/passwd"); +} + +#[test] +#[should_panic = "path separator"] +#[cfg(windows)] +fn test_extension_path_sep_alternate() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d\\test"); +} + +#[test] +#[cfg(not(windows))] +fn test_extension_path_sep_alternate() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d\\test"); + assert_eq!(path, Path::new("path/to/file.d\\test")); +} + #[bench] #[cfg_attr(miri, ignore)] // Miri isn't fast... fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) { From 531dae1cdfaea537f7f1d5ff7db6bd2adb4d414a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 12 May 2024 14:22:12 +0000 Subject: [PATCH 016/101] Only allow immutable statics with #[linkage] --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 12 ++++++++++++ tests/ui/issues/issue-33992.rs | 3 --- .../linkage-attr/linkage-attr-mutable-static.rs | 15 +++++++++++++++ .../linkage-attr-mutable-static.stderr | 10 ++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/ui/linkage-attr/linkage-attr-mutable-static.rs create mode 100644 tests/ui/linkage-attr/linkage-attr-mutable-static.stderr diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index c28b0d644e67..b479b0376684 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -327,6 +327,18 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else { codegen_fn_attrs.linkage = linkage; } + if tcx.is_mutable_static(did.into()) { + let mut diag = tcx.dcx().struct_span_err( + attr.span, + "mutable statics are not allowed with `#[linkage]`", + ); + diag.note( + "making the static mutable would allow changing which symbol the \ + static references rather than make the target of the symbol \ + mutable", + ); + diag.emit(); + } } } sym::link_section => { diff --git a/tests/ui/issues/issue-33992.rs b/tests/ui/issues/issue-33992.rs index 177ff234bb29..495751436e12 100644 --- a/tests/ui/issues/issue-33992.rs +++ b/tests/ui/issues/issue-33992.rs @@ -5,9 +5,6 @@ #![feature(linkage)] -#[linkage = "common"] -pub static mut TEST1: u32 = 0u32; - #[linkage = "external"] pub static TEST2: bool = true; diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs new file mode 100644 index 000000000000..a7109c6d930b --- /dev/null +++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs @@ -0,0 +1,15 @@ +//! The symbols are resolved by the linker. It doesn't make sense to change +//! them at runtime, so deny mutable statics with #[linkage]. + +#![feature(linkage)] + +fn main() { + extern "C" { + #[linkage = "weak"] //~ ERROR mutable statics are not allowed with `#[linkage]` + static mut ABC: *const u8; + } + + unsafe { + assert_eq!(ABC as usize, 0); + } +} diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr new file mode 100644 index 000000000000..4db41b623938 --- /dev/null +++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr @@ -0,0 +1,10 @@ +error: mutable statics are not allowed with `#[linkage]` + --> $DIR/linkage-attr-mutable-static.rs:8:9 + | +LL | #[linkage = "weak"] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: making the static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable + +error: aborting due to 1 previous error + From 8da41b107debc95250078049eae63e5ab3601476 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 15 May 2024 00:38:34 +0300 Subject: [PATCH 017/101] Divide float nanoseconds instead of seconds --- library/core/src/time.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index a4de3d099b3e..bbeacac05104 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1074,7 +1074,9 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f64(self, rhs: Duration) -> f64 { - self.as_secs_f64() / rhs.as_secs_f64() + let self_nanos = (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.0 as f64); + let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.0 as f64); + self_nanos / rhs_nanos } /// Divide `Duration` by `Duration` and return `f32`. @@ -1093,7 +1095,9 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f32(self, rhs: Duration) -> f32 { - self.as_secs_f32() / rhs.as_secs_f32() + let self_nanos = (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.0 as f32); + let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.0 as f32); + self_nanos / rhs_nanos } } From 1287e868e942a352da41a531e4cc9ff5b73ea5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ml=C3=A1dek?= Date: Fri, 17 May 2024 01:30:01 +0200 Subject: [PATCH 018/101] Clear diagnostics only after new ones were received --- .../crates/rust-analyzer/src/global_state.rs | 2 ++ .../rust-analyzer/crates/rust-analyzer/src/main_loop.rs | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index f64e66183d1b..79b87ecd58ff 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -87,6 +87,7 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, pub(crate) last_flycheck_error: Option, + pub(crate) diagnostics_received: bool, // Test explorer pub(crate) test_run_session: Option>, @@ -224,6 +225,7 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, + diagnostics_received: false, test_run_session: None, test_run_sender, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 5435be3dc272..7acd302867c3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -804,6 +804,10 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: flycheck::Message) { match message { flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => { + if !self.diagnostics_received { + self.diagnostics.clear_check(id); + self.diagnostics_received = true; + } let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(), @@ -832,7 +836,7 @@ impl GlobalState { flycheck::Message::Progress { id, progress } => { let (state, message) = match progress { flycheck::Progress::DidStart => { - self.diagnostics.clear_check(id); + self.diagnostics_received = false; (Progress::Begin, None) } flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), @@ -848,6 +852,9 @@ impl GlobalState { flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); + if !self.diagnostics_received { + self.diagnostics.clear_check(id); + } (Progress::End, None) } }; From ea2a16cadb93d7ab8ee08dbe4d0527faaf94b329 Mon Sep 17 00:00:00 2001 From: roife Date: Fri, 17 May 2024 23:24:03 +0800 Subject: [PATCH 019/101] fix: resolve extern prelude for local mods in block modules --- .../crates/hir-def/src/nameres/collector.rs | 2 ++ .../hir-def/src/nameres/path_resolution.rs | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 262bc538b941..587997c47361 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -395,6 +395,8 @@ impl DefCollector<'_> { .cfg() .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)); if is_cfg_enabled { + self.inject_prelude(); + ModCollector { def_collector: self, macro_depth: 0, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index ee29b89f3d3b..7776cb706824 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -18,7 +18,9 @@ use crate::{ db::DefDatabase, item_scope::{ImportOrExternCrate, BUILTIN_SCOPE}, item_tree::Fields, - nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs}, + nameres::{ + sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs, ModuleOrigin, + }, path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, @@ -221,7 +223,7 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(db, segment) + self.resolve_name_in_crate_root_or_extern_prelude(db, original_module, segment) } PathKind::Plain => { let (_, segment) = match segments.next() { @@ -470,9 +472,9 @@ impl DefMap { }; let extern_prelude = || { - if self.block.is_some() { - // Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so - // that blocks can properly shadow them + if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) { + // Don't resolve extern prelude in pseudo-modules of blocks, because + // they might been shadowed by local names. return PerNs::none(); } self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| { @@ -505,6 +507,7 @@ impl DefMap { fn resolve_name_in_crate_root_or_extern_prelude( &self, db: &dyn DefDatabase, + module: LocalModuleId, name: &Name, ) -> PerNs { let from_crate_root = match self.block { @@ -515,8 +518,8 @@ impl DefMap { None => self[Self::ROOT].scope.get(name), }; let from_extern_prelude = || { - if self.block.is_some() { - // Don't resolve extern prelude in block `DefMap`s. + if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) { + // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } self.data.extern_prelude.get(name).copied().map_or( From 9ff4ffb81763a1532d792c81f1e4f61f8d04440b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 18 May 2024 10:52:05 +0200 Subject: [PATCH 020/101] Update builtin tool list --- .../crates/hir-def/src/attr/builtin.rs | 3 --- .../crates/hir-def/src/nameres.rs | 10 +++++++- .../hir-def/src/nameres/attr_resolution.rs | 5 ++-- src/tools/rust-analyzer/crates/hir/src/lib.rs | 23 ++++--------------- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs index 55b9a1dfdcb9..8c8df08e8559 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs @@ -12,9 +12,6 @@ use std::sync::OnceLock; use rustc_hash::FxHashMap; -/// Ignored attribute namespaces used by tools. -pub const TOOL_MODULES: &[&str] = &["rustfmt", "clippy"]; - pub struct BuiltinAttribute { pub name: &'static str, pub template: AttributeTemplate, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index a528c4cc6972..497b69889acc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -84,6 +84,14 @@ use crate::{ LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, }; +const PREDEFINED_TOOLS: &[SmolStr] = &[ + SmolStr::new_static("clippy"), + SmolStr::new_static("rustfmt"), + SmolStr::new_static("diagnostic"), + SmolStr::new_static("miri"), + SmolStr::new_static("rust_analyzer"), +]; + /// Contains the results of (early) name resolution. /// /// A `DefMap` stores the module tree and the definitions that are in scope in every module after @@ -160,7 +168,7 @@ impl DefMapCrateData { fn_proc_macro_mapping: FxHashMap::default(), proc_macro_loading_error: None, registered_attrs: Vec::new(), - registered_tools: Vec::new(), + registered_tools: PREDEFINED_TOOLS.into(), unstable_features: FxHashSet::default(), rustc_coherence_is_core: false, no_core: false, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index eb7f4c05ae21..3cb0666edf9c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -10,7 +10,7 @@ use syntax::{ast, SmolStr}; use triomphe::Arc; use crate::{ - attr::builtin::{find_builtin_attr_idx, TOOL_MODULES}, + attr::builtin::find_builtin_attr_idx, db::DefDatabase, item_scope::BuiltinShadowMode, nameres::path_resolution::ResolveMode, @@ -82,8 +82,7 @@ impl DefMap { let name = name.to_smol_str(); let pred = |n: &_| *n == name; - let registered = self.data.registered_tools.iter().map(SmolStr::as_str); - let is_tool = TOOL_MODULES.iter().copied().chain(registered).any(pred); + let is_tool = self.data.registered_tools.iter().map(SmolStr::as_str).any(pred); // FIXME: tool modules can be shadowed by actual modules if is_tool { return true; diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 85f33a10fcb2..a902ae2d3363 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -3372,34 +3372,21 @@ impl BuiltinAttr { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ToolModule { - krate: Option, + krate: CrateId, idx: u32, } impl ToolModule { - // FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs? pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option { - if let builtin @ Some(_) = Self::builtin(name) { - return builtin; - } + let krate = krate.id; let idx = - db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32; - Some(ToolModule { krate: Some(krate.id), idx }) - } - - fn builtin(name: &str) -> Option { - hir_def::attr::builtin::TOOL_MODULES - .iter() - .position(|&tool| tool == name) - .map(|idx| ToolModule { krate: None, idx: idx as u32 }) + db.crate_def_map(krate).registered_tools().iter().position(|it| it == name)? as u32; + Some(ToolModule { krate, idx }) } pub fn name(&self, db: &dyn HirDatabase) -> SmolStr { // FIXME: Return a `Name` here - match self.krate { - Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(), - None => SmolStr::new(hir_def::attr::builtin::TOOL_MODULES[self.idx as usize]), - } + db.crate_def_map(self.krate).registered_tools()[self.idx as usize].clone() } } From 7045044da359af8be28f44a8acfaa69f6b2682a9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 18 May 2024 12:35:55 +0200 Subject: [PATCH 021/101] Allow hir::Param to refer to other entity params aside from functions --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 127 +++++++++--------- .../src/handlers/replace_method_eager_lazy.rs | 4 +- .../ide-assists/src/utils/suggest_name.rs | 7 +- .../crates/ide-db/src/active_parameter.rs | 14 +- .../src/syntax_helpers/format_string.rs | 1 + .../crates/ide/src/inlay_hints/param_name.rs | 8 +- .../crates/ide/src/signature_help.rs | 17 ++- .../ide/src/syntax_highlighting/escape.rs | 35 +++-- .../crates/syntax/src/ast/token_ext.rs | 19 +-- 9 files changed, 114 insertions(+), 118 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index a902ae2d3363..49e6241f7aa7 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -35,7 +35,7 @@ pub mod term_search; mod display; -use std::{iter, mem::discriminant, ops::ControlFlow}; +use std::{mem::discriminant, ops::ControlFlow}; use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateId, CrateOrigin, FileId}; @@ -52,7 +52,6 @@ use hir_def::{ path::ImportAlias, per_ns::PerNs, resolver::{HasResolver, Resolver}, - src::HasSource as _, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, @@ -1965,7 +1964,7 @@ impl Function { .enumerate() .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -1991,7 +1990,7 @@ impl Function { .skip(skip) .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -2037,7 +2036,7 @@ impl Function { .skip(skip) .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -2167,17 +2166,24 @@ impl From for Access { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Param { - func: Function, + func: Callee, /// The index in parameter list, including self parameter. idx: usize, ty: Type, } impl Param { - pub fn parent_fn(&self) -> Function { - self.func + pub fn parent_fn(&self) -> Option { + match self.func { + Callee::Def(CallableDefId::FunctionId(f)) => Some(f.into()), + _ => None, + } } + // pub fn parent_closure(&self) -> Option { + // self.func.as_ref().right().cloned() + // } + pub fn index(&self) -> usize { self.idx } @@ -2191,7 +2197,11 @@ impl Param { } pub fn as_local(&self, db: &dyn HirDatabase) -> Option { - let parent = DefWithBodyId::FunctionId(self.func.into()); + let parent = match self.func { + Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it), + Callee::Closure(closure) => db.lookup_intern_closure(closure.into()).0, + _ => return None, + }; let body = db.body(parent); if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { Some(Local { parent, binding_id: self_param }) @@ -2205,18 +2215,45 @@ impl Param { } pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option { - self.source(db).and_then(|p| p.value.pat()) + self.source(db).and_then(|p| p.value.right()?.pat()) } - pub fn source(&self, db: &dyn HirDatabase) -> Option> { - let InFile { file_id, value } = self.func.source(db)?; - let params = value.param_list()?; - if params.self_param().is_some() { - params.params().nth(self.idx.checked_sub(params.self_param().is_some() as usize)?) - } else { - params.params().nth(self.idx) + pub fn source( + &self, + db: &dyn HirDatabase, + ) -> Option>> { + match self.func { + Callee::Def(CallableDefId::FunctionId(func)) => { + let InFile { file_id, value } = Function { id: func }.source(db)?; + let params = value.param_list()?; + if let Some(self_param) = params.self_param() { + if let Some(idx) = self.idx.checked_sub(1 as usize) { + params.params().nth(idx).map(Either::Right) + } else { + Some(Either::Left(self_param)) + } + } else { + params.params().nth(self.idx).map(Either::Right) + } + .map(|value| InFile { file_id, value }) + } + Callee::Closure(closure) => { + let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into()); + let (_, source_map) = db.body_with_source_map(owner); + let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?; + let root = db.parse_or_expand(file_id); + match value.to_node(&root) { + ast::Expr::ClosureExpr(it) => it + .param_list()? + .params() + .nth(self.idx) + .map(Either::Right) + .map(|value| InFile { file_id: ast.file_id, value }), + _ => None, + } + } + _ => None, } - .map(|value| InFile { file_id, value }) } } @@ -4919,7 +4956,7 @@ pub struct Callable { pub(crate) is_bound_method: bool, } -#[derive(Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] enum Callee { Def(CallableDefId), Closure(ClosureId), @@ -4960,43 +4997,15 @@ impl Callable { pub fn n_params(&self) -> usize { self.sig.params().len() - if self.is_bound_method { 1 } else { 0 } } - pub fn params( - &self, - db: &dyn HirDatabase, - ) -> Vec<(Option>, Type)> { - let types = self - .sig + pub fn params(&self) -> Vec { + self.sig .params() .iter() + .enumerate() .skip(if self.is_bound_method { 1 } else { 0 }) - .map(|ty| self.ty.derived(ty.clone())); - let map_param = |it: ast::Param| it.pat().map(Either::Right); - let patterns = match self.callee { - Callee::Def(CallableDefId::FunctionId(func)) => { - let src = func.lookup(db.upcast()).source(db.upcast()); - src.value.param_list().map(|param_list| { - param_list - .self_param() - .map(|it| Some(Either::Left(it))) - .filter(|_| !self.is_bound_method) - .into_iter() - .chain(param_list.params().map(map_param)) - }) - } - Callee::Closure(closure_id) => match closure_source(db, closure_id) { - Some(src) => src.param_list().map(|param_list| { - param_list - .self_param() - .map(|it| Some(Either::Left(it))) - .filter(|_| !self.is_bound_method) - .into_iter() - .chain(param_list.params().map(map_param)) - }), - None => None, - }, - _ => None, - }; - patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect() + .map(|(idx, ty)| (idx, self.ty.derived(ty.clone()))) + .map(|(idx, ty)| Param { func: self.callee, idx, ty }) + .collect() } pub fn return_type(&self) -> Type { self.ty.derived(self.sig.ret().clone()) @@ -5006,18 +5015,6 @@ impl Callable { } } -fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option { - let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into()); - let (_, source_map) = db.body_with_source_map(owner); - let ast = source_map.expr_syntax(expr_id).ok()?; - let root = ast.file_syntax(db.upcast()); - let expr = ast.value.to_node(&root); - match expr { - ast::Expr::ClosureExpr(it) => Some(it), - _ => None, - } -} - #[derive(Clone, Debug, Eq, PartialEq)] pub struct Layout(Arc, Arc); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 7f3b0d758839..37ea5123a71e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -114,10 +114,10 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<' let callable = ctx.sema.resolve_method_call_as_callable(&call)?; let (_, receiver_ty) = callable.receiver_param(ctx.sema.db)?; let n_params = callable.n_params() + 1; - let params = callable.params(ctx.sema.db); + let params = callable.params(); // FIXME: Check that the arg is of the form `() -> T` - if !params.first()?.1.impls_fnonce(ctx.sema.db) { + if !params.first()?.ty().impls_fnonce(ctx.sema.db) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs index 1859825b3d65..23a06404f301 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs @@ -253,11 +253,8 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option pat, - _ => return None, - }; + let param = func.params().into_iter().nth(idx)?; + let pat = param.source(sema.db)?.value.right()?.pat()?; let name = var_name_from_pat(&pat)?; normalize(&name.to_string()) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs index 5780b5a5bb93..abc60a77a564 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs @@ -1,7 +1,7 @@ //! This module provides functionality for querying callable information about a token. use either::Either; -use hir::{Semantics, Type}; +use hir::{InFile, Semantics, Type}; use parser::T; use syntax::{ ast::{self, HasArgList, HasName}, @@ -13,7 +13,7 @@ use crate::RootDatabase; #[derive(Debug)] pub struct ActiveParameter { pub ty: Type, - pub pat: Option>, + pub src: Option>>, } impl ActiveParameter { @@ -22,18 +22,18 @@ impl ActiveParameter { let (signature, active_parameter) = callable_for_token(sema, token)?; let idx = active_parameter?; - let mut params = signature.params(sema.db); + let mut params = signature.params(); if idx >= params.len() { cov_mark::hit!(too_many_arguments); return None; } - let (pat, ty) = params.swap_remove(idx); - Some(ActiveParameter { ty, pat }) + let param = params.swap_remove(idx); + Some(ActiveParameter { ty: param.ty().clone(), src: param.source(sema.db) }) } pub fn ident(&self) -> Option { - self.pat.as_ref().and_then(|param| match param { - Either::Right(ast::Pat::IdentPat(ident)) => ident.name(), + self.src.as_ref().and_then(|param| match param.value.as_ref().right()?.pat()? { + ast::Pat::IdentPat(ident) => ident.name(), _ => None, }) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs index 8302b015ddaf..92478ef480d6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs @@ -41,6 +41,7 @@ pub enum FormatSpecifier { Escape, } +// FIXME: Remove this, we can use rustc_format_parse instead pub fn lex_format_specifiers( string: &ast::String, mut callback: &mut dyn FnMut(TextRange, FormatSpecifier), diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index 96e845b2f323..20e8aca84915 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -24,15 +24,15 @@ pub(super) fn hints( let (callable, arg_list) = get_callable(sema, &expr)?; let hints = callable - .params(sema.db) + .params() .into_iter() .zip(arg_list.args()) - .filter_map(|((param, _ty), arg)| { + .filter_map(|(p, arg)| { // Only annotate hints for expressions that exist in the original file let range = sema.original_range_opt(arg.syntax())?; - let (param_name, name_syntax) = match param.as_ref()? { + let (param_name, name_syntax) = match p.source(sema.db)?.value.as_ref() { Either::Left(pat) => (pat.name()?, pat.name()), - Either::Right(pat) => match pat { + Either::Right(param) => match param.pat()? { ast::Pat::IdentPat(it) => (it.name()?, it.name()), _ => return None, }, diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index b2eb5a5fff1e..05e605f6e4a1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -210,12 +210,15 @@ fn signature_help_for_call( format_to!(res.signature, "{}", self_param.display(db)) } let mut buf = String::new(); - for (idx, (pat, ty)) in callable.params(db).into_iter().enumerate() { + for (idx, p) in callable.params().into_iter().enumerate() { buf.clear(); - if let Some(pat) = pat { - match pat { - Either::Left(_self) => format_to!(buf, "self: "), - Either::Right(pat) => format_to!(buf, "{}: ", pat), + if let Some(param) = p.source(sema.db) { + match param.value { + Either::Right(param) => match param.pat() { + Some(pat) => format_to!(buf, "{}: ", pat), + None => format_to!(buf, "?: "), + }, + Either::Left(_) => format_to!(buf, "self: "), } } // APITs (argument position `impl Trait`s) are inferred as {unknown} as the user is @@ -223,9 +226,9 @@ fn signature_help_for_call( // In that case, fall back to render definitions of the respective parameters. // This is overly conservative: we do not substitute known type vars // (see FIXME in tests::impl_trait) and falling back on any unknowns. - match (ty.contains_unknown(), fn_params.as_deref()) { + match (p.ty().contains_unknown(), fn_params.as_deref()) { (true, Some(fn_params)) => format_to!(buf, "{}", fn_params[idx].ty().display(db)), - _ => format_to!(buf, "{}", ty.display(db)), + _ => format_to!(buf, "{}", p.ty().display(db)), } res.push_call_param(&buf); } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs index 0439e509d21d..2f387968c96a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs @@ -9,8 +9,9 @@ pub(super) fn highlight_escape_string( string: &T, start: TextSize, ) { + let text = string.text(); string.escaped_char_ranges(&mut |piece_range, char| { - if string.text()[piece_range.start().into()..].starts_with('\\') { + if text[piece_range.start().into()..].starts_with('\\') { let highlight = match char { Ok(_) => HlTag::EscapeSequence, Err(_) => HlTag::InvalidEscapeSequence, @@ -33,17 +34,15 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: } let text = char.text(); - if !text.starts_with('\'') || !text.ends_with('\'') { + let Some(text) = text + .strip_prefix('\'') + .and_then(|it| it.strip_suffix('\'')) + .filter(|it| it.starts_with('\\')) + else { return; - } + }; - let text = &text[1..text.len() - 1]; - if !text.starts_with('\\') { - return; - } - - let range = - TextRange::new(start + TextSize::from(1), start + TextSize::from(text.len() as u32 + 1)); + let range = TextRange::at(start + TextSize::from(1), TextSize::from(text.len() as u32)); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } @@ -54,16 +53,14 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: } let text = byte.text(); - if !text.starts_with("b'") || !text.ends_with('\'') { + let Some(text) = text + .strip_prefix("b'") + .and_then(|it| it.strip_suffix('\'')) + .filter(|it| it.starts_with('\\')) + else { return; - } + }; - let text = &text[2..text.len() - 1]; - if !text.starts_with('\\') { - return; - } - - let range = - TextRange::new(start + TextSize::from(2), start + TextSize::from(text.len() as u32 + 2)); + let range = TextRange::at(start + TextSize::from(2), TextSize::from(text.len() as u32)); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs index 16599881d643..1ce548f8fc70 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs @@ -8,6 +8,7 @@ use std::{ use rustc_lexer::unescape::{ unescape_byte, unescape_char, unescape_mixed, unescape_unicode, EscapeError, MixedUnit, Mode, }; +use stdx::always; use crate::{ ast::{self, AstToken}, @@ -181,25 +182,25 @@ pub trait IsString: AstToken { self.quote_offsets().map(|it| it.quotes.1) } fn escaped_char_ranges(&self, cb: &mut dyn FnMut(TextRange, Result)) { - let text_range_no_quotes = match self.text_range_between_quotes() { - Some(it) => it, - None => return, - }; + let Some(text_range_no_quotes) = self.text_range_between_quotes() else { return }; let start = self.syntax().text_range().start(); let text = &self.text()[text_range_no_quotes - start]; let offset = text_range_no_quotes.start() - start; unescape_unicode(text, Self::MODE, &mut |range, unescaped_char| { - let text_range = - TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap()); - cb(text_range + offset, unescaped_char); + if let Some((s, e)) = range.start.try_into().ok().zip(range.end.try_into().ok()) { + cb(TextRange::new(s, e) + offset, unescaped_char); + } }); } fn map_range_up(&self, range: TextRange) -> Option { let contents_range = self.text_range_between_quotes()?; - assert!(TextRange::up_to(contents_range.len()).contains_range(range)); - Some(range + contents_range.start()) + if always!(TextRange::up_to(contents_range.len()).contains_range(range)) { + Some(range + contents_range.start()) + } else { + None + } } } From 4b3d7f60390b73078c8614ea210196e425844368 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 18 May 2024 15:01:37 +0200 Subject: [PATCH 022/101] Render closure fn trait kind in siganture help --- .../rust-analyzer/crates/hir-ty/src/traits.rs | 11 ++++ src/tools/rust-analyzer/crates/hir/src/lib.rs | 54 +++++++++++-------- .../crates/ide/src/signature_help.rs | 41 ++++++++++++-- 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 930bc7df5e01..7266cbb7b222 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -1,5 +1,6 @@ //! Trait solving using Chalk. +use core::fmt; use std::env::var; use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData}; @@ -209,6 +210,16 @@ pub enum FnTrait { Fn, } +impl fmt::Display for FnTrait { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FnTrait::FnOnce => write!(f, "FnOnce"), + FnTrait::FnMut => write!(f, "FnMut"), + FnTrait::Fn => write!(f, "Fn"), + } + } +} + impl FnTrait { const fn lang_item(self) -> LangItem { match self { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 49e6241f7aa7..beb97d545850 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2199,7 +2199,7 @@ impl Param { pub fn as_local(&self, db: &dyn HirDatabase) -> Option { let parent = match self.func { Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it), - Callee::Closure(closure) => db.lookup_intern_closure(closure.into()).0, + Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0, _ => return None, }; let body = db.body(parent); @@ -2237,7 +2237,7 @@ impl Param { } .map(|value| InFile { file_id, value }) } - Callee::Closure(closure) => { + Callee::Closure(closure, _) => { let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into()); let (_, source_map) = db.body_with_source_map(owner); let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?; @@ -4316,16 +4316,23 @@ impl Type { } pub fn as_callable(&self, db: &dyn HirDatabase) -> Option { - let mut the_ty = &self.ty; let callee = match self.ty.kind(Interner) { - TyKind::Ref(_, _, ty) if ty.as_closure().is_some() => { - the_ty = ty; - Callee::Closure(ty.as_closure().unwrap()) - } - TyKind::Closure(id, _) => Callee::Closure(*id), + TyKind::Closure(id, subst) => Callee::Closure(*id, subst.clone()), TyKind::Function(_) => Callee::FnPtr, TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?), - _ => { + kind => { + // This branch shouldn't be necessary? + if let TyKind::Ref(_, _, ty) = kind { + if let TyKind::Closure(closure, subst) = ty.kind(Interner) { + let sig = ty.callable_sig(db)?; + return Some(Callable { + ty: self.clone(), + sig, + callee: Callee::Closure(*closure, subst.clone()), + is_bound_method: false, + }); + } + } let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?; return Some(Callable { ty: self.clone(), @@ -4336,7 +4343,7 @@ impl Type { } }; - let sig = the_ty.callable_sig(db)?; + let sig = self.ty.callable_sig(db)?; Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false }) } @@ -4953,13 +4960,13 @@ pub struct Callable { sig: CallableSig, callee: Callee, /// Whether this is a method that was called with method call syntax. - pub(crate) is_bound_method: bool, + is_bound_method: bool, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] enum Callee { Def(CallableDefId), - Closure(ClosureId), + Closure(ClosureId, Substitution), FnPtr, Other, } @@ -4968,7 +4975,7 @@ pub enum CallableKind { Function(Function), TupleStruct(Struct), TupleEnumVariant(Variant), - Closure, + Closure(Closure), FnPtr, /// Some other type that implements `FnOnce`. Other, @@ -4976,14 +4983,17 @@ pub enum CallableKind { impl Callable { pub fn kind(&self) -> CallableKind { - use Callee::*; match self.callee { - Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), - Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), - Def(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()), - Closure(_) => CallableKind::Closure, - FnPtr => CallableKind::FnPtr, - Other => CallableKind::Other, + Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), + Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), + Callee::Def(CallableDefId::EnumVariantId(it)) => { + CallableKind::TupleEnumVariant(it.into()) + } + Callee::Closure(id, ref subst) => { + CallableKind::Closure(Closure { id, subst: subst.clone() }) + } + Callee::FnPtr => CallableKind::FnPtr, + Callee::Other => CallableKind::Other, } } pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> { @@ -5004,7 +5014,7 @@ impl Callable { .enumerate() .skip(if self.is_bound_method { 1 } else { 0 }) .map(|(idx, ty)| (idx, self.ty.derived(ty.clone()))) - .map(|(idx, ty)| Param { func: self.callee, idx, ty }) + .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty }) .collect() } pub fn return_type(&self) -> Type { diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index 05e605f6e4a1..96301ea0cee2 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -201,7 +201,10 @@ fn signature_help_for_call( variant.name(db).display(db) ); } - hir::CallableKind::Closure | hir::CallableKind::FnPtr | hir::CallableKind::Other => (), + hir::CallableKind::Closure(closure) => { + format_to!(res.signature, "impl {}", closure.fn_trait(db)); + } + hir::CallableKind::FnPtr | hir::CallableKind::Other => (), } res.signature.push('('); @@ -245,7 +248,7 @@ fn signature_help_for_call( render(func.ret_type(db)) } hir::CallableKind::Function(_) - | hir::CallableKind::Closure + | hir::CallableKind::Closure(_) | hir::CallableKind::FnPtr | hir::CallableKind::Other => render(callable.return_type()), hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {} @@ -1348,15 +1351,43 @@ fn test() { S.foo($0); } r#" struct S; fn foo(s: S) -> i32 { 92 } +fn main() { + let _move = S; + (|s| {{_move}; foo(s)})($0) +} + "#, + expect![[r#" + impl FnOnce(s: S) -> i32 + ^^^^ + "#]], + ); + check( + r#" +struct S; +fn foo(s: S) -> i32 { 92 } fn main() { (|s| foo(s))($0) } "#, expect![[r#" - (s: S) -> i32 - ^^^^ + impl Fn(s: S) -> i32 + ^^^^ "#]], - ) + ); + check( + r#" +struct S; +fn foo(s: S) -> i32 { 92 } +fn main() { + let mut mutate = 0; + (|s| { mutate = 1; foo(s) })($0) +} + "#, + expect![[r#" + impl FnMut(s: S) -> i32 + ^^^^ + "#]], + ); } #[test] From f42e55dfc8378010144183f5985a7e48e9378c9a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 18 May 2024 15:06:46 +0200 Subject: [PATCH 023/101] Enable linked locations for closure param inlay hints --- .../crates/ide/src/inlay_hints/param_name.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index 20e8aca84915..fb50c49a3ae8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -30,28 +30,23 @@ pub(super) fn hints( .filter_map(|(p, arg)| { // Only annotate hints for expressions that exist in the original file let range = sema.original_range_opt(arg.syntax())?; - let (param_name, name_syntax) = match p.source(sema.db)?.value.as_ref() { + let source = p.source(sema.db)?; + let (param_name, name_syntax) = match source.value.as_ref() { Either::Left(pat) => (pat.name()?, pat.name()), Either::Right(param) => match param.pat()? { ast::Pat::IdentPat(it) => (it.name()?, it.name()), _ => return None, }, }; + // make sure the file is cached so we can map out of macros + sema.parse_or_expand(source.file_id); Some((name_syntax, param_name, arg, range)) }) .filter(|(_, param_name, arg, _)| { !should_hide_param_name_hint(sema, &callable, ¶m_name.text(), arg) }) .map(|(param, param_name, _, FileRange { range, .. })| { - let mut linked_location = None; - if let Some(name) = param { - if let hir::CallableKind::Function(f) = callable.kind() { - // assert the file is cached so we can map out of macros - if sema.source(f).is_some() { - linked_location = sema.original_range_opt(name.syntax()); - } - } - } + let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax())); let colon = if config.render_colons { ":" } else { "" }; let label = From 6438554bce9ad9cc378986d89ff0bea0cebd239b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 18 May 2024 16:22:59 +0200 Subject: [PATCH 024/101] Show fn traits in signature info for trait implementors --- .../crates/hir-ty/src/infer/unify.rs | 21 ++-- .../rust-analyzer/crates/hir-ty/src/lib.rs | 71 ++++++++---- .../rust-analyzer/crates/hir-ty/src/traits.rs | 8 ++ src/tools/rust-analyzer/crates/hir/src/lib.rs | 44 ++++---- .../crates/hir/src/source_analyzer.rs | 3 +- .../crates/ide-db/src/active_parameter.rs | 5 +- .../crates/ide/src/call_hierarchy.rs | 8 +- .../crates/ide/src/signature_help.rs | 102 ++++++++++++++++-- 8 files changed, 195 insertions(+), 67 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index b68fefc5150b..36e3a458898d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -797,19 +797,22 @@ impl<'a> InferenceTable<'a> { }) .build(); - let projection = { - let b = TyBuilder::subst_for_def(self.db, fn_once_trait, None); - if b.remaining() != 2 { - return None; - } - let fn_once_subst = b.push(ty.clone()).push(arg_ty).build(); + let b = TyBuilder::trait_ref(self.db, fn_once_trait); + if b.remaining() != 2 { + return None; + } + let mut trait_ref = b.push(ty.clone()).push(arg_ty).build(); - TyBuilder::assoc_type_projection(self.db, output_assoc_type, Some(fn_once_subst)) - .build() + let projection = { + TyBuilder::assoc_type_projection( + self.db, + output_assoc_type, + Some(trait_ref.substitution.clone()), + ) + .build() }; let trait_env = self.trait_env.env.clone(); - let mut trait_ref = projection.trait_ref(self.db); let obligation = InEnvironment { goal: trait_ref.clone().cast(Interner), environment: trait_env.clone(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 1727cec9893b..26a839f0e9fa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -570,6 +570,10 @@ impl CallableSig { } } + pub fn abi(&self) -> FnAbi { + self.abi + } + pub fn params(&self) -> &[Ty] { &self.params_and_return[0..self.params_and_return.len() - 1] } @@ -892,20 +896,16 @@ where Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) } } -pub fn callable_sig_from_fnonce( - mut self_ty: &Ty, - env: Arc, +pub fn callable_sig_from_fn_trait( + self_ty: &Ty, + trait_env: Arc, db: &dyn HirDatabase, -) -> Option { - if let Some((ty, _, _)) = self_ty.as_reference() { - // This will happen when it implements fn or fn mut, since we add a autoborrow adjustment - self_ty = ty; - } - let krate = env.krate; +) -> Option<(FnTrait, CallableSig)> { + let krate = trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; - let mut table = InferenceTable::new(db, env); + let mut table = InferenceTable::new(db, trait_env.clone()); let b = TyBuilder::trait_ref(db, fn_once_trait); if b.remaining() != 2 { return None; @@ -915,23 +915,56 @@ pub fn callable_sig_from_fnonce( // - Self: FnOnce // - >::Output == ?ret_ty let args_ty = table.new_type_var(); - let trait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build(); + let mut trait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build(); let projection = TyBuilder::assoc_type_projection( db, output_assoc_type, Some(trait_ref.substitution.clone()), ) .build(); - table.register_obligation(trait_ref.cast(Interner)); - let ret_ty = table.normalize_projection_ty(projection); - let ret_ty = table.resolve_completely(ret_ty); - let args_ty = table.resolve_completely(args_ty); + let block = trait_env.block; + let trait_env = trait_env.env.clone(); + let obligation = + InEnvironment { goal: trait_ref.clone().cast(Interner), environment: trait_env.clone() }; + let canonical = table.canonicalize(obligation.clone()); + if db.trait_solve(krate, block, canonical.cast(Interner)).is_some() { + table.register_obligation(obligation.goal); + let return_ty = table.normalize_projection_ty(projection); + for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] { + let fn_x_trait = fn_x.get_id(db, krate)?; + trait_ref.trait_id = to_chalk_trait_id(fn_x_trait); + let obligation: chalk_ir::InEnvironment> = InEnvironment { + goal: trait_ref.clone().cast(Interner), + environment: trait_env.clone(), + }; + let canonical = table.canonicalize(obligation.clone()); + if db.trait_solve(krate, block, canonical.cast(Interner)).is_some() { + let ret_ty = table.resolve_completely(return_ty); + let args_ty = table.resolve_completely(args_ty); + let params = args_ty + .as_tuple()? + .iter(Interner) + .map(|it| it.assert_ty_ref(Interner)) + .cloned() + .collect(); - let params = - args_ty.as_tuple()?.iter(Interner).map(|it| it.assert_ty_ref(Interner)).cloned().collect(); - - Some(CallableSig::from_params_and_return(params, ret_ty, false, Safety::Safe, FnAbi::RustCall)) + return Some(( + fn_x, + CallableSig::from_params_and_return( + params, + ret_ty, + false, + Safety::Safe, + FnAbi::RustCall, + ), + )); + } + } + unreachable!("It should at least implement FnOnce at this point"); + } else { + None + } } struct PlaceholderCollector<'db> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 7266cbb7b222..02f2cd761599 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -221,6 +221,14 @@ impl fmt::Display for FnTrait { } impl FnTrait { + pub const fn function_name(&self) -> &'static str { + match self { + FnTrait::FnOnce => "call_once", + FnTrait::FnMut => "call_mut", + FnTrait::Fn => "call", + } + } + const fn lang_item(self) -> LangItem { match self { FnTrait::FnOnce => LangItem::FnOnce, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index beb97d545850..82d2bbb6cf31 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -140,7 +140,7 @@ pub use { display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite}, layout::LayoutError, mir::{MirEvalError, MirLowerError}, - PointerCast, Safety, + FnAbi, PointerCast, Safety, }, // FIXME: Properly encapsulate mir hir_ty::{mir, Interner as ChalkTyInterner}, @@ -2227,7 +2227,7 @@ impl Param { let InFile { file_id, value } = Function { id: func }.source(db)?; let params = value.param_list()?; if let Some(self_param) = params.self_param() { - if let Some(idx) = self.idx.checked_sub(1 as usize) { + if let Some(idx) = self.idx.checked_sub(1) { params.params().nth(idx).map(Either::Right) } else { Some(Either::Left(self_param)) @@ -4321,23 +4321,26 @@ impl Type { TyKind::Function(_) => Callee::FnPtr, TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?), kind => { - // This branch shouldn't be necessary? - if let TyKind::Ref(_, _, ty) = kind { - if let TyKind::Closure(closure, subst) = ty.kind(Interner) { - let sig = ty.callable_sig(db)?; - return Some(Callable { - ty: self.clone(), - sig, - callee: Callee::Closure(*closure, subst.clone()), - is_bound_method: false, - }); - } + // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment + let (ty, kind) = if let TyKind::Ref(_, _, ty) = kind { + (ty, ty.kind(Interner)) + } else { + (&self.ty, kind) + }; + if let TyKind::Closure(closure, subst) = kind { + let sig = ty.callable_sig(db)?; + return Some(Callable { + ty: self.clone(), + sig, + callee: Callee::Closure(*closure, subst.clone()), + is_bound_method: false, + }); } - let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?; + let (fn_trait, sig) = hir_ty::callable_sig_from_fn_trait(ty, self.env.clone(), db)?; return Some(Callable { ty: self.clone(), sig, - callee: Callee::Other, + callee: Callee::FnImpl(fn_trait), is_bound_method: false, }); } @@ -4968,7 +4971,7 @@ enum Callee { Def(CallableDefId), Closure(ClosureId, Substitution), FnPtr, - Other, + FnImpl(FnTrait), } pub enum CallableKind { @@ -4977,8 +4980,7 @@ pub enum CallableKind { TupleEnumVariant(Variant), Closure(Closure), FnPtr, - /// Some other type that implements `FnOnce`. - Other, + FnImpl(FnTrait), } impl Callable { @@ -4993,7 +4995,7 @@ impl Callable { CallableKind::Closure(Closure { id, subst: subst.clone() }) } Callee::FnPtr => CallableKind::FnPtr, - Callee::Other => CallableKind::Other, + Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_), } } pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> { @@ -5023,6 +5025,10 @@ impl Callable { pub fn sig(&self) -> &CallableSig { &self.sig } + + pub fn ty(&self) -> &Type { + &self.ty + } } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 057b03baef07..d22958406420 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -307,7 +307,8 @@ impl SourceAnalyzer { db: &dyn HirDatabase, call: &ast::Expr, ) -> Option { - self.type_of_expr(db, &call.clone())?.0.as_callable(db) + let (orig, adjusted) = self.type_of_expr(db, &call.clone())?; + adjusted.unwrap_or(orig).as_callable(db) } pub(crate) fn resolve_field( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs index abc60a77a564..98d2e8175461 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs @@ -60,10 +60,7 @@ pub fn callable_for_node( token: &SyntaxToken, ) -> Option<(hir::Callable, Option)> { let callable = match calling_node { - ast::CallableExpr::Call(call) => { - let expr = call.expr()?; - sema.type_of_expr(&expr)?.adjusted().as_callable(sema.db) - } + ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?), ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call), }?; let active_param = calling_node.arg_list().map(|arg_list| { diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs index 458b852e2a1e..654a1cd31647 100644 --- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs +++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs @@ -109,12 +109,12 @@ pub(crate) fn outgoing_calls( let expr = call.expr()?; let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?; match callable.kind() { - hir::CallableKind::Function(it) => { - let range = expr.syntax().text_range(); - it.try_to_nav(db).zip(Some(range)) - } + hir::CallableKind::Function(it) => it.try_to_nav(db), + hir::CallableKind::TupleEnumVariant(it) => it.try_to_nav(db), + hir::CallableKind::TupleStruct(it) => it.try_to_nav(db), _ => None, } + .zip(Some(expr.syntax().text_range())) } ast::CallableExpr::MethodCall(expr) => { let range = expr.name_ref()?.syntax().text_range(); diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index 96301ea0cee2..378a38892c7d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -202,9 +202,20 @@ fn signature_help_for_call( ); } hir::CallableKind::Closure(closure) => { - format_to!(res.signature, "impl {}", closure.fn_trait(db)); + let fn_trait = closure.fn_trait(db); + format_to!(res.signature, "impl {fn_trait}") } - hir::CallableKind::FnPtr | hir::CallableKind::Other => (), + hir::CallableKind::FnPtr => format_to!(res.signature, "fn"), + hir::CallableKind::FnImpl(fn_trait) => match callable.ty().as_adt() { + // FIXME: Render docs of the concrete trait impl function + Some(adt) => format_to!( + res.signature, + "<{} as {fn_trait}>::{}", + adt.name(db).display(db), + fn_trait.function_name() + ), + None => format_to!(res.signature, "impl {fn_trait}"), + }, } res.signature.push('('); @@ -250,7 +261,7 @@ fn signature_help_for_call( hir::CallableKind::Function(_) | hir::CallableKind::Closure(_) | hir::CallableKind::FnPtr - | hir::CallableKind::Other => render(callable.return_type()), + | hir::CallableKind::FnImpl(_) => render(callable.return_type()), hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {} } Some(res) @@ -1417,12 +1428,81 @@ fn main(f: fn(i32, f64) -> char) { } "#, expect![[r#" - (i32, f64) -> char - --- ^^^ + fn(i32, f64) -> char + --- ^^^ "#]], ) } + #[test] + fn call_info_for_fn_impl() { + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnMut<(i32, f64)> for S {} +impl core::ops::Fn<(i32, f64)> for S {} +fn main() { + S($0); +} + "#, + expect![[r#" + ::call(i32, f64) -> char + ^^^ --- + "#]], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnMut<(i32, f64)> for S {} +impl core::ops::Fn<(i32, f64)> for S {} +fn main() { + S(1, $0); +} + "#, + expect![[r#" + ::call(i32, f64) -> char + --- ^^^ + "#]], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnOnce<(char, char)> for S { + type Output = f64; +} +fn main() { + S($0); +} + "#, + expect![""], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnOnce<(char, char)> for S { + type Output = f64; +} +fn main() { + // FIXME: The ide layer loses the calling info here so we get an ambiguous trait solve result + S(0i32, $0); +} + "#, + expect![""], + ); + } + #[test] fn call_info_for_unclosed_call() { check( @@ -1828,19 +1908,19 @@ fn f i32>(f: F) { } "#, expect![[r#" - (u8, u16) -> i32 - ^^ --- + impl FnOnce(u8, u16) -> i32 + ^^ --- "#]], ); check( r#" -fn f &T>(f: F) { +fn f &T>(f: F) { f($0) } "#, expect![[r#" - (&T, u16) -> &T - ^^ --- + impl FnMut(&T, u16) -> &T + ^^ --- "#]], ); } @@ -1860,7 +1940,7 @@ fn take( } "#, expect![[r#" - () -> i32 + impl Fn() -> i32 "#]], ); } From e7772f20881282ede329ed2c19eb479fded4aecd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 May 2024 14:58:48 +0200 Subject: [PATCH 025/101] use posix_memalign on most Unix targets --- library/std/src/sys/pal/unix/alloc.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs index 2f908e3d0e95..242a054199f4 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/pal/unix/alloc.rs @@ -59,10 +59,9 @@ unsafe impl GlobalAlloc for System { } cfg_if::cfg_if! { - // We use posix_memalign wherever possible, but not all targets have that function. + // We use posix_memalign wherever possible, but some targets have very incomplete POSIX coverage + // so we need a fallback for those. if #[cfg(any( - target_os = "redox", - target_os = "espidf", target_os = "horizon", target_os = "vita", ))] { @@ -74,12 +73,11 @@ cfg_if::cfg_if! { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); - // We prefer posix_memalign over aligned_malloc since with aligned_malloc, - // implementations are making almost arbitrary choices for which alignments are - // "supported", making it hard to use. For instance, some implementations require the - // size to be a multiple of the alignment (wasi emmalloc), while others require the - // alignment to be at least the pointer size (Illumos, macOS) -- which may or may not be - // standards-compliant, but that does not help us. + // We prefer posix_memalign over aligned_malloc since it is more widely available, and + // since with aligned_malloc, implementations are making almost arbitrary choices for + // which alignments are "supported", making it hard to use. For instance, some + // implementations require the size to be a multiple of the alignment (wasi emmalloc), + // while others require the alignment to be at least the pointer size (Illumos, macOS). // posix_memalign only has one, clear requirement: that the alignment be a multiple of // `sizeof(void*)`. Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::()); From 3c2d9c2dbe0fd764b4af473a75fb4f44616f6b4c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 May 2024 20:40:46 +0200 Subject: [PATCH 026/101] fix typo Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/std/src/sys/pal/unix/alloc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs index 242a054199f4..eb3a57c212b4 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/pal/unix/alloc.rs @@ -73,8 +73,8 @@ cfg_if::cfg_if! { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); - // We prefer posix_memalign over aligned_malloc since it is more widely available, and - // since with aligned_malloc, implementations are making almost arbitrary choices for + // We prefer posix_memalign over aligned_alloc since it is more widely available, and + // since with aligned_alloc, implementations are making almost arbitrary choices for // which alignments are "supported", making it hard to use. For instance, some // implementations require the size to be a multiple of the alignment (wasi emmalloc), // while others require the alignment to be at least the pointer size (Illumos, macOS). From c31ec4fb043a8008785d21fb0d5fd9690d66f346 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 24 Mar 2024 18:00:56 +0900 Subject: [PATCH 027/101] Fix c_char on AIX Refs: https://github.com/rust-lang/rust/issues/122985 --- library/core/src/ffi/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 27dacbb23d95..618897b3abab 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -133,7 +133,8 @@ mod c_char_definition { any(target_arch = "aarch64", target_arch = "riscv64") ), all(target_os = "nto", target_arch = "aarch64"), - target_os = "horizon" + target_os = "horizon", + target_os = "aix", ))] { pub type c_char = u8; } else { From 719eee2d822e83dd74da46dfaa759acb9074d3aa Mon Sep 17 00:00:00 2001 From: roife Date: Tue, 21 May 2024 20:35:55 +0800 Subject: [PATCH 028/101] test: add tests for extern preludes resolving in local mods --- .../crates/hir-def/src/body/tests/block.rs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs index 985c6387ba0b..f483efa85179 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs @@ -528,3 +528,65 @@ fn f() {$0 "#]], ) } + +#[test] +fn resolve_extern_prelude_in_block() { + check_at( + r#" +//- /main.rs crate:main deps:core +fn main() { + mod f { + use core::S; + $0 + } +} + +//- /core.rs crate:core +pub struct S; + "#, + expect![[r#" + block scope + f: t + + block scope::f + S: ti vi + + crate + main: v + "#]], + ) +} + +#[test] +fn shadow_extern_prelude_in_block() { + check_at( + r#" +//- /main.rs crate:main deps:core +fn main() { + mod core { pub struct S; } + { + fn inner() {} // forces a block def map + use core::S; // should resolve to the local one + $0 + } +} + +//- /core.rs crate:core +pub const S; + "#, + expect![[r#" + block scope + S: ti vi + inner: v + + block scope + core: t + + block scope::core + S: t v + + crate + main: v + "#]], + ) +} From c773debc87c99a97def1e2a3e0d83d0167cc9d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 21 May 2024 19:31:38 +0200 Subject: [PATCH 029/101] Create a triagebot ping group for Rust for Linux --- triagebot.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2e45b257f812..a0581a298702 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -122,6 +122,17 @@ issues). """ label = "O-apple" +[ping.rust-for-linux] +alias = ["rfl"] +message = """\ +Hey Rust for Linux group! It looks like something broke the Rust for Linux integration. +Could you try to take a look? +In case it's useful, here are some [instructions] for tackling these sorts of issues. + +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/rust-for-linux.html +""" +label = "O-rfl" + [prioritize] label = "I-prioritize" From d0b45a951bddc4ed46cbbaff15818065795d0c2b Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 19 May 2024 20:56:46 -0700 Subject: [PATCH 030/101] tidy: stop special-casing tests/ui entry limit --- src/tools/tidy/src/ui_tests.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index e1c6c9a2dacd..37324639edfc 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -16,7 +16,6 @@ const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1676; -const ROOT_ENTRY_LIMIT: usize = 757; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files @@ -63,14 +62,10 @@ fn check_entries(tests_path: &Path, bad: &mut bool) { } } - let (mut max, mut max_root, mut max_issues) = (0usize, 0usize, 0usize); + let (mut max, mut max_issues) = (0usize, 0usize); for (dir_path, count) in directories { - // Use special values for these dirs. - let is_root = tests_path.join("ui") == dir_path; let is_issues_dir = tests_path.join("ui/issues") == dir_path; - let (limit, maxcnt) = if is_root { - (ROOT_ENTRY_LIMIT, &mut max_root) - } else if is_issues_dir { + let (limit, maxcnt) = if is_issues_dir { (ISSUES_ENTRY_LIMIT, &mut max_issues) } else { (ENTRY_LIMIT, &mut max) @@ -87,12 +82,6 @@ fn check_entries(tests_path: &Path, bad: &mut bool) { ); } } - if ROOT_ENTRY_LIMIT > max_root { - tidy_error!( - bad, - "`ROOT_ENTRY_LIMIT` is too high (is {ROOT_ENTRY_LIMIT}, should be {max_root})" - ); - } if ISSUES_ENTRY_LIMIT > max_issues { tidy_error!( bad, From ab73bb25cfad9643c67db8b4a89f1aaaae8ddd21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 22 May 2024 13:04:14 +0200 Subject: [PATCH 031/101] Add a comment --- triagebot.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index a0581a298702..ec3061f69557 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -122,6 +122,8 @@ issues). """ label = "O-apple" +# This ping group is meant for situations where a rustc/stdlib change breaks RfL. +# In that case, we want to notify the RfL group. [ping.rust-for-linux] alias = ["rfl"] message = """\ From 5992af6506088db3f907744b5a09e0ae99e83de4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 22 May 2024 13:49:56 +0200 Subject: [PATCH 032/101] fix: Fix general find-path inconsistencies --- .../crates/hir-def/src/find_path.rs | 281 ++++++++++-------- .../crates/hir-def/src/import_map.rs | 8 +- .../crates/hir-def/src/item_scope.rs | 2 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 23 ++ .../crates/hir-def/src/nameres.rs | 9 +- .../crates/hir-def/src/resolver.rs | 12 +- .../crates/hir-ty/src/display.rs | 4 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 9 +- .../crates/hir/src/term_search/expr.rs | 15 +- .../src/handlers/add_missing_match_arms.rs | 2 +- .../ide-assists/src/handlers/bool_to_enum.rs | 2 +- .../src/handlers/convert_into_to_from.rs | 2 +- .../convert_tuple_return_type_to_struct.rs | 2 +- .../handlers/destructure_struct_binding.rs | 2 +- .../src/handlers/extract_function.rs | 2 +- .../extract_struct_from_enum_variant.rs | 2 +- .../src/handlers/generate_deref.rs | 4 +- .../ide-assists/src/handlers/generate_new.rs | 2 +- .../src/handlers/qualify_method_call.rs | 2 +- .../replace_derive_with_manual_impl.rs | 2 +- .../replace_qualified_name_with_use.rs | 2 +- .../crates/ide-completion/src/completions.rs | 2 +- .../ide-completion/src/completions/expr.rs | 4 +- .../ide-completion/src/completions/postfix.rs | 2 +- .../crates/ide-completion/src/lib.rs | 2 +- .../crates/ide-completion/src/render.rs | 2 +- .../crates/ide-completion/src/snippet.rs | 2 +- .../ide-db/src/imports/import_assets.rs | 18 +- .../crates/ide-db/src/path_transform.rs | 6 +- .../src/handlers/json_is_not_rust.rs | 4 +- .../src/handlers/missing_fields.rs | 2 +- .../crates/ide-ssr/src/matching.rs | 2 +- 32 files changed, 242 insertions(+), 193 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 4e57845a694d..68e0a8bc693a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -1,6 +1,9 @@ //! An algorithm to find a path to refer to a certain item. -use std::{cmp::Ordering, iter}; +use std::{ + cmp::Ordering, + iter::{self, once}, +}; use hir_expand::{ name::{known, AsName, Name}, @@ -14,7 +17,7 @@ use crate::{ nameres::DefMap, path::{ModPath, PathKind}, visibility::{Visibility, VisibilityExplicitness}, - CrateRootModuleId, ModuleDefId, ModuleId, + ModuleDefId, ModuleId, }; /// Find a path that can be used to refer to a certain item. This can depend on @@ -23,26 +26,20 @@ pub fn find_path( db: &dyn DefDatabase, item: ItemInNs, from: ModuleId, + prefix_kind: PrefixKind, + ignore_local_imports: bool, prefer_no_std: bool, prefer_prelude: bool, ) -> Option { let _p = tracing::span!(tracing::Level::INFO, "find_path").entered(); - find_path_inner(FindPathCtx { db, prefixed: None, prefer_no_std, prefer_prelude }, item, from) -} - -/// Find a path that can be used to refer to a certain item. This can depend on -/// *from where* you're referring to the item, hence the `from` parameter. -pub fn find_path_prefixed( - db: &dyn DefDatabase, - item: ItemInNs, - from: ModuleId, - prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, -) -> Option { - let _p = tracing::span!(tracing::Level::INFO, "find_path_prefixed").entered(); find_path_inner( - FindPathCtx { db, prefixed: Some(prefix_kind), prefer_no_std, prefer_prelude }, + FindPathCtx { + db, + prefix: prefix_kind, + prefer_no_std, + prefer_prelude, + ignore_local_imports, + }, item, from, ) @@ -70,7 +67,7 @@ pub enum PrefixKind { /// This is the same as plain, just that paths will start with `self` prepended if the path /// starts with an identifier that is not a crate. BySelf, - /// Causes paths to ignore imports in the local module. + /// Causes paths to not use a self, super or crate prefix. Plain, /// Causes paths to start with `crate` where applicable, effectively forcing paths to be absolute. ByCrate, @@ -78,37 +75,33 @@ pub enum PrefixKind { impl PrefixKind { #[inline] - fn prefix(self) -> PathKind { + fn path_kind(self) -> PathKind { match self { PrefixKind::BySelf => PathKind::Super(0), PrefixKind::Plain => PathKind::Plain, PrefixKind::ByCrate => PathKind::Crate, } } - - #[inline] - fn is_absolute(&self) -> bool { - self == &PrefixKind::ByCrate - } } #[derive(Copy, Clone)] struct FindPathCtx<'db> { db: &'db dyn DefDatabase, - prefixed: Option, + prefix: PrefixKind, prefer_no_std: bool, prefer_prelude: bool, + ignore_local_imports: bool, } /// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Option { // - if the item is a builtin, it's in scope if let ItemInNs::Types(ModuleDefId::BuiltinType(builtin)) = item { - return Some(ModPath::from_segments(PathKind::Plain, Some(builtin.as_name()))); + return Some(ModPath::from_segments(PathKind::Plain, once(builtin.as_name()))); } let def_map = from.def_map(ctx.db); - let crate_root = def_map.crate_root(); + let crate_root = from.derive_crate_root(); // - if the item is a module, jump straight to module search if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item { let mut visited_modules = FxHashSet::default(); @@ -119,7 +112,6 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti }, &def_map, &mut visited_modules, - crate_root, from, module_id, MAX_PATH_LEN, @@ -127,11 +119,20 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti .map(|(item, _)| item); } - // - if the item is already in scope, return the name under which it is - let scope_name = find_in_scope(ctx.db, &def_map, from, item); - if ctx.prefixed.is_none() { + let prefix = if item.module(ctx.db).is_some_and(|it| it.is_within_block()) { + PrefixKind::Plain + } else { + ctx.prefix + }; + let may_be_in_scope = match prefix { + PrefixKind::Plain | PrefixKind::BySelf => true, + PrefixKind::ByCrate => from.is_crate_root(), + }; + if may_be_in_scope { + // - if the item is already in scope, return the name under which it is + let scope_name = find_in_scope(ctx.db, &def_map, from, item, ctx.ignore_local_imports); if let Some(scope_name) = scope_name { - return Some(ModPath::from_segments(PathKind::Plain, Some(scope_name))); + return Some(ModPath::from_segments(prefix.path_kind(), Some(scope_name))); } } @@ -164,11 +165,9 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti }, &def_map, &mut visited_modules, - crate_root, MAX_PATH_LEN, item, from, - scope_name, ) .map(|(item, _)| item) } @@ -178,7 +177,6 @@ fn find_path_for_module( ctx: FindPathCtx<'_>, def_map: &DefMap, visited_modules: &mut FxHashSet, - crate_root: CrateRootModuleId, from: ModuleId, module_id: ModuleId, max_len: usize, @@ -187,38 +185,25 @@ fn find_path_for_module( return None; } - // Base cases: - // - if the item is already in scope, return the name under which it is - let scope_name = find_in_scope(ctx.db, def_map, from, ItemInNs::Types(module_id.into())); - if ctx.prefixed.is_none() { - if let Some(scope_name) = scope_name { - return Some((ModPath::from_segments(PathKind::Plain, Some(scope_name)), Stable)); - } - } - + let is_crate_root = module_id.as_crate_root(); // - if the item is the crate root, return `crate` - if module_id == crate_root { + if is_crate_root.is_some_and(|it| it == from.derive_crate_root()) { return Some((ModPath::from_segments(PathKind::Crate, None), Stable)); } - // - if relative paths are fine, check if we are searching for a parent - if ctx.prefixed.filter(PrefixKind::is_absolute).is_none() { - if let modpath @ Some(_) = find_self_super(def_map, module_id, from) { - return modpath.zip(Some(Stable)); - } - } - + let root_def_map = from.derive_crate_root().def_map(ctx.db); // - if the item is the crate root of a dependency crate, return the name from the extern prelude - let root_def_map = crate_root.def_map(ctx.db); - for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() { - if module_id == def_id { - let name = scope_name.unwrap_or_else(|| name.clone()); - + if let Some(crate_root) = is_crate_root { + // rev here so we prefer looking at renamed extern decls first + for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude().rev() { + if crate_root != def_id { + continue; + } let name_already_occupied_in_type_ns = def_map .with_ancestor_maps(ctx.db, from.local_id, &mut |def_map, local_id| { def_map[local_id] .scope - .type_(&name) + .type_(name) .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into())) }) .is_some(); @@ -228,24 +213,48 @@ fn find_path_for_module( } else { PathKind::Plain }; - return Some((ModPath::from_segments(kind, Some(name)), Stable)); + return Some((ModPath::from_segments(kind, once(name.clone())), Stable)); + } + } + let prefix = if module_id.is_within_block() { PrefixKind::Plain } else { ctx.prefix }; + let may_be_in_scope = match prefix { + PrefixKind::Plain | PrefixKind::BySelf => true, + PrefixKind::ByCrate => from.is_crate_root(), + }; + if may_be_in_scope { + let scope_name = find_in_scope( + ctx.db, + def_map, + from, + ItemInNs::Types(module_id.into()), + ctx.ignore_local_imports, + ); + if let Some(scope_name) = scope_name { + // - if the item is already in scope, return the name under which it is + return Some((ModPath::from_segments(prefix.path_kind(), once(scope_name)), Stable)); } } - if let value @ Some(_) = + // - if the module can be referenced as self, super or crate, do that + if let Some(mod_path) = is_kw_kind_relative_to_from(def_map, module_id, from) { + if ctx.prefix != PrefixKind::ByCrate || mod_path.kind == PathKind::Crate { + return Some((mod_path, Stable)); + } + } + + // - if the module is in the prelude, return it by that path + if let Some(mod_path) = find_in_prelude(ctx.db, &root_def_map, def_map, ItemInNs::Types(module_id.into()), from) { - return value.zip(Some(Stable)); + return Some((mod_path, Stable)); } calculate_best_path( ctx, def_map, visited_modules, - crate_root, max_len, ItemInNs::Types(module_id.into()), from, - scope_name, ) } @@ -255,9 +264,13 @@ fn find_in_scope( def_map: &DefMap, from: ModuleId, item: ItemInNs, + ignore_local_imports: bool, ) -> Option { + // FIXME: We could have multiple applicable names here, but we currently only return the first def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { - def_map[local_id].scope.names_of(item, |name, _, _| Some(name.clone())) + def_map[local_id].scope.names_of(item, |name, _, declared| { + (declared || !ignore_local_imports).then(|| name.clone()) + }) }) } @@ -292,21 +305,32 @@ fn find_in_prelude( }); if found_and_same_def.unwrap_or(true) { - Some(ModPath::from_segments(PathKind::Plain, Some(name.clone()))) + Some(ModPath::from_segments(PathKind::Plain, once(name.clone()))) } else { None } } -fn find_self_super(def_map: &DefMap, item: ModuleId, from: ModuleId) -> Option { +fn is_kw_kind_relative_to_from( + def_map: &DefMap, + item: ModuleId, + from: ModuleId, +) -> Option { + if item.krate != from.krate || item.is_within_block() || from.is_within_block() { + return None; + } + let item = item.local_id; + let from = from.local_id; if item == from { // - if the item is the module we're in, use `self` Some(ModPath::from_segments(PathKind::Super(0), None)) - } else if let Some(parent_id) = def_map[from.local_id].parent { - // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) - let parent_id = def_map.module_id(parent_id); + } else if let Some(parent_id) = def_map[from].parent { if item == parent_id { - Some(ModPath::from_segments(PathKind::Super(1), None)) + // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) + Some(ModPath::from_segments( + if parent_id == DefMap::ROOT { PathKind::Crate } else { PathKind::Super(1) }, + None, + )) } else { None } @@ -320,11 +344,9 @@ fn calculate_best_path( ctx: FindPathCtx<'_>, def_map: &DefMap, visited_modules: &mut FxHashSet, - crate_root: CrateRootModuleId, max_len: usize, item: ItemInNs, from: ModuleId, - scope_name: Option, ) -> Option<(ModPath, Stability)> { if max_len <= 1 { return None; @@ -346,14 +368,12 @@ fn calculate_best_path( // dependency in this case. for (module_id, name) in find_local_import_locations(ctx.db, item, from) { if !visited_modules.insert(module_id) { - cov_mark::hit!(recursive_imports); continue; } if let Some(mut path) = find_path_for_module( ctx, def_map, visited_modules, - crate_root, from, module_id, best_path_len - 1, @@ -390,7 +410,6 @@ fn calculate_best_path( ctx, def_map, visited_modules, - crate_root, from, info.container, max_len - 1, @@ -418,19 +437,7 @@ fn calculate_best_path( } } } - let mut prefixed = ctx.prefixed; - if let Some(module) = item.module(ctx.db) { - if module.containing_block().is_some() && ctx.prefixed.is_some() { - cov_mark::hit!(prefixed_in_block_expression); - prefixed = Some(PrefixKind::Plain); - } - } - match prefixed.map(PrefixKind::prefix) { - Some(prefix) => best_path.or_else(|| { - scope_name.map(|scope_name| (ModPath::from_segments(prefix, Some(scope_name)), Stable)) - }), - None => best_path, - } + best_path } /// Select the best (most relevant) path between two paths. @@ -535,7 +542,6 @@ fn find_local_import_locations( if !seen.insert(module) { continue; // already processed this module } - let ext_def_map; let data = if module.krate == from.krate { if module.block.is_some() { @@ -571,7 +577,7 @@ fn find_local_import_locations( // what the user wants; and if this module can import // the item and we're a submodule of it, so can we. // Also this keeps the cached data smaller. - if is_pub_or_explicit || declared { + if declared || is_pub_or_explicit { locations.push((module, name.clone())); } } @@ -605,8 +611,9 @@ mod tests { fn check_found_path_( ra_fixture: &str, path: &str, - prefix_kind: Option, + prefix_kind: PrefixKind, prefer_prelude: bool, + ignore_local_imports: bool, ) { let (db, pos) = TestDB::with_position(ra_fixture); let module = db.module_at_position(pos); @@ -628,43 +635,51 @@ mod tests { crate::item_scope::BuiltinShadowMode::Module, None, ) - .0 + .0; + let resolved = resolved .take_types() - .expect("path does not resolve to a type"); + .map(ItemInNs::Types) + .or_else(|| resolved.take_values().map(ItemInNs::Values)) + .expect("path does not resolve to a type or value"); let found_path = find_path_inner( - FindPathCtx { prefer_no_std: false, db: &db, prefixed: prefix_kind, prefer_prelude }, - ItemInNs::Types(resolved), + FindPathCtx { + prefer_no_std: false, + db: &db, + prefix: prefix_kind, + prefer_prelude, + ignore_local_imports, + }, + resolved, module, ); - assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?}"); + assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?} ({ignore_local_imports})"); } - #[track_caller] fn check_found_path( ra_fixture: &str, - unprefixed: &str, - prefixed: &str, - absolute: &str, - self_prefixed: &str, + plain_non_local: &str, + plain: &str, + by_crate: &str, + by_self: &str, ) { - check_found_path_(ra_fixture, unprefixed, None, false); - check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), false); - check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), false); - check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), false); + check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, false, true); + check_found_path_(ra_fixture, plain, PrefixKind::Plain, false, false); + check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, false, false); + check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, false, false); } fn check_found_path_prelude( ra_fixture: &str, - unprefixed: &str, - prefixed: &str, - absolute: &str, - self_prefixed: &str, + plain_non_local: &str, + plain: &str, + by_crate: &str, + by_self: &str, ) { - check_found_path_(ra_fixture, unprefixed, None, true); - check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), true); - check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), true); - check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), true); + check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, true, true); + check_found_path_(ra_fixture, plain, PrefixKind::Plain, true, false); + check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, true, false); + check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, true, false); } #[test] @@ -831,10 +846,10 @@ pub mod ast { } } "#, + "syntax::ast::ModuleItem", "ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", + "crate::ast::ModuleItem", + "self::ast::ModuleItem", ); check_found_path( @@ -965,8 +980,8 @@ pub mod prelude { "#, "S", "S", - "S", - "S", + "crate::S", + "self::S", ); } @@ -1271,12 +1286,11 @@ fn main() { #[test] fn inner_items_from_inner_module() { - cov_mark::check!(prefixed_in_block_expression); check_found_path( r#" fn main() { mod module { - struct Struct {} + pub struct Struct {} } { $0 @@ -1303,11 +1317,10 @@ fn main() { $0 } "#, - // FIXME: these could use fewer/better prefixes + "module::CompleteMe", "module::CompleteMe", "crate::module::CompleteMe", - "crate::module::CompleteMe", - "crate::module::CompleteMe", + "self::module::CompleteMe", ) } @@ -1358,7 +1371,6 @@ mod bar { #[test] fn recursive_pub_mod_reexport() { - cov_mark::check!(recursive_imports); check_found_path( r#" fn main() { @@ -1587,4 +1599,25 @@ pub mod prelude { "petgraph::graph::NodeIndex", ); } + + #[test] + fn regression_17271() { + check_found_path( + r#" +//- /lib.rs crate:main +mod foo; + +//- /foo.rs +mod bar; + +pub fn b() {$0} +//- /foo/bar.rs +pub fn c() {} +"#, + "bar::c", + "bar::c", + "crate::foo::bar::c", + "self::bar::c", + ); + } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index faa1eed15a45..6e40293dbf8e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -1,13 +1,12 @@ //! A map of all publicly exported items in a crate. -use std::{fmt, hash::BuildHasherDefault}; +use std::fmt; use base_db::CrateId; use fst::{raw::IndexedValue, Automaton, Streamer}; use hir_expand::name::Name; -use indexmap::IndexMap; use itertools::Itertools; -use rustc_hash::{FxHashSet, FxHasher}; +use rustc_hash::FxHashSet; use smallvec::SmallVec; use stdx::{format_to, TupleExt}; use triomphe::Arc; @@ -17,7 +16,7 @@ use crate::{ item_scope::{ImportOrExternCrate, ItemInNs}, nameres::DefMap, visibility::Visibility, - AssocItemId, ModuleDefId, ModuleId, TraitId, + AssocItemId, FxIndexMap, ModuleDefId, ModuleId, TraitId, }; /// Item import details stored in the `ImportMap`. @@ -58,7 +57,6 @@ enum IsTraitAssocItem { No, } -type FxIndexMap = IndexMap>; type ImportMapIndex = FxIndexMap, IsTraitAssocItem)>; impl ImportMap { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 54cd57110ea8..9c7dfa05b0e4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -295,7 +295,7 @@ impl ItemScope { pub(crate) fn names_of( &self, item: ItemInNs, - mut cb: impl FnMut(&Name, Visibility, bool) -> Option, + mut cb: impl FnMut(&Name, Visibility, /*declared*/ bool) -> Option, ) -> Option { match item { ItemInNs::Macros(def) => self diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 88d4572196cd..ca8cc1c3ead1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -106,6 +106,9 @@ use crate::{ }, }; +type FxIndexMap = + indexmap::IndexMap>; + #[derive(Debug)] pub struct ItemLoc { pub container: ModuleId, @@ -455,6 +458,26 @@ impl ModuleId { pub fn is_block_module(self) -> bool { self.block.is_some() && self.local_id == DefMap::ROOT } + + pub fn is_within_block(self) -> bool { + self.block.is_some() + } + + pub fn as_crate_root(&self) -> Option { + if self.local_id == DefMap::ROOT && self.block.is_none() { + Some(CrateRootModuleId { krate: self.krate }) + } else { + None + } + } + + pub fn derive_crate_root(&self) -> CrateRootModuleId { + CrateRootModuleId { krate: self.krate } + } + + fn is_crate_root(&self) -> bool { + self.local_id == DefMap::ROOT && self.block.is_none() + } } impl PartialEq for ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index a528c4cc6972..a66c0585a368 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -81,7 +81,7 @@ use crate::{ per_ns::PerNs, visibility::{Visibility, VisibilityExplicitness}, AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId, - LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, + FxIndexMap, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, }; /// Contains the results of (early) name resolution. @@ -129,7 +129,7 @@ pub struct DefMap { #[derive(Clone, Debug, PartialEq, Eq)] struct DefMapCrateData { /// The extern prelude which contains all root modules of external crates that are in scope. - extern_prelude: FxHashMap)>, + extern_prelude: FxIndexMap)>, /// Side table for resolving derive helpers. exported_derives: FxHashMap>, @@ -155,7 +155,7 @@ struct DefMapCrateData { impl DefMapCrateData { fn new(edition: Edition) -> Self { Self { - extern_prelude: FxHashMap::default(), + extern_prelude: FxIndexMap::default(), exported_derives: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(), proc_macro_loading_error: None, @@ -578,7 +578,8 @@ impl DefMap { pub(crate) fn extern_prelude( &self, - ) -> impl Iterator))> + '_ { + ) -> impl DoubleEndedIterator))> + '_ + { self.data.extern_prelude.iter().map(|(name, &def)| (name, def)) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 1602b173858d..9794963203bc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -1,12 +1,11 @@ //! Name resolution façade. -use std::{fmt, hash::BuildHasherDefault, iter, mem}; +use std::{fmt, iter, mem}; use base_db::CrateId; use hir_expand::{ name::{name, Name}, MacroDefId, }; -use indexmap::IndexMap; use intern::Interned; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -27,10 +26,10 @@ use crate::{ type_ref::LifetimeRef, visibility::{RawVisibility, Visibility}, AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, - ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, - ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, - MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, - TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, + ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, + ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, + MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, + TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, }; #[derive(Debug, Clone)] @@ -957,7 +956,6 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option)> { Some((res, import)) } -type FxIndexMap = IndexMap>; #[derive(Default)] struct ScopeNames { map: FxIndexMap>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index c010f5d22b68..82bbc28884e1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -13,7 +13,7 @@ use either::Either; use hir_def::{ data::adt::VariantData, db::DefDatabase, - find_path, + find_path::{self, PrefixKind}, generics::{TypeOrConstParamData, TypeParamProvenance}, item_scope::ItemInNs, lang_item::{LangItem, LangItemTarget}, @@ -999,6 +999,8 @@ impl HirDisplay for Ty { db.upcast(), ItemInNs::Types((*def_id).into()), module_id, + PrefixKind::Plain, + false, false, true, ) { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 85f33a10fcb2..773ac01e0e3f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -789,7 +789,7 @@ impl Module { /// Finds a path that can be used to refer to the given item from within /// this module, if possible. - pub fn find_use_path( + pub fn find_path( self, db: &dyn DefDatabase, item: impl Into, @@ -800,6 +800,8 @@ impl Module { db, item.into().into(), self.into(), + PrefixKind::Plain, + false, prefer_no_std, prefer_prelude, ) @@ -807,7 +809,7 @@ impl Module { /// Finds a path that can be used to refer to the given item from within /// this module, if possible. This is used for returning import paths for use-statements. - pub fn find_use_path_prefixed( + pub fn find_use_path( self, db: &dyn DefDatabase, item: impl Into, @@ -815,11 +817,12 @@ impl Module { prefer_no_std: bool, prefer_prelude: bool, ) -> Option { - hir_def::find_path::find_path_prefixed( + hir_def::find_path::find_path( db, item.into().into(), self.into(), prefix_kind, + true, prefer_no_std, prefer_prelude, ) diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index 9f56a1ee55d3..45c0dd8da75f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -33,16 +33,11 @@ fn mod_item_path( }); let m = sema_scope.module(); - match name_hit_count { - Some(0..=1) | None => m.find_use_path(db.upcast(), *def, prefer_no_std, prefer_prelude), - Some(_) => m.find_use_path_prefixed( - db.upcast(), - *def, - PrefixKind::ByCrate, - prefer_no_std, - prefer_prelude, - ), - } + let prefix = match name_hit_count { + Some(0..=1) | None => PrefixKind::Plain, + Some(_) => PrefixKind::ByCrate, + }; + m.find_use_path(db.upcast(), *def, prefix, prefer_no_std, prefer_prelude) } /// Helper function to get path to `ModuleDef` as string diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 5ef374506ecc..8eddc562bef4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -462,7 +462,7 @@ fn build_pat( ) -> Option { match var { ExtendedVariant::Variant(var) => { - let path = mod_path_to_ast(&module.find_use_path( + let path = mod_path_to_ast(&module.find_path( db, ModuleDef::from(var), prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index fd3a0506ab67..df87e2d04498 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -341,7 +341,7 @@ fn augment_references_with_imports( let import_scope = ImportScope::find_insert_use_container(name.syntax(), &ctx.sema); let path = ref_module - .find_use_path_prefixed( + .find_use_path( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs index d649f13d6ee3..e0e2ac758533 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs @@ -50,7 +50,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - _ => return None, }; - mod_path_to_ast(&module.find_use_path( + mod_path_to_ast(&module.find_path( ctx.db(), src_type_def, ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 41366658a74b..367cf0bc8b96 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -201,7 +201,7 @@ fn augment_references_with_imports( let import_scope = ImportScope::find_insert_use_container(new_name.syntax(), &ctx.sema); let path = ref_module - .find_use_path_prefixed( + .find_use_path( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index c1a3f9302650..bdcefe0b4fda 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -90,7 +90,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> Op FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow(); if let Some(control_flow_enum) = control_flow_enum { - let mod_path = module.find_use_path_prefixed( + let mod_path = module.find_use_path( ctx.sema.db, ModuleDef::from(control_flow_enum), ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 81a639e0b9f3..24bda139b2cd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -386,7 +386,7 @@ fn process_references( let segment = builder.make_mut(segment); let scope_node = builder.make_syntax_mut(scope_node); if !visited_modules.contains(&module) { - let mod_path = module.find_use_path_prefixed( + let mod_path = module.find_use_path( ctx.sema.db, *enum_module_def, ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index 473c699b595c..54c320a39b1a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -58,7 +58,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; - let trait_path = module.find_use_path( + let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), ctx.config.prefer_no_std, @@ -103,7 +103,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; - let trait_path = module.find_use_path( + let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 22c75cd5eefc..50342b0284e3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -58,7 +58,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); - let type_path = current_module.find_use_path( + let type_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index ff65aac82e07..196b33e0f675 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -44,7 +44,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> let current_module = ctx.sema.scope(call.syntax())?.module(); let target_module_def = ModuleDef::from(resolved_call); let item_in_ns = ItemInNs::from(target_module_def); - let receiver_path = current_module.find_use_path( + let receiver_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 3420d906dea5..8cc7c883f4ce 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -83,7 +83,7 @@ pub(crate) fn replace_derive_with_manual_impl( }) .flat_map(|trait_| { current_module - .find_use_path( + .find_path( ctx.sema.db, hir::ModuleDef::Trait(trait_), ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index ba1c25fa5a74..cb9de32d9cd0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -63,7 +63,7 @@ pub(crate) fn replace_qualified_name_with_use( ); let path_to_qualifier = starts_with_name_ref .then(|| { - ctx.sema.scope(path.syntax())?.module().find_use_path_prefixed( + ctx.sema.scope(path.syntax())?.module().find_use_path( ctx.sema.db, module, ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 1ea7220960d2..69b0289fc1dd 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -633,7 +633,7 @@ fn enum_variants_with_paths( } for variant in variants { - if let Some(path) = ctx.module.find_use_path( + if let Some(path) = ctx.module.find_path( ctx.db, hir::ModuleDef::from(variant), ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 1e31d65fddfe..f350c2743c7c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -171,7 +171,7 @@ pub(crate) fn complete_expr_path( hir::Adt::Struct(strukt) => { let path = ctx .module - .find_use_path( + .find_path( ctx.db, hir::ModuleDef::from(strukt), ctx.config.prefer_no_std, @@ -194,7 +194,7 @@ pub(crate) fn complete_expr_path( hir::Adt::Union(un) => { let path = ctx .module - .find_use_path( + .find_path( ctx.db, hir::ModuleDef::from(un), ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index c6e243b31a79..c14da34874b3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -63,7 +63,7 @@ pub(crate) fn complete_postfix( if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() { if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) { if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() { - if let Some(path) = ctx.module.find_use_path( + if let Some(path) = ctx.module.find_path( ctx.db, ItemInNs::Values(drop_fn.into()), ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index d89cfc8b6cb8..4165dd48af46 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -260,7 +260,7 @@ pub fn resolve_completion_edits( ); let import = items_with_name .filter_map(|candidate| { - current_module.find_use_path_prefixed( + current_module.find_use_path( db, candidate, config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 7fa31e2757db..d7b27f8b3b3a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -333,7 +333,7 @@ pub(crate) fn render_expr( }); for trait_ in expr.traits_used(ctx.db) { let trait_item = hir::ItemInNs::from(hir::ModuleDef::from(trait_)); - let Some(path) = ctx.module.find_use_path( + let Some(path) = ctx.module.find_path( ctx.db, trait_item, ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs index 7d710f1e1308..37bb6cfef0a9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs @@ -174,7 +174,7 @@ fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option def.into(), _ => return None, }; - let path = ctx.module.find_use_path_prefixed( + let path = ctx.module.find_use_path( ctx.db, item, ctx.config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 766bfcf4d094..5e33b08e4a41 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -637,17 +637,13 @@ fn get_mod_path( prefer_no_std: bool, prefer_prelude: bool, ) -> Option { - if let Some(prefix_kind) = prefixed { - module_with_candidate.find_use_path_prefixed( - db, - item_to_search, - prefix_kind, - prefer_no_std, - prefer_prelude, - ) - } else { - module_with_candidate.find_use_path(db, item_to_search, prefer_no_std, prefer_prelude) - } + module_with_candidate.find_use_path( + db, + item_to_search, + prefixed.unwrap_or(PrefixKind::Plain), + prefer_no_std, + prefer_prelude, + ) } impl ImportCandidate { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 7e1811b4cacb..6f4f97e0b86c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -308,7 +308,7 @@ impl Ctx<'_> { parent.segment()?.name_ref()?, ) .and_then(|trait_ref| { - let found_path = self.target_module.find_use_path( + let found_path = self.target_module.find_path( self.source_scope.db.upcast(), hir::ModuleDef::Trait(trait_ref), false, @@ -347,7 +347,7 @@ impl Ctx<'_> { } } - let found_path = self.target_module.find_use_path( + let found_path = self.target_module.find_path( self.source_scope.db.upcast(), def, false, @@ -385,7 +385,7 @@ impl Ctx<'_> { if let Some(adt) = ty.as_adt() { if let ast::Type::PathType(path_ty) = &ast_ty { - let found_path = self.target_module.find_use_path( + let found_path = self.target_module.find_path( self.source_scope.db.upcast(), ModuleDef::from(adt), false, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index b3dde977b1c4..71958bc8660f 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -144,7 +144,7 @@ pub(crate) fn json_in_items( let current_module = semantics_scope.module(); if !scope_has("Serialize") { if let Some(PathResolution::Def(it)) = serialize_resolved { - if let Some(it) = current_module.find_use_path_prefixed( + if let Some(it) = current_module.find_use_path( sema.db, it, config.insert_use.prefix_kind, @@ -157,7 +157,7 @@ pub(crate) fn json_in_items( } if !scope_has("Deserialize") { if let Some(PathResolution::Def(it)) = deserialize_resolved { - if let Some(it) = current_module.find_use_path_prefixed( + if let Some(it) = current_module.find_use_path( sema.db, it, config.insert_use.prefix_kind, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index f92ba576d3ab..ed9094f1f361 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -122,7 +122,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option Option { let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); - let type_path = current_module?.find_use_path( + let type_path = current_module?.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, ctx.config.prefer_no_std, diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index cfda1c692aea..99df3f2563df 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -664,7 +664,7 @@ impl Match { for (path, resolved_path) in &template.resolved_paths { if let hir::PathResolution::Def(module_def) = resolved_path.resolution { let mod_path = - module.find_use_path(sema.db, module_def, false, true).ok_or_else(|| { + module.find_path(sema.db, module_def, false, true).ok_or_else(|| { match_error!("Failed to render template path `{}` at match location") })?; self.rendered_template_paths.insert(path.clone(), mod_path); From b29c755572685ee3fae302c7bcf2b25006e01d8e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 22 May 2024 14:04:56 +0200 Subject: [PATCH 033/101] expectify find_path tests --- .../crates/hir-def/src/find_path.rs | 623 +++++++++++++----- 1 file changed, 443 insertions(+), 180 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 68e0a8bc693a..52d940d63563 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -596,7 +596,10 @@ fn find_local_import_locations( #[cfg(test)] mod tests { + use expect_test::{expect, Expect}; use hir_expand::db::ExpandDatabase; + use itertools::Itertools; + use stdx::format_to; use syntax::ast::AstNode; use test_fixture::WithFixture; @@ -608,13 +611,7 @@ mod tests { /// item the `path` refers to returns that same path when called from the /// module the cursor is in. #[track_caller] - fn check_found_path_( - ra_fixture: &str, - path: &str, - prefix_kind: PrefixKind, - prefer_prelude: bool, - ignore_local_imports: bool, - ) { + fn check_found_path_(ra_fixture: &str, path: &str, prefer_prelude: bool, expect: Expect) { let (db, pos) = TestDB::with_position(ra_fixture); let module = db.module_at_position(pos); let parsed_path_file = @@ -642,44 +639,41 @@ mod tests { .or_else(|| resolved.take_values().map(ItemInNs::Values)) .expect("path does not resolve to a type or value"); - let found_path = find_path_inner( - FindPathCtx { - prefer_no_std: false, - db: &db, - prefix: prefix_kind, - prefer_prelude, - ignore_local_imports, - }, - resolved, - module, - ); - assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?} ({ignore_local_imports})"); + let mut res = String::new(); + for (prefix, ignore_local_imports) in + [PrefixKind::Plain, PrefixKind::ByCrate, PrefixKind::BySelf] + .into_iter() + .cartesian_product([false, true]) + { + let found_path = find_path_inner( + FindPathCtx { + prefer_no_std: false, + db: &db, + prefix, + prefer_prelude, + ignore_local_imports, + }, + resolved, + module, + ); + format_to!( + res, + "{:7}(imports {}): {}\n", + format!("{:?}", prefix), + if ignore_local_imports { '✖' } else { '✔' }, + found_path + .map_or_else(|| "".to_owned(), |it| it.display(&db).to_string()), + ); + } + expect.assert_eq(&res); } - fn check_found_path( - ra_fixture: &str, - plain_non_local: &str, - plain: &str, - by_crate: &str, - by_self: &str, - ) { - check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, false, true); - check_found_path_(ra_fixture, plain, PrefixKind::Plain, false, false); - check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, false, false); - check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, false, false); + fn check_found_path(ra_fixture: &str, path: &str, expect: Expect) { + check_found_path_(ra_fixture, path, false, expect); } - fn check_found_path_prelude( - ra_fixture: &str, - plain_non_local: &str, - plain: &str, - by_crate: &str, - by_self: &str, - ) { - check_found_path_(ra_fixture, plain_non_local, PrefixKind::Plain, true, true); - check_found_path_(ra_fixture, plain, PrefixKind::Plain, true, false); - check_found_path_(ra_fixture, by_crate, PrefixKind::ByCrate, true, false); - check_found_path_(ra_fixture, by_self, PrefixKind::BySelf, true, false); + fn check_found_path_prelude(ra_fixture: &str, path: &str, expect: Expect) { + check_found_path_(ra_fixture, path, true, expect); } #[test] @@ -690,9 +684,14 @@ struct S; $0 "#, "S", - "S", - "crate::S", - "self::S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): self::S + BySelf (imports ✖): self::S + "#]], ); } @@ -704,9 +703,14 @@ enum E { A } $0 "#, "E::A", - "E::A", - "crate::E::A", - "self::E::A", + expect![[r#" + Plain (imports ✔): E::A + Plain (imports ✖): E::A + ByCrate(imports ✔): crate::E::A + ByCrate(imports ✖): crate::E::A + BySelf (imports ✔): self::E::A + BySelf (imports ✖): self::E::A + "#]], ); } @@ -720,9 +724,14 @@ mod foo { $0 "#, "foo::S", - "foo::S", - "crate::foo::S", - "self::foo::S", + expect![[r#" + Plain (imports ✔): foo::S + Plain (imports ✖): foo::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): self::foo::S + BySelf (imports ✖): self::foo::S + "#]], ); } @@ -739,9 +748,14 @@ struct S; $0 "#, "super::S", - "super::S", - "crate::foo::S", - "super::S", + expect![[r#" + Plain (imports ✔): super::S + Plain (imports ✖): super::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): super::S + BySelf (imports ✖): super::S + "#]], ); } @@ -755,9 +769,14 @@ mod foo; $0 "#, "self", - "self", - "crate::foo", - "self", + expect![[r#" + Plain (imports ✔): self + Plain (imports ✖): self + ByCrate(imports ✔): crate::foo + ByCrate(imports ✖): crate::foo + BySelf (imports ✔): self + BySelf (imports ✖): self + "#]], ); } @@ -771,9 +790,14 @@ mod foo; $0 "#, "crate", - "crate", - "crate", - "crate", + expect![[r#" + Plain (imports ✔): crate + Plain (imports ✖): crate + ByCrate(imports ✔): crate + ByCrate(imports ✖): crate + BySelf (imports ✔): crate + BySelf (imports ✖): crate + "#]], ); } @@ -788,9 +812,14 @@ struct S; $0 "#, "crate::S", - "crate::S", - "crate::S", - "crate::S", + expect![[r#" + Plain (imports ✔): crate::S + Plain (imports ✖): crate::S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): crate::S + BySelf (imports ✖): crate::S + "#]], ); } @@ -804,9 +833,14 @@ $0 pub struct S; "#, "std::S", - "std::S", - "std::S", - "std::S", + expect![[r#" + Plain (imports ✔): std::S + Plain (imports ✖): std::S + ByCrate(imports ✔): std::S + ByCrate(imports ✖): std::S + BySelf (imports ✔): std::S + BySelf (imports ✖): std::S + "#]], ); } @@ -821,9 +855,14 @@ $0 pub struct S; "#, "std_renamed::S", - "std_renamed::S", - "std_renamed::S", - "std_renamed::S", + expect![[r#" + Plain (imports ✔): std_renamed::S + Plain (imports ✖): std_renamed::S + ByCrate(imports ✔): std_renamed::S + ByCrate(imports ✖): std_renamed::S + BySelf (imports ✔): std_renamed::S + BySelf (imports ✖): std_renamed::S + "#]], ); } @@ -847,9 +886,14 @@ pub mod ast { } "#, "syntax::ast::ModuleItem", - "ast::ModuleItem", - "crate::ast::ModuleItem", - "self::ast::ModuleItem", + expect![[r#" + Plain (imports ✔): ast::ModuleItem + Plain (imports ✖): syntax::ast::ModuleItem + ByCrate(imports ✔): crate::ast::ModuleItem + ByCrate(imports ✖): syntax::ast::ModuleItem + BySelf (imports ✔): self::ast::ModuleItem + BySelf (imports ✖): syntax::ast::ModuleItem + "#]], ); check_found_path( @@ -865,9 +909,14 @@ pub mod ast { } "#, "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", + expect![[r#" + Plain (imports ✔): syntax::ast::ModuleItem + Plain (imports ✖): syntax::ast::ModuleItem + ByCrate(imports ✔): syntax::ast::ModuleItem + ByCrate(imports ✖): syntax::ast::ModuleItem + BySelf (imports ✔): syntax::ast::ModuleItem + BySelf (imports ✖): syntax::ast::ModuleItem + "#]], ); } @@ -882,9 +931,14 @@ mod bar { $0 "#, "bar::S", - "bar::S", - "crate::bar::S", - "self::bar::S", + expect![[r#" + Plain (imports ✔): bar::S + Plain (imports ✖): bar::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): self::bar::S + BySelf (imports ✖): self::bar::S + "#]], ); } @@ -899,9 +953,14 @@ mod bar { $0 "#, "bar::U", - "bar::U", - "crate::bar::U", - "self::bar::U", + expect![[r#" + Plain (imports ✔): bar::U + Plain (imports ✖): bar::U + ByCrate(imports ✔): crate::bar::U + ByCrate(imports ✖): crate::bar::U + BySelf (imports ✔): self::bar::U + BySelf (imports ✖): self::bar::U + "#]], ); } @@ -917,9 +976,14 @@ pub use core::S; pub struct S; "#, "std::S", - "std::S", - "std::S", - "std::S", + expect![[r#" + Plain (imports ✔): std::S + Plain (imports ✖): std::S + ByCrate(imports ✔): std::S + ByCrate(imports ✖): std::S + BySelf (imports ✔): std::S + BySelf (imports ✖): std::S + "#]], ); } @@ -937,9 +1001,14 @@ pub mod prelude { } "#, "S", - "S", - "S", - "S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): S + ByCrate(imports ✖): S + BySelf (imports ✔): S + BySelf (imports ✖): S + "#]], ); } @@ -958,9 +1027,14 @@ pub mod prelude { } "#, "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", + expect![[r#" + Plain (imports ✔): std::prelude::rust_2018::S + Plain (imports ✖): std::prelude::rust_2018::S + ByCrate(imports ✔): std::prelude::rust_2018::S + ByCrate(imports ✖): std::prelude::rust_2018::S + BySelf (imports ✔): std::prelude::rust_2018::S + BySelf (imports ✖): std::prelude::rust_2018::S + "#]], ); } @@ -979,9 +1053,14 @@ pub mod prelude { } "#, "S", - "S", - "crate::S", - "self::S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): S + BySelf (imports ✔): self::S + BySelf (imports ✖): S + "#]], ); } @@ -998,8 +1077,30 @@ pub mod prelude { } } "#; - check_found_path(code, "None", "None", "None", "None"); - check_found_path(code, "Some", "Some", "Some", "Some"); + check_found_path( + code, + "None", + expect![[r#" + Plain (imports ✔): None + Plain (imports ✖): None + ByCrate(imports ✔): None + ByCrate(imports ✖): None + BySelf (imports ✔): None + BySelf (imports ✖): None + "#]], + ); + check_found_path( + code, + "Some", + expect![[r#" + Plain (imports ✔): Some + Plain (imports ✖): Some + ByCrate(imports ✔): Some + ByCrate(imports ✖): Some + BySelf (imports ✔): Some + BySelf (imports ✖): Some + "#]], + ); } #[test] @@ -1017,9 +1118,14 @@ pub mod bar { pub struct S; } pub use crate::foo::bar::S; "#, "baz::S", - "baz::S", - "crate::baz::S", - "self::baz::S", + expect![[r#" + Plain (imports ✔): baz::S + Plain (imports ✖): baz::S + ByCrate(imports ✔): crate::baz::S + ByCrate(imports ✖): crate::baz::S + BySelf (imports ✔): self::baz::S + BySelf (imports ✖): self::baz::S + "#]], ); } @@ -1037,9 +1143,14 @@ $0 "#, // crate::S would be shorter, but using private imports seems wrong "crate::bar::S", - "crate::bar::S", - "crate::bar::S", - "crate::bar::S", + expect![[r#" + Plain (imports ✔): crate::bar::S + Plain (imports ✖): crate::bar::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): crate::bar::S + BySelf (imports ✖): crate::bar::S + "#]], ); } @@ -1056,9 +1167,14 @@ pub(crate) use bar::S; $0 "#, "crate::S", - "crate::S", - "crate::S", - "crate::S", + expect![[r#" + Plain (imports ✔): crate::S + Plain (imports ✖): crate::S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): crate::S + BySelf (imports ✖): crate::S + "#]], ); } @@ -1078,9 +1194,14 @@ pub mod bar { $0 "#, "super::S", - "super::S", - "crate::bar::S", - "super::S", + expect![[r#" + Plain (imports ✔): super::S + Plain (imports ✖): super::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): super::S + BySelf (imports ✖): super::S + "#]], ); } @@ -1101,9 +1222,14 @@ pub struct S; pub use super::foo; "#, "crate::foo::S", - "crate::foo::S", - "crate::foo::S", - "crate::foo::S", + expect![[r#" + Plain (imports ✔): crate::foo::S + Plain (imports ✖): crate::foo::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): crate::foo::S + BySelf (imports ✖): crate::foo::S + "#]], ); } @@ -1125,9 +1251,14 @@ pub mod sync { } "#, "std::sync::Arc", - "std::sync::Arc", - "std::sync::Arc", - "std::sync::Arc", + expect![[r#" + Plain (imports ✔): std::sync::Arc + Plain (imports ✖): std::sync::Arc + ByCrate(imports ✔): std::sync::Arc + ByCrate(imports ✖): std::sync::Arc + BySelf (imports ✔): std::sync::Arc + BySelf (imports ✖): std::sync::Arc + "#]], ); } @@ -1153,9 +1284,14 @@ pub mod fmt { } "#, "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", + expect![[r#" + Plain (imports ✔): core::fmt::Error + Plain (imports ✖): core::fmt::Error + ByCrate(imports ✔): core::fmt::Error + ByCrate(imports ✖): core::fmt::Error + BySelf (imports ✔): core::fmt::Error + BySelf (imports ✖): core::fmt::Error + "#]], ); // Should also work (on a best-effort basis) if `no_std` is conditional. @@ -1179,9 +1315,14 @@ pub mod fmt { } "#, "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", + expect![[r#" + Plain (imports ✔): core::fmt::Error + Plain (imports ✖): core::fmt::Error + ByCrate(imports ✔): core::fmt::Error + ByCrate(imports ✖): core::fmt::Error + BySelf (imports ✔): core::fmt::Error + BySelf (imports ✖): core::fmt::Error + "#]], ); } @@ -1209,9 +1350,14 @@ pub mod sync { } "#, "alloc::sync::Arc", - "alloc::sync::Arc", - "alloc::sync::Arc", - "alloc::sync::Arc", + expect![[r#" + Plain (imports ✔): alloc::sync::Arc + Plain (imports ✖): alloc::sync::Arc + ByCrate(imports ✔): alloc::sync::Arc + ByCrate(imports ✖): alloc::sync::Arc + BySelf (imports ✔): alloc::sync::Arc + BySelf (imports ✖): alloc::sync::Arc + "#]], ); } @@ -1231,9 +1377,14 @@ pub mod sync { pub struct Arc; "#, "megaalloc::Arc", - "megaalloc::Arc", - "megaalloc::Arc", - "megaalloc::Arc", + expect![[r#" + Plain (imports ✔): megaalloc::Arc + Plain (imports ✖): megaalloc::Arc + ByCrate(imports ✔): megaalloc::Arc + ByCrate(imports ✖): megaalloc::Arc + BySelf (imports ✔): megaalloc::Arc + BySelf (imports ✖): megaalloc::Arc + "#]], ); } @@ -1246,8 +1397,30 @@ pub mod primitive { pub use u8; } "#; - check_found_path(code, "u8", "u8", "u8", "u8"); - check_found_path(code, "u16", "u16", "u16", "u16"); + check_found_path( + code, + "u8", + expect![[r#" + Plain (imports ✔): u8 + Plain (imports ✖): u8 + ByCrate(imports ✔): u8 + ByCrate(imports ✖): u8 + BySelf (imports ✔): u8 + BySelf (imports ✖): u8 + "#]], + ); + check_found_path( + code, + "u16", + expect![[r#" + Plain (imports ✔): u16 + Plain (imports ✖): u16 + ByCrate(imports ✔): u16 + ByCrate(imports ✖): u16 + BySelf (imports ✔): u16 + BySelf (imports ✖): u16 + "#]], + ); } #[test] @@ -1260,9 +1433,14 @@ fn main() { } "#, "Inner", - "Inner", - "Inner", - "Inner", + expect![[r#" + Plain (imports ✔): Inner + Plain (imports ✖): Inner + ByCrate(imports ✔): Inner + ByCrate(imports ✖): Inner + BySelf (imports ✔): Inner + BySelf (imports ✖): Inner + "#]], ); } @@ -1278,9 +1456,14 @@ fn main() { } "#, "Struct", - "Struct", - "Struct", - "Struct", + expect![[r#" + Plain (imports ✔): Struct + Plain (imports ✖): Struct + ByCrate(imports ✔): Struct + ByCrate(imports ✖): Struct + BySelf (imports ✔): Struct + BySelf (imports ✖): Struct + "#]], ); } @@ -1298,9 +1481,14 @@ fn main() { } "#, "module::Struct", - "module::Struct", - "module::Struct", - "module::Struct", + expect![[r#" + Plain (imports ✔): module::Struct + Plain (imports ✖): module::Struct + ByCrate(imports ✔): module::Struct + ByCrate(imports ✖): module::Struct + BySelf (imports ✔): module::Struct + BySelf (imports ✖): module::Struct + "#]], ); } @@ -1318,9 +1506,14 @@ fn main() { } "#, "module::CompleteMe", - "module::CompleteMe", - "crate::module::CompleteMe", - "self::module::CompleteMe", + expect![[r#" + Plain (imports ✔): module::CompleteMe + Plain (imports ✖): module::CompleteMe + ByCrate(imports ✔): crate::module::CompleteMe + ByCrate(imports ✖): crate::module::CompleteMe + BySelf (imports ✔): self::module::CompleteMe + BySelf (imports ✖): self::module::CompleteMe + "#]], ) } @@ -1341,9 +1534,14 @@ mod bar { } "#, "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", + expect![[r#" + Plain (imports ✔): crate::baz::Foo + Plain (imports ✖): crate::baz::Foo + ByCrate(imports ✔): crate::baz::Foo + ByCrate(imports ✖): crate::baz::Foo + BySelf (imports ✔): crate::baz::Foo + BySelf (imports ✖): crate::baz::Foo + "#]], ) } @@ -1363,9 +1561,14 @@ mod bar { } "#, "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", + expect![[r#" + Plain (imports ✔): crate::baz::Foo + Plain (imports ✖): crate::baz::Foo + ByCrate(imports ✔): crate::baz::Foo + ByCrate(imports ✖): crate::baz::Foo + BySelf (imports ✔): crate::baz::Foo + BySelf (imports ✖): crate::baz::Foo + "#]], ) } @@ -1390,9 +1593,14 @@ pub mod name { } "#, "name::AsName", - "name::AsName", - "crate::name::AsName", - "self::name::AsName", + expect![[r#" + Plain (imports ✔): name::AsName + Plain (imports ✖): name::AsName + ByCrate(imports ✔): crate::name::AsName + ByCrate(imports ✖): crate::name::AsName + BySelf (imports ✔): self::name::AsName + BySelf (imports ✖): self::name::AsName + "#]], ); } @@ -1405,9 +1613,14 @@ $0 //- /dep.rs crate:dep "#, "dep", - "dep", - "dep", - "dep", + expect![[r#" + Plain (imports ✔): dep + Plain (imports ✖): dep + ByCrate(imports ✔): dep + ByCrate(imports ✖): dep + BySelf (imports ✔): dep + BySelf (imports ✖): dep + "#]], ); check_found_path( @@ -1420,9 +1633,14 @@ fn f() { //- /dep.rs crate:dep "#, "dep", - "dep", - "dep", - "dep", + expect![[r#" + Plain (imports ✔): dep + Plain (imports ✖): dep + ByCrate(imports ✔): dep + ByCrate(imports ✖): dep + BySelf (imports ✔): dep + BySelf (imports ✖): dep + "#]], ); } @@ -1444,9 +1662,14 @@ pub mod prelude { } "#, "None", - "None", - "None", - "None", + expect![[r#" + Plain (imports ✔): None + Plain (imports ✖): None + ByCrate(imports ✔): None + ByCrate(imports ✖): None + BySelf (imports ✔): None + BySelf (imports ✖): None + "#]], ); } @@ -1462,9 +1685,14 @@ pub extern crate std as std_renamed; pub struct S; "#, "intermediate::std_renamed::S", - "intermediate::std_renamed::S", - "intermediate::std_renamed::S", - "intermediate::std_renamed::S", + expect![[r#" + Plain (imports ✔): intermediate::std_renamed::S + Plain (imports ✖): intermediate::std_renamed::S + ByCrate(imports ✔): intermediate::std_renamed::S + ByCrate(imports ✖): intermediate::std_renamed::S + BySelf (imports ✔): intermediate::std_renamed::S + BySelf (imports ✖): intermediate::std_renamed::S + "#]], ); } @@ -1482,9 +1710,14 @@ pub extern crate std as longer; pub struct S; "#, "intermediate::longer::S", - "intermediate::longer::S", - "intermediate::longer::S", - "intermediate::longer::S", + expect![[r#" + Plain (imports ✔): intermediate::longer::S + Plain (imports ✖): intermediate::longer::S + ByCrate(imports ✔): intermediate::longer::S + ByCrate(imports ✖): intermediate::longer::S + BySelf (imports ✔): intermediate::longer::S + BySelf (imports ✖): intermediate::longer::S + "#]], ); } @@ -1505,9 +1738,14 @@ pub mod ops { } "#, "std::ops::Deref", - "std::ops::Deref", - "std::ops::Deref", - "std::ops::Deref", + expect![[r#" + Plain (imports ✔): std::ops::Deref + Plain (imports ✖): std::ops::Deref + ByCrate(imports ✔): std::ops::Deref + ByCrate(imports ✖): std::ops::Deref + BySelf (imports ✔): std::ops::Deref + BySelf (imports ✖): std::ops::Deref + "#]], ); } @@ -1530,9 +1768,14 @@ pub mod error { } "#, "std::error::Error", - "std::error::Error", - "std::error::Error", - "std::error::Error", + expect![[r#" + Plain (imports ✔): std::error::Error + Plain (imports ✖): std::error::Error + ByCrate(imports ✔): std::error::Error + ByCrate(imports ✖): std::error::Error + BySelf (imports ✔): std::error::Error + BySelf (imports ✖): std::error::Error + "#]], ); } @@ -1553,16 +1796,26 @@ pub mod foo { check_found_path( ra_fixture, "krate::foo::Foo", - "krate::foo::Foo", - "krate::foo::Foo", - "krate::foo::Foo", + expect![[r#" + Plain (imports ✔): krate::foo::Foo + Plain (imports ✖): krate::foo::Foo + ByCrate(imports ✔): krate::foo::Foo + ByCrate(imports ✖): krate::foo::Foo + BySelf (imports ✔): krate::foo::Foo + BySelf (imports ✖): krate::foo::Foo + "#]], ); check_found_path_prelude( ra_fixture, "krate::prelude::Foo", - "krate::prelude::Foo", - "krate::prelude::Foo", - "krate::prelude::Foo", + expect![[r#" + Plain (imports ✔): krate::prelude::Foo + Plain (imports ✖): krate::prelude::Foo + ByCrate(imports ✔): krate::prelude::Foo + ByCrate(imports ✖): krate::prelude::Foo + BySelf (imports ✔): krate::prelude::Foo + BySelf (imports ✖): krate::prelude::Foo + "#]], ); } @@ -1594,9 +1847,14 @@ pub mod prelude { } "#, "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", + expect![[r#" + Plain (imports ✔): petgraph::graph::NodeIndex + Plain (imports ✖): petgraph::graph::NodeIndex + ByCrate(imports ✔): petgraph::graph::NodeIndex + ByCrate(imports ✖): petgraph::graph::NodeIndex + BySelf (imports ✔): petgraph::graph::NodeIndex + BySelf (imports ✖): petgraph::graph::NodeIndex + "#]], ); } @@ -1615,9 +1873,14 @@ pub fn b() {$0} pub fn c() {} "#, "bar::c", - "bar::c", - "crate::foo::bar::c", - "self::bar::c", + expect![[r#" + Plain (imports ✔): bar::c + Plain (imports ✖): bar::c + ByCrate(imports ✔): crate::foo::bar::c + ByCrate(imports ✖): crate::foo::bar::c + BySelf (imports ✔): self::bar::c + BySelf (imports ✖): self::bar::c + "#]], ); } } From b1830a5fe64d50cb819830400c51ccac558bbdf4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 22 May 2024 14:28:07 +0200 Subject: [PATCH 034/101] Update assists test fixtures --- .../crates/hir/src/term_search/expr.rs | 18 +----------------- .../ide-assists/src/handlers/bool_to_enum.rs | 4 ++-- .../convert_tuple_return_type_to_struct.rs | 2 +- .../extract_struct_from_enum_variant.rs | 2 +- .../crates/ide-db/src/imports/import_assets.rs | 18 +++++++++++------- .../ide-diagnostics/src/handlers/typed_hole.rs | 3 ++- 6 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index 45c0dd8da75f..3cbe0d217c28 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -1,6 +1,5 @@ //! Type tree for term search -use hir_def::find_path::PrefixKind; use hir_expand::mod_path::ModPath; use hir_ty::{ db::HirDatabase, @@ -21,23 +20,8 @@ fn mod_item_path( prefer_prelude: bool, ) -> Option { let db = sema_scope.db; - // Account for locals shadowing items from module - let name_hit_count = def.name(db).map(|def_name| { - let mut name_hit_count = 0; - sema_scope.process_all_names(&mut |name, _| { - if name == def_name { - name_hit_count += 1; - } - }); - name_hit_count - }); - let m = sema_scope.module(); - let prefix = match name_hit_count { - Some(0..=1) | None => PrefixKind::Plain, - Some(_) => PrefixKind::ByCrate, - }; - m.find_use_path(db.upcast(), *def, prefix, prefer_no_std, prefer_prelude) + m.find_path(db.upcast(), *def, prefer_no_std, prefer_prelude) } /// Helper function to get path to `ModuleDef` as string diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index df87e2d04498..934d1f3b65ba 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -1521,7 +1521,7 @@ mod foo { } "#, r#" -use crate::foo::Bool; +use foo::Bool; fn main() { use foo::FOO; @@ -1602,7 +1602,7 @@ pub mod bar { "#, r#" //- /main.rs -use crate::foo::bar::Bool; +use foo::bar::Bool; mod foo; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 367cf0bc8b96..1f579d4221b9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -811,7 +811,7 @@ pub mod bar { "#, r#" //- /main.rs -use crate::foo::bar::BarResult; +use foo::bar::BarResult; mod foo; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 24bda139b2cd..2e4541b18119 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -881,7 +881,7 @@ fn another_fn() { r#"use my_mod::my_other_mod::MyField; mod my_mod { - use self::my_other_mod::MyField; + use my_other_mod::MyField; fn another_fn() { let m = my_other_mod::MyEnum::MyField(MyField(1, 1)); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 5e33b08e4a41..530020f1168b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -637,13 +637,17 @@ fn get_mod_path( prefer_no_std: bool, prefer_prelude: bool, ) -> Option { - module_with_candidate.find_use_path( - db, - item_to_search, - prefixed.unwrap_or(PrefixKind::Plain), - prefer_no_std, - prefer_prelude, - ) + if let Some(prefix_kind) = prefixed { + module_with_candidate.find_use_path( + db, + item_to_search, + prefix_kind, + prefer_no_std, + prefer_prelude, + ) + } else { + module_with_candidate.find_path(db, item_to_search, prefer_no_std, prefer_prelude) + } } impl ImportCandidate { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 656d79dc7324..b819cc5b2495 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -368,6 +368,7 @@ fn main() { ); } + // FIXME #[test] fn local_shadow_fn() { check_fixes_unordered( @@ -385,7 +386,7 @@ fn f() { r#" fn f() { let f: i32 = 0; - crate::f() + f() }"#, ], ); From 2ff9bab2eb746b97f653b15e1528f4a87477a066 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 22 May 2024 15:44:51 +0200 Subject: [PATCH 035/101] fix: Fix format_args lowering passing incorrect parameters to rustc_parse_format --- .../rust-analyzer/crates/hir-def/src/body/lower.rs | 10 ++++++++-- .../rust-analyzer/crates/hir-def/src/body/tests.rs | 4 ++-- .../crates/hir-def/src/hir/format_args.rs | 10 ++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index 82f89393add6..c6d9ba6cfe45 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -17,7 +17,7 @@ use syntax::{ self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName, RangeItem, SlicePatComponents, }, - AstNode, AstPtr, SyntaxNodePtr, + AstNode, AstPtr, AstToken as _, SyntaxNodePtr, }; use triomphe::Arc; @@ -1577,7 +1577,13 @@ impl ExprCollector<'_> { }); }); let template = f.template(); - let fmt_snippet = template.as_ref().map(ToString::to_string); + let fmt_snippet = template.as_ref().and_then(|it| match it { + ast::Expr::Literal(literal) => match literal.kind() { + ast::LiteralKind::String(s) => Some(s.text().to_owned()), + _ => None, + }, + _ => None, + }); let mut mappings = vec![]; let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) { Some((s, is_direct_literal)) => format_args::parse( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs index 4c8a54f7c8c7..e8b26d537345 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs @@ -150,7 +150,7 @@ fn desugar_builtin_format_args() { fn main() { let are = "are"; let count = 10; - builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!"); + builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!"); } "#, ); @@ -161,7 +161,7 @@ fn main() { let count = 10; builtin#lang(Arguments::new_v1_formatted)( &[ - "hello ", " ", " friends, we ", " ", "", + "\u{1b}hello ", " ", " friends, we ", " ", "", ], &[ builtin#lang(Argument::new_display)( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index b097a721c758..de0fa982c86a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -175,7 +175,13 @@ pub(crate) fn parse( mut synth: impl FnMut(Name) -> ExprId, mut record_usage: impl FnMut(Name, Option), ) -> FormatArgs { - let text = s.text_without_quotes(); + let Ok(text) = s.value() else { + return FormatArgs { + template: Default::default(), + arguments: args.finish(), + orphans: vec![], + }; + }; let str_style = match s.quote_offsets() { Some(offsets) => { let raw = usize::from(offsets.quotes.0.len()) - 1; @@ -186,7 +192,7 @@ pub(crate) fn parse( }; let mut parser = - parse::Parser::new(text, str_style, fmt_snippet, false, parse::ParseMode::Format); + parse::Parser::new(&text, str_style, fmt_snippet, false, parse::ParseMode::Format); let mut pieces = Vec::new(); while let Some(piece) = parser.next() { From 4e9b12870c705e72c0e85ae286f1b5738fc2a1d9 Mon Sep 17 00:00:00 2001 From: roife Date: Thu, 23 May 2024 02:39:53 +0800 Subject: [PATCH 036/101] fix: check pseudo-block by local_id instead of ModuleOrigin --- .../crates/hir-def/src/nameres/path_resolution.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index 7776cb706824..d621f3a360a9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -18,9 +18,7 @@ use crate::{ db::DefDatabase, item_scope::{ImportOrExternCrate, BUILTIN_SCOPE}, item_tree::Fields, - nameres::{ - sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs, ModuleOrigin, - }, + nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs}, path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, @@ -472,7 +470,7 @@ impl DefMap { }; let extern_prelude = || { - if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) { + if self.block.is_some() && module == DefMap::ROOT { // Don't resolve extern prelude in pseudo-modules of blocks, because // they might been shadowed by local names. return PerNs::none(); @@ -518,7 +516,7 @@ impl DefMap { None => self[Self::ROOT].scope.get(name), }; let from_extern_prelude = || { - if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) { + if self.block.is_some() && module == DefMap::ROOT { // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } From 7a21dff517c761b2d6c1138c34035c8680ab10b1 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Fri, 17 May 2024 15:00:21 -0400 Subject: [PATCH 037/101] internal: refactor `prefer_no_std`/`prefer_prelude` bools into a struct --- .../crates/hir-def/src/find_path.rs | 53 ++++----- .../rust-analyzer/crates/hir-def/src/lib.rs | 9 ++ .../crates/hir-ty/src/display.rs | 6 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 20 +--- .../crates/hir/src/term_search/expr.rs | 104 +++++------------- .../src/handlers/add_missing_match_arms.rs | 50 +++------ .../ide-assists/src/handlers/auto_import.rs | 14 +-- .../ide-assists/src/handlers/bool_to_enum.rs | 10 +- .../src/handlers/convert_into_to_from.rs | 14 +-- .../convert_tuple_return_type_to_struct.rs | 10 +- .../handlers/destructure_struct_binding.rs | 14 +-- .../src/handlers/extract_function.rs | 10 +- .../extract_struct_from_enum_variant.rs | 8 +- .../src/handlers/generate_deref.rs | 14 ++- .../ide-assists/src/handlers/generate_new.rs | 7 +- .../src/handlers/qualify_method_call.rs | 11 +- .../ide-assists/src/handlers/qualify_path.rs | 12 +- .../replace_derive_with_manual_impl.rs | 8 +- .../replace_qualified_name_with_use.rs | 8 +- .../ide-assists/src/handlers/term_search.rs | 11 +- .../crates/ide-completion/src/completions.rs | 8 +- .../ide-completion/src/completions/expr.rs | 14 ++- .../src/completions/flyimport.rs | 38 +++---- .../ide-completion/src/completions/postfix.rs | 16 +-- .../crates/ide-completion/src/lib.rs | 9 +- .../crates/ide-completion/src/render.rs | 35 ++---- .../crates/ide-completion/src/snippet.rs | 9 +- .../crates/ide-completion/src/tests.rs | 6 +- .../ide-db/src/imports/import_assets.rs | 33 ++---- .../crates/ide-db/src/path_transform.rs | 20 ++-- .../src/handlers/json_is_not_rust.rs | 14 ++- .../src/handlers/missing_fields.rs | 8 +- .../src/handlers/typed_hole.rs | 8 +- .../crates/ide-ssr/src/matching.rs | 10 +- .../rust-analyzer/src/cli/analysis_stats.rs | 12 +- .../crates/rust-analyzer/src/config.rs | 10 +- .../src/integrated_benchmarks.rs | 12 +- 37 files changed, 304 insertions(+), 351 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 52d940d63563..d9ef28785cbf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -17,7 +17,7 @@ use crate::{ nameres::DefMap, path::{ModPath, PathKind}, visibility::{Visibility, VisibilityExplicitness}, - ModuleDefId, ModuleId, + ImportPathConfig, ModuleDefId, ModuleId, }; /// Find a path that can be used to refer to a certain item. This can depend on @@ -28,21 +28,10 @@ pub fn find_path( from: ModuleId, prefix_kind: PrefixKind, ignore_local_imports: bool, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { let _p = tracing::span!(tracing::Level::INFO, "find_path").entered(); - find_path_inner( - FindPathCtx { - db, - prefix: prefix_kind, - prefer_no_std, - prefer_prelude, - ignore_local_imports, - }, - item, - from, - ) + find_path_inner(FindPathCtx { db, prefix: prefix_kind, cfg, ignore_local_imports }, item, from) } #[derive(Copy, Clone, Debug)] @@ -88,8 +77,7 @@ impl PrefixKind { struct FindPathCtx<'db> { db: &'db dyn DefDatabase, prefix: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ignore_local_imports: bool, } @@ -107,7 +95,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti let mut visited_modules = FxHashSet::default(); return find_path_for_module( FindPathCtx { - prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate), + cfg: ImportPathConfig { + prefer_no_std: ctx.cfg.prefer_no_std + || ctx.db.crate_supports_no_std(crate_root.krate), + ..ctx.cfg + }, ..ctx }, &def_map, @@ -160,7 +152,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti calculate_best_path( FindPathCtx { - prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate), + cfg: ImportPathConfig { + prefer_no_std: ctx.cfg.prefer_no_std + || ctx.db.crate_supports_no_std(crate_root.krate), + ..ctx.cfg + }, ..ctx }, &def_map, @@ -381,9 +377,7 @@ fn calculate_best_path( path.0.push_segment(name); let new_path = match best_path.take() { - Some(best_path) => { - select_best_path(best_path, path, ctx.prefer_no_std, ctx.prefer_prelude) - } + Some(best_path) => select_best_path(best_path, path, ctx.cfg), None => path, }; best_path_len = new_path.0.len(); @@ -425,12 +419,7 @@ fn calculate_best_path( ); let new_path_with_stab = match best_path.take() { - Some(best_path) => select_best_path( - best_path, - path_with_stab, - ctx.prefer_no_std, - ctx.prefer_prelude, - ), + Some(best_path) => select_best_path(best_path, path_with_stab, ctx.cfg), None => path_with_stab, }; update_best_path(&mut best_path, new_path_with_stab); @@ -446,8 +435,7 @@ fn calculate_best_path( fn select_best_path( old_path @ (_, old_stability): (ModPath, Stability), new_path @ (_, new_stability): (ModPath, Stability), - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> (ModPath, Stability) { match (old_stability, new_stability) { (Stable, Unstable) => return old_path, @@ -461,7 +449,7 @@ fn select_best_path( let (old_path, _) = &old; let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude); let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude); - match (new_has_prelude, old_has_prelude, prefer_prelude) { + match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) { (true, false, true) | (false, true, false) => new, (true, false, false) | (false, true, true) => old, // no prelude difference in the paths, so pick the shorter one @@ -482,7 +470,7 @@ fn select_best_path( match (old_path.0.segments().first(), new_path.0.segments().first()) { (Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => { - let rank = match prefer_no_std { + let rank = match cfg.prefer_no_std { false => |name: &Name| match name { name if name == &known::core => 0, name if name == &known::alloc => 1, @@ -647,10 +635,9 @@ mod tests { { let found_path = find_path_inner( FindPathCtx { - prefer_no_std: false, db: &db, prefix, - prefer_prelude, + cfg: ImportPathConfig { prefer_no_std: false, prefer_prelude }, ignore_local_imports, }, resolved, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index ca8cc1c3ead1..682d169adb11 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -108,6 +108,15 @@ use crate::{ type FxIndexMap = indexmap::IndexMap>; +/// A wrapper around two booleans, [`ImportPathConfig::prefer_no_std`] and [`ImportPathConfig::prefer_prelude`]. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] +pub struct ImportPathConfig { + /// If true, prefer to unconditionally use imports of the `core` and `alloc` crate + /// over the std. + pub prefer_no_std: bool, + /// If true, prefer import paths containing a prelude module. + pub prefer_prelude: bool, +} #[derive(Debug)] pub struct ItemLoc { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 82bbc28884e1..94a6066ee795 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -21,7 +21,8 @@ use hir_def::{ path::{Path, PathKind}, type_ref::{TraitBoundModifier, TypeBound, TypeRef}, visibility::Visibility, - HasModule, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId, + HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId, + TraitId, }; use hir_expand::name::Name; use intern::{Internable, Interned}; @@ -1000,9 +1001,8 @@ impl HirDisplay for Ty { ItemInNs::Types((*def_id).into()), module_id, PrefixKind::Plain, - false, - false, true, + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }, ) { write!(f, "{}", path.display(f.db.upcast()))?; } else { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 7f0b0cd48c91..0b68762e4f4c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -122,6 +122,7 @@ pub use { per_ns::Namespace, type_ref::{Mutability, TypeRef}, visibility::Visibility, + ImportPathConfig, // FIXME: This is here since some queries take it as input that are used // outside of hir. {AdtId, MacroId, ModuleDefId}, @@ -792,8 +793,7 @@ impl Module { self, db: &dyn DefDatabase, item: impl Into, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { hir_def::find_path::find_path( db, @@ -801,8 +801,7 @@ impl Module { self.into(), PrefixKind::Plain, false, - prefer_no_std, - prefer_prelude, + cfg, ) } @@ -813,18 +812,9 @@ impl Module { db: &dyn DefDatabase, item: impl Into, prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { - hir_def::find_path::find_path( - db, - item.into().into(), - self.into(), - prefix_kind, - true, - prefer_no_std, - prefer_prelude, - ) + hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg) } } diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index 3cbe0d217c28..8173427cd907 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -1,5 +1,6 @@ //! Type tree for term search +use hir_def::ImportPathConfig; use hir_expand::mod_path::ModPath; use hir_ty::{ db::HirDatabase, @@ -16,22 +17,20 @@ use crate::{ fn mod_item_path( sema_scope: &SemanticsScope<'_>, def: &ModuleDef, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { let db = sema_scope.db; let m = sema_scope.module(); - m.find_path(db.upcast(), *def, prefer_no_std, prefer_prelude) + m.find_path(db.upcast(), *def, cfg) } /// Helper function to get path to `ModuleDef` as string fn mod_item_path_str( sema_scope: &SemanticsScope<'_>, def: &ModuleDef, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { - let path = mod_item_path(sema_scope, def, prefer_no_std, prefer_prelude); + let path = mod_item_path(sema_scope, def, cfg); path.map(|it| it.display(sema_scope.db.upcast()).to_string()) .ok_or(DisplaySourceCodeError::PathNotFound) } @@ -40,8 +39,7 @@ fn mod_item_path_str( fn type_path( sema_scope: &SemanticsScope<'_>, ty: &Type, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { let db = sema_scope.db; let m = sema_scope.module(); @@ -50,9 +48,7 @@ fn type_path( Some(adt) => { let ty_name = ty.display_source_code(db, m.id, true)?; - let mut path = - mod_item_path(sema_scope, &ModuleDef::Adt(adt), prefer_no_std, prefer_prelude) - .unwrap(); + let mut path = mod_item_path(sema_scope, &ModuleDef::Adt(adt), cfg).unwrap(); path.pop_segment(); let path = path.display(db.upcast()).to_string(); let res = match path.is_empty() { @@ -137,11 +133,10 @@ impl Expr { &self, sema_scope: &SemanticsScope<'_>, many_formatter: &mut dyn FnMut(&Type) -> String, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { let db = sema_scope.db; - let mod_item_path_str = |s, def| mod_item_path_str(s, def, prefer_no_std, prefer_prelude); + let mod_item_path_str = |s, def| mod_item_path_str(s, def, cfg); match self { Expr::Const(it) => mod_item_path_str(sema_scope, &ModuleDef::Const(*it)), Expr::Static(it) => mod_item_path_str(sema_scope, &ModuleDef::Static(*it)), @@ -151,9 +146,7 @@ impl Expr { Expr::Function { func, params, .. } => { let args = params .iter() - .map(|f| { - f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -167,14 +160,10 @@ impl Expr { crate::AssocItemContainer::Impl(imp) => { let self_ty = imp.self_ty(db); // Should it be guaranteed that `mod_item_path` always exists? - match self_ty.as_adt().and_then(|adt| { - mod_item_path( - sema_scope, - &adt.into(), - prefer_no_std, - prefer_prelude, - ) - }) { + match self_ty + .as_adt() + .and_then(|adt| mod_item_path(sema_scope, &adt.into(), cfg)) + { Some(path) => path.display(sema_scope.db.upcast()).to_string(), None => self_ty.display(db).to_string(), } @@ -196,17 +185,10 @@ impl Expr { let func_name = func.name(db).display(db.upcast()).to_string(); let self_param = func.self_param(db).unwrap(); - let target_str = target.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let target_str = target.gen_source_code(sema_scope, many_formatter, cfg)?; let args = params .iter() - .map(|f| { - f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -238,7 +220,7 @@ impl Expr { false => { let generics = generics .iter() - .map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude)) + .map(|it| type_path(sema_scope, it, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -249,14 +231,7 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|f| { - f.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - ) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -271,12 +246,7 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast()), - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude - )? + a.gen_source_code(sema_scope, many_formatter, cfg)? ); Ok(tmp) }) @@ -297,14 +267,7 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|a| { - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - ) - }) + .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -319,12 +282,7 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast()), - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude - )? + a.gen_source_code(sema_scope, many_formatter, cfg)? ); Ok(tmp) }) @@ -338,7 +296,7 @@ impl Expr { false => { let generics = generics .iter() - .map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude)) + .map(|it| type_path(sema_scope, it, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -353,9 +311,7 @@ impl Expr { Expr::Tuple { params, .. } => { let args = params .iter() - .map(|a| { - a.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -367,12 +323,7 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let strukt = expr.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let strukt = expr.gen_source_code(sema_scope, many_formatter, cfg)?; let field = field.name(db).display(db.upcast()).to_string(); Ok(format!("{strukt}.{field}")) } @@ -381,12 +332,7 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let inner = expr.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let inner = expr.gen_source_code(sema_scope, many_formatter, cfg)?; Ok(format!("&{inner}")) } Expr::Many(ty) => Ok(many_formatter(ty)), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 8eddc562bef4..22a4674fd46c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,7 +1,7 @@ use std::iter::{self, Peekable}; use either::Either; -use hir::{Adt, Crate, HasAttrs, HasSource, ModuleDef, Semantics}; +use hir::{Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; @@ -71,6 +71,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .filter(|pat| !matches!(pat, Pat::WildcardPat(_))) .collect(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( Peekable>>, @@ -88,13 +93,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .filter_map(|variant| { Some(( - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - )?, + build_pat(ctx.db(), module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -145,15 +144,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg)); (ast::Pat::from(make::tuple_pat(patterns)), is_hidden) }) @@ -184,15 +177,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg)); (ast::Pat::from(make::slice_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); @@ -457,18 +444,11 @@ fn build_pat( db: &RootDatabase, module: hir::Module, var: ExtendedVariant, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { match var { ExtendedVariant::Variant(var) => { - let path = mod_path_to_ast(&module.find_path( - db, - ModuleDef::from(var), - prefer_no_std, - prefer_prelude, - )?); - + let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?); // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though Some(match var.source(db)?.value.kind() { ast::StructKind::Tuple(field_list) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index b90bccb48ede..3bd003a267a2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -1,6 +1,6 @@ use std::cmp::Reverse; -use hir::{db::HirDatabase, Module}; +use hir::{db::HirDatabase, ImportPathConfig, Module}; use ide_db::{ helpers::mod_path_to_ast, imports::{ @@ -90,14 +90,14 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; // # pub mod std { pub mod collections { pub struct HashMap { } } } // ``` pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let (import_assets, syntax_under_caret) = find_importable_node(ctx)?; let mut proposed_imports: Vec<_> = import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_no_std, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .collect(); if proposed_imports.is_empty() { return None; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index 934d1f3b65ba..71436e658047 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -1,4 +1,4 @@ -use hir::ModuleDef; +use hir::{ImportPathConfig, ModuleDef}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -326,6 +326,11 @@ fn augment_references_with_imports( ) -> Vec { let mut visited_modules = FxHashSet::default(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + references .into_iter() .filter_map(|FileReference { range, name, .. }| { @@ -345,8 +350,7 @@ fn augment_references_with_imports( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + cfg, ) .map(|mod_path| { make::path_concat(mod_path_to_ast(&mod_path), make::path_from_text("Bool")) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs index e0e2ac758533..be433c333385 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs @@ -1,3 +1,4 @@ +use hir::ImportPathConfig; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast, traits::resolve_target_trait}; use syntax::ast::{self, AstNode, HasName}; @@ -43,19 +44,18 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - return None; } + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let src_type_path = { let src_type_path = src_type.syntax().descendants().find_map(ast::Path::cast)?; let src_type_def = match ctx.sema.resolve_path(&src_type_path) { Some(hir::PathResolution::Def(module_def)) => module_def, _ => return None, }; - - mod_path_to_ast(&module.find_path( - ctx.db(), - src_type_def, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - )?) + mod_path_to_ast(&module.find_path(ctx.db(), src_type_def, cfg)?) }; let dest_type = match &ast_trait { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 1f579d4221b9..241fc3b7a379 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::ModuleDef; +use hir::{ImportPathConfig, ModuleDef}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -183,6 +183,11 @@ fn augment_references_with_imports( ) -> Vec<(ast::NameLike, Option<(ImportScope, ast::Path)>)> { let mut visited_modules = FxHashSet::default(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + references .iter() .filter_map(|FileReference { name, .. }| { @@ -205,8 +210,7 @@ fn augment_references_with_imports( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + cfg, ) .map(|mod_path| { make::path_concat( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index bdcefe0b4fda..9adbdd220c2b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -1,4 +1,4 @@ -use hir::HasVisibility; +use hir::{HasVisibility, ImportPathConfig}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -87,15 +87,15 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> Op ctx.sema.db, ModuleDef::from(control_flow_enum), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ); if let Some(mod_path) = mod_path { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 2e4541b18119..3c6d73b62e73 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -1,7 +1,7 @@ use std::iter; use either::Either; -use hir::{Module, ModuleDef, Name, Variant}; +use hir::{ImportPathConfig, Module, ModuleDef, Name, Variant}; use ide_db::{ defs::Definition, helpers::mod_path_to_ast, @@ -390,8 +390,10 @@ fn process_references( ctx.sema.db, *enum_module_def, ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ); if let Some(mut mod_path) = mod_path { mod_path.pop_segment(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index 54c320a39b1a..9a441fc5ebcd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use hir::{ModPath, ModuleDef}; +use hir::{ImportPathConfig, ModPath, ModuleDef}; use ide_db::{famous_defs::FamousDefs, RootDatabase}; use syntax::{ ast::{self, HasName}, @@ -61,8 +61,10 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let field_type = field.ty()?; @@ -106,8 +108,10 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let field_type = field.ty()?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 50342b0284e3..52007e0e297b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -1,3 +1,4 @@ +use hir::ImportPathConfig; use ide_db::{ imports::import_assets::item_for_path_search, use_trivial_constructor::use_trivial_constructor, }; @@ -61,8 +62,10 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let type_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let expr = use_trivial_constructor( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index 196b33e0f675..5d1140d57ac9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -1,4 +1,7 @@ -use hir::{db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef}; +use hir::{ + db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, ImportPathConfig, ItemInNs, + ModuleDef, +}; use ide_db::assists::{AssistId, AssistKind}; use syntax::{ast, AstNode}; @@ -47,8 +50,10 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> let receiver_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let qualify_candidate = QualifyCandidate::ImplMethod(ctx.sema.db, call, resolved_call); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index 63a09ce2e976..978b719c30a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs @@ -1,6 +1,6 @@ use std::iter; -use hir::AsAssocItem; +use hir::{AsAssocItem, ImportPathConfig}; use ide_db::RootDatabase; use ide_db::{ helpers::mod_path_to_ast, @@ -37,9 +37,13 @@ use crate::{ // ``` pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let (import_assets, syntax_under_caret) = find_importable_node(ctx)?; - let mut proposed_imports: Vec<_> = import_assets - .search_for_relative_paths(&ctx.sema, ctx.config.prefer_no_std, ctx.config.prefer_prelude) - .collect(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + + let mut proposed_imports: Vec<_> = + import_assets.search_for_relative_paths(&ctx.sema, cfg).collect(); if proposed_imports.is_empty() { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 8cc7c883f4ce..e792debaa517 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,4 +1,4 @@ -use hir::{InFile, MacroFileIdExt, ModuleDef}; +use hir::{ImportPathConfig, InFile, MacroFileIdExt, ModuleDef}; use ide_db::{helpers::mod_path_to_ast, imports::import_assets::NameToImport, items_locator}; use itertools::Itertools; use syntax::{ @@ -86,8 +86,10 @@ pub(crate) fn replace_derive_with_manual_impl( .find_path( ctx.sema.db, hir::ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .as_ref() .map(mod_path_to_ast) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index cb9de32d9cd0..188165e77645 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,4 +1,4 @@ -use hir::AsAssocItem; +use hir::{AsAssocItem, ImportPathConfig}; use ide_db::{ helpers::mod_path_to_ast, imports::insert_use::{insert_use, ImportScope}, @@ -67,8 +67,10 @@ pub(crate) fn replace_qualified_name_with_use( ctx.sema.db, module, ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) }) .flatten(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index d0c6ae21988d..ffd1508ccbdc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -1,5 +1,8 @@ //! Term search assist -use hir::term_search::{TermSearchConfig, TermSearchCtx}; +use hir::{ + term_search::{TermSearchConfig, TermSearchCtx}, + ImportPathConfig, +}; use ide_db::{ assists::{AssistId, AssistKind, GroupLabel}, famous_defs::FamousDefs, @@ -50,8 +53,10 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< path.gen_source_code( &scope, &mut formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .ok() }) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 69b0289fc1dd..11ffc8bc4414 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -24,7 +24,7 @@ pub(crate) mod vis; use std::iter; -use hir::{known, HasAttrs, ScopeDef, Variant}; +use hir::{known, HasAttrs, ImportPathConfig, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; use syntax::{ast, SmolStr}; @@ -636,8 +636,10 @@ fn enum_variants_with_paths( if let Some(path) = ctx.module.find_path( ctx.db, hir::ModuleDef::from(variant), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) { // Variants with trivial paths are already added by the existing completion logic, // so we should avoid adding these twice diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index f350c2743c7c..ddb1aeb3711d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -1,6 +1,6 @@ //! Completion of names from the current scope in expression position. -use hir::ScopeDef; +use hir::{ImportPathConfig, ScopeDef}; use syntax::ast; use crate::{ @@ -174,8 +174,10 @@ pub(crate) fn complete_expr_path( .find_path( ctx.db, hir::ModuleDef::from(strukt), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .filter(|it| it.len() > 1); @@ -197,8 +199,10 @@ pub(crate) fn complete_expr_path( .find_path( ctx.db, hir::ModuleDef::from(un), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .filter(|it| it.len() > 1); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs index bf6747d71b7a..d5a4e9ecdcc1 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs @@ -1,5 +1,5 @@ //! See [`import_on_the_fly`]. -use hir::{ItemInNs, ModuleDef}; +use hir::{ImportPathConfig, ItemInNs, ModuleDef}; use ide_db::imports::{ import_assets::{ImportAssets, LocatedImport}, insert_use::ImportScope, @@ -257,13 +257,13 @@ fn import_on_the_fly( }; let user_input_lowercased = potential_import_name.to_lowercase(); + let import_cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, import_cfg, ctx.config.insert_use.prefix_kind) .filter(ns_filter) .filter(|import| { let original_item = &import.original_item; @@ -308,13 +308,13 @@ fn import_on_the_fly_pat_( }; let user_input_lowercased = potential_import_name.to_lowercase(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .filter(ns_filter) .filter(|import| { let original_item = &import.original_item; @@ -355,13 +355,13 @@ fn import_on_the_fly_method( let user_input_lowercased = potential_import_name.to_lowercase(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .filter(|import| { !ctx.is_item_hidden(&import.item_to_import) && !ctx.is_item_hidden(&import.original_item) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index c14da34874b3..a230edd39b6d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -2,7 +2,7 @@ mod format_like; -use hir::ItemInNs; +use hir::{ImportPathConfig, ItemInNs}; use ide_db::{ documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, @@ -60,15 +60,17 @@ pub(crate) fn complete_postfix( None => return, }; + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() { if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) { if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() { - if let Some(path) = ctx.module.find_path( - ctx.db, - ItemInNs::Values(drop_fn.into()), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) { + if let Some(path) = + ctx.module.find_path(ctx.db, ItemInNs::Values(drop_fn.into()), cfg) + { cov_mark::hit!(postfix_drop_completion); let mut item = postfix_snippet( "drop", diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 4165dd48af46..2b9e46a70fd2 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -12,6 +12,7 @@ mod snippet; #[cfg(test)] mod tests; +use hir::ImportPathConfig; use ide_db::{ base_db::FilePosition, helpers::mod_path_to_ast, @@ -251,6 +252,11 @@ pub fn resolve_completion_edits( let new_ast = scope.clone_for_update(); let mut import_insert = TextEdit::builder(); + let cfg = ImportPathConfig { + prefer_no_std: config.prefer_no_std, + prefer_prelude: config.prefer_prelude, + }; + imports.into_iter().for_each(|(full_import_path, imported_name)| { let items_with_name = items_locator::items_with_name( &sema, @@ -264,8 +270,7 @@ pub fn resolve_completion_edits( db, candidate, config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, + cfg, ) }) .find(|mod_path| mod_path.display(db).to_string() == full_import_path); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index d7b27f8b3b3a..8f563790737e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -10,7 +10,7 @@ pub(crate) mod type_alias; pub(crate) mod union_literal; pub(crate) mod variant; -use hir::{AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type}; +use hir::{AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; use ide_db::{ documentation::{Documentation, HasDocs}, helpers::item_name, @@ -295,14 +295,12 @@ pub(crate) fn render_expr( .unwrap_or_else(|| String::from("...")) }; - let label = expr - .gen_source_code( - &ctx.scope, - &mut label_formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - .ok()?; + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + + let label = expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg).ok()?; let source_range = match ctx.original_token.parent() { Some(node) => match node.ancestors().find_map(ast::Path::cast) { @@ -314,16 +312,8 @@ pub(crate) fn render_expr( let mut item = CompletionItem::new(CompletionItemKind::Expression, source_range, label); - let snippet = format!( - "{}$0", - expr.gen_source_code( - &ctx.scope, - &mut snippet_formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude - ) - .ok()? - ); + let snippet = + format!("{}$0", expr.gen_source_code(&ctx.scope, &mut snippet_formatter, cfg).ok()?); let edit = TextEdit::replace(source_range, snippet); item.snippet_edit(ctx.config.snippet_cap?, edit); item.documentation(Documentation::new(String::from("Autogenerated expression by term search"))); @@ -333,12 +323,7 @@ pub(crate) fn render_expr( }); for trait_ in expr.traits_used(ctx.db) { let trait_item = hir::ItemInNs::from(hir::ModuleDef::from(trait_)); - let Some(path) = ctx.module.find_path( - ctx.db, - trait_item, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) else { + let Some(path) = ctx.module.find_path(ctx.db, trait_item, cfg) else { continue; }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs index 37bb6cfef0a9..07836040b487 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs @@ -100,6 +100,7 @@ // } // ---- +use hir::ImportPathConfig; use ide_db::imports::import_assets::LocatedImport; use itertools::Itertools; use syntax::{ast, AstNode, GreenNode, SyntaxNode}; @@ -168,6 +169,11 @@ impl Snippet { } fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option> { + let import_cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let resolve = |import: &GreenNode| { let path = ast::Path::cast(SyntaxNode::new_root(import.clone()))?; let item = match ctx.scope.speculative_resolve(&path)? { @@ -178,8 +184,7 @@ fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option 1).then(|| LocatedImport::new(path.clone(), item, item))) }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs index 70e0aa4e9a91..c1a67315b75c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs @@ -66,11 +66,10 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { enable_self_on_the_fly: true, enable_private_editable: false, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), - prefer_no_std: false, - prefer_prelude: true, insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: PrefixKind::Plain, @@ -78,9 +77,10 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { group: true, skip_glob_imports: true, }, + prefer_no_std: false, + prefer_prelude: true, snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; pub(crate) fn completion_list(ra_fixture: &str) -> String { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 530020f1168b..6e708182d09f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -1,8 +1,8 @@ //! Look up accessible paths for items. use hir::{ - db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ItemInNs, - ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, + db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, + ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Trait, Type, }; use itertools::{EitherOrBoth, Itertools}; @@ -205,24 +205,22 @@ impl ImportAssets { pub fn search_for_imports( &self, sema: &Semantics<'_, RootDatabase>, + cfg: ImportPathConfig, prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for_imports").entered(); - self.search_for(sema, Some(prefix_kind), prefer_no_std, prefer_prelude) + self.search_for(sema, Some(prefix_kind), cfg) } /// This may return non-absolute paths if a part of the returned path is already imported into scope. pub fn search_for_relative_paths( &self, sema: &Semantics<'_, RootDatabase>, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for_relative_paths") .entered(); - self.search_for(sema, None, prefer_no_std, prefer_prelude) + self.search_for(sema, None, cfg) } /// Requires imports to by prefix instead of fuzzily. @@ -259,8 +257,7 @@ impl ImportAssets { &self, sema: &Semantics<'_, RootDatabase>, prefixed: Option, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for").entered(); @@ -277,8 +274,7 @@ impl ImportAssets { item_for_path_search(sema.db, item)?, &self.module_with_candidate, prefixed, - prefer_no_std, - prefer_prelude, + cfg, ) .filter(|path| path.len() > 1) }; @@ -634,19 +630,12 @@ fn get_mod_path( item_to_search: ItemInNs, module_with_candidate: &Module, prefixed: Option, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { if let Some(prefix_kind) = prefixed { - module_with_candidate.find_use_path( - db, - item_to_search, - prefix_kind, - prefer_no_std, - prefer_prelude, - ) + module_with_candidate.find_use_path(db, item_to_search, prefix_kind, cfg) } else { - module_with_candidate.find_path(db, item_to_search, prefer_no_std, prefer_prelude) + module_with_candidate.find_path(db, item_to_search, cfg) } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 6f4f97e0b86c..7c11dd3e2a4e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -2,7 +2,7 @@ use crate::helpers::mod_path_to_ast; use either::Either; -use hir::{AsAssocItem, HirDisplay, ModuleDef, SemanticsScope}; +use hir::{AsAssocItem, HirDisplay, ImportPathConfig, ModuleDef, SemanticsScope}; use itertools::Itertools; use rustc_hash::FxHashMap; use syntax::{ @@ -308,11 +308,12 @@ impl Ctx<'_> { parent.segment()?.name_ref()?, ) .and_then(|trait_ref| { + let cfg = + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; let found_path = self.target_module.find_path( self.source_scope.db.upcast(), hir::ModuleDef::Trait(trait_ref), - false, - true, + cfg, )?; match make::ty_path(mod_path_to_ast(&found_path)) { ast::Type::PathType(path_ty) => Some(path_ty), @@ -347,12 +348,9 @@ impl Ctx<'_> { } } - let found_path = self.target_module.find_path( - self.source_scope.db.upcast(), - def, - false, - true, - )?; + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let found_path = + self.target_module.find_path(self.source_scope.db.upcast(), def, cfg)?; let res = mod_path_to_ast(&found_path).clone_for_update(); if let Some(args) = path.segment().and_then(|it| it.generic_arg_list()) { if let Some(segment) = res.segment() { @@ -385,11 +383,11 @@ impl Ctx<'_> { if let Some(adt) = ty.as_adt() { if let ast::Type::PathType(path_ty) = &ast_ty { + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; let found_path = self.target_module.find_path( self.source_scope.db.upcast(), ModuleDef::from(adt), - false, - true, + cfg, )?; if let Some(qual) = mod_path_to_ast(&found_path).qualifier() { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index 71958bc8660f..132b93df10ab 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -1,7 +1,7 @@ //! This diagnostic provides an assist for creating a struct definition from a JSON //! example. -use hir::{PathResolution, Semantics}; +use hir::{ImportPathConfig, PathResolution, Semantics}; use ide_db::{ base_db::{FileId, FileRange}, helpers::mod_path_to_ast, @@ -142,14 +142,19 @@ pub(crate) fn json_in_items( ImportScope::Block(it) => ImportScope::Block(scb.make_mut(it)), }; let current_module = semantics_scope.module(); + + let cfg = ImportPathConfig { + prefer_no_std: config.prefer_no_std, + prefer_prelude: config.prefer_prelude, + }; + if !scope_has("Serialize") { if let Some(PathResolution::Def(it)) = serialize_resolved { if let Some(it) = current_module.find_use_path( sema.db, it, config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, + cfg, ) { insert_use(&scope, mod_path_to_ast(&it), &config.insert_use); } @@ -161,8 +166,7 @@ pub(crate) fn json_in_items( sema.db, it, config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, + cfg, ) { insert_use(&scope, mod_path_to_ast(&it), &config.insert_use); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index ed9094f1f361..9eff84b89879 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -1,7 +1,7 @@ use either::Either; use hir::{ db::{ExpandDatabase, HirDatabase}, - known, AssocItem, HirDisplay, HirFileIdExt, InFile, Type, + known, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, }; use ide_db::{ assists::Assist, famous_defs::FamousDefs, imports::import_assets::item_for_path_search, @@ -125,8 +125,10 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option, d: &hir::TypedHole) -> Option path.gen_source_code( &scope, &mut formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .ok() }) diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index 99df3f2563df..cf7e7e08bc52 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -6,7 +6,7 @@ use crate::{ resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo}, SsrMatches, }; -use hir::Semantics; +use hir::{ImportPathConfig, Semantics}; use ide_db::{base_db::FileRange, FxHashMap}; use std::{cell::Cell, iter::Peekable}; use syntax::{ @@ -663,10 +663,10 @@ impl Match { .module(); for (path, resolved_path) in &template.resolved_paths { if let hir::PathResolution::Def(module_def) = resolved_path.resolution { - let mod_path = - module.find_path(sema.db, module_def, false, true).ok_or_else(|| { - match_error!("Failed to render template path `{}` at match location") - })?; + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let mod_path = module.find_path(sema.db, module_def, cfg).ok_or_else(|| { + match_error!("Failed to render template path `{}` at match location") + })?; self.rendered_template_paths.insert(path.clone(), mod_path); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 5208aa9bf08c..bded41932c03 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -8,7 +8,8 @@ use std::{ use hir::{ db::{DefDatabase, ExpandDatabase, HirDatabase}, - Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, HirFileIdExt, ModuleDef, Name, + Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, HirFileIdExt, ImportPathConfig, + ModuleDef, Name, }; use hir_def::{ body::{BodySourceMap, SyntheticSyntax}, @@ -438,8 +439,13 @@ impl flags::AnalysisStats { let mut formatter = |_: &hir::Type| todo.clone(); let mut syntax_hit_found = false; for term in found_terms { - let generated = - term.gen_source_code(&scope, &mut formatter, false, true).unwrap(); + let generated = term + .gen_source_code( + &scope, + &mut formatter, + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }, + ) + .unwrap(); syntax_hit_found |= trim(&original_text) == trim(&generated); // Validate if type-checks diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6c332ae1cb2f..a8d1e72aed9f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1031,6 +1031,8 @@ impl Config { && completion_item_edit_resolve(&self.caps), enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(), enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(), + enable_term_search: self.completion_termSearch_enable(source_root).to_owned(), + term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64, full_function_signatures: self .completion_fullFunctionSignatures_enable(source_root) .to_owned(), @@ -1039,8 +1041,6 @@ impl Config { CallableCompletionDef::AddParentheses => Some(CallableSnippets::AddParentheses), CallableCompletionDef::None => None, }, - insert_use: self.insert_use_config(source_root), - prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), snippet_cap: SnippetCap::new(try_or_def!( self.caps .text_document @@ -1051,11 +1051,11 @@ impl Config { .as_ref()? .snippet_support? )), + insert_use: self.insert_use_config(source_root), + prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), + prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), snippets: self.snippets.clone().to_vec(), limit: self.completion_limit(source_root).to_owned(), - enable_term_search: self.completion_termSearch_enable(source_root).to_owned(), - term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64, - prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index cc83d6246bf5..5d617780b6df 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -139,6 +139,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -149,11 +150,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; @@ -184,6 +184,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -194,11 +195,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; @@ -227,6 +227,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -237,11 +238,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; From f50f8fbcb98d2212defdc1acd1b15cbd74f3e8eb Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 22 May 2024 20:45:54 +0200 Subject: [PATCH 038/101] Simplify --- .../crates/hir-def/src/find_path.rs | 18 +++++++++--------- .../rust-analyzer/crates/hir-ty/src/display.rs | 2 +- .../crates/ide-completion/src/lib.rs | 7 +------ 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index d9ef28785cbf..d9495d36c0d9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -1,9 +1,6 @@ //! An algorithm to find a path to refer to a certain item. -use std::{ - cmp::Ordering, - iter::{self, once}, -}; +use std::{cmp::Ordering, iter}; use hir_expand::{ name::{known, AsName, Name}, @@ -85,7 +82,7 @@ struct FindPathCtx<'db> { fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Option { // - if the item is a builtin, it's in scope if let ItemInNs::Types(ModuleDefId::BuiltinType(builtin)) = item { - return Some(ModPath::from_segments(PathKind::Plain, once(builtin.as_name()))); + return Some(ModPath::from_segments(PathKind::Plain, iter::once(builtin.as_name()))); } let def_map = from.def_map(ctx.db); @@ -124,7 +121,7 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti // - if the item is already in scope, return the name under which it is let scope_name = find_in_scope(ctx.db, &def_map, from, item, ctx.ignore_local_imports); if let Some(scope_name) = scope_name { - return Some(ModPath::from_segments(prefix.path_kind(), Some(scope_name))); + return Some(ModPath::from_segments(prefix.path_kind(), iter::once(scope_name))); } } @@ -209,7 +206,7 @@ fn find_path_for_module( } else { PathKind::Plain }; - return Some((ModPath::from_segments(kind, once(name.clone())), Stable)); + return Some((ModPath::from_segments(kind, iter::once(name.clone())), Stable)); } } let prefix = if module_id.is_within_block() { PrefixKind::Plain } else { ctx.prefix }; @@ -227,7 +224,10 @@ fn find_path_for_module( ); if let Some(scope_name) = scope_name { // - if the item is already in scope, return the name under which it is - return Some((ModPath::from_segments(prefix.path_kind(), once(scope_name)), Stable)); + return Some(( + ModPath::from_segments(prefix.path_kind(), iter::once(scope_name)), + Stable, + )); } } @@ -301,7 +301,7 @@ fn find_in_prelude( }); if found_and_same_def.unwrap_or(true) { - Some(ModPath::from_segments(PathKind::Plain, once(name.clone()))) + Some(ModPath::from_segments(PathKind::Plain, iter::once(name.clone()))) } else { None } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 94a6066ee795..5a9621bb69a4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1001,7 +1001,7 @@ impl HirDisplay for Ty { ItemInNs::Types((*def_id).into()), module_id, PrefixKind::Plain, - true, + false, ImportPathConfig { prefer_no_std: false, prefer_prelude: true }, ) { write!(f, "{}", path.display(f.db.upcast()))?; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 2b9e46a70fd2..a83fa28b8758 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -266,12 +266,7 @@ pub fn resolve_completion_edits( ); let import = items_with_name .filter_map(|candidate| { - current_module.find_use_path( - db, - candidate, - config.insert_use.prefix_kind, - cfg, - ) + current_module.find_use_path(db, candidate, config.insert_use.prefix_kind, cfg) }) .find(|mod_path| mod_path.display(db).to_string() == full_import_path); if let Some(import_path) = import { From f2c3ef77b1976eee67ae88ac12cbd1eb4e2da398 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Wed, 22 May 2024 16:16:19 -0400 Subject: [PATCH 039/101] fix: ensure implied bounds from associated types are considered in autocomplete --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 3 +- .../ide-completion/src/tests/flyimport.rs | 41 +++++++++++++++++++ .../ide-db/src/imports/import_assets.rs | 11 ++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 0b68762e4f4c..777be711a5e6 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -68,7 +68,7 @@ use hir_ty::{ diagnostics::BodyValidationDiagnostic, error_lifetime, known_const_to_ast, layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding}, - method_resolution::{self, TyFingerprint}, + method_resolution::{self}, mir::{interpret_mir, MutBorrowKind}, primitive::UintTy, traits::FnTrait, @@ -99,6 +99,7 @@ pub use crate::{ VisibleTraits, }, }; +pub use hir_ty::method_resolution::TyFingerprint; // Be careful with these re-exports. // diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index d2227d23cd77..abffa73c3b4c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -472,6 +472,47 @@ fn main() { ); } +#[test] +fn trait_completions_handle_associated_types() { + let fixture = r#" +//- /foo.rs crate:foo +pub trait NotInScope { + fn not_in_scope(&self); +} + +pub trait Wrapper { + type Inner: NotInScope; + fn inner(&self) -> Self::Inner; +} + +//- /main.rs crate:main deps:foo +use foo::Wrapper; + +fn completion(whatever: T) { + whatever.inner().$0 +} +"#; + + check( + fixture, + expect![[r#" + me not_in_scope() (use foo::NotInScope) fn(&self) + "#]], + ); + + check_edit( + "not_in_scope", + fixture, + r#" +use foo::{NotInScope, Wrapper}; + +fn completion(whatever: T) { + whatever.inner().not_in_scope()$0 +} +"#, + ); +} + #[test] fn trait_method_fuzzy_completion_aware_of_unit_type() { let fixture = r#" diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 6e708182d09f..4caecb3f2fe1 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -3,7 +3,7 @@ use hir::{ db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, - SemanticsScope, Trait, Type, + SemanticsScope, Trait, TyFingerprint, Type, }; use itertools::{EitherOrBoth, Itertools}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -545,6 +545,15 @@ fn trait_applicable_items( let Some(receiver) = trait_candidate.receiver_ty.fingerprint_for_trait_impl() else { return false; }; + + // in order to handle implied bounds through an associated type, keep any + // method receiver that matches `TyFingerprint::Unnameable`. this receiver + // won't be in `TraitImpls` anyways, as `TraitImpls` only contains actual + // implementations. + if matches!(receiver, TyFingerprint::Unnameable) { + return true; + } + let definitions_exist_in_trait_crate = db .trait_impls_in_crate(defining_crate_for_trait.into()) .has_impls_for_trait_and_self_ty(candidate_trait_id, receiver); From 366ef954073bdaebe83e6619430ae0e8d17b9850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 22 May 2024 14:45:48 +0200 Subject: [PATCH 040/101] Slightly clean up some lint infra code * inline `LintBuffer::add_lint`, it only had a single use * update a lint infra example code snippet * it used the wrong API (the snippet isn't tested) * presumably the arguments were updated from builder to diag struct style at some point without updating the method --- compiler/rustc_lint_defs/src/lib.rs | 25 +++++++------------- compiler/rustc_macros/src/diagnostics/mod.rs | 2 +- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1941b0b12643..c8a9fb02bf2e 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -764,19 +764,7 @@ pub struct LintBuffer { impl LintBuffer { pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) { - let arr = self.map.entry(early_lint.node_id).or_default(); - arr.push(early_lint); - } - - pub fn add_lint( - &mut self, - lint: &'static Lint, - node_id: NodeId, - span: MultiSpan, - diagnostic: BuiltinLintDiag, - ) { - let lint_id = LintId::of(lint); - self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, diagnostic }); + self.map.entry(early_lint.node_id).or_default().push(early_lint); } pub fn take(&mut self, id: NodeId) -> Vec { @@ -787,11 +775,16 @@ impl LintBuffer { pub fn buffer_lint( &mut self, lint: &'static Lint, - id: NodeId, - sp: impl Into, + node_id: NodeId, + span: impl Into, diagnostic: BuiltinLintDiag, ) { - self.add_lint(lint, id, sp.into(), diagnostic) + self.add_early_lint(BufferedEarlyLint { + lint_id: LintId::of(lint), + node_id, + span: span.into(), + diagnostic, + }); } } diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 389d88bebc78..134045d0644c 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -91,7 +91,7 @@ pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { +/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { /// method, /// success_ordering, /// fail_ordering, From 06bc4fc67145e3a7be9b5a2cf2b5968cef36e587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 22 May 2024 16:46:05 +0200 Subject: [PATCH 041/101] Remove `LintDiagnostic::msg` * instead simply set the primary message inside the lint decorator functions * it used to be this way before [#]101986 which introduced `msg` to prevent good path delayed bugs (which no longer exist) from firing under certain circumstances when lints were suppressed / silenced * this is no longer necessary for various reasons I presume * it shaves off complexity and makes further changes easier to implement --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 2 - .../rustc_hir_analysis/src/check/check.rs | 18 ++- .../src/check/intrinsicck.rs | 2 +- .../rustc_hir_analysis/src/check_unused.rs | 13 +- .../src/collect/generics_of.rs | 5 +- .../src/hir_ty_lowering/generics.rs | 5 +- .../src/hir_ty_lowering/lint.rs | 4 +- .../src/hir_ty_lowering/mod.rs | 47 +++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 20 +-- .../src/method/prelude_edition_lints.rs | 128 +++++++++--------- compiler/rustc_hir_typeck/src/method/probe.rs | 85 ++++++------ compiler/rustc_hir_typeck/src/pat.rs | 19 +-- compiler/rustc_hir_typeck/src/upvar.rs | 3 +- compiler/rustc_lint/src/context.rs | 31 ++--- .../rustc_lint/src/impl_trait_overcaptures.rs | 5 +- compiler/rustc_lint/src/levels.rs | 42 +++--- compiler/rustc_lint/src/lints.rs | 56 ++------ compiler/rustc_lint/src/non_fmt_panic.rs | 3 +- .../src/diagnostics/diagnostic.rs | 32 ++--- compiler/rustc_middle/src/lint.rs | 10 +- compiler/rustc_middle/src/middle/stability.rs | 21 ++- .../rustc_middle/src/mir/interpret/queries.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 19 +-- compiler/rustc_mir_transform/src/errors.rs | 22 ++- compiler/rustc_pattern_analysis/src/lints.rs | 1 - .../src/traits/object_safety.rs | 63 ++++----- .../src/traits/specialize/mod.rs | 21 ++- src/librustdoc/core.rs | 2 +- src/librustdoc/html/markdown.rs | 11 +- .../passes/check_doc_test_visibility.rs | 15 +- .../passes/collect_intra_doc_links.rs | 4 +- src/librustdoc/passes/lint/bare_urls.rs | 5 +- .../passes/lint/check_code_block_syntax.rs | 4 +- src/librustdoc/passes/lint/html_tags.rs | 5 +- .../passes/lint/redundant_explicit_links.rs | 10 +- .../passes/lint/unescaped_backticks.rs | 73 ++++++++-- .../clippy/clippy_utils/src/diagnostics.rs | 18 ++- .../tests/ui-internal/disallow_span_lint.rs | 4 +- .../ui-internal/disallow_span_lint.stderr | 8 +- .../ui-fulldeps/internal-lints/diagnostics.rs | 8 -- .../internal-lints/diagnostics.stderr | 6 +- .../session-diagnostic/diagnostic-derive.rs | 1 - .../diagnostic-derive.stderr | 62 ++++----- 44 files changed, 430 insertions(+), 488 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9bf055b17394..304c604100af 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -564,8 +564,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, - "`no_sanitize` will have no effect after inlining", |lint| { + lint.primary_message("`no_sanitize` will have no effect after inlining"); lint.span_note(inline_span, "inlining requested here"); }, ) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 18bb71bd99f7..34b569c42068 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -200,8 +200,6 @@ pub trait SubdiagMessageOp = pub trait LintDiagnostic<'a, G: EmissionGuarantee> { /// Decorate and emit a lint. fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>); - - fn msg(&self) -> DiagMessage; } #[derive(Clone, Debug, Encodable, Decodable)] diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b5c067514059..b46b1d5a26b4 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { .emit(); } None => { - tcx.node_span_lint( - UNSUPPORTED_CALLING_CONVENTIONS, - hir_id, - span, - "use of calling convention not supported on this target", - |_| {}, - ); + tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message("use of calling convention not supported on this target"); + }); } } @@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { UNINHABITED_STATIC, tcx.local_def_id_to_hir_id(def_id), span, - "static of uninhabited type", |lint| { + lint.primary_message("static of uninhabited type"); lint .note("uninhabited statics cannot be initialized, and any access would be an immediate error"); }, @@ -1315,9 +1311,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, tcx.local_def_id_to_hir_id(adt.did().expect_local()), span, - "zero-sized fields in `repr(transparent)` cannot \ - contain external non-exhaustive types", |lint| { + lint.primary_message( + "zero-sized fields in `repr(transparent)` cannot \ + contain external non-exhaustive types", + ); let note = if non_exhaustive { "is marked with `#[non_exhaustive]`" } else { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b09de1a4a098..2672614a8954 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint::builtin::ASM_SUB_REGISTER, expr.hir_id, spans, - "formatting may not be suitable for sub-register argument", |lint| { + lint.primary_message("formatting may not be suitable for sub-register argument"); lint.span_label(expr.span, "for this argument"); lint.help(format!( "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)", diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index aa5db4f6aa7b..ed23dc2a827b 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { continue; } let (path, _) = item.expect_use(); - let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { - format!("unused import: `{snippet}`") - } else { - "unused import".to_owned() - }; - tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {}); + tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| { + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { + lint.primary_message(format!("unused import: `{snippet}`")); + } else { + lint.primary_message("unused import"); + } + }); } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 6b41f79cf1e7..abdf85ad707b 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { lint::builtin::INVALID_TYPE_PARAM_DEFAULT, param.hir_id, param.span, - TYPE_DEFAULT_NOT_ALLOWED, - |_| {}, + |lint| { + lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED); + }, ); } Defaults::Deny => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 749f78e79201..7b67030836d1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].hir_id(), multispan, - msg, - |_| {}, + |lint| { + lint.primary_message(msg); + }, ); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index d9d36f5299b5..997db338a43f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag); diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { - let msg = "trait objects without an explicit `dyn` are deprecated"; - tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { + tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| { + lint.primary_message("trait objects without an explicit `dyn` are deprecated"); if self_ty.span.can_be_used_for_suggestions() { lint.multipart_suggestion_verbose( "if this is an object-safe trait, use `dyn`", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 8caeb85204b7..c0da9941dc12 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1164,33 +1164,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound); if let Some(variant_def_id) = variant_resolution { - tcx.node_span_lint( - AMBIGUOUS_ASSOCIATED_ITEMS, - hir_ref_id, - span, - "ambiguous associated item", - |lint| { - let mut could_refer_to = |kind: DefKind, def_id, also| { - let note_msg = format!( - "`{}` could{} refer to the {} defined here", - assoc_ident, - also, - tcx.def_kind_descr(kind, def_id) - ); - lint.span_note(tcx.def_span(def_id), note_msg); - }; - - could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(DefKind::AssocTy, assoc_ty_did, " also"); - - lint.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), - Applicability::MachineApplicable, + tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { + lint.primary_message("ambiguous associated item"); + let mut could_refer_to = |kind: DefKind, def_id, also| { + let note_msg = format!( + "`{}` could{} refer to the {} defined here", + assoc_ident, + also, + tcx.def_kind_descr(kind, def_id) ); - }, - ); + lint.span_note(tcx.def_span(def_id), note_msg); + }; + + could_refer_to(DefKind::Variant, variant_def_id, ""); + could_refer_to(DefKind::AssocTy, assoc_ty_did, " also"); + + lint.span_suggestion( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), + Applicability::MachineApplicable, + ); + }); } Ok((ty, DefKind::AssocTy, assoc_ty_did)) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 77f90c0c1310..301ebe685d92 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -63,19 +63,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); let msg = format!("unreachable {kind}"); - self.tcx().node_span_lint( - lint::builtin::UNREACHABLE_CODE, - id, - span, - msg.clone(), - |lint| { - lint.span_label(span, msg).span_label( - orig_span, - custom_note - .unwrap_or("any code following this expression is unreachable"), - ); - }, - ) + self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { + lint.primary_message(msg.clone()); + lint.span_label(span, msg).span_label( + orig_span, + custom_note.unwrap_or("any code following this expression is unreachable"), + ); + }) } } } diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index e9eab6969b34..3ee10f74d98a 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -91,11 +91,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, self_expr.hir_id, self_expr.span, - format!( - "trait method `{}` will become ambiguous in Rust {edition}", - segment.ident.name - ), |lint| { + lint.primary_message(format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + )); + let sp = self_expr.span; let derefs = "*".repeat(pick.autoderefs); @@ -144,11 +145,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, call_expr.hir_id, call_expr.span, - format!( - "trait method `{}` will become ambiguous in Rust {edition}", - segment.ident.name - ), |lint| { + lint.primary_message(format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + )); + let sp = call_expr.span; let trait_name = self.trait_path_or_bare_name( span, @@ -251,73 +253,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.tcx.node_span_lint( - RUST_2021_PRELUDE_COLLISIONS, - expr_id, - span, - format!( + self.tcx.node_span_lint(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| { + lint.primary_message(format!( "trait-associated function `{}` will become ambiguous in Rust 2021", method_name.name - ), - |lint| { - // "type" refers to either a type or, more likely, a trait from which - // the associated function or method is from. - let container_id = pick.item.container_id(self.tcx); - let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); - let trait_generics = self.tcx.generics_of(container_id); + )); - let trait_name = - if trait_generics.own_params.len() <= trait_generics.has_self as usize { - trait_path - } else { - let counts = trait_generics.own_counts(); - format!( - "{}<{}>", - trait_path, + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let container_id = pick.item.container_id(self.tcx); + let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); + let trait_generics = self.tcx.generics_of(container_id); + + let trait_name = + if trait_generics.own_params.len() <= trait_generics.has_self as usize { + trait_path + } else { + let counts = trait_generics.own_counts(); + format!( + "{}<{}>", + trait_path, + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain(std::iter::repeat("_").take( + counts.types + counts.consts - trait_generics.has_self as usize + )) + .collect::>() + .join(", ") + ) + }; + + let mut self_ty_name = self_ty_span + .find_ancestor_inside(span) + .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) + .unwrap_or_else(|| self_ty.to_string()); + + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + if !self_ty_name.contains('<') { + if let ty::Adt(def, _) = self_ty.kind() { + let generics = self.tcx.generics_of(def.did()); + if !generics.is_own_empty() { + let counts = generics.own_counts(); + self_ty_name += &format!( + "<{}>", std::iter::repeat("'_") .take(counts.lifetimes) - .chain(std::iter::repeat("_").take( - counts.types + counts.consts - trait_generics.has_self as usize - )) + .chain(std::iter::repeat("_").take(counts.types + counts.consts)) .collect::>() .join(", ") - ) - }; - - let mut self_ty_name = self_ty_span - .find_ancestor_inside(span) - .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) - .unwrap_or_else(|| self_ty.to_string()); - - // Get the number of generics the self type has (if an Adt) unless we can determine that - // the user has written the self type with generics already which we (naively) do by looking - // for a "<" in `self_ty_name`. - if !self_ty_name.contains('<') { - if let ty::Adt(def, _) = self_ty.kind() { - let generics = self.tcx.generics_of(def.did()); - if !generics.is_own_empty() { - let counts = generics.own_counts(); - self_ty_name += &format!( - "<{}>", - std::iter::repeat("'_") - .take(counts.lifetimes) - .chain( - std::iter::repeat("_").take(counts.types + counts.consts) - ) - .collect::>() - .join(", ") - ); - } + ); } } - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); - }, - ); + } + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + }); } fn trait_path_or_bare_name( diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e0a60337c3ba..4d33f7e237e3 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -408,8 +408,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - "type annotations needed", - |_| {}, + |lint| { + lint.primary_message("type annotations needed"); + }, ); } else { // Ended up encountering a type variable when doing autoderef, @@ -1279,53 +1280,49 @@ impl<'tcx> Pick<'tcx> { return; } let def_kind = self.item.kind.as_def_kind(); - tcx.node_span_lint( - lint::builtin::UNSTABLE_NAME_COLLISIONS, - scope_expr_id, - span, - format!( + tcx.node_span_lint(lint::builtin::UNSTABLE_NAME_COLLISIONS, scope_expr_id, span, |lint| { + lint.primary_message(format!( "{} {} with this name may be added to the standard library in the future", tcx.def_kind_descr_article(def_kind, self.item.def_id), tcx.def_kind_descr(def_kind, self.item.def_id), - ), - |lint| { - match (self.item.kind, self.item.container) { - (ty::AssocKind::Fn, _) => { - // FIXME: This should be a `span_suggestion` instead of `help` - // However `self.span` only - // highlights the method name, so we can't use it. Also consider reusing - // the code from `report_method_error()`. - lint.help(format!( - "call with fully qualified syntax `{}(...)` to keep using the current \ + )); + + match (self.item.kind, self.item.container) { + (ty::AssocKind::Fn, _) => { + // FIXME: This should be a `span_suggestion` instead of `help` + // However `self.span` only + // highlights the method name, so we can't use it. Also consider reusing + // the code from `report_method_error()`. + lint.help(format!( + "call with fully qualified syntax `{}(...)` to keep using the current \ method", - tcx.def_path_str(self.item.def_id), - )); - } - (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { - let def_id = self.item.container_id(tcx); - lint.span_suggestion( - span, - "use the fully qualified path to the associated const", - format!( - "<{} as {}>::{}", - self.self_ty, - tcx.def_path_str(def_id), - self.item.name - ), - Applicability::MachineApplicable, - ); - } - _ => {} + tcx.def_path_str(self.item.def_id), + )); } - tcx.disabled_nightly_features( - lint, - Some(scope_expr_id), - self.unstable_candidates.iter().map(|(candidate, feature)| { - (format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature) - }), - ); - }, - ); + (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { + let def_id = self.item.container_id(tcx); + lint.span_suggestion( + span, + "use the fully qualified path to the associated const", + format!( + "<{} as {}>::{}", + self.self_ty, + tcx.def_path_str(def_id), + self.item.name + ), + Applicability::MachineApplicable, + ); + } + _ => {} + } + tcx.disabled_nightly_features( + lint, + Some(scope_expr_id), + self.unstable_candidates.iter().map(|(candidate, feature)| { + (format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature) + }), + ); + }); } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b9b220d5af8e..b37aba386196 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1950,15 +1950,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &unmentioned_fields.iter().map(|(_, i)| i).collect::>(), ); - self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| { - lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); - lint.help( - "ensure that all fields are mentioned explicitly by adding the suggested fields", - ); - lint.note(format!( - "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", - )); - }); + self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |lint| { + lint.primary_message("some fields are not explicitly listed"); + lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); + lint.help( + "ensure that all fields are mentioned explicitly by adding the suggested fields", + ); + lint.note(format!( + "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", + )); + }); } /// Returns a diagnostic reporting a struct pattern which does not mention some fields. diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 9d16f0d48159..89ac33dcfc02 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -928,8 +928,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_hir_id, closure_head_span, - reasons.migration_message(), |lint| { + lint.primary_message(reasons.migration_message()); + for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations { // Labels all the usage of the captured variable and why they are responsible // for migration being needed diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index deeb3ae090c5..34b84658dc0b 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -21,7 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::def::Res; @@ -556,7 +556,6 @@ pub trait LintContext { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ); @@ -568,8 +567,8 @@ pub trait LintContext { span: S, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - self.opt_span_lint(lint, Some(span), decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.opt_span_lint(lint, Some(span), |lint| { + decorator.decorate_lint(lint); }); } @@ -581,17 +580,16 @@ pub trait LintContext { &self, lint: &'static Lint, span: S, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { - self.opt_span_lint(lint, Some(span), msg, decorate); + self.opt_span_lint(lint, Some(span), decorate); } /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) { - self.opt_span_lint(lint, None as Option, decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.opt_span_lint(lint, None as Option, |lint| { + decorator.decorate_lint(lint); }); } @@ -599,13 +597,8 @@ pub trait LintContext { /// /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature #[rustc_lint_diagnostics] - fn lint( - &self, - lint: &'static Lint, - msg: impl Into, - decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), - ) { - self.opt_span_lint(lint, None as Option, msg, decorate); + fn lint(&self, lint: &'static Lint, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)) { + self.opt_span_lint(lint, None as Option, decorate); } /// This returns the lint level for the given lint at the current location. @@ -668,14 +661,13 @@ impl<'tcx> LintContext for LateContext<'tcx> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; match span { - Some(s) => self.tcx.node_span_lint(lint, hir_id, s, msg, decorate), - None => self.tcx.node_lint(lint, hir_id, msg, decorate), + Some(s) => self.tcx.node_span_lint(lint, hir_id, s, decorate), + None => self.tcx.node_lint(lint, hir_id, decorate), } } @@ -695,10 +687,9 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { - self.builder.opt_span_lint(lint, span.map(|s| s.into()), msg, decorate) + self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate) } fn get_lint_level(&self, lint: &'static Lint) -> Level { diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 30bf80b915b8..ca3e1ee06d94 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -369,6 +369,7 @@ struct ImplTraitOvercapturesLint<'tcx> { impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::lint_impl_trait_overcaptures); diag.arg("self_ty", self.self_ty.to_string()) .arg("num_captured", self.num_captured) .span_note(self.uncaptured_spans, fluent::lint_note) @@ -382,10 +383,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { ); } } - - fn msg(&self) -> rustc_errors::DiagMessage { - fluent::lint_impl_trait_overcaptures - } } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 12b3d1d2f9e4..5d0656865461 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -16,7 +16,7 @@ use crate::{ use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::{Features, GateIssue}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; @@ -1063,26 +1063,19 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // FIXME: make this translatable #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] - lint_level( - self.sess, - lint, - level, - src, - Some(span.into()), - fluent::lint_unknown_gated_lint, - |lint| { - lint.arg("name", lint_id.lint.name_lower()); - lint.note(fluent::lint_note); - rustc_session::parse::add_feature_diagnostics_for_issue( - lint, - &self.sess, - feature, - GateIssue::Language, - lint_from_cli, - None, - ); - }, - ); + lint_level(self.sess, lint, level, src, Some(span.into()), |lint| { + lint.primary_message(fluent::lint_unknown_gated_lint); + lint.arg("name", lint_id.lint.name_lower()); + lint.note(fluent::lint_note); + rustc_session::parse::add_feature_diagnostics_for_issue( + lint, + &self.sess, + feature, + GateIssue::Language, + lint_from_cli, + None, + ); + }); } false @@ -1103,11 +1096,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, span, msg, decorate) + lint_level(self.sess, lint, level, src, span, decorate) } #[track_caller] @@ -1118,7 +1110,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { decorate: impl for<'a> LintDiagnostic<'a, ()>, ) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| { + lint_level(self.sess, lint, level, src, Some(span), |lint| { decorate.decorate_lint(lint); }); } @@ -1126,7 +1118,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { #[track_caller] pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { + lint_level(self.sess, lint, level, src, None, |lint| { decorate.decorate_lint(lint); }); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3bd6faca3796..4b1626ca5560 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -145,12 +145,9 @@ pub struct BuiltinMissingDebugImpl<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::lint_builtin_missing_debug_impl); diag.arg("debug", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_builtin_missing_debug_impl - } } #[derive(LintDiagnostic)] @@ -250,6 +247,7 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_ungated_async_fn_track_caller); diag.span_label(self.label, fluent::lint_label); rustc_session::parse::add_feature_diagnostics( diag, @@ -257,10 +255,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { sym::async_fn_track_caller, ); } - - fn msg(&self) -> DiagMessage { - fluent::lint_ungated_async_fn_track_caller - } } #[derive(LintDiagnostic)] @@ -432,6 +426,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(self.msg); diag.arg("ty", self.ty); diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { @@ -443,10 +438,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { } self.sub.add_to_diag(diag); } - - fn msg(&self) -> DiagMessage { - self.msg.clone() - } } // FIXME(davidtwco): make translatable @@ -1168,6 +1159,7 @@ pub struct NonFmtPanicUnused { // Used because of two suggestions based on one Option impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_non_fmt_panic_unused); diag.arg("count", self.count); diag.note(fluent::lint_note); if let Some(span) = self.suggestion { @@ -1185,10 +1177,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { ); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_non_fmt_panic_unused - } } #[derive(LintDiagnostic)] @@ -1410,13 +1398,10 @@ pub struct DropTraitConstraintsDiag<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_drop_trait_constraints); diag.arg("predicate", self.predicate); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_drop_trait_constraints - } } pub struct DropGlue<'a> { @@ -1427,12 +1412,9 @@ pub struct DropGlue<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_drop_glue); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_drop_glue - } } // types.rs @@ -1710,6 +1692,7 @@ pub struct ImproperCTypes<'a> { // Used because of the complexity of Option, DiagMessage, and Option impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_improper_ctypes); diag.arg("ty", self.ty); diag.arg("desc", self.desc); diag.span_label(self.label, fluent::lint_label); @@ -1721,10 +1704,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { diag.span_note(note, fluent::lint_note); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_improper_ctypes - } } #[derive(LintDiagnostic)] @@ -1853,6 +1832,7 @@ pub enum UnusedDefSuggestion { // Needed because of def_path_str impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_unused_def); diag.arg("pre", self.pre); diag.arg("post", self.post); diag.arg("def", self.cx.tcx.def_path_str(self.def_id)); @@ -1864,10 +1844,6 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { diag.subdiagnostic(diag.dcx, sugg); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_unused_def - } } #[derive(LintDiagnostic)] @@ -1936,15 +1912,12 @@ pub struct AsyncFnInTraitDiag { impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_async_fn_in_trait); diag.note(fluent::lint_note); if let Some(sugg) = self.sugg { diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_async_fn_in_trait - } } #[derive(LintDiagnostic)] @@ -2260,10 +2233,8 @@ pub struct UnstableFeature { } impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { - fn decorate_lint<'b>(self, _diag: &'b mut Diag<'a, ()>) {} - - fn msg(&self) -> DiagMessage { - self.msg.clone() + fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(self.msg); } } @@ -2725,12 +2696,9 @@ pub struct AmbiguousGlobImports { impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(self.ambiguity.msg.clone()); rustc_errors::report_ambiguity_error(diag, self.ambiguity); } - - fn msg(&self) -> DiagMessage { - DiagMessage::Str(self.ambiguity.msg.clone().into()) - } } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index a6057afcbd6b..c9d678541123 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -123,7 +123,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } #[allow(rustc::diagnostic_outside_of_impl)] - cx.span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| { + cx.span_lint(NON_FMT_PANICS, arg_span, |lint| { + lint.primary_message(fluent::lint_non_fmt_panic); lint.arg("name", symbol); lint.note(fluent::lint_note); lint.note(fluent::lint_more_info_note); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 9d21d88165e0..ef6005283d6b 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -105,25 +105,12 @@ impl<'a> LintDiagnosticDerive<'a> { pub(crate) fn into_tokens(self) -> TokenStream { let LintDiagnosticDerive { mut structure } = self; let kind = DiagnosticDeriveKind::LintDiagnostic; + let slugs = RefCell::new(Vec::new()); let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); - let formatting_init = &builder.formatting_init; - quote! { - #preamble - #formatting_init - #body - diag - } - }); - - let slugs = RefCell::new(Vec::new()); - let msg = kind.each_variant(&mut structure, |mut builder, variant| { - // Collect the slug by generating the preamble. - let _ = builder.preamble(variant); - - match builder.slug.value_ref() { + let primary_message = match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") .help( @@ -146,9 +133,18 @@ impl<'a> LintDiagnosticDerive<'a> { Some(slug) => { slugs.borrow_mut().push(slug.clone()); quote! { - crate::fluent_generated::#slug.into() + diag.primary_message(crate::fluent_generated::#slug); } } + }; + + let formatting_init = &builder.formatting_init; + quote! { + #primary_message + #preamble + #formatting_init + #body + diag } }); @@ -161,10 +157,6 @@ impl<'a> LintDiagnosticDerive<'a> { ) { #implementation; } - - fn msg(&self) -> rustc_errors::DiagMessage { - #msg - } } }); for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 086582e60a3c..1e374715fd09 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -2,7 +2,7 @@ use std::cmp; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_errors::{Diag, DiagMessage, MultiSpan}; +use rustc_errors::{Diag, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; use rustc_macros::HashStable; use rustc_session::lint::{ @@ -269,7 +269,6 @@ pub fn lint_level( level: Level, src: LintLevelSource, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to @@ -281,7 +280,6 @@ pub fn lint_level( level: Level, src: LintLevelSource, span: Option, - msg: impl Into, decorate: Box FnOnce(&'b mut Diag<'a, ()>)>, ) { // Check for future incompatibility lints and issue a stronger warning. @@ -350,10 +348,6 @@ pub fn lint_level( } } - // Delay evaluating and setting the primary message until after we've - // suppressed the lint due to macros. - err.primary_message(msg); - err.is_lint(lint.name_lower(), has_future_breakage); // Lint diagnostics that are covered by the expect level will not be emitted outside @@ -418,7 +412,7 @@ pub fn lint_level( explain_lint_level_source(lint, level, src, &mut err); err.emit() } - lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate)) + lint_level_impl(sess, lint, level, src, span, Box::new(decorate)) } /// Returns whether `span` originates in a foreign crate's external macro. diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index e5df05763b02..30f93577b7fa 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -156,6 +156,13 @@ pub struct Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(match &self.since_kind { + DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated, + DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future, + DeprecatedSinceKind::InVersion(_) => { + crate::fluent_generated::middle_deprecated_in_version + } + }); diag.arg("kind", self.kind); diag.arg("path", self.path); if let DeprecatedSinceKind::InVersion(version) = self.since_kind { @@ -171,16 +178,6 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate diag.subdiagnostic(diag.dcx, sub); } } - - fn msg(&self) -> rustc_errors::DiagMessage { - match &self.since_kind { - DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated, - DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future, - DeprecatedSinceKind::InVersion(_) => { - crate::fluent_generated::middle_deprecated_in_version - } - } - } } fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind { @@ -597,7 +594,9 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: String| { - self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {}) + self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { + lint.primary_message(msg); + }) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 04d6301116ee..9addf937f94b 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -112,8 +112,7 @@ impl<'tcx> TyCtxt<'tcx> { lint::builtin::CONST_EVALUATABLE_UNCHECKED, self.local_def_id_to_hir_id(local_def_id), self.def_span(ct.def), - "cannot use constants which depend on generic parameters in types", - |_| {}, + |lint| { lint.primary_message("cannot use constants which depend on generic parameters in types"); }, ) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8185c99c2fd2..eaa969a90f8a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -48,9 +48,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work #[cfg(parallel_compiler)] use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{ - Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan, -}; +use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; @@ -2475,10 +2473,9 @@ impl<'tcx> TyCtxt<'tcx> { span: impl Into, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - let msg = decorator.msg(); let (level, src) = self.lint_level_at_node(lint, hir_id); - lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { - decorator.decorate_lint(diag); + lint_level(self.sess, lint, level, src, Some(span.into()), |lint| { + decorator.decorate_lint(lint); }) } @@ -2492,11 +2489,10 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, hir_id: HirId, span: impl Into, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); - lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); + lint_level(self.sess, lint, level, src, Some(span.into()), decorate); } /// Find the crate root and the appropriate span where `use` and outer attributes can be @@ -2547,8 +2543,8 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - self.node_lint(lint, id, decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.node_lint(lint, id, |lint| { + decorator.decorate_lint(lint); }) } @@ -2561,11 +2557,10 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, id: HirId, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); - lint_level(self.sess, lint, level, src, None, msg, decorate); + lint_level(self.sess, lint, level, src, None, decorate); } pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 0634e321ea30..b28dcb38cb6b 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic}; +use rustc_errors::{codes::*, Diag, LintDiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; @@ -50,18 +50,15 @@ pub(crate) enum AssertLintKind { impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint

{ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - let message = self.assert_kind.diagnostic_message(); + diag.primary_message(match self.lint_kind { + AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, + AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, + }); + let label = self.assert_kind.diagnostic_message(); self.assert_kind.add_args(&mut |name, value| { diag.arg(name, value); }); - diag.span_label(self.span, message); - } - - fn msg(&self) -> DiagMessage { - match self.lint_kind { - AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, - AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, - } + diag.span_label(self.span, label); } } @@ -104,6 +101,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::mir_transform_must_not_suspend); diag.span_label(self.yield_sp, fluent::_subdiag::label); if let Some(reason) = self.reason { diag.subdiagnostic(diag.dcx, reason); @@ -113,10 +111,6 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { diag.arg("def_path", self.tcx.def_path_str(self.def_id)); diag.arg("post", self.post); } - - fn msg(&self) -> rustc_errors::DiagMessage { - fluent::mir_transform_must_not_suspend - } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index 1d10c9df4ab2..892aacd7ac5d 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -99,7 +99,6 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>( use rustc_errors::LintDiagnostic; let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, ""); - err.primary_message(decorator.msg()); decorator.decorate_lint(&mut err); err.emit(); } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8ce1271fc17a..f4051561dae4 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,7 @@ use super::elaborate; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use rustc_errors::{DelayDm, FatalError, MultiSpan}; +use rustc_errors::{FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; @@ -162,41 +162,36 @@ fn lint_object_unsafe_trait( ) { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.node_span_lint( - WHERE_CLAUSES_OBJECT_SAFETY, - hir::CRATE_HIR_ID, - span, - DelayDm(|| format!("the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id))), - |err| { - let node = tcx.hir().get_if_local(trait_def_id); - let mut spans = MultiSpan::from_span(span); - if let Some(hir::Node::Item(item)) = node { - spans.push_span_label( - item.ident.span, - "this trait cannot be made into an object...", - ); - spans.push_span_label(span, format!("...because {}", violation.error_msg())); - } else { - spans.push_span_label( - span, - format!( - "the trait cannot be made into an object because {}", - violation.error_msg() - ), - ); - }; - err.span_note( - spans, - "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ + tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| { + err.primary_message(format!( + "the trait `{}` cannot be made into an object", + tcx.def_path_str(trait_def_id) + )); + let node = tcx.hir().get_if_local(trait_def_id); + let mut spans = MultiSpan::from_span(span); + if let Some(hir::Node::Item(item)) = node { + spans.push_span_label(item.ident.span, "this trait cannot be made into an object..."); + spans.push_span_label(span, format!("...because {}", violation.error_msg())); + } else { + spans.push_span_label( + span, + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ), + ); + }; + err.span_note( + spans, + "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ call to be resolvable dynamically; for more information visit \ ", - ); - if node.is_some() { - // Only provide the help if its a local trait, otherwise it's not - violation.solution().add_to(err); - } - }, - ); + ); + if node.is_some() { + // Only provide the help if its a local trait, otherwise it's not + violation.solution().add_to(err); + } + }); } fn sized_trait_bound_spans<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 826bb706f48b..c2727ae6bfd9 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -21,7 +21,7 @@ use crate::traits::{ self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, }; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee}; +use rustc_errors::{codes::*, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; @@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>( } } - let msg = DelayDm(|| { + let msg = || { format!( "conflicting implementations of trait `{}`{}{}", overlap.trait_ref.print_trait_sugared(), @@ -459,7 +459,7 @@ fn report_conflicting_impls<'tcx>( _ => "", } ) - }); + }; // Don't report overlap errors if the header references error if let Err(err) = (overlap.trait_ref, overlap.self_ty).error_reported() { @@ -471,7 +471,7 @@ fn report_conflicting_impls<'tcx>( let reported = if overlap.with_impl.is_local() || tcx.ensure().orphan_check_impl(impl_def_id).is_ok() { - let mut err = tcx.dcx().struct_span_err(impl_span, msg); + let mut err = tcx.dcx().struct_span_err(impl_span, msg()); err.code(E0119); decorate(tcx, &overlap, impl_span, &mut err); err.emit() @@ -485,15 +485,10 @@ fn report_conflicting_impls<'tcx>( FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS, FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; - tcx.node_span_lint( - lint, - tcx.local_def_id_to_hir_id(impl_def_id), - impl_span, - msg, - |err| { - decorate(tcx, &overlap, impl_span, err); - }, - ); + tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| { + err.primary_message(msg()); + decorate(tcx, &overlap, impl_span, err); + }); Ok(()) } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index feb03b9a823e..4b132cf60d3b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -372,8 +372,8 @@ pub(crate) fn run_global_ctxt( tcx.node_lint( crate::lint::MISSING_CRATE_LEVEL_DOCS, DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), - "no documentation found for this crate's top-level module", |lint| { + lint.primary_message("no documentation found for this crate's top-level module"); lint.help(help); }, ); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5c5651f3ef0e..362f9021671f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -834,8 +834,9 @@ impl<'tcx> ExtraInfo<'tcx> { crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, self.tcx.local_def_id_to_hir_id(def_id), self.sp, - msg, - |_| {}, + |lint| { + lint.primary_message(msg); + }, ); } } @@ -850,8 +851,10 @@ impl<'tcx> ExtraInfo<'tcx> { crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, self.tcx.local_def_id_to_hir_id(def_id), self.sp, - msg, - f, + |lint| { + lint.primary_message(msg); + f(lint); + }, ); } } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index e85b998bfbe1..257bab3e9fcb 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -125,13 +125,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item if should_have_doc_example(cx, item) { debug!("reporting error for {item:?} (hir_id={hir_id:?})"); let sp = item.attr_span(cx.tcx); - cx.tcx.node_span_lint( - crate::lint::MISSING_DOC_CODE_EXAMPLES, - hir_id, - sp, - "missing code example in this documentation", - |_| {}, - ); + cx.tcx.node_span_lint(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, |lint| { + lint.primary_message("missing code example in this documentation"); + }); } } else if tests.found_tests > 0 && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id()) @@ -140,8 +136,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - "documentation test in private item", - |_| {}, + |lint| { + lint.primary_message("documentation test in private item"); + }, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 747f5c0a8356..8ab24a8c12e5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1689,7 +1689,9 @@ fn report_diagnostic( let sp = item.attr_span(tcx); - tcx.node_span_lint(lint, hir_id, sp, msg, |lint| { + tcx.node_span_lint(lint, hir_id, sp, |lint| { + lint.primary_message(msg); + let (span, link_range) = match link_range { MarkdownLinkRange::Destination(md_range) => { let mut md_range = md_range.clone(); diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index c6989fbbf255..8f68f6ff4764 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -24,8 +24,9 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) .unwrap_or_else(|| item.attr_span(cx.tcx)); - cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| { - lint.note("bare URLs are not automatically turned into clickable links") + cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| { + lint.primary_message(msg) + .note("bare URLs are not automatically turned into clickable links") .span_suggestion( sp, "use an automatic link instead", diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 7b81b5e63be6..9562559fba26 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -99,7 +99,9 @@ fn check_rust_syntax( // All points of divergence have been handled earlier so this can be // done the same way whether the span is precise or not. let hir_id = cx.tcx.local_def_id_to_hir_id(local_id); - cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| { + cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, |lint| { + lint.primary_message(msg); + let explanation = if is_ignore { "`ignore` code blocks require valid Rust code for syntax highlighting; \ mark blocks that do not contain Rust code as text" diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index da3770aa927a..25b0c61b826f 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -25,8 +25,11 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { Some(sp) => sp, None => item.attr_span(tcx), }; - tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| { + tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| { use rustc_lint_defs::Applicability; + + lint.primary_message(msg); + // If a tag looks like ``, it might actually be a generic. // We don't try to detect stuff `` because that's not valid HTML, // and we don't try to detect stuff `` because that's not valid Rust. diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 098860245951..7ab974046b9c 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -188,8 +188,9 @@ fn check_inline_or_reference_unknown_redundancy( &item.attrs.doc_strings, )?; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { - lint.span_label(explicit_span, "explicit target is redundant") + cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { + lint.primary_message("redundant explicit link target") + .span_label(explicit_span, "explicit target is redundant") .span_label(display_span, "because label contains path that resolves to same destination") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); @@ -238,8 +239,9 @@ fn check_reference_redundancy( &item.attrs.doc_strings, )?; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { - lint.span_label(explicit_span, "explicit target is redundant") + cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { + lint.primary_message("redundant explicit link target") + .span_label(explicit_span, "explicit target is redundant") .span_label(display_span, "because label contains path that resolves to same destination") .span_note(def_span, "referenced explicit link target defined here") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index 4ea926cb79aa..be9670077d17 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -56,17 +56,28 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { ) .unwrap_or_else(|| item.attr_span(tcx)); - tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| { + tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| { + lint.primary_message("unescaped backtick"); + let mut help_emitted = false; match element.prev_code_guess { PrevCodeGuess::None => {} PrevCodeGuess::Start { guess, .. } => { // "foo` `bar`" -> "`foo` `bar`" - if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + if let Some(suggest_index) = + clamp_start(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of a previous inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the opening backtick of a previous inline code may be missing", + ); help_emitted = true; } } @@ -76,7 +87,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { // an inline code node and we intentionally "break" the inline code here. let suggest_index = guess; if can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "a previous inline code might be longer than expected"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "a previous inline code might be longer than expected", + ); help_emitted = true; } } @@ -84,11 +103,21 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { if !element.prev_code_guess.is_confident() { // "`foo` bar`" -> "`foo` `bar`" - if let Some(guess) = guess_start_of_code(&dox, element.element_range.start..backtick_index) - && let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + if let Some(guess) = + guess_start_of_code(&dox, element.element_range.start..backtick_index) + && let Some(suggest_index) = + clamp_start(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of an inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the opening backtick of an inline code may be missing", + ); help_emitted = true; } @@ -96,21 +125,41 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { // Don't suggest closing backtick after single trailing char, // if we already suggested opening backtick. For example: // "foo`." -> "`foo`." or "foo`s" -> "`foo`s". - if let Some(guess) = guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) - && let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges) + if let Some(guess) = + guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) + && let Some(suggest_index) = + clamp_end(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) && (!help_emitted || suggest_index - backtick_index > 2) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the closing backtick of an inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the closing backtick of an inline code may be missing", + ); help_emitted = true; } } if !help_emitted { - lint.help("the opening or closing backtick of an inline code may be missing"); + lint.help( + "the opening or closing backtick of an inline code may be missing", + ); } - suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); + suggest_insertion( + cx, + item, + &dox, + lint, + backtick_index, + '\\', + "if you meant to use a literal backtick, escape it", + ); }); } Event::Code(_) => { diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index dc0a139e3c78..0641d37cd9a6 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -61,7 +61,8 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) { /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: impl Into) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, sp, msg.into(), |diag| { + cx.span_lint(lint, sp, |diag| { + diag.primary_message(msg); docs_link(diag, lint); }); } @@ -109,7 +110,8 @@ pub fn span_lint_and_help( help: impl Into, ) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, span, msg.into(), |diag| { + cx.span_lint(lint, span, |diag| { + diag.primary_message(msg); if let Some(help_span) = help_span { diag.span_help(help_span, help.into()); } else { @@ -165,7 +167,8 @@ pub fn span_lint_and_note( note: impl Into, ) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, span, msg.into(), |diag| { + cx.span_lint(lint, span, |diag| { + diag.primary_message(msg); if let Some(note_span) = note_span { diag.span_note(note_span, note.into()); } else { @@ -201,7 +204,8 @@ where F: FnOnce(&mut Diag<'_, ()>), { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, sp, msg, |diag| { + cx.span_lint(lint, sp, |diag| { + diag.primary_message(msg); f(diag); docs_link(diag, lint); }); @@ -233,7 +237,8 @@ where /// the `#[allow]` will work. pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into) { #[expect(clippy::disallowed_methods)] - cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, |diag| { + diag.primary_message(msg); docs_link(diag, lint); }); } @@ -271,7 +276,8 @@ pub fn span_lint_hir_and_then( f: impl FnOnce(&mut Diag<'_, ()>), ) { #[expect(clippy::disallowed_methods)] - cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, |diag| { + diag.primary_message(msg); f(diag); docs_link(diag, lint); }); diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs index 5a2a868ed3ec..b91a83308b5f 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs @@ -11,11 +11,11 @@ use rustc_lint::{Lint, LintContext}; use rustc_middle::ty::TyCtxt; pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into, msg: impl Into) { - cx.span_lint(lint, span, msg, |_| {}); + cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); } pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into, msg: impl Into) { - tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); + tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); } fn main() {} diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr index cfc590bed369..1cfbc8efc8ed 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr @@ -1,8 +1,8 @@ error: use of a disallowed method `rustc_lint::context::LintContext::span_lint` --> tests/ui-internal/disallow_span_lint.rs:14:5 | -LL | cx.span_lint(lint, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead (from clippy.toml) = note: `-D clippy::disallowed-methods` implied by `-D warnings` @@ -11,8 +11,8 @@ LL | cx.span_lint(lint, span, msg, |_| {}); error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint` --> tests/ui-internal/disallow_span_lint.rs:18:5 | -LL | tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead (from clippy.toml) diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 380b2b6c431d..7c3a2c97474d 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -85,10 +85,6 @@ impl<'a> LintDiagnostic<'a, ()> for UntranslatableInLintDiagnostic { diag.note("untranslatable diagnostic"); //~^ ERROR diagnostics should be created using translatable messages } - - fn msg(&self) -> DiagMessage { - unreachable!(); - } } pub struct TranslatableInLintDiagnostic; @@ -97,10 +93,6 @@ impl<'a> LintDiagnostic<'a, ()> for TranslatableInLintDiagnostic { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.note(crate::fluent_generated::no_crate_note); } - - fn msg(&self) -> DiagMessage { - unreachable!(); - } } pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) { diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index ee5400f6f951..669324ce5d4c 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -23,7 +23,7 @@ LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:107:21 + --> $DIR/diagnostics.rs:99:21 | LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ @@ -35,13 +35,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:110:21 + --> $DIR/diagnostics.rs:102:21 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:110:21 + --> $DIR/diagnostics.rs:102:21 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 043c7c166540..4f50837d5fe4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -603,7 +603,6 @@ struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] #[lint(no_crate_example, code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnLintDiag {} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 1266430e2f77..e36c6852d3b2 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -378,14 +378,6 @@ error: `#[lint(...)]` is not a valid attribute LL | #[lint(no_crate_example, code = E0123)] | ^ -error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:604:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:604:1 | @@ -395,19 +387,19 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:614:53 + --> $DIR/diagnostic-derive.rs:613:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:614:39 + --> $DIR/diagnostic-derive.rs:613:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:623:24 + --> $DIR/diagnostic-derive.rs:622:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -415,7 +407,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:631:17 + --> $DIR/diagnostic-derive.rs:630:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -423,13 +415,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:638:5 + --> $DIR/diagnostic-derive.rs:637:5 | LL | #[suggestion(no_crate_suggestion)] | ^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:645:1 + --> $DIR/diagnostic-derive.rs:644:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -437,7 +429,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:648:1 + --> $DIR/diagnostic-derive.rs:647:1 | LL | #[multipart_suggestion()] | ^ @@ -445,7 +437,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:652:5 + --> $DIR/diagnostic-derive.rs:651:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -453,7 +445,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:660:1 + --> $DIR/diagnostic-derive.rs:659:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^ @@ -461,7 +453,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:669:1 + --> $DIR/diagnostic-derive.rs:668:1 | LL | #[label] | ^ @@ -469,61 +461,61 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:703:5 + --> $DIR/diagnostic-derive.rs:702:5 | LL | #[subdiagnostic(bad)] | ^ error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:711:5 + --> $DIR/diagnostic-derive.rs:710:5 | LL | #[subdiagnostic = "bad"] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:719:5 + --> $DIR/diagnostic-derive.rs:718:5 | LL | #[subdiagnostic(bad, bad)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:727:5 + --> $DIR/diagnostic-derive.rs:726:5 | LL | #[subdiagnostic("bad")] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:735:5 + --> $DIR/diagnostic-derive.rs:734:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:743:5 + --> $DIR/diagnostic-derive.rs:742:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:764:5 + --> $DIR/diagnostic-derive.rs:763:5 | LL | #[subdiagnostic(eager)] | ^ error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:795:23 + --> $DIR/diagnostic-derive.rs:794:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:803:23 + --> $DIR/diagnostic-derive.rs:802:23 | LL | #[suggestion(code(foo))] | ^^^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:827:5 + --> $DIR/diagnostic-derive.rs:826:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^ @@ -539,13 +531,13 @@ LL | #[diag = "E0123"] | ^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:803:23 + --> $DIR/diagnostic-derive.rs:802:23 | LL | #[suggestion(code(foo))] | ^^^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:812:25 + --> $DIR/diagnostic-derive.rs:811:25 | LL | #[suggestion(code = 3)] | ^ maybe a missing crate `core`? @@ -587,19 +579,19 @@ LL | #[lint(no_crate_example, code = E0123)] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:645:3 + --> $DIR/diagnostic-derive.rs:644:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:648:3 + --> $DIR/diagnostic-derive.rs:647:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:652:7 + --> $DIR/diagnostic-derive.rs:651:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -611,7 +603,7 @@ LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:809:10 + --> $DIR/diagnostic-derive.rs:808:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -632,7 +624,7 @@ note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 86 previous errors +error: aborting due to 85 previous errors Some errors have detailed explanations: E0277, E0425, E0433. For more information about an error, try `rustc --explain E0277`. From 9f67c50128f7ef57295c5f9b56e22031f4ed8d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 23 May 2024 03:50:43 +0200 Subject: [PATCH 042/101] Remove `DelayDm` With the removal of `LintDiagnostic::msg` / the `msg` param from lint diag APIs, primary messages for lint diags are always constructed lazily inside decorator fns rendering this wrapper type unused / useless. --- compiler/rustc_error_messages/src/lib.rs | 11 ----------- compiler/rustc_errors/src/lib.rs | 6 +++--- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ad82c2d96e7a..c04386c03f2f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -367,17 +367,6 @@ impl From> for DiagMessage { } } -/// A workaround for must_produce_diag ICEs when formatting types in disabled lints. -/// -/// Delays formatting until `.into(): DiagMessage` is used. -pub struct DelayDm(pub F); - -impl String> From> for DiagMessage { - fn from(DelayDm(f): DelayDm) -> Self { - DiagMessage::from(f()) - } -} - /// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but /// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagMessage` and the /// subdiagnostic derive refers to typed identifiers that are `DiagMessage`s, so need to be diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 3b884ff864ab..4dc5d84b318b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -39,7 +39,7 @@ pub use diagnostic_impls::{ }; pub use emitter::ColorConfig; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent_bundle, DelayDm, DiagMessage, FluentBundle, LanguageIdentifier, + fallback_fluent_bundle, fluent_bundle, DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, }; pub use rustc_lint_defs::{pluralize, Applicability}; @@ -572,8 +572,8 @@ impl Drop for DiagCtxtInner { if let Some(backtrace) = &self.must_produce_diag { panic!( "must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; \ - use `DelayDm` for lints or `with_no_trimmed_paths` for debugging. \ - called at: {backtrace}" + `with_no_trimmed_paths` for debugging. \ + called at: {backtrace}" ); } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0dbb17e9db44..cfe52980e1cc 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3327,7 +3327,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N /// /// The implementation uses similar import discovery logic to that of 'use' suggestions. /// -/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`]. +/// See also [`with_no_trimmed_paths!`]. // this is pub to be able to intra-doc-link it pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { // Trimming paths is expensive and not optimized, since we expect it to only be used for error From 37bf2d2dabdbdce9473b0fed1708fcbf31ba9c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 22 May 2024 17:03:25 +0200 Subject: [PATCH 043/101] Delay the construction of early lint diag structs Fixes a slew of perf regressions. --- compiler/rustc_lint/src/context.rs | 4 +- .../rustc_lint/src/context/diagnostics.rs | 379 +++++++----------- 2 files changed, 154 insertions(+), 229 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 34b84658dc0b..1a51f4f388d6 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -539,7 +539,9 @@ impl EarlyContext<'_> { span: MultiSpan, diagnostic: BuiltinLintDiag, ) { - diagnostics::emit_buffered_lint(self, lint, span, diagnostic) + self.opt_span_lint(lint, Some(span), |diag| { + diagnostics::decorate_lint(self.sess(), diagnostic, diag); + }); } } diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 236eeee61521..1d9365ab9683 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -4,23 +4,18 @@ use std::borrow::Cow; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::Applicability; -use rustc_errors::{elided_lifetime_in_path_suggestion, DiagArgValue, MultiSpan}; +use rustc_errors::elided_lifetime_in_path_suggestion; +use rustc_errors::{Applicability, Diag, DiagArgValue, LintDiagnostic}; use rustc_middle::middle::stability; -use rustc_session::lint::{BuiltinLintDiag, Lint}; +use rustc_session::lint::BuiltinLintDiag; +use rustc_session::Session; use rustc_span::BytePos; -use crate::{lints, EarlyContext, LintContext as _}; +use crate::lints; mod check_cfg; -pub(super) fn emit_buffered_lint( - ctx: &EarlyContext<'_>, - lint: &'static Lint, - span: MultiSpan, - diagnostic: BuiltinLintDiag, -) { - let sess = ctx.sess(); +pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { let spans: Vec<_> = content @@ -39,16 +34,14 @@ pub(super) fn emit_buffered_lint( let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { spans: spans.iter().map(|(_c, span)| *span).collect(), }); - ctx.emit_span_lint( - lint, - span, - lints::UnicodeTextFlow { - comment_span, - characters, - suggestions, - num_codepoints: spans.len(), - }, - ) + + lints::UnicodeTextFlow { + comment_span, + characters, + suggestions, + num_codepoints: spans.len(), + } + .decorate_lint(diag); } BuiltinLintDiag::AbsPathWithModule(mod_span) => { let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { @@ -61,48 +54,35 @@ pub(super) fn emit_buffered_lint( } Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), }; - ctx.emit_span_lint( - lint, - span, - lints::AbsPathWithModule { - sugg: lints::AbsPathWithModuleSugg { - span: mod_span, - applicability, - replacement, - }, - }, - ); + lints::AbsPathWithModule { + sugg: lints::AbsPathWithModuleSugg { span: mod_span, applicability, replacement }, + } + .decorate_lint(diag); } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => ctx - .emit_span_lint( - lint, - span, - lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident }, - ), - BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => ctx - .emit_span_lint( - lint, - span, - lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def }, - ), + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => { + lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } + .decorate_lint(diag) + } + BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { + lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def } + .decorate_lint(diag) + } + BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { - ctx.emit_span_lint( - lint, - span, - lints::ElidedLifetimesInPaths { - subdiag: elided_lifetime_in_path_suggestion( - sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), - }, - ); + lints::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + sess.source_map(), + n, + path_span, + incl_angl_brckt, + insertion_span, + ), + } + .decorate_lint(diag); } BuiltinLintDiag::UnknownCrateTypes { span, candidate } => { let sugg = candidate.map(|candidate| lints::UnknownCrateTypesSub { span, candidate }); - ctx.emit_span_lint(lint, span, lints::UnknownCrateTypes { sugg }); + lints::UnknownCrateTypes { sugg }.decorate_lint(diag); } BuiltinLintDiag::UnusedImports { remove_whole_use, @@ -119,18 +99,15 @@ pub(super) fn emit_buffered_lint( let test_module_span = test_module_span.map(|span| sess.source_map().guess_head_span(span)); - ctx.emit_span_lint( - lint, - span, - lints::UnusedImports { - sugg, - test_module_span, - num_snippets: span_snippets.len(), - span_snippets: DiagArgValue::StrListSepByAnd( - span_snippets.into_iter().map(Cow::Owned).collect(), - ), - }, - ); + lints::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImport(spans, ident) => { let subs = spans @@ -144,7 +121,7 @@ pub(super) fn emit_buffered_lint( })(span) }) .collect(); - ctx.emit_span_lint(lint, span, lints::RedundantImport { subs, ident }); + lints::RedundantImport { subs, ident }.decorate_lint(diag); } BuiltinLintDiag::DeprecatedMacro { suggestion, @@ -158,90 +135,63 @@ pub(super) fn emit_buffered_lint( kind: "macro".to_owned(), suggestion, }); - ctx.emit_span_lint( - lint, - span, - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }, - ); + + stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } + .decorate_lint(diag); } BuiltinLintDiag::UnusedDocComment(attr_span) => { - ctx.emit_span_lint(lint, span, lints::UnusedDocComment { span: attr_span }); + lints::UnusedDocComment { span: attr_span }.decorate_lint(diag); } BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - - ctx.emit_span_lint( - lint, - span, - if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - }, - ); + if is_foreign { + lints::PatternsInFnsWithoutBody::Foreign { sub } + } else { + lints::PatternsInFnsWithoutBody::Bodiless { sub } + } + .decorate_lint(diag); } BuiltinLintDiag::MissingAbi(label_span, default_abi) => { - ctx.emit_span_lint( - lint, - span, - lints::MissingAbi { span: label_span, default_abi: default_abi.name() }, - ); + lints::MissingAbi { span: label_span, default_abi: default_abi.name() } + .decorate_lint(diag); } BuiltinLintDiag::LegacyDeriveHelpers(label_span) => { - ctx.emit_span_lint(lint, span, lints::LegacyDeriveHelpers { span: label_span }); + lints::LegacyDeriveHelpers { span: label_span }.decorate_lint(diag); } BuiltinLintDiag::ProcMacroBackCompat { crate_name, fixed_version } => { - ctx.emit_span_lint( - lint, - span, - lints::ProcMacroBackCompat { crate_name, fixed_version }, - ); + lints::ProcMacroBackCompat { crate_name, fixed_version }.decorate_lint(diag); } BuiltinLintDiag::OrPatternsBackCompat(suggestion_span, suggestion) => { - ctx.emit_span_lint( - lint, - span, - lints::OrPatternsBackCompat { span: suggestion_span, suggestion }, - ); + lints::OrPatternsBackCompat { span: suggestion_span, suggestion }.decorate_lint(diag); } BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { - ctx.emit_span_lint( - lint, - span, - lints::ReservedPrefix { - label: label_span, - suggestion: label_span.shrink_to_hi(), - prefix, - }, - ); + lints::ReservedPrefix { + label: label_span, + suggestion: label_span.shrink_to_hi(), + prefix, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => { - ctx.emit_span_lint( - lint, - span, - lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }, - ); + lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag); } BuiltinLintDiag::TrailingMacro(is_trailing, name) => { - ctx.emit_span_lint(lint, span, lints::TrailingMacro { is_trailing, name }); + lints::TrailingMacro { is_trailing, name }.decorate_lint(diag); } BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { - ctx.emit_span_lint( - lint, - span, - lints::BreakWithLabelAndLoop { - sub: lints::BreakWithLabelAndLoopSub { - left: sugg_span.shrink_to_lo(), - right: sugg_span.shrink_to_hi(), - }, + lints::BreakWithLabelAndLoop { + sub: lints::BreakWithLabelAndLoopSub { + left: sugg_span.shrink_to_lo(), + right: sugg_span.shrink_to_hi(), }, - ); + } + .decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgName(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_name(sess, name, value)); + check_cfg::unexpected_cfg_name(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgValue(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_value(sess, name, value)); + check_cfg::unexpected_cfg_value(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { @@ -252,7 +202,7 @@ pub(super) fn emit_buffered_lint( }, None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, }; - ctx.emit_span_lint(lint, span, lints::DeprecatedWhereClauseLocation { suggestion }); + lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { param_span, @@ -279,15 +229,12 @@ pub(super) fn emit_buffered_lint( None }; - ctx.emit_span_lint( - lint, - span, - lints::SingleUseLifetime { suggestion, param_span, use_span, ident }, - ); + lints::SingleUseLifetime { suggestion, param_span, use_span, ident } + .decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { debug!(?deletion_span); - ctx.emit_span_lint(lint, span, lints::UnusedLifetime { deletion_span, ident }); + lints::UnusedLifetime { deletion_span, ident }.decorate_lint(diag); } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, @@ -315,35 +262,29 @@ pub(super) fn emit_buffered_lint( (None, String::new()) }; - ctx.emit_span_lint( - lint, - span, - lints::NamedArgumentUsedPositionally { - named_arg_sp, - position_label_sp: position_sp_for_msg, - suggestion, - name, - named_arg_name, - }, - ) + lints::NamedArgumentUsedPositionally { + named_arg_sp, + position_label_sp: position_sp_for_msg, + suggestion, + name, + named_arg_name, + } + .decorate_lint(diag); } BuiltinLintDiag::ByteSliceInPackedStructWithDerive { ty } => { - ctx.emit_span_lint(lint, span, lints::ByteSliceInPackedStructWithDerive { ty }) + lints::ByteSliceInPackedStructWithDerive { ty }.decorate_lint(diag); } BuiltinLintDiag::UnusedExternCrate { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedExternCrate { removal_span }) + lints::UnusedExternCrate { removal_span }.decorate_lint(diag); } BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span } => { let suggestion_span = vis_span.between(ident_span); let code = if vis_span.is_empty() { "use " } else { " use " }; - ctx.emit_span_lint( - lint, - span, - lints::ExternCrateNotIdiomatic { span: suggestion_span, code }, - ); + + lints::ExternCrateNotIdiomatic { span: suggestion_span, code }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => { - ctx.emit_span_lint(lint, span, lints::AmbiguousGlobImports { ambiguity }); + lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobReexports { name, @@ -351,16 +292,13 @@ pub(super) fn emit_buffered_lint( first_reexport_span, duplicate_reexport_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::AmbiguousGlobReexports { - first_reexport: first_reexport_span, - duplicate_reexport: duplicate_reexport_span, - name, - namespace, - }, - ); + lints::AmbiguousGlobReexports { + first_reexport: first_reexport_span, + duplicate_reexport: duplicate_reexport_span, + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::HiddenGlobReexports { name, @@ -368,127 +306,112 @@ pub(super) fn emit_buffered_lint( glob_reexport_span, private_item_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::HiddenGlobReexports { - glob_reexport: glob_reexport_span, - private_item: private_item_span, + lints::HiddenGlobReexports { + glob_reexport: glob_reexport_span, + private_item: private_item_span, - name, - namespace, - }, - ); + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedQualifications { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedQualifications { removal_span }); + lints::UnusedQualifications { removal_span }.decorate_lint(diag); } BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span } => { let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; let code = if elided { "'static " } else { "'static" }; - ctx.emit_span_lint( - lint, - span, - lints::AssociatedConstElidedLifetime { span: lt_span, code, elided }, - ); + lints::AssociatedConstElidedLifetime { span: lt_span, code, elided } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => { - ctx.emit_span_lint( - lint, - span, - lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }, - ); + lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis } + .decorate_lint(diag); } BuiltinLintDiag::UnknownDiagnosticAttribute { span: typo_span, typo_name } => { let typo = typo_name.map(|typo_name| lints::UnknownDiagnosticAttributeTypoSugg { span: typo_span, typo_name, }); - ctx.emit_span_lint(lint, span, lints::UnknownDiagnosticAttribute { typo }); + lints::UnknownDiagnosticAttribute { typo }.decorate_lint(diag); } BuiltinLintDiag::MacroUseDeprecated => { - ctx.emit_span_lint(lint, span, lints::MacroUseDeprecated) + lints::MacroUseDeprecated.decorate_lint(diag); } - BuiltinLintDiag::UnusedMacroUse => ctx.emit_span_lint(lint, span, lints::UnusedMacroUse), + BuiltinLintDiag::UnusedMacroUse => lints::UnusedMacroUse.decorate_lint(diag), BuiltinLintDiag::PrivateExternCrateReexport(ident) => { - ctx.emit_span_lint(lint, span, lints::PrivateExternCrateReexport { ident }) + lints::PrivateExternCrateReexport { ident }.decorate_lint(diag); } - BuiltinLintDiag::UnusedLabel => ctx.emit_span_lint(lint, span, lints::UnusedLabel), + BuiltinLintDiag::UnusedLabel => lints::UnusedLabel.decorate_lint(diag), BuiltinLintDiag::MacroIsPrivate(ident) => { - ctx.emit_span_lint(lint, span, lints::MacroIsPrivate { ident }) + lints::MacroIsPrivate { ident }.decorate_lint(diag); } BuiltinLintDiag::UnusedMacroDefinition(name) => { - ctx.emit_span_lint(lint, span, lints::UnusedMacroDefinition { name }) + lints::UnusedMacroDefinition { name }.decorate_lint(diag); } BuiltinLintDiag::MacroRuleNeverUsed(n, name) => { - ctx.emit_span_lint(lint, span, lints::MacroRuleNeverUsed { n: n + 1, name }) + lints::MacroRuleNeverUsed { n: n + 1, name }.decorate_lint(diag); } BuiltinLintDiag::UnstableFeature(msg) => { - ctx.emit_span_lint(lint, span, lints::UnstableFeature { msg }) + lints::UnstableFeature { msg }.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingIntelSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidIntelSyntax) + lints::AvoidIntelSyntax.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingAttSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidAttSyntax) + lints::AvoidAttSyntax.decorate_lint(diag); } BuiltinLintDiag::IncompleteInclude => { - ctx.emit_span_lint(lint, span, lints::IncompleteInclude) + lints::IncompleteInclude.decorate_lint(diag); } BuiltinLintDiag::UnnameableTestItems => { - ctx.emit_span_lint(lint, span, lints::UnnameableTestItems) + lints::UnnameableTestItems.decorate_lint(diag); } BuiltinLintDiag::DuplicateMacroAttribute => { - ctx.emit_span_lint(lint, span, lints::DuplicateMacroAttribute) + lints::DuplicateMacroAttribute.decorate_lint(diag); } BuiltinLintDiag::CfgAttrNoAttributes => { - ctx.emit_span_lint(lint, span, lints::CfgAttrNoAttributes) + lints::CfgAttrNoAttributes.decorate_lint(diag); } BuiltinLintDiag::CrateTypeInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateTypeInCfgAttr) + lints::CrateTypeInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::CrateNameInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateNameInCfgAttr) + lints::CrateNameInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::MissingFragmentSpecifier => { - ctx.emit_span_lint(lint, span, lints::MissingFragmentSpecifier) + lints::MissingFragmentSpecifier.decorate_lint(diag); } BuiltinLintDiag::MetaVariableStillRepeating(name) => { - ctx.emit_span_lint(lint, span, lints::MetaVariableStillRepeating { name }) + lints::MetaVariableStillRepeating { name }.decorate_lint(diag); } BuiltinLintDiag::MetaVariableWrongOperator => { - ctx.emit_span_lint(lint, span, lints::MetaVariableWrongOperator) + lints::MetaVariableWrongOperator.decorate_lint(diag); } BuiltinLintDiag::DuplicateMatcherBinding => { - ctx.emit_span_lint(lint, span, lints::DuplicateMatcherBinding) + lints::DuplicateMatcherBinding.decorate_lint(diag); } BuiltinLintDiag::UnknownMacroVariable(name) => { - ctx.emit_span_lint(lint, span, lints::UnknownMacroVariable { name }) + lints::UnknownMacroVariable { name }.decorate_lint(diag); } - BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => ctx.emit_span_lint( - lint, - span, - lints::UnusedCrateDependency { extern_crate, local_crate }, - ), - BuiltinLintDiag::WasmCAbi => ctx.emit_span_lint(lint, span, lints::WasmCAbi), - BuiltinLintDiag::IllFormedAttributeInput { suggestions } => ctx.emit_span_lint( - lint, - span, + BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { + lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) + } + BuiltinLintDiag::WasmCAbi => lints::WasmCAbi.decorate_lint(diag), + BuiltinLintDiag::IllFormedAttributeInput { suggestions } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), ), - }, - ), - BuiltinLintDiag::InnerAttributeUnstable { is_macro } => ctx.emit_span_lint( - lint, - span, - if is_macro { - lints::InnerAttributeUnstable::InnerMacroAttribute - } else { - lints::InnerAttributeUnstable::CustomInnerAttribute - }, - ), + } + .decorate_lint(diag) + } + BuiltinLintDiag::InnerAttributeUnstable { is_macro } => if is_macro { + lints::InnerAttributeUnstable::InnerMacroAttribute + } else { + lints::InnerAttributeUnstable::CustomInnerAttribute + } + .decorate_lint(diag), } } From 425ed6a181e07abde8d6a722179a953639b34aaf Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 23 May 2024 10:36:57 +0200 Subject: [PATCH 044/101] Update crates/hir-ty/src/infer/expr.rs --- src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index bccad751fc20..4c12786362f0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -933,6 +933,7 @@ impl InferenceContext<'_> { let prev_ret_coercion = mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone()))); + // FIXME: We should handle async blocks like we handle closures let expected = &Expectation::has_type(ret_ty); let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected); From 616fdd04bb8768dd332701ca970849815469075f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 23 May 2024 10:42:15 +0200 Subject: [PATCH 045/101] Use correct toolchain channel when generating builtin type doc links --- src/tools/rust-analyzer/crates/ide/src/doc_links.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 8d765dfc91b4..f42613637b25 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -487,19 +487,23 @@ fn get_doc_base_urls( let system_doc = sysroot .map(|sysroot| format!("file:///{sysroot}/share/doc/rust/html/")) .and_then(|it| Url::parse(&it).ok()); + let krate = def.krate(db); + let channel = krate + .and_then(|krate| db.toolchain_channel(krate.into())) + .unwrap_or(ReleaseChannel::Nightly) + .as_str(); // special case base url of `BuiltinType` to core // https://github.com/rust-lang/rust-analyzer/issues/12250 if let Definition::BuiltinType(..) = def { - let web_link = Url::parse("https://doc.rust-lang.org/nightly/core/").ok(); + let web_link = Url::parse(&format!("https://doc.rust-lang.org/{channel}/core/")).ok(); let system_link = system_doc.and_then(|it| it.join("core/").ok()); return (web_link, system_link); }; - let Some(krate) = def.krate(db) else { return Default::default() }; + let Some(krate) = krate else { return Default::default() }; let Some(display_name) = krate.display_name(db) else { return Default::default() }; let crate_data = &db.crate_graph()[krate.into()]; - let channel = db.toolchain_channel(krate.into()).unwrap_or(ReleaseChannel::Nightly).as_str(); let (web_base, local_base) = match &crate_data.origin { // std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself. From dc8d1bc3733bf922a11197649b9a41360a3aacd3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 23 May 2024 15:46:56 +0000 Subject: [PATCH 046/101] Add more tests --- tests/ui/impl-trait/unsize_adt.rs | 14 ++++++++ tests/ui/impl-trait/unsize_adt.stderr | 17 ++++++++++ tests/ui/impl-trait/unsize_slice.rs | 12 +++++++ tests/ui/impl-trait/unsize_slice.stderr | 17 ++++++++++ tests/ui/impl-trait/unsize_tuple.rs | 14 ++++++++ tests/ui/impl-trait/unsize_tuple.stderr | 17 ++++++++++ .../illegal-upcast-to-impl-opaque.rs | 28 ++++++++++++++++ .../trait-upcasting/type-checking-test-4.rs | 4 +++ .../type-checking-test-4.stderr | 12 +++---- .../type-checking-test-opaques.rs | 21 ++++++++++++ .../type-checking-test-opaques.stderr | 9 ++++++ .../constrain_in_projection.current.stderr | 11 +++++++ .../constrain_in_projection.rs | 28 ++++++++++++++++ .../constrain_in_projection2.current.stderr | 13 ++++++++ .../constrain_in_projection2.next.stderr | 19 +++++++++++ .../constrain_in_projection2.rs | 32 +++++++++++++++++++ 16 files changed, 262 insertions(+), 6 deletions(-) create mode 100644 tests/ui/impl-trait/unsize_adt.rs create mode 100644 tests/ui/impl-trait/unsize_adt.stderr create mode 100644 tests/ui/impl-trait/unsize_slice.rs create mode 100644 tests/ui/impl-trait/unsize_slice.stderr create mode 100644 tests/ui/impl-trait/unsize_tuple.rs create mode 100644 tests/ui/impl-trait/unsize_tuple.stderr create mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs create mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs create mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection.rs create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection2.rs diff --git a/tests/ui/impl-trait/unsize_adt.rs b/tests/ui/impl-trait/unsize_adt.rs new file mode 100644 index 000000000000..fce5094bd404 --- /dev/null +++ b/tests/ui/impl-trait/unsize_adt.rs @@ -0,0 +1,14 @@ +//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`. + +struct Foo(T); + +fn hello() -> Foo<[impl Sized; 2]> { + if false { + let x = hello(); + let _: &Foo<[i32]> = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_adt.stderr b/tests/ui/impl-trait/unsize_adt.stderr new file mode 100644 index 000000000000..2b93b4a571b1 --- /dev/null +++ b/tests/ui/impl-trait/unsize_adt.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_adt.rs:8:30 + | +LL | fn hello() -> Foo<[impl Sized; 2]> { + | ---------- the found opaque type +... +LL | let _: &Foo<[i32]> = &x; + | ----------- ^^ expected `&Foo<[i32]>`, found `&Foo<[impl Sized; 2]>` + | | + | expected due to this + | + = note: expected reference `&Foo<[i32]>` + found reference `&Foo<[impl Sized; 2]>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_slice.rs b/tests/ui/impl-trait/unsize_slice.rs new file mode 100644 index 000000000000..ec0f16265640 --- /dev/null +++ b/tests/ui/impl-trait/unsize_slice.rs @@ -0,0 +1,12 @@ +//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`. + +fn hello() -> [impl Sized; 2] { + if false { + let x = hello(); + let _: &[i32] = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_slice.stderr b/tests/ui/impl-trait/unsize_slice.stderr new file mode 100644 index 000000000000..6a7fdb46163b --- /dev/null +++ b/tests/ui/impl-trait/unsize_slice.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_slice.rs:6:25 + | +LL | fn hello() -> [impl Sized; 2] { + | ---------- the found opaque type +... +LL | let _: &[i32] = &x; + | ------ ^^ expected `&[i32]`, found `&[impl Sized; 2]` + | | + | expected due to this + | + = note: expected reference `&[i32]` + found reference `&[impl Sized; 2]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_tuple.rs b/tests/ui/impl-trait/unsize_tuple.rs new file mode 100644 index 000000000000..630b8fd430f1 --- /dev/null +++ b/tests/ui/impl-trait/unsize_tuple.rs @@ -0,0 +1,14 @@ +//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`. + +#![feature(unsized_tuple_coercion)] + +fn hello() -> ([impl Sized; 2],) { + if false { + let x = hello(); + let _: &([i32],) = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_tuple.stderr b/tests/ui/impl-trait/unsize_tuple.stderr new file mode 100644 index 000000000000..8d3cf15887c0 --- /dev/null +++ b/tests/ui/impl-trait/unsize_tuple.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_tuple.rs:8:28 + | +LL | fn hello() -> ([impl Sized; 2],) { + | ---------- the found opaque type +... +LL | let _: &([i32],) = &x; + | --------- ^^ expected `&([i32],)`, found `&([impl Sized; 2],)` + | | + | expected due to this + | + = note: expected reference `&([i32],)` + found reference `&([impl Sized; 2],)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs new file mode 100644 index 000000000000..5820e49a4e52 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -0,0 +1,28 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] failure-status: 101 +//@[next] known-bug: unknown +//@[next] normalize-stderr-test "note: .*\n\n" -> "" +//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr-test "delayed at .*" -> "" +//@[next] rustc-env:RUST_BACKTRACE=0 +//@ check-pass + +#![feature(trait_upcasting)] + +trait Super { + type Assoc; +} + +trait Sub: Super {} + +impl Super for T { + type Assoc = i32; +} + +fn illegal(x: &dyn Sub) -> &dyn Super { + x +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs index f40c48f0d125..01759ec7a93c 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -11,6 +11,10 @@ fn test_correct(x: &dyn Foo<'static>) { let _ = x as &dyn Bar<'static, 'static>; } +fn test_correct2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'_, '_>; +} + fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { let _ = x as &dyn Bar<'static, 'a>; // Error //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index 8d506e5807ec..ccced5875778 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:15:13 + --> $DIR/type-checking-test-4.rs:19:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:20:13 + --> $DIR/type-checking-test-4.rs:24:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:26:5 + --> $DIR/type-checking-test-4.rs:30:5 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | y.get_b() // ERROR | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:31:5 + --> $DIR/type-checking-test-4.rs:35:5 | LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:36:5 + --> $DIR/type-checking-test-4.rs:40:5 | LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:44:5 + --> $DIR/type-checking-test-4.rs:48:5 | LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs new file mode 100644 index 000000000000..edad62fa4dbc --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs @@ -0,0 +1,21 @@ +#![feature(trait_upcasting, type_alias_impl_trait)] + +type Tait = impl Sized; + +trait Foo<'a>: Bar<'a, 'a, Tait> {} +trait Bar<'a, 'b, T> {} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static, 'static, Tait>; +} + +fn test_correct2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'_, '_, Tait>; +} + +fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { + let _ = x as &dyn Bar<'_, '_, ()>; + //~^ ERROR: non-primitive cast +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr new file mode 100644 index 000000000000..b2982f581ea0 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr @@ -0,0 +1,9 @@ +error[E0605]: non-primitive cast: `&dyn Foo<'a>` as `&dyn Bar<'_, '_, ()>` + --> $DIR/type-checking-test-opaques.rs:17:13 + | +LL | let _ = x as &dyn Bar<'_, '_, ()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr new file mode 100644 index 000000000000..c215d197db43 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection.rs:24:14 + | +LL | let x = >::Assoc::default(); + | ^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the trait `Trait<()>` is implemented for `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs new file mode 100644 index 000000000000..7d7d16361ae6 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -0,0 +1,28 @@ +//! Check that projections will constrain opaque types while looking for +//! matching impls. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next]check-pass + +#![feature(type_alias_impl_trait)] + +struct Foo; + +type Bar = impl Sized; + +trait Trait { + type Assoc: Default; +} + +impl Trait<()> for Foo { + type Assoc = u32; +} + +fn bop(_: Bar) { + let x = >::Assoc::default(); + //[current]~^ `Foo: Trait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr new file mode 100644 index 000000000000..69df5c77f9de --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection2.rs:27:14 + | +LL | let x = >::Assoc::default(); + | ^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the following other types implement trait `Trait`: + > + > + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr new file mode 100644 index 000000000000..0d6eac4216ba --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` + --> $DIR/constrain_in_projection2.rs:27:14 + | +LL | let x = >::Assoc::default(); + | ^^^ help: use the fully qualified path to an implementation: `::Assoc` + | +note: multiple `impl`s satisfying `Foo: Trait` found + --> $DIR/constrain_in_projection2.rs:18:1 + | +LL | impl Trait<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Trait for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs new file mode 100644 index 000000000000..af222f6c1534 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -0,0 +1,32 @@ +//! Check that projections will constrain opaque types while looking for +//! matching impls and error if ambiguous. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +struct Foo; + +type Bar = impl Sized; + +trait Trait { + type Assoc: Default; +} + +impl Trait<()> for Foo { + type Assoc = u32; +} + +impl Trait for Foo { + type Assoc = u32; +} + +fn bop(_: Bar) { + let x = >::Assoc::default(); + //[next]~^ ERROR: cannot satisfy `Foo: Trait` + //[current]~^^ ERROR: `Foo: Trait` is not satisfied +} + +fn main() {} From 29a630eb72ffb94c3708947afae1e948ad3cb189 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 17 Apr 2024 09:29:13 +0000 Subject: [PATCH 047/101] When checking whether an impl applies, constrain hidden types of opaque types. We already handle this case this way on the coherence side, and it matches the new solver's behaviour. While there is some breakage around type-alias-impl-trait (see new "type annotations needed" in tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs), no stable code breaks, and no new stable code is accepted. --- .../src/traits/select/mod.rs | 2 +- tests/ui/impl-trait/equality.rs | 13 +++++++---- tests/ui/impl-trait/equality.stderr | 15 ++++-------- tests/ui/impl-trait/nested_impl_trait.stderr | 16 ++++++++----- ...rsive-type-alias-impl-trait-declaration.rs | 2 +- ...e-type-alias-impl-trait-declaration.stderr | 12 +++------- .../constrain_in_projection.current.stderr | 11 --------- .../constrain_in_projection.rs | 3 +-- .../constrain_in_projection2.current.stderr | 18 ++++++++++----- .../constrain_in_projection2.rs | 3 +-- ...=> issue-84660-unsoundness.current.stderr} | 2 +- .../issue-84660-unsoundness.next.stderr | 23 +++++++++++++++++++ .../issue-84660-unsoundness.rs | 8 ++++++- .../nested-tait-inference.rs | 13 +++++++---- .../nested-tait-inference2.current.stderr | 17 ++++++++++++++ .../nested-tait-inference2.next.stderr | 9 ++++++++ .../nested-tait-inference2.rs | 7 +++++- .../nested-tait-inference2.stderr | 16 ------------- .../normalize-hidden-types.current.stderr | 19 ++++++--------- .../self-referential-2.current.stderr | 14 ----------- .../self-referential-2.rs | 4 ++-- .../self-referential-3.rs | 2 +- .../self-referential-3.stderr | 12 ++++------ 23 files changed, 126 insertions(+), 115 deletions(-) delete mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr rename tests/ui/type-alias-impl-trait/{issue-84660-unsoundness.stderr => issue-84660-unsoundness.current.stderr} (90%) create mode 100644 tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr delete mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr delete mode 100644 tests/ui/type-alias-impl-trait/self-referential-2.current.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4a94643d908b..86a5d464b7bb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2539,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 828b5aac896b..952f81f19784 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot add `impl Foo` to `u32` + //~^ ERROR cannot satisfy `>::Output == i32` } } @@ -32,12 +32,15 @@ trait Leak: Sized { } impl Leak for T { default type T = (); - default fn leak(self) -> Self::T { panic!() } + default fn leak(self) -> Self::T { + panic!() + } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { self } + fn leak(self) -> i32 { + self + } } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 69f4cbbbf429..c9ba1a5ba32d 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0277]: cannot add `impl Foo` to `u32` +error[E0284]: type annotations needed: cannot satisfy `>::Output == i32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ no implementation for `u32 + impl Foo` - | - = help: the trait `Add` is not implemented for `u32` - = help: the following other types implement trait `Add`: - <&'a u32 as Add> - <&u32 as Add<&u32>> - > - + | ^ cannot satisfy `>::Output == i32` error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 1f9a2a5e9d60..f7c708a1dfae 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,19 +46,23 @@ error[E0277]: the trait bound `impl Into: Into` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` +help: consider further restricting this bound + | +LL | fn bad_in_ret_position(x: impl Into + std::fmt::Debug) -> impl Into { x } + | +++++++++++++++++ error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` +help: consider further restricting this bound + | +LL | fn bad(x: impl Into + std::fmt::Debug) -> impl Into { x } + | +++++++++++++++++ error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index aab10be2de27..7874a21f3aec 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR can't compare `Bar` with `(Foo, i32)` + //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index bc810c0f88f3..2d4707f8a279 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,15 +1,9 @@ -error[E0277]: can't compare `Bar` with `(Foo, i32)` +error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ no implementation for `Bar == (Foo, i32)` -LL | -LL | Bar - | --- return type was inferred to be `Bar` here - | - = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` - = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` + | ^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr deleted file mode 100644 index c215d197db43..000000000000 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0277]: the trait bound `Foo: Trait` is not satisfied - --> $DIR/constrain_in_projection.rs:24:14 - | -LL | let x = >::Assoc::default(); - | ^^^ the trait `Trait` is not implemented for `Foo` - | - = help: the trait `Trait<()>` is implemented for `Foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 7d7d16361ae6..2a246900106c 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next]check-pass +//@check-pass #![feature(type_alias_impl_trait)] @@ -22,7 +22,6 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); - //[current]~^ `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 69df5c77f9de..0d6eac4216ba 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,13 +1,19 @@ -error[E0277]: the trait bound `Foo: Trait` is not satisfied +error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` --> $DIR/constrain_in_projection2.rs:27:14 | LL | let x = >::Assoc::default(); - | ^^^ the trait `Trait` is not implemented for `Foo` + | ^^^ help: use the fully qualified path to an implementation: `::Assoc` | - = help: the following other types implement trait `Trait`: - > - > +note: multiple `impl`s satisfying `Foo: Trait` found + --> $DIR/constrain_in_projection2.rs:18:1 + | +LL | impl Trait<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Trait for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index af222f6c1534..0066131f0155 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -25,8 +25,7 @@ impl Trait for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); - //[next]~^ ERROR: cannot satisfy `Foo: Trait` - //[current]~^^ ERROR: `Foo: Trait` is not satisfied + //~^ ERROR: cannot satisfy `Foo: Trait` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr rename to tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index 461da20f37b6..a7ff097e8bf3 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:23:1 + --> $DIR/issue-84660-unsoundness.rs:28:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr new file mode 100644 index 000000000000..607f0b062abd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -0,0 +1,23 @@ +error[E0284]: type annotations needed: cannot satisfy `>::Out == ()` + --> $DIR/issue-84660-unsoundness.rs:22:37 + | +LL | fn convert(_i: In) -> Self::Out { + | _____________________________________^ +LL | | +LL | | unreachable!(); +LL | | } + | |_____^ cannot satisfy `>::Out == ()` + +error[E0119]: conflicting implementations of trait `Trait` + --> $DIR/issue-84660-unsoundness.rs:28:1 + | +LL | impl Trait for Out { + | ------------------------------------ first implementation here +... +LL | impl Trait<(), In> for Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0284. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 48d4b0c96ff0..99a5d36066b0 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -1,6 +1,10 @@ // Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an // impl header being accepted was used to create unsoundness. +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(type_alias_impl_trait)] trait Foo {} @@ -16,11 +20,13 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { + //[next]~^ ERROR: type annotations needed unreachable!(); } } -impl Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait` +impl Trait<(), In> for Out { + //~^ ERROR conflicting implementations of trait `Trait` type Out = In; fn convert(i: In) -> Self::Out { i diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 82248971692c..70495c44706a 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -1,18 +1,21 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@check-pass + use std::fmt::Debug; type FooX = impl Debug; -trait Foo { } +trait Foo {} -impl Foo<()> for () { } +impl Foo<()> for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied - // FIXME(type-alias-impl-trait): We could probably make this work. () } -fn main() { } +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr new file mode 100644 index 000000000000..c7b7af152ab3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -0,0 +1,17 @@ +error[E0283]: type annotations needed: cannot satisfy `(): Foo` + --> $DIR/nested-tait-inference2.rs:17:13 + | +LL | fn foo() -> impl Foo { + | ^^^^^^^^^^^^^^ + | +note: multiple `impl`s satisfying `(): Foo` found + --> $DIR/nested-tait-inference2.rs:14:1 + | +LL | impl Foo<()> for () {} + | ^^^^^^^^^^^^^^^^^^^ +LL | impl Foo for () {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr new file mode 100644 index 000000000000..9647d9e376eb --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `impl Foo == ()` + --> $DIR/nested-tait-inference2.rs:19:5 + | +LL | () + | ^^ cannot satisfy `impl Foo == ()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index 0d7f5bad25f1..fe2f76e552ad 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -1,6 +1,10 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::fmt::Debug; type FooX = impl Debug; @@ -11,8 +15,9 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied + //[current]~^ ERROR: cannot satisfy `(): Foo` () + //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr deleted file mode 100644 index 241342b05096..000000000000 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference2.rs:13:13 - | -LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` -LL | -LL | () - | -- return type was inferred to be `()` here - | - = help: the following other types implement trait `Foo`: - <() as Foo<()>> - <() as Foo> - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index a40dac06a01c..eff29303bf18 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,21 +22,17 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:43:25 | -LL | type Opaque = impl Sized; - | ---------- the expected opaque type -... LL | let _: Opaque = dyn_hoops::(0); - | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` - | | - | expected due to this + | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` | - = note: expected opaque type `typeck::Opaque` - found raw pointer `*const (dyn FnOnce(()) + 'static)` - = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: previous use here + --> $DIR/normalize-hidden-types.rs:44:9 + | +LL | None + | ^^^^ error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -52,4 +48,3 @@ LL | None error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr deleted file mode 100644 index 3ae3590ca7fe..000000000000 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:10:13 - | -LL | fn bar() -> Bar { - | ^^^ no implementation for `i32 == Foo` -LL | 42_i32 - | ------ return type was inferred to be `i32` here - | - = help: the trait `PartialEq` is not implemented for `i32` - = help: the trait `PartialEq` is implemented for `i32` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f96364ccfcdd..f4102f2e2cb7 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; fn bar() -> Bar { - 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` + 42_i32 } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index b33051da2d77..3b015ab322ac 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` + //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 32eac622e518..caa9f9691dda 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,15 +1,11 @@ -error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` +error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` -LL | -LL | i - | - return type was inferred to be `&i32` here + | ^^^^^^^^^^^ | - = help: the trait `PartialEq>` is not implemented for `&i32` - = help: the trait `PartialEq` is implemented for `i32` + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. From 7f292f41a0c6c5ebbc915d487dd49741f9982684 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 17 Apr 2024 10:01:34 +0000 Subject: [PATCH 048/101] Allow defining opaque types during trait object upcasting. No stable code is affected, as this requires the `trait_upcasting` feature gate. --- .../src/traits/select/mod.rs | 2 +- .../upcast-defining-opaque.current.stderr | 17 ----------------- .../trait-upcasting/upcast-defining-opaque.rs | 4 ++-- 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 86a5d464b7bb..ee4b81b046f4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2631,7 +2631,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, source_projection, target_projection) + .eq(DefineOpaqueTypes::Yes, source_projection, target_projection) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr deleted file mode 100644 index a259abb28ae3..000000000000 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/upcast-defining-opaque.rs:21:5 - | -LL | type Foo = impl Sized; - | ---------- the found opaque type -LL | -LL | fn upcast(x: &dyn Sub) -> &dyn Super { - | ----------------------- expected `&dyn Super` because of return type -LL | x - | ^ expected trait `Super`, found trait `Sub` - | - = note: expected reference `&dyn Super` - found reference `&dyn Sub` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs index cb1501a94a2a..07f1549e177f 100644 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs @@ -1,7 +1,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] check-pass +//@check-pass #![feature(trait_upcasting, type_alias_impl_trait)] @@ -18,7 +18,7 @@ impl Super for T { type Foo = impl Sized; fn upcast(x: &dyn Sub) -> &dyn Super { - x //[current]~ mismatched types + x } fn main() {} From 4387eea7f76e82d6f6050df99196c15d53b4914a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 17 Apr 2024 10:48:20 +0000 Subject: [PATCH 049/101] Support constraining opaque types while trait upcasting with binders --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- .../traits/trait-upcasting/type-checking-test-opaques.rs | 3 ++- .../trait-upcasting/type-checking-test-opaques.stderr | 9 --------- 3 files changed, 3 insertions(+), 11 deletions(-) delete mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ee4b81b046f4..696b1c151153 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2594,7 +2594,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { self.infcx .at(&obligation.cause, obligation.param_env) .eq( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, upcast_principal.map_bound(|trait_ref| { ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) }), diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs index edad62fa4dbc..a3a1ce29465b 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs @@ -1,5 +1,7 @@ #![feature(trait_upcasting, type_alias_impl_trait)] +//@ check-pass + type Tait = impl Sized; trait Foo<'a>: Bar<'a, 'a, Tait> {} @@ -15,7 +17,6 @@ fn test_correct2<'a>(x: &dyn Foo<'a>) { fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { let _ = x as &dyn Bar<'_, '_, ()>; - //~^ ERROR: non-primitive cast } fn main() {} diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr deleted file mode 100644 index b2982f581ea0..000000000000 --- a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0605]: non-primitive cast: `&dyn Foo<'a>` as `&dyn Bar<'_, '_, ()>` - --> $DIR/type-checking-test-opaques.rs:17:13 - | -LL | let _ = x as &dyn Bar<'_, '_, ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0605`. From f93256ca42afb93f2dada055bb695c30d7abccb3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 23 May 2024 19:23:04 +0200 Subject: [PATCH 050/101] Allow sysroots to only consist of the source root dir --- .../crates/hir-ty/src/layout/tests.rs | 4 +- .../crates/project-model/src/build_scripts.rs | 14 +- .../project-model/src/cargo_workspace.rs | 14 +- .../crates/project-model/src/env.rs | 4 +- .../crates/project-model/src/rustc_cfg.rs | 8 +- .../crates/project-model/src/sysroot.rs | 206 +++++++------- .../project-model/src/target_data_layout.rs | 6 +- .../crates/project-model/src/tests.rs | 13 +- .../crates/project-model/src/workspace.rs | 262 +++++++----------- .../rust-analyzer/src/cli/rustc_tests.rs | 6 +- .../rust-analyzer/src/handlers/request.rs | 6 +- .../crates/rust-analyzer/src/lsp/ext.rs | 1 - .../crates/rust-analyzer/src/reload.rs | 75 ++--- .../crates/rust-analyzer/tests/crate_graph.rs | 4 +- .../rust-analyzer/tests/slow-tests/main.rs | 6 +- .../rust-analyzer/docs/dev/lsp-extensions.md | 2 +- .../rust-analyzer/editors/code/src/ctx.ts | 6 - .../rust-analyzer/editors/code/src/lsp_ext.ts | 1 - 18 files changed, 277 insertions(+), 361 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 6c1eccb75e63..392bda51b528 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -1,7 +1,7 @@ use chalk_ir::{AdtId, TyKind}; use either::Either; use hir_def::db::DefDatabase; -use project_model::target_data_layout::RustcDataLayoutConfig; +use project_model::{target_data_layout::RustcDataLayoutConfig, Sysroot}; use rustc_hash::FxHashMap; use test_fixture::WithFixture; use triomphe::Arc; @@ -17,7 +17,7 @@ mod closure; fn current_machine_data_layout() -> String { project_model::target_data_layout::get( - RustcDataLayoutConfig::Rustc(None), + RustcDataLayoutConfig::Rustc(&Sysroot::empty()), None, &FxHashMap::default(), ) diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs index 8e1f7fdcded7..d2f423590e2c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs @@ -65,7 +65,7 @@ impl WorkspaceBuildScripts { allowed_features: &FxHashSet, manifest_path: &ManifestPath, toolchain: Option<&Version>, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> io::Result { const RUST_1_75: Version = Version::new(1, 75, 0); let mut cmd = match config.run_build_script_command.as_deref() { @@ -75,7 +75,7 @@ impl WorkspaceBuildScripts { cmd } _ => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]); cmd.args(&config.extra_args); @@ -149,7 +149,7 @@ impl WorkspaceBuildScripts { workspace: &CargoWorkspace, progress: &dyn Fn(String), toolchain: Option<&Version>, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> io::Result { let current_dir = match &config.invocation_location { InvocationLocation::Root(root) if config.run_build_script_command.is_some() => { @@ -195,7 +195,7 @@ impl WorkspaceBuildScripts { // This is not gonna be used anyways, so just construct a dummy here &ManifestPath::try_from(workspace_root.clone()).unwrap(), None, - None, + &Sysroot::empty(), )?; // NB: Cargo.toml could have been modified between `cargo metadata` and // `cargo check`. We shouldn't assume that package ids we see here are @@ -412,7 +412,7 @@ impl WorkspaceBuildScripts { rustc: &CargoWorkspace, current_dir: &AbsPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Self { let mut bs = WorkspaceBuildScripts::default(); for p in rustc.packages() { @@ -420,7 +420,7 @@ impl WorkspaceBuildScripts { } let res = (|| { let target_libdir = (|| { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(current_dir) @@ -429,7 +429,7 @@ impl WorkspaceBuildScripts { if let Ok(it) = utf8_stdout(cargo_config) { return Ok(it); } - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc); + let mut cmd = sysroot.tool(Tool::Rustc); cmd.envs(extra_env); cmd.args(["--print", "target-libdir"]); utf8_stdout(cmd) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 9955f2687c91..632ba1cacf21 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -258,12 +258,12 @@ impl CargoWorkspace { cargo_toml: &ManifestPath, current_dir: &AbsPath, config: &CargoConfig, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, progress: &dyn Fn(String), ) -> anyhow::Result { let targets = find_list_of_build_targets(config, cargo_toml, sysroot); - let cargo = Sysroot::tool(sysroot, Tool::Cargo); + let cargo = sysroot.tool(Tool::Cargo); let mut meta = MetadataCommand::new(); meta.cargo_path(cargo.get_program()); cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default())); @@ -536,7 +536,7 @@ impl CargoWorkspace { fn find_list_of_build_targets( config: &CargoConfig, cargo_toml: &ManifestPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Vec { if let Some(target) = &config.target { return [target.into()].to_vec(); @@ -553,9 +553,9 @@ fn find_list_of_build_targets( fn rustc_discover_host_triple( cargo_toml: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Option { - let mut rustc = Sysroot::tool(sysroot, Tool::Rustc); + let mut rustc = sysroot.tool(Tool::Rustc); rustc.envs(extra_env); rustc.current_dir(cargo_toml.parent()).arg("-vV"); tracing::debug!("Discovering host platform by {:?}", rustc); @@ -581,9 +581,9 @@ fn rustc_discover_host_triple( fn cargo_config_build_target( cargo_toml: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Vec { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(cargo_toml.parent()) diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs index 5520cdaff6b0..88fb10a68c61 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/env.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs @@ -62,9 +62,9 @@ pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: Targe pub(crate) fn cargo_config_env( manifest: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> FxHashMap { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(manifest.parent()) diff --git a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs index 4f69b2b96f0c..26499308ce96 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs @@ -10,10 +10,10 @@ use crate::{cfg::CfgFlag, utf8_stdout, ManifestPath, Sysroot}; pub(crate) enum RustcCfgConfig<'a> { /// Use `rustc --print cfg`, either from with the binary from the sysroot or by discovering via /// [`toolchain::rustc`]. - Rustc(Option<&'a Sysroot>), + Rustc(&'a Sysroot), /// Use `cargo --print cfg`, either from with the binary from the sysroot or by discovering via /// [`toolchain::cargo`]. - Cargo(Option<&'a Sysroot>, &'a ManifestPath), + Cargo(&'a Sysroot, &'a ManifestPath), } pub(crate) fn get( @@ -65,7 +65,7 @@ fn get_rust_cfgs( ) -> anyhow::Result { let sysroot = match config { RustcCfgConfig::Cargo(sysroot, cargo_toml) => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.envs(extra_env); cmd.current_dir(cargo_toml.parent()) @@ -86,7 +86,7 @@ fn get_rust_cfgs( RustcCfgConfig::Rustc(sysroot) => sysroot, }; - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc); + let mut cmd = sysroot.tool(Tool::Rustc); cmd.envs(extra_env); cmd.args(["--print", "cfg", "-O"]); if let Some(target) = target { diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index e6bbe6ede8a0..653e7157bcb3 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -4,7 +4,7 @@ //! but we can't process `.rlib` and need source code instead. The source code //! is typically installed with `rustup component add rust-src` command. -use std::{env, fs, ops, process::Command, sync::Arc}; +use std::{env, fs, ops, process::Command}; use anyhow::{format_err, Result}; use base_db::CrateName; @@ -16,30 +16,19 @@ use toolchain::{probe_for_binary, Tool}; use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Sysroot { - root: AbsPathBuf, - src_root: Option>>, + root: Option, + src_root: Option, mode: SysrootMode, -} - -impl Eq for Sysroot {} -impl PartialEq for Sysroot { - fn eq(&self, other: &Self) -> bool { - self.root == other.root - && self.mode == other.mode - && match (&self.src_root, &other.src_root) { - (Some(Ok(this)), Some(Ok(other))) => this == other, - (None, None) | (Some(Err(_)), Some(Err(_))) => true, - _ => false, - } - } + error: Option, } #[derive(Debug, Clone, Eq, PartialEq)] pub(crate) enum SysrootMode { Workspace(CargoWorkspace), Stitched(Stitched), + Empty, } #[derive(Debug, Clone, Eq, PartialEq)] @@ -89,70 +78,40 @@ pub(crate) struct SysrootCrateData { } impl Sysroot { + pub const fn empty() -> Sysroot { + Sysroot { root: None, src_root: None, mode: SysrootMode::Empty, error: None } + } + /// Returns sysroot "root" directory, where `bin/`, `etc/`, `lib/`, `libexec/` /// subfolder live, like: /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu` - pub fn root(&self) -> &AbsPath { - &self.root + pub fn root(&self) -> Option<&AbsPath> { + self.root.as_deref() } /// Returns the sysroot "source" directory, where stdlib sources are located, like: /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library` pub fn src_root(&self) -> Option<&AbsPath> { - self.src_root.as_ref()?.as_deref().ok() + self.src_root.as_deref() } pub fn is_empty(&self) -> bool { match &self.mode { SysrootMode::Workspace(ws) => ws.packages().next().is_none(), SysrootMode::Stitched(stitched) => stitched.crates.is_empty(), + SysrootMode::Empty => true, } } - pub fn loading_warning(&self) -> Option { - let src_root = match &self.src_root { - None => return Some(format!("sysroot at `{}` has no library sources", self.root)), - Some(Ok(src_root)) => src_root, - Some(Err(e)) => return Some(e.to_string()), - }; - let has_core = match &self.mode { - SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), - SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), - }; - if !has_core { - let var_note = if env::var_os("RUST_SRC_PATH").is_some() { - " (`RUST_SRC_PATH` might be incorrect, try unsetting it)" - } else { - " try running `rustup component add rust-src` to possible fix this" - }; - Some(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,)) - } else { - None - } - } - - pub fn check_has_core(&self) -> Result<(), String> { - let Some(Ok(src_root)) = &self.src_root else { return Ok(()) }; - let has_core = match &self.mode { - SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), - SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), - }; - if !has_core { - let var_note = if env::var_os("RUST_SRC_PATH").is_some() { - " (`RUST_SRC_PATH` might be incorrect, try unsetting it)" - } else { - " try running `rustup component add rust-src` to possible fix this" - }; - Err(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,)) - } else { - Ok(()) - } + pub fn error(&self) -> Option<&str> { + self.error.as_deref() } pub fn num_packages(&self) -> usize { match &self.mode { SysrootMode::Workspace(ws) => ws.packages().count(), SysrootMode::Stitched(c) => c.crates().count(), + SysrootMode::Empty => 0, } } @@ -168,63 +127,50 @@ impl Sysroot { dir: &AbsPath, extra_env: &FxHashMap, metadata: bool, - ) -> Result { - tracing::debug!("discovering sysroot for {dir}"); - let sysroot_dir = discover_sysroot_dir(dir, extra_env)?; - let sysroot_src_dir = - discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata)) - } - - pub fn discover_no_source( - dir: &AbsPath, - extra_env: &FxHashMap, - ) -> Result { - tracing::debug!("discovering sysroot for {dir}"); - let sysroot_dir = discover_sysroot_dir(dir, extra_env)?; - let sysroot_src_dir = - discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), false)) + ) -> Sysroot { + let sysroot_dir = discover_sysroot_dir(dir, extra_env); + let sysroot_src_dir = sysroot_dir.as_ref().ok().map(|sysroot_dir| { + discover_sysroot_src_dir_or_add_component(sysroot_dir, dir, extra_env) + }); + Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir, metadata) } pub fn discover_with_src_override( current_dir: &AbsPath, extra_env: &FxHashMap, - src: AbsPathBuf, + sysroot_src_dir: AbsPathBuf, metadata: bool, - ) -> Result { - tracing::debug!("discovering sysroot for {current_dir}"); - let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?; - Ok(Sysroot::load(sysroot_dir, Some(Ok(src)), metadata)) + ) -> Sysroot { + let sysroot_dir = discover_sysroot_dir(current_dir, extra_env); + Sysroot::load_core_check(Some(sysroot_dir), Some(Ok(sysroot_src_dir)), metadata) + } + + pub fn discover_sysroot_src_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Sysroot { + let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir) + .ok_or_else(|| format_err!("can't find standard library sources in {sysroot_dir}")); + Sysroot::load_core_check(Some(Ok(sysroot_dir)), Some(sysroot_src_dir), metadata) } pub fn discover_rustc_src(&self) -> Option { - get_rustc_src(&self.root) - } - - pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Result { - let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir).ok_or_else(|| { - format_err!("can't load standard library from sysroot path {sysroot_dir}") - }); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata)) + get_rustc_src(self.root()?) } /// Returns a command to run a tool preferring the cargo proxies if the sysroot exists. - pub fn tool(sysroot: Option<&Self>, tool: Tool) -> Command { - match sysroot { - Some(sysroot) => { + pub fn tool(&self, tool: Tool) -> Command { + match self.root() { + Some(root) => { // special case rustc, we can look that up directly in the sysroot's bin folder // as it should never invoke another cargo binary if let Tool::Rustc = tool { if let Some(path) = - probe_for_binary(sysroot.root.join("bin").join(Tool::Rustc.name()).into()) + probe_for_binary(root.join("bin").join(Tool::Rustc.name()).into()) { return Command::new(path); } } let mut cmd = Command::new(tool.prefer_proxy()); - cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(&sysroot.root)); + cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(root)); cmd } _ => Command::new(tool.path()), @@ -232,35 +178,89 @@ impl Sysroot { } pub fn discover_proc_macro_srv(&self) -> anyhow::Result { + let Some(root) = self.root() else { + return Err(anyhow::format_err!("no sysroot",)); + }; ["libexec", "lib"] .into_iter() - .map(|segment| self.root().join(segment).join("rust-analyzer-proc-macro-srv")) + .map(|segment| root.join(segment).join("rust-analyzer-proc-macro-srv")) .find_map(|server_path| probe_for_binary(server_path.into())) .map(AbsPathBuf::assert) .ok_or_else(|| { - anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", self.root()) + anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", root) }) } pub fn load( - sysroot_dir: AbsPathBuf, + sysroot_dir: Option, + sysroot_src_dir: Option, + metadata: bool, + ) -> Sysroot { + Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), metadata) + } + + fn load_core_check( + sysroot_dir: Option>, sysroot_src_dir: Option>, metadata: bool, ) -> Sysroot { + let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, metadata); + if sysroot.error.is_none() { + if let Some(src_root) = &sysroot.src_root { + let has_core = match &sysroot.mode { + SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), + SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), + SysrootMode::Empty => true, + }; + if !has_core { + let var_note = if env::var_os("RUST_SRC_PATH").is_some() { + " (env var `RUST_SRC_PATH` is set and may be incorrect, try unsetting it)" + } else { + ", try running `rustup component add rust-src` to possibly fix this" + }; + sysroot.error = Some(format!( + "sysroot at `{}` is missing a `core` library{var_note}", + src_root, + )); + } + } + } + sysroot + } + + fn load_( + sysroot_dir: Option>, + sysroot_src_dir: Option>, + metadata: bool, + ) -> Sysroot { + let sysroot_dir = match sysroot_dir { + Some(Ok(sysroot_dir)) => Some(sysroot_dir), + Some(Err(e)) => { + return Sysroot { + root: None, + src_root: None, + mode: SysrootMode::Empty, + error: Some(e.to_string()), + } + } + None => None, + }; let sysroot_src_dir = match sysroot_src_dir { Some(Ok(sysroot_src_dir)) => sysroot_src_dir, Some(Err(e)) => { return Sysroot { root: sysroot_dir, - src_root: Some(Err(Arc::new(e))), - mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }), + src_root: None, + mode: SysrootMode::Empty, + error: Some(e.to_string()), } } None => { return Sysroot { root: sysroot_dir, src_root: None, - mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }), + mode: SysrootMode::Empty, + error: None, } } }; @@ -284,7 +284,7 @@ impl Sysroot { &sysroot_cargo_toml, ¤t_dir, &cargo_config, - None, + &Sysroot::empty(), &|_| (), ) .map_err(|e| { @@ -368,8 +368,9 @@ impl Sysroot { let cargo_workspace = CargoWorkspace::new(res, sysroot_cargo_toml); Some(Sysroot { root: sysroot_dir.clone(), - src_root: Some(Ok(sysroot_src_dir.clone())), + src_root: Some(sysroot_src_dir.clone()), mode: SysrootMode::Workspace(cargo_workspace), + error: None, }) })(); if let Some(sysroot) = sysroot { @@ -420,8 +421,9 @@ impl Sysroot { } Sysroot { root: sysroot_dir, - src_root: Some(Ok(sysroot_src_dir)), + src_root: Some(sysroot_src_dir), mode: SysrootMode::Stitched(stitched), + error: None, } } } diff --git a/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs b/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs index 4e810a0232ea..8a8a2d32558b 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs @@ -9,10 +9,10 @@ use crate::{utf8_stdout, ManifestPath, Sysroot}; pub enum RustcDataLayoutConfig<'a> { /// Use `rustc --print target-spec-json`, either from with the binary from the sysroot or by discovering via /// [`toolchain::rustc`]. - Rustc(Option<&'a Sysroot>), + Rustc(&'a Sysroot), /// Use `cargo --print target-spec-json`, either from with the binary from the sysroot or by discovering via /// [`toolchain::cargo`]. - Cargo(Option<&'a Sysroot>, &'a ManifestPath), + Cargo(&'a Sysroot, &'a ManifestPath), } pub fn get( @@ -28,7 +28,7 @@ pub fn get( }; let sysroot = match config { RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.envs(extra_env); cmd.current_dir(cargo_toml.parent()) .args([ diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 3d5a934fc92e..a6730863d6b2 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -34,7 +34,7 @@ fn load_cargo_with_overrides( cargo_config_extra_env: Default::default(), }, cfg_overrides, - sysroot: Err(None), + sysroot: Sysroot::empty(), rustc_cfg: Vec::new(), toolchain: None, target_layout: Err("target_data_layout not loaded".into()), @@ -57,7 +57,7 @@ fn load_cargo_with_fake_sysroot( rustc: Err(None), cargo_config_extra_env: Default::default(), }, - sysroot: Ok(get_fake_sysroot()), + sysroot: get_fake_sysroot(), rustc_cfg: Vec::new(), cfg_overrides: Default::default(), toolchain: None, @@ -77,7 +77,7 @@ fn load_cargo_with_fake_sysroot( fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) { let data = get_test_json_file(file); let project = rooted_project_json(data); - let sysroot = Ok(get_fake_sysroot()); + let sysroot = get_fake_sysroot(); let project_workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project), sysroot, @@ -144,7 +144,7 @@ fn get_fake_sysroot() -> Sysroot { // fake sysroot, so we give them both the same path: let sysroot_dir = AbsPathBuf::assert(sysroot_path); let sysroot_src_dir = sysroot_dir.clone(); - Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false) + Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false) } fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { @@ -281,12 +281,11 @@ fn smoke_test_real_sysroot_cargo() { let manifest_path = ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap(); let cargo_workspace = CargoWorkspace::new(meta, manifest_path); - let sysroot = Ok(Sysroot::discover( + let sysroot = Sysroot::discover( AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))), &Default::default(), true, - ) - .unwrap()); + ); let project_workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::Cargo { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 85621444e339..0d2174073a2a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -48,7 +48,7 @@ pub struct PackageRoot { pub struct ProjectWorkspace { pub kind: ProjectWorkspaceKind, /// The sysroot loaded for this workspace. - pub sysroot: Result>, + pub sysroot: Sysroot, /// Holds cfg flags for the current target. We get those by running /// `rustc --print cfg`. // FIXME: make this a per-crate map, as, eg, build.rs might have a @@ -112,7 +112,7 @@ impl fmt::Debug for ProjectWorkspace { .debug_struct("Cargo") .field("root", &cargo.workspace_root().file_name()) .field("n_packages", &cargo.packages().len()) - .field("sysroot", &sysroot.is_ok()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field( "n_rustc_compiler_crates", &rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(rc, _)| rc.packages().len()), @@ -125,11 +125,9 @@ impl fmt::Debug for ProjectWorkspace { .finish(), ProjectWorkspaceKind::Json(project) => { let mut debug_struct = f.debug_struct("Json"); - debug_struct.field("n_crates", &project.n_crates()); - if let Ok(sysroot) = sysroot { - debug_struct.field("n_sysroot_crates", &sysroot.num_packages()); - } debug_struct + .field("n_crates", &project.n_crates()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field("n_rustc_cfg", &rustc_cfg.len()) .field("toolchain", &toolchain) .field("data_layout", &target_layout) @@ -144,7 +142,7 @@ impl fmt::Debug for ProjectWorkspace { .debug_struct("DetachedFiles") .field("file", &file) .field("cargo_script", &cargo_script.is_some()) - .field("sysroot", &sysroot.is_ok()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field("cargo_script", &cargo_script.is_some()) .field("n_rustc_cfg", &rustc_cfg.len()) .field("toolchain", &toolchain) @@ -158,7 +156,7 @@ impl fmt::Debug for ProjectWorkspace { fn get_toolchain_version( current_dir: &AbsPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, tool: Tool, extra_env: &FxHashMap, prefix: &str, @@ -213,41 +211,37 @@ impl ProjectWorkspace { } ProjectManifest::CargoToml(cargo_toml) => { let sysroot = match (&config.sysroot, &config.sysroot_src) { - (Some(RustLibSource::Path(path)), None) => { - Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata).map_err(|e| { - Some(format!("Failed to find sysroot at {path}:{e}")) - }) - } - (Some(RustLibSource::Discover), None) => { - Sysroot::discover(cargo_toml.parent(), &config.extra_env, config.sysroot_query_metadata).map_err(|e| { - Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}")) - }) - } - (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => { - Ok(Sysroot::load(sysroot.clone(), Some(Ok(sysroot_src.clone())), config.sysroot_query_metadata)) - } + (Some(RustLibSource::Discover), None) => Sysroot::discover( + cargo_toml.parent(), + &config.extra_env, + config.sysroot_query_metadata, + ), (Some(RustLibSource::Discover), Some(sysroot_src)) => { Sysroot::discover_with_src_override( cargo_toml.parent(), &config.extra_env, - sysroot_src.clone(), config.sysroot_query_metadata, - ).map_err(|e| { - Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}")) - }) + sysroot_src.clone(), + config.sysroot_query_metadata, + ) } - (None, _) => Err(None), + (Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir( + path.clone(), + config.sysroot_query_metadata, + ), + (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load( + Some(sysroot.clone()), + Some(sysroot_src.clone()), + config.sysroot_query_metadata, + ), + (None, _) => Sysroot::empty(), }; - let sysroot_ref = sysroot.as_ref().ok(); - - if let Ok(sysroot) = &sysroot { - tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = %sysroot.root(), "Using sysroot"); - } + tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot"); let rustc_dir = match &config.rustc_source { Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone()) .map_err(|p| Some(format!("rustc source path is not absolute: {p}"))), Some(RustLibSource::Discover) => { - sysroot_ref.and_then(Sysroot::discover_rustc_src).ok_or_else(|| { + sysroot.discover_rustc_src().ok_or_else(|| { Some("Failed to discover rustc source for sysroot.".to_owned()) }) } @@ -263,7 +257,7 @@ impl ProjectWorkspace { features: crate::CargoFeatures::default(), ..config.clone() }, - sysroot_ref, + &sysroot, progress, ) { Ok(meta) => { @@ -272,7 +266,7 @@ impl ProjectWorkspace { &workspace, cargo_toml.parent(), &config.extra_env, - sysroot_ref + &sysroot ); Ok(Box::new((workspace, buildscripts))) } @@ -290,7 +284,7 @@ impl ProjectWorkspace { let toolchain = get_toolchain_version( cargo_toml.parent(), - sysroot_ref, + &sysroot, Tool::Cargo, &config.extra_env, "cargo ", @@ -298,12 +292,12 @@ impl ProjectWorkspace { let rustc_cfg = rustc_cfg::get( config.target.as_deref(), &config.extra_env, - RustcCfgConfig::Cargo(sysroot_ref, cargo_toml), + RustcCfgConfig::Cargo(&sysroot, cargo_toml), ); let cfg_overrides = config.cfg_overrides.clone(); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Cargo(sysroot_ref, cargo_toml), + RustcDataLayoutConfig::Cargo(&sysroot, cargo_toml), config.target.as_deref(), &config.extra_env, ); @@ -315,7 +309,7 @@ impl ProjectWorkspace { cargo_toml, cargo_toml.parent(), config, - sysroot_ref, + &sysroot, progress, ) .with_context(|| { @@ -326,7 +320,7 @@ impl ProjectWorkspace { let cargo = CargoWorkspace::new(meta, cargo_toml.clone()); let cargo_config_extra_env = - cargo_config_env(cargo_toml, &config.extra_env, sysroot_ref); + cargo_config_env(cargo_toml, &config.extra_env, &sysroot); ProjectWorkspace { kind: ProjectWorkspaceKind::Cargo { cargo, @@ -354,32 +348,13 @@ impl ProjectWorkspace { extra_env: &FxHashMap, cfg_overrides: &CfgOverrides, ) -> ProjectWorkspace { - let sysroot = match (project_json.sysroot.clone(), project_json.sysroot_src.clone()) { - (Some(sysroot), Some(sysroot_src)) => { - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (Some(sysroot), None) => { - // assume sysroot is structured like rustup's and guess `sysroot_src` - let sysroot_src = - sysroot.join("lib").join("rustlib").join("src").join("rust").join("library"); - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (None, Some(sysroot_src)) => { - // assume sysroot is structured like rustup's and guess `sysroot` - let mut sysroot = sysroot_src.clone(); - for _ in 0..5 { - sysroot.pop(); - } - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (None, None) => Err(None), - }; - let sysroot_ref = sysroot.as_ref().ok(); - let cfg_config = RustcCfgConfig::Rustc(sysroot_ref); - let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref); + let sysroot = + Sysroot::load(project_json.sysroot.clone(), project_json.sysroot_src.clone(), false); + let cfg_config = RustcCfgConfig::Rustc(&sysroot); + let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot); let toolchain = match get_toolchain_version( project_json.path(), - sysroot_ref, + &sysroot, Tool::Rustc, extra_env, "rustc ", @@ -410,24 +385,16 @@ impl ProjectWorkspace { let dir = detached_file.parent(); let sysroot = match &config.sysroot { Some(RustLibSource::Path(path)) => { - Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata) - .map_err(|e| Some(format!("Failed to find sysroot at {path}:{e}"))) + Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata) } - Some(RustLibSource::Discover) => Sysroot::discover( - dir, - &config.extra_env, - config.sysroot_query_metadata, - ) - .map_err(|e| { - Some(format!("Failed to find sysroot for {dir}. Is rust-src installed? {e}")) - }), - None => Err(None), + Some(RustLibSource::Discover) => { + Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata) + } + None => Sysroot::empty(), }; - let sysroot_ref = sysroot.as_ref().ok(); let toolchain = - match get_toolchain_version(dir, sysroot_ref, Tool::Rustc, &config.extra_env, "rustc ") - { + match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") { Ok(it) => it, Err(e) => { tracing::error!("{e}"); @@ -435,25 +402,24 @@ impl ProjectWorkspace { } }; - let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref)); + let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(&sysroot)); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Rustc(sysroot_ref), + RustcDataLayoutConfig::Rustc(&sysroot), None, &config.extra_env, ); let cargo_script = - CargoWorkspace::fetch_metadata(detached_file, dir, config, sysroot_ref, &|_| ()) - .ok() - .map(|ws| { + CargoWorkspace::fetch_metadata(detached_file, dir, config, &sysroot, &|_| ()).ok().map( + |ws| { ( CargoWorkspace::new(ws, detached_file.clone()), WorkspaceBuildScripts::default(), ) - }); + }, + ); - let cargo_config_extra_env = - cargo_config_env(detached_file, &config.extra_env, sysroot_ref); + let cargo_config_extra_env = cargo_config_env(detached_file, &config.extra_env, &sysroot); Ok(ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile { file: detached_file.to_owned(), @@ -489,7 +455,7 @@ impl ProjectWorkspace { cargo, progress, self.toolchain.as_ref(), - self.sysroot.as_ref().ok(), + &self.sysroot, ) .with_context(|| { format!("Failed to run build scripts for {}", cargo.workspace_root()) @@ -562,17 +528,7 @@ impl ProjectWorkspace { } pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result { - match &self.sysroot { - Ok(sysroot) => sysroot.discover_proc_macro_srv(), - Err(None) => Err(anyhow::format_err!( - "cannot find proc-macro server, the workspace `{}` is missing a sysroot", - self.manifest_or_root() - )), - Err(Some(e)) => Err(anyhow::format_err!( - "cannot find proc-macro server, the workspace `{}` is missing a sysroot: {e}", - self.manifest_or_root() - )), - } + self.sysroot.discover_proc_macro_srv() } /// Returns the roots for the current `ProjectWorkspace` @@ -580,39 +536,37 @@ impl ProjectWorkspace { /// the root is a member of the current workspace pub fn to_roots(&self) -> Vec { let mk_sysroot = || { - self.sysroot.as_ref().into_iter().flat_map(move |sysroot: &Sysroot| { - let mut r = match sysroot.mode() { - SysrootMode::Workspace(ws) => ws - .packages() - .filter_map(|pkg| { - if ws[pkg].is_local { - // the local ones are included in the main `PackageRoot`` below - return None; - } - let pkg_root = ws[pkg].manifest.parent().to_path_buf(); + let mut r = match self.sysroot.mode() { + SysrootMode::Workspace(ws) => ws + .packages() + .filter_map(|pkg| { + if ws[pkg].is_local { + // the local ones are included in the main `PackageRoot`` below + return None; + } + let pkg_root = ws[pkg].manifest.parent().to_path_buf(); - let include = vec![pkg_root.clone()]; + let include = vec![pkg_root.clone()]; - let exclude = vec![ - pkg_root.join(".git"), - pkg_root.join("target"), - pkg_root.join("tests"), - pkg_root.join("examples"), - pkg_root.join("benches"), - ]; - Some(PackageRoot { is_local: false, include, exclude }) - }) - .collect(), - SysrootMode::Stitched(_) => vec![], - }; + let exclude = vec![ + pkg_root.join(".git"), + pkg_root.join("target"), + pkg_root.join("tests"), + pkg_root.join("examples"), + pkg_root.join("benches"), + ]; + Some(PackageRoot { is_local: false, include, exclude }) + }) + .collect(), + SysrootMode::Stitched(_) | SysrootMode::Empty => vec![], + }; - r.push(PackageRoot { - is_local: false, - include: sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(), - exclude: Vec::new(), - }); - r - }) + r.push(PackageRoot { + is_local: false, + include: self.sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(), + exclude: Vec::new(), + }); + r }; match &self.kind { ProjectWorkspaceKind::Json(project) => project @@ -731,19 +685,15 @@ impl ProjectWorkspace { } pub fn n_packages(&self) -> usize { + let sysroot_package_len = self.sysroot.num_packages(); match &self.kind { - ProjectWorkspaceKind::Json(project) => { - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); - sysroot_package_len + project.n_crates() - } + ProjectWorkspaceKind::Json(project) => sysroot_package_len + project.n_crates(), ProjectWorkspaceKind::Cargo { cargo, rustc, .. } => { let rustc_package_len = rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(it, _)| it.packages().len()); - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); cargo.packages().len() + sysroot_package_len + rustc_package_len } ProjectWorkspaceKind::DetachedFile { cargo: cargo_script, .. } => { - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); sysroot_package_len + cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len()) } @@ -764,7 +714,7 @@ impl ProjectWorkspace { rustc_cfg.clone(), load, project, - sysroot.as_ref().ok(), + sysroot, extra_env, cfg_overrides, ), @@ -780,7 +730,7 @@ impl ProjectWorkspace { load, rustc.as_ref().map(|a| a.as_ref()).ok(), cargo, - sysroot.as_ref().ok(), + sysroot, rustc_cfg.clone(), cfg_overrides, build_scripts, @@ -793,7 +743,7 @@ impl ProjectWorkspace { &mut |path| load(path), None, cargo, - sysroot.as_ref().ok(), + sysroot, rustc_cfg.clone(), cfg_overrides, build_scripts, @@ -803,7 +753,7 @@ impl ProjectWorkspace { rustc_cfg.clone(), load, file, - sysroot.as_ref().ok(), + sysroot, cfg_overrides, ) }, @@ -811,9 +761,7 @@ impl ProjectWorkspace { ), }; - if matches!(sysroot.as_ref().map(|it| it.mode()), Ok(SysrootMode::Stitched(_))) - && crate_graph.patch_cfg_if() - { + if matches!(sysroot.mode(), SysrootMode::Stitched(_)) && crate_graph.patch_cfg_if() { tracing::debug!("Patched std to depend on cfg-if") } else { tracing::debug!("Did not patch std to depend on cfg-if") @@ -892,15 +840,14 @@ fn project_json_to_crate_graph( rustc_cfg: Vec, load: FileLoader<'_>, project: &ProjectJson, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, extra_env: &FxHashMap, override_cfg: &CfgOverrides, ) -> (CrateGraph, ProcMacroPaths) { let mut res = (CrateGraph::default(), ProcMacroPaths::default()); let (crate_graph, proc_macros) = &mut res; - let sysroot_deps = sysroot - .as_ref() - .map(|sysroot| sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load)); + let (public_deps, libproc_macro) = + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let r_a_cfg_flag = CfgFlag::Atom("rust_analyzer".to_owned()); let mut cfg_cache: FxHashMap<&str, Vec> = FxHashMap::default(); @@ -978,11 +925,9 @@ fn project_json_to_crate_graph( for (from_idx, krate) in project.crates() { if let Some(&from) = idx_to_crate_id.get(&from_idx) { - if let Some((public_deps, libproc_macro)) = &sysroot_deps { - public_deps.add_to_crate_graph(crate_graph, from); - if let Some(proc_macro) = libproc_macro { - add_proc_macro_dep(crate_graph, from, *proc_macro, krate.is_proc_macro); - } + public_deps.add_to_crate_graph(crate_graph, from); + if let Some(proc_macro) = libproc_macro { + add_proc_macro_dep(crate_graph, from, proc_macro, krate.is_proc_macro); } for dep in &krate.deps { @@ -999,7 +944,7 @@ fn cargo_to_crate_graph( load: FileLoader<'_>, rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>, cargo: &CargoWorkspace, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, rustc_cfg: Vec, override_cfg: &CfgOverrides, build_scripts: &WorkspaceBuildScripts, @@ -1008,10 +953,8 @@ fn cargo_to_crate_graph( let mut res = (CrateGraph::default(), ProcMacroPaths::default()); let crate_graph = &mut res.0; let proc_macros = &mut res.1; - let (public_deps, libproc_macro) = match sysroot { - Some(sysroot) => sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load), - None => (SysrootPublicDeps::default(), None), - }; + let (public_deps, libproc_macro) = + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let cfg_options = CfgOptions::from_iter(rustc_cfg); @@ -1188,15 +1131,13 @@ fn detached_file_to_crate_graph( rustc_cfg: Vec, load: FileLoader<'_>, detached_file: &ManifestPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, override_cfg: &CfgOverrides, ) -> (CrateGraph, ProcMacroPaths) { let _p = tracing::span!(tracing::Level::INFO, "detached_file_to_crate_graph").entered(); let mut crate_graph = CrateGraph::default(); - let (public_deps, _libproc_macro) = match sysroot { - Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load), - None => (SysrootPublicDeps::default(), None), - }; + let (public_deps, _libproc_macro) = + sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); let mut cfg_options = CfgOptions::from_iter(rustc_cfg); cfg_options.insert_atom("test".into()); @@ -1431,7 +1372,7 @@ fn sysroot_to_crate_graph( load, None, cargo, - None, + &Sysroot::empty(), rustc_cfg, &CfgOverrides { global: CfgDiff::new( @@ -1554,6 +1495,7 @@ fn sysroot_to_crate_graph( stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); (public_deps, libproc_macro) } + SysrootMode::Empty => (SysrootPublicDeps { deps: vec![] }, None), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 85f964b1dd93..e9a4db7a2b0d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -69,11 +69,9 @@ impl Tester { let cargo_config = CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() }; - let sysroot = - Ok(Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false) - .unwrap()); + let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Rustc(sysroot.as_ref().ok()), + RustcDataLayoutConfig::Rustc(&sysroot), None, &cargo_config.extra_env, ); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 5ee0456c15df..41996db32ea9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -1783,18 +1783,18 @@ pub(crate) fn handle_open_docs( let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => { - Some((cargo, ws.sysroot.as_ref().ok())) + Some((cargo, &ws.sysroot)) } ProjectWorkspaceKind::Json { .. } => None, ProjectWorkspaceKind::DetachedFile { .. } => None, }); let (cargo, sysroot) = match ws_and_sysroot { - Some((ws, sysroot)) => (Some(ws), sysroot), + Some((ws, sysroot)) => (Some(ws), Some(sysroot)), _ => (None, None), }; - let sysroot = sysroot.map(|p| p.root().as_str()); + let sysroot = sysroot.and_then(|p| p.root()).map(|it| it.as_str()); let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_str()); let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs index 2cf9b53f7c8d..03bd83aab5f5 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs @@ -500,7 +500,6 @@ pub struct ServerStatusParams { pub health: Health, pub quiescent: bool, pub message: Option, - pub workspace_info: Option, } #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index fd14efa1da56..627be7e951ad 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -103,7 +103,6 @@ impl GlobalState { health: lsp_ext::Health::Ok, quiescent: self.is_quiescent(), message: None, - workspace_info: None, }; let mut message = String::new(); @@ -164,53 +163,37 @@ impl GlobalState { let proc_macro_clients = self.proc_macro_clients.iter().map(Some).chain(iter::repeat_with(|| None)); - let mut workspace_info = "Loaded workspaces:\n".to_owned(); for (ws, proc_macro_client) in self.workspaces.iter().zip(proc_macro_clients) { - format_to!(workspace_info, "- `{}`\n", ws.manifest_or_root()); - format_to!(workspace_info, " - sysroot:"); - - match ws.sysroot.as_ref() { - Err(None) => format_to!(workspace_info, " None"), - Err(Some(e)) => { - status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, " {e}"); - } - Ok(s) => { - format_to!(workspace_info, " `{}`", s.root().to_string()); - if let Some(err) = s - .check_has_core() - .err() - .inspect(|_| status.health |= lsp_ext::Health::Warning) - { - format_to!(workspace_info, " ({err})"); - } - if let Some(src_root) = s.src_root() { - format_to!( - workspace_info, - "\n - sysroot source: `{}`", - src_root - ); - } - format_to!(workspace_info, "\n"); - } - } - - if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(e)), .. } = &ws.kind { + if let Some(err) = ws.sysroot.error() { status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, " - rustc workspace: {e}\n"); + format_to!( + message, + "Workspace `{}` has sysroot errors: ", + ws.manifest_or_root() + ); + message.push_str(err); + message.push_str("\n\n"); + } + if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(err)), .. } = &ws.kind { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Failed loading rustc_private crates for workspace `{}`: ", + ws.manifest_or_root() + ); + message.push_str(err); + message.push_str("\n\n"); }; - if let Some(proc_macro_client) = proc_macro_client { - format_to!(workspace_info, " - proc-macro server: "); - match proc_macro_client { - Ok(it) => format_to!(workspace_info, "`{}`\n", it.path()), - Err(e) => { - status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, "{e}\n") - } - } + if let Some(Err(err)) = proc_macro_client { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Failed spawning proc-macro server for workspace `{}`: {err}", + ws.manifest_or_root() + ); + message.push_str("\n\n"); } } - status.workspace_info = Some(workspace_info); } if !message.is_empty() { @@ -534,8 +517,8 @@ impl GlobalState { .map(|(a, b)| (a.clone(), b.clone())) .chain( ws.sysroot - .as_ref() - .map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.root().to_string())), + .root() + .map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.to_string())), ) .collect(), @@ -719,7 +702,7 @@ impl GlobalState { } ProjectWorkspaceKind::DetachedFile { .. } => return None, }, - ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()), + ws.sysroot.root().map(ToOwned::to_owned), )) }) .map(|(id, (root, manifest_path), sysroot_root)| { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs index 59b229cd0645..66481d3d7f5e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs @@ -21,7 +21,7 @@ fn load_cargo_with_fake_sysroot(file: &str) -> ProjectWorkspace { rustc: Err(None), cargo_config_extra_env: Default::default(), }, - sysroot: Ok(get_fake_sysroot()), + sysroot: get_fake_sysroot(), rustc_cfg: Vec::new(), cfg_overrides: Default::default(), toolchain: None, @@ -69,7 +69,7 @@ fn get_fake_sysroot() -> Sysroot { // fake sysroot, so we give them both the same path: let sysroot_dir = AbsPathBuf::assert_utf8(sysroot_path); let sysroot_src_dir = sysroot_dir.clone(); - Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false) + Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false) } #[test] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 5a1397bbb0e7..d886e405e14e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -1059,11 +1059,11 @@ fn resolve_proc_macro() { return; } - let sysroot = project_model::Sysroot::discover_no_source( + let sysroot = project_model::Sysroot::discover( &AbsPathBuf::assert_utf8(std::env::current_dir().unwrap()), &Default::default(), - ) - .unwrap(); + false, + ); let proc_macro_server_path = sysroot.discover_proc_macro_srv().unwrap(); diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md index 46c1ccb79bf9..c8728c33ea09 100644 --- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@ $DIR/suggest-method-on-call-for-ambig-receiver.rs:10:13 + | +LL | consume(right); + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From c58b7c9c81cf150bf307ca13375f12fb1c8f6420 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 May 2024 19:48:54 -0400 Subject: [PATCH 057/101] Don't skip inner const when looking for body for suggestion --- compiler/rustc_hir_typeck/src/coercion.rs | 9 +++------ .../return/dont-suggest-through-inner-const.rs | 9 +++++++++ .../dont-suggest-through-inner-const.stderr | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 tests/ui/return/dont-suggest-through-inner-const.rs create mode 100644 tests/ui/return/dont-suggest-through-inner-const.stderr diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 11a1c65b7495..ebdc558282a9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1871,11 +1871,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If this is due to a block, then maybe we forgot a `return`/`break`. if due_to_block && let Some(expr) = expression - && let Some((parent_fn_decl, parent_id)) = fcx - .tcx - .hir() - .parent_iter(block_or_return_id) - .find_map(|(_, node)| Some((node.fn_decl()?, node.associated_body()?.0))) + && let Some(parent_fn_decl) = + fcx.tcx.hir().fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) { fcx.suggest_missing_break_or_return_expr( &mut err, @@ -1884,7 +1881,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expected, found, block_or_return_id, - parent_id, + fcx.body_id, ); } diff --git a/tests/ui/return/dont-suggest-through-inner-const.rs b/tests/ui/return/dont-suggest-through-inner-const.rs new file mode 100644 index 000000000000..b2347dedd52d --- /dev/null +++ b/tests/ui/return/dont-suggest-through-inner-const.rs @@ -0,0 +1,9 @@ +const fn f() -> usize { + //~^ ERROR mismatched types + const FIELD: usize = loop { + 0 + //~^ ERROR mismatched types + }; +} + +fn main() {} diff --git a/tests/ui/return/dont-suggest-through-inner-const.stderr b/tests/ui/return/dont-suggest-through-inner-const.stderr new file mode 100644 index 000000000000..6aeee74b0adf --- /dev/null +++ b/tests/ui/return/dont-suggest-through-inner-const.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-through-inner-const.rs:4:9 + | +LL | 0 + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/dont-suggest-through-inner-const.rs:1:17 + | +LL | const fn f() -> usize { + | - ^^^^^ expected `usize`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 72b71710318e2da2a230f3cc01686b006e85ebe6 Mon Sep 17 00:00:00 2001 From: ltdk Date: Tue, 9 Apr 2024 02:01:21 -0400 Subject: [PATCH 058/101] Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods --- library/core/src/lib.rs | 1 + library/core/src/num/int_macros.rs | 99 +++++++++++++++---- library/core/src/num/mod.rs | 1 + library/core/src/num/uint_macros.rs | 80 ++++++++++++--- library/core/src/ops/index_range.rs | 11 +-- library/core/src/ptr/const_ptr.rs | 3 +- library/core/src/ptr/mut_ptr.rs | 3 +- library/core/src/ptr/non_null.rs | 3 +- library/core/src/slice/index.rs | 5 +- ...l_unsigned_smaller.Inline.panic-abort.diff | 22 ++++- ..._unsigned_smaller.Inline.panic-unwind.diff | 22 ++++- ...d_smaller.PreCodegen.after.panic-abort.mir | 4 + ..._smaller.PreCodegen.after.panic-unwind.mir | 4 + ..._shr_signed_bigger.Inline.panic-abort.diff | 22 ++++- ...shr_signed_bigger.Inline.panic-unwind.diff | 22 ++++- ...ed_bigger.PreCodegen.after.panic-abort.mir | 4 + ...d_bigger.PreCodegen.after.panic-unwind.mir | 4 + ...ecked_shl.PreCodegen.after.panic-abort.mir | 4 + ...cked_shl.PreCodegen.after.panic-unwind.mir | 4 + ...mut_range.PreCodegen.after.panic-abort.mir | 47 ++------- ...ut_range.PreCodegen.after.panic-unwind.mir | 47 ++------- ...ked_range.PreCodegen.after.panic-abort.mir | 35 +------ ...ed_range.PreCodegen.after.panic-unwind.mir | 35 +------ 23 files changed, 289 insertions(+), 193 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index dcf68b36c7a2..6b3ce47da414 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -191,6 +191,7 @@ #![feature(str_split_remainder)] #![feature(strict_provenance)] #![feature(ub_checks)] +#![feature(unchecked_neg)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 77b1039039b1..b8b4f581a7e6 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -488,9 +488,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with an unsigned integer. Computes `self + rhs`, @@ -630,9 +640,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked subtraction with an unsigned integer. Computes `self - rhs`, @@ -772,9 +792,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` @@ -1111,9 +1141,22 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_neg`. - unsafe { intrinsics::unchecked_sub(0, self) } + // ICE resolved by #125184 isn't in bootstrap compiler + #[cfg(not(bootstrap))] + { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), + ( + lhs: $SelfT = self, + ) => !lhs.overflowing_neg().1, + ); + } + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(0, self) + } } /// Strict negation. Computes `-self`, panicking if `self == MIN`. @@ -1234,9 +1277,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -1323,9 +1376,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked absolute value. Computes `self.abs()`, returning `None` if diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 09a341e4d80a..ab1ede38979d 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -7,6 +7,7 @@ use crate::hint; use crate::intrinsics; use crate::mem; use crate::str::FromStr; +use crate::ub_checks::assert_unsafe_precondition; // Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 446d0658c126..141d164de14a 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -495,9 +495,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with a signed integer. Computes `self + rhs`, @@ -677,9 +687,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked integer multiplication. Computes `self * rhs`, returning @@ -763,9 +783,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` @@ -1334,9 +1364,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -1423,9 +1463,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + bits: u32 = Self::BITS, + ) => rhs < bits, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 65bda9177c7b..64214eae377d 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -1,4 +1,3 @@ -use crate::intrinsics::{unchecked_add, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen}; use crate::num::NonZero; use crate::ub_checks; @@ -46,7 +45,7 @@ impl IndexRange { #[inline] pub const fn len(&self) -> usize { // SAFETY: By invariant, this cannot wrap - unsafe { unchecked_sub(self.end, self.start) } + unsafe { self.end.unchecked_sub(self.start) } } /// # Safety @@ -57,7 +56,7 @@ impl IndexRange { let value = self.start; // SAFETY: The range isn't empty, so this cannot overflow - self.start = unsafe { unchecked_add(value, 1) }; + self.start = unsafe { value.unchecked_add(1) }; value } @@ -68,7 +67,7 @@ impl IndexRange { debug_assert!(self.start < self.end); // SAFETY: The range isn't empty, so this cannot overflow - let value = unsafe { unchecked_sub(self.end, 1) }; + let value = unsafe { self.end.unchecked_sub(1) }; self.end = value; value } @@ -83,7 +82,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_add(self.start, n) } + unsafe { self.start.unchecked_add(n) } } else { self.end }; @@ -102,7 +101,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_sub(self.end, n) } + unsafe { self.end.unchecked_sub(n) } } else { self.start }; diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c8065b2e7090..8c02aee8bfb4 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1080,6 +1080,7 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1093,7 +1094,7 @@ impl *const T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c53953400add..7c685156cbb0 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1224,6 +1224,7 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1237,7 +1238,7 @@ impl *mut T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 617890cf083b..aac5c745d635 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -701,6 +701,7 @@ impl NonNull { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -712,7 +713,7 @@ impl NonNull { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 8d7b6165510a..98513340a474 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,7 +1,6 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::const_eval_select; -use crate::intrinsics::unchecked_sub; use crate::ops; use crate::ptr; use crate::ub_checks::assert_unsafe_precondition; @@ -374,7 +373,7 @@ unsafe impl SliceIndex<[T]> for ops::Range { // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, // so the call to `add` is safe and the length calculation cannot overflow. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) } } @@ -392,7 +391,7 @@ unsafe impl SliceIndex<[T]> for ops::Range { ); // SAFETY: see comments for `get_unchecked` above. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff index a624ab78dad1..652e24a5f8ec 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -8,6 +8,12 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::::unchecked_shl::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShlUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff index 81a0a5b39f71..dbcae605f769 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff @@ -8,6 +8,12 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::::unchecked_shl::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShlUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir index 9e3802b7501f..dc27685ee79b 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir @@ -5,6 +5,10 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { debug b => _2; let mut _0: u16; scope 1 (inlined core::num::::unchecked_shl) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir index 9e3802b7501f..dc27685ee79b 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir @@ -5,6 +5,10 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { debug b => _2; let mut _0: u16; scope 1 (inlined core::num::::unchecked_shl) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff index a2b3ad4b3bab..88d0621c2877 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff @@ -8,6 +8,12 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::::unchecked_shr::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShrUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff index 2ff6b532d61f..6d4c73cf576a 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff @@ -8,6 +8,12 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { ++ let mut _5: bool; ++ let _6: (); ++ scope 2 (inlined core::ub_checks::check_language_ub) { ++ scope 3 (inlined core::ub_checks::check_language_ub::runtime) { ++ } ++ } + } bb0: { @@ -16,10 +22,20 @@ StorageLive(_4); _4 = _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue]; -- } -- -- bb1: { ++ StorageLive(_6); ++ StorageLive(_5); ++ _5 = UbChecks(); ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; + } + + bb1: { ++ _6 = core::num::::unchecked_shr::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ } ++ ++ bb2: { ++ StorageDead(_5); + _0 = ShrUnchecked(_3, _4); ++ StorageDead(_6); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir index f3961982648a..54f093b87d19 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir @@ -5,6 +5,10 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 { debug b => _2; let mut _0: i64; scope 1 (inlined core::num::::unchecked_shr) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir index f3961982648a..54f093b87d19 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir @@ -5,6 +5,10 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 { debug b => _2; let mut _0: i64; scope 1 (inlined core::num::::unchecked_shr) { + scope 2 (inlined core::ub_checks::check_language_ub) { + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } bb0: { diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir index af0a0efc2a66..4edf0d2c47c0 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir @@ -8,6 +8,10 @@ fn checked_shl(_1: u32, _2: u32) -> Option { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::::unchecked_shl) { + scope 3 (inlined core::ub_checks::check_language_ub) { + scope 4 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } } diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir index af0a0efc2a66..4edf0d2c47c0 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir @@ -8,6 +8,10 @@ fn checked_shl(_1: u32, _2: u32) -> Option { let mut _3: bool; let mut _4: u32; scope 2 (inlined core::num::::unchecked_shl) { + scope 3 (inlined core::ub_checks::check_language_ub) { + scope 4 (inlined core::ub_checks::check_language_ub::runtime) { + } + } } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 62fe1a868578..ef3f4a217200 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -4,47 +4,20 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> debug slice => _1; debug index => _2; let mut _0: &mut [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined core::slice::::get_unchecked_mut::>) { - let mut _5: *mut [u32]; - let mut _9: *mut [u32]; - scope 2 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { - let _6: usize; - let mut _7: *mut u32; - let mut _8: *mut u32; - scope 3 { - scope 6 (inlined std::ptr::mut_ptr::::as_mut_ptr) { - } - scope 7 (inlined std::ptr::mut_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts_mut::) { - } - } - scope 4 (inlined std::ptr::mut_ptr::::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } + let mut _3: *mut [u32]; + let mut _4: *mut [u32]; } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = SubUnchecked(_4, _3); - StorageLive(_8); - StorageLive(_7); - _7 = _5 as *mut u32 (PtrToPtr); - _8 = Offset(_7, _3); - StorageDead(_7); - _9 = *mut [u32] from (_8, _6); - StorageDead(_8); - StorageDead(_6); - StorageDead(_5); - _0 = &mut (*_9); + StorageLive(_3); + _3 = &raw mut (*_1); + _4 = as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); + _0 = &mut (*_4); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 62fe1a868578..9e93a43ac725 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -4,47 +4,20 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> debug slice => _1; debug index => _2; let mut _0: &mut [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined core::slice::::get_unchecked_mut::>) { - let mut _5: *mut [u32]; - let mut _9: *mut [u32]; - scope 2 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { - let _6: usize; - let mut _7: *mut u32; - let mut _8: *mut u32; - scope 3 { - scope 6 (inlined std::ptr::mut_ptr::::as_mut_ptr) { - } - scope 7 (inlined std::ptr::mut_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts_mut::) { - } - } - scope 4 (inlined std::ptr::mut_ptr::::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } + let mut _3: *mut [u32]; + let mut _4: *mut [u32]; } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = &raw mut (*_1); - StorageLive(_6); - _6 = SubUnchecked(_4, _3); - StorageLive(_8); - StorageLive(_7); - _7 = _5 as *mut u32 (PtrToPtr); - _8 = Offset(_7, _3); - StorageDead(_7); - _9 = *mut [u32] from (_8, _6); - StorageDead(_8); - StorageDead(_6); - StorageDead(_5); - _0 = &mut (*_9); + StorageLive(_3); + _3 = &raw mut (*_1); + _4 = as SliceIndex<[u32]>>::get_unchecked_mut(move _2, move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); + _0 = &mut (*_4); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir index 000432ccca7d..650069ee6cea 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir @@ -4,41 +4,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - debug slice => _1; debug index => _2; let mut _0: *const [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined std::ptr::const_ptr::::get_unchecked::>) { - scope 2 (inlined as SliceIndex<[u32]>>::get_unchecked) { - let _5: usize; - let mut _6: *const u32; - let mut _7: *const u32; - scope 3 { - scope 6 (inlined std::ptr::const_ptr::::as_ptr) { - } - scope 7 (inlined std::ptr::const_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts::) { - } - } - scope 4 (inlined std::ptr::const_ptr::::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = SubUnchecked(_4, _3); - StorageLive(_7); - StorageLive(_6); - _6 = _1 as *const u32 (PtrToPtr); - _7 = Offset(_6, _3); - StorageDead(_6); - _0 = *const [u32] from (_7, _5); - StorageDead(_7); - StorageDead(_5); + _0 = as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind unreachable]; + } + + bb1: { return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir index 000432ccca7d..74e8158e7543 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir @@ -4,41 +4,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range) - debug slice => _1; debug index => _2; let mut _0: *const [u32]; - let mut _3: usize; - let mut _4: usize; scope 1 (inlined std::ptr::const_ptr::::get_unchecked::>) { - scope 2 (inlined as SliceIndex<[u32]>>::get_unchecked) { - let _5: usize; - let mut _6: *const u32; - let mut _7: *const u32; - scope 3 { - scope 6 (inlined std::ptr::const_ptr::::as_ptr) { - } - scope 7 (inlined std::ptr::const_ptr::::add) { - } - scope 8 (inlined slice_from_raw_parts::) { - } - } - scope 4 (inlined std::ptr::const_ptr::::len) { - scope 5 (inlined std::ptr::metadata::<[u32]>) { - } - } - } } bb0: { - _3 = move (_2.0: usize); - _4 = move (_2.1: usize); - StorageLive(_5); - _5 = SubUnchecked(_4, _3); - StorageLive(_7); - StorageLive(_6); - _6 = _1 as *const u32 (PtrToPtr); - _7 = Offset(_6, _3); - StorageDead(_6); - _0 = *const [u32] from (_7, _5); - StorageDead(_7); - StorageDead(_5); + _0 = as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind continue]; + } + + bb1: { return; } } From 5888de8cbe20589846f459bb35bfa26206c81e50 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Thu, 23 May 2024 22:47:27 -0400 Subject: [PATCH 059/101] tidy: validate LLVM component names in tests LLVM component names are not immediately obvious (they usually omit any suffixes on the target arch name), and if they're incorrect, the test will silently never run. --- src/tools/tidy/src/target_specific_tests.rs | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index c876aae494dd..5a402f3cc601 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -10,6 +10,25 @@ use crate::walk::filter_not_rust; const LLVM_COMPONENTS_HEADER: &str = "needs-llvm-components:"; const COMPILE_FLAGS_HEADER: &str = "compile-flags:"; +const KNOWN_LLVM_COMPONENTS: &[&str] = &[ + "aarch64", + "arm", + "avr", + "bpf", + "hexagon", + "loongarch", + "m68k", + "mips", + "msp430", + "nvptx", + "powerpc", + "riscv", + "sparc", + "systemz", + "webassembly", + "x86", +]; + #[derive(Default, Debug)] struct RevisionInfo<'a> { target_arch: Option<&'a str>, @@ -68,6 +87,17 @@ pub fn check(path: &Path, bad: &mut bool) { // gathered. } } + if let Some(llvm_components) = llvm_components { + for component in llvm_components { + if !KNOWN_LLVM_COMPONENTS.contains(component) { + eprintln!( + "{}: revision {} specifies unknown LLVM component `{}`", + file, rev, component + ); + *bad = true; + } + } + } } }); } From 1eda5805168172d5f9aa00f9f1d872e8ebbb78a9 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 24 May 2024 08:05:37 +0200 Subject: [PATCH 060/101] Bump bootstrap compiler to the latest beta compiler --- src/stage0 | 856 ++++++++++++++++++++++++++--------------------------- 1 file changed, 428 insertions(+), 428 deletions(-) diff --git a/src/stage0 b/src/stage0 index 5ec8f5b715e0..72f50b787a7a 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,434 +14,434 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-04-29 +compiler_date=2024-05-24 compiler_version=beta -rustfmt_date=2024-04-29 +rustfmt_date=2024-05-24 rustfmt_version=nightly -dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz=5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb -dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz=0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2 -dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f -dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz=7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81 -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz=a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891 -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz=2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c -dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e -dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c -dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz=d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84 -dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz=65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db -dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz=d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403 -dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz=23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba -dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz=b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c -dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz=6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9 -dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae -dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da -dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d -dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c -dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c -dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3 -dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9 -dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f -dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3 -dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a -dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz=c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e -dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz=47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee -dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz=f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791 -dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz=96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz=517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz=a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz=4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e -dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz=08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7 -dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz=9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815 -dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz=7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6 -dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz=4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0 -dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz=0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz=0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445 -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz=70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13 -dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz=f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a -dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz=53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40 -dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz=7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c -dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz=2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62 -dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz=90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736 -dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz=f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73 -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807 -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz=4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz=3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03 -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399 -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5 -dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd -dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a -dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz=325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588 -dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz=536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123 -dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz=c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b -dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz=0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245 -dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz=c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511 -dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz=6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304 -dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93 -dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514 -dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6 -dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8 -dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737 -dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf -dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4 -dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e -dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9 -dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f -dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz=3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7 -dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz=0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1 -dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz=9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326 -dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz=49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af -dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6 -dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz=0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb -dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz=52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab -dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz=8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6 -dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz=509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d -dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz=2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f -dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz=ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0 -dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz=5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9 -dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz=1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328 -dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz=da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4 -dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz=2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5 -dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz=bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529 -dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz=9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e -dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz=50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c -dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz=56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751 -dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz=3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163 -dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz=bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03 -dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz=46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8 -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4 -dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66 -dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz=96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz=3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89 -dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz=8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2 -dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz=80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff -dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz=2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de -dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz=9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz=345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz=6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz=a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz=3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554 -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4 -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c -dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz=6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f -dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz=9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc -dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz=cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8 -dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz=8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f -dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz=e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4 -dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz=d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab -dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz=1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1 -dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz=4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0 -dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz=ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8 -dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz=fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2 -dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz=6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568 -dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b -dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz=26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e -dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz=c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065 -dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz=f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea -dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz=f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz=8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0 -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz=4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a -dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz=e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08 -dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz=a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e -dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz=d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11 -dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz=4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz=1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz=98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a -dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz=dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz=f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29 -dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz=3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887 -dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz=72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz=e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz=364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9 -dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a -dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c -dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39 -dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60 -dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270 -dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49 -dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7 -dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af -dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd -dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52 -dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a -dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a -dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c -dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab -dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271 -dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec -dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17 -dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba -dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5 -dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657 -dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6 -dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd -dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7 -dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa -dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz=25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9 -dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz=5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554 -dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz=a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d -dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz=4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz=32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz=112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz=7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz=49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36 -dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz=518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845 -dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz=2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394 -dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17 -dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3 -dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc -dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45 -dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9 -dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb -dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz=731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709 -dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz=8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07 -dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz=7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0 -dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz=d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b -dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz=07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3 -dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz=79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744 -dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz=b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938 -dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz=2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11 -dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz=792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0 -dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz=abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e -dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz=0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b -dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz=c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045 -dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz=7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0 -dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz=f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2 -dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556 -dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e -dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz=5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f -dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz=9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b -dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz=d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70 -dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz=6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7 -dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz=340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4 -dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz=69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a -dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f -dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d -dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313 -dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz=7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a -dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz=57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee -dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz=e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6 -dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz=d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce -dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz=5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97 -dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz=0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2 -dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz=b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651 -dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz=24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1 -dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz=1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc -dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz=ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2 -dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz=e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4 -dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz=52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13 -dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz=843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9 -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9 -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz=40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz=804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1 -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085 -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc -dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd -dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc -dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz=de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1 -dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz=a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b -dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz=88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db -dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz=1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9 -dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz=3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18 -dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz=2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f -dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b -dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2 -dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec -dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f -dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651 -dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201 -dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249 -dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a -dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71 -dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb -dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz=664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a -dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz=a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d -dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz=59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3 -dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz=f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff -dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz=f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz=045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz=398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9 -dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz=38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17 -dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz=786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff -dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz=7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618 -dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz=bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56 -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866 -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz=87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz=469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67 -dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz=4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf -dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz=45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1 -dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz=0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f -dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz=143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46 -dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e -dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4 -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99 -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37 -dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914 -dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98 -dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58 -dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54 -dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4 -dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7 -dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a -dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad -dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15 -dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c -dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c -dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272 -dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa -dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c -dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b -dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e -dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1 -dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed -dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be -dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb -dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz=64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c -dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz=0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244 -dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca -dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e -dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35 -dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc -dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a -dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275 -dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d -dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe -dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752 -dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb -dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f -dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0 -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39 -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942 -dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf -dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e -dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd -dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57 -dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac -dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08 -dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8 -dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e -dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87 -dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c -dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5 -dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20 -dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd -dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe -dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470 -dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927 -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28 -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308 \ No newline at end of file +dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=502e7f1a05acd503079654dca24a1a9945452580d835d0b6a2cc21155837a4c7 +dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=0bcf49fe166183955a27a0be2e83aa6d6ee9820a475323d8f61c6b159960d3f8 +dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.gz=234d90368b765cbe8824068eb2d21ca4c9d7f5cd401f686ef5b338a1781d1468 +dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.xz=085cc56230431db4c6088e0f9c4d63fb5af2a7064a5a7e21d5d19be1d3026d18 +dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.gz=790bcf8e2fe47efc4a0071093df383d70c3383ba3290aaa2f6b5eade8e2f35f0 +dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.xz=7f8df95a04a6e57db99fb84d60baeddef4a69f13f026f5cc5719a8b6c231d4b8 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=939759a91a408b4ecd8921e0cf07676cc473d1c23a2021a57f0f8b04465e9ed4 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=5ac62bb9f5d7e7e499598f5579156e593d07c91eadfd1326b29f2bea29122164 +dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.gz=134d09a9f7c51f1862f1b361da5608bdae02bef2fdb994e30404a8b0e309b7d6 +dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.xz=c3eae7e3583a6f4e68d388a73d2414ca355ef98215417f908ac81e1ea90b2d51 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=0f9aa17c2a8748cdf06bbd77bb948ba65794b89587744839db503bb0988e0824 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=390c430ffe5f237d547ae2c93a058122d3b8fbf4ea71b20018f0f8bf83858398 +dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=bf6a18c4f54921c46d90fe2a53f6e3044a32f327d6cd13e8308db683a428aef7 +dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=27dcf104f3ca958f0ef3bed47c26e3318e545d1de06f27bf9b25aac97a21c06b +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.gz=07c74d5cc87fba304d33ac7844a1e762225f9ec8ca5a5c6b7bab4c427ffed80a +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.xz=08b6c39e9315c0eee5174d540851c6530e6b1c900db4396fdf8a967b88d69a75 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.gz=c3aa3cead301f7081c88b5bbd0c0b5a24eab203cbdb2d772ed0ddba8e3034928 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.xz=943a3fd053657bce6cafb589665c5ad98d5c453ab7c594650ed8c3cd15356647 +dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b8db693c04ad41d1e90b7a3bec7f41a0a21872a220342742402dcd0cb4f28799 +dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.xz=ec509af079e002d181b092f1a9e768744656b93fc78466efad8fac567d2184f1 +dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=50f60b246b50778720557f16e87cc19373dd44a77e423bc1e2db1e504557cb58 +dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=ed2a36058a7f0a2393309fbbe435a0c498ab682e91d757f6d70d9c16091dd646 +dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.gz=9b931dc596fd980a66507ca9c83b17c4e6d376a9741361a41dfb176f41b4bd2c +dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.xz=e1bb3f44adf89ff9900ed3bdabb7ab386018c8894d6d92c68f3881077f777a1c +dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.gz=c5427a8ba5dc41aa00b8194c49b711685a6c6bd0674ab93ec44b953897def2f4 +dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.xz=274545121eb6003eb52fddf030f8893ad63cebee564648dbef312aa28853cb54 +dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.gz=36185524fe00de47a92cb0fb766a4a7afadee469cd5f1ef1345ac24364499425 +dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.xz=7681b6695ac56c50277318fb9deec495fcadcb266a763f1ad3d19b88c9a520fb +dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d1115327b8cfb23e60a70510f78e39329f2092a0a99763b2cbd25929c41cb24f +dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=7bb0b5b15e5218d9e4554ff2eec03cbe2fde2e957f954fa08aa7079b334bad05 +dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.gz=6a46a111e30efc6f8f090b2c9e547465e6fcf836b9433fc1f8c53276a0ef63fb +dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.xz=9516471cb5d3377e1430e64171b7a289bd8a8674032d73c739e0cffa85e87e92 +dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.gz=63331eea78233ec4ee4d9390a509a587bbb6e07ce0748fca36cf93a0f4ecb216 +dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.xz=b668abe9cb4c5366ee866f8e399ced6c9a8b560f5e5adbe7d6c07058762be21d +dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.gz=076e95ca2413fc3f07257ce0b94212db0331e797679a60695929cb588c6047cf +dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.xz=d1d006a216c2358a33000e400b5a2c223ee0ab875cfd57eca95b9bd230494d62 +dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.gz=48ccaab8b59f8bb3e1e0fb82368b79d317e66e4b6a2c6d18d0d49b32e96b2e95 +dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.xz=a050b10d6f67c1f1d2cdb2425ffb51445ade293328ec3e235400c151a447beb9 +dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=21f26e3028f1174184be66ce88597e1551d2dbf7d9458f528f15366c6cf52c30 +dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=fe504571f52c9eaba68fcc07398db049e3dd6131daa14c2b999540b84cec4885 +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=082828da023201d2b8f84e686d727f77b76a71c929c5588098d8c4609ffca336 +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=13bf4a5f012b29334dececacfe16ab6755f7b97165229cff7c27d37b6acb455f +dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=f4584c00af06eb05e6f238f3ce8cbb39ace84e3aad7a3b158b5bb591e522eab8 +dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=8fe01de1853880df20e355ba3925eb1cc537a6fb6aca53b638ee74f689f15cdf +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=7a24b865db48708120ad670811238fccfd054bba0a92d6b436237c0726678413 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=3716d2a3896a2f3cb774c265e58d29e4f8ea35228261f499b96887cb40ff5cd9 +dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.gz=336dd7b17d5ea546f359fff5e7697f82022b0710e1d6ab513370f21741d6f737 +dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.xz=829a078f5d4126d90e117c2c5d31f259b3ba4960b834830c0e49a23ce3bb339f +dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.gz=3522e09c17465ceda12ad69adc341cda01171cc7275623ea55cc0a56611fcff9 +dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.xz=d71dac0e0316928d2e5c83c092fab2605b3e46b75a0de867e838067a5134851d +dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.gz=d9fe62eafe589b5223097d35104c5d32b623e98a0e60284254770dc5a760ded8 +dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.xz=0ed3d3b74882594f08be828a491bad42c5b73914c461346e634a38dbf609de0e +dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.gz=850236f8f00bfdf0f032a2f4b2c3ee1c71ddd7fe11a87648066eb63801d302ff +dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.xz=db1c182ddbb3276752c16d4d9c9ee94f97b426349fb44a456c276268c4aa8be4 +dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=ce22565ddab95e2f43abc8a864787820f3b1dd0a0f174639b90c26726da667ab +dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=214c16191cc3a3623a7b8d3a995c50132c03f90b3fad0d08927a5e449ea13923 +dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.gz=478c1de19c252d581b4438af70b37b36c0bd240e5bf5ca5ba4e752438e80707b +dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.xz=0948aa34ea060445ca2a410df33622a9228f3fe0f24a94442799568b251c1e10 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=e139b5a0151a1a3ff8e6bc94ff856522be558cffbf51fd76a434591e30d51ccd +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=dccf2fcff4e0980b3e0edd30a565c6bc3f994812f2acce9c7a07eb6ea8ad84ab +dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.gz=2f6aff225189a507b79e84388b69fdcfe12ac29a6a955cd60d34298bb7435c79 +dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.xz=2b623f3318ff77aada72d0ca8ce46e807f8e4833dd74717d1a4102f1ee3bef78 +dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.gz=85e016d2c36da363618b184576e35263034ef0291e8a36f9380879917e757f67 +dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.xz=fb0be15c71068cdec7e8b75f6ebcf1094d610c0e41d1cec08c2031d8583d10c5 +dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.gz=96c68111c9a491f816f56ae8f1f552ce31738fa9b9d9d00e42c2d1f0a3628ef0 +dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.xz=a6e20d5c434cbe9b86e406c6132d1986489fe76168be7a60b6459b0f2691877b +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=933e7b14c199d36f6eb51ae6527c9af2d094ec13bb1299bcf8c72ba9b0d69515 +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=ade7325d0787ade9c3122a042baf7238ba5d493a6b7b7ea311421e11a15586cb +dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8816d3c9fbe0dfadfab0ba7db858bfd32546161f6460b4c9160a4e77ab54ac8f +dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=da52d6feb060edada6fb0f747ef1c1ea658f2070c024a873c69ba909ade175b2 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b699e48e19a1860132719487bf287a3a3f014257182a53b4ed95f1316f401fec +dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=402cad3c14a356f7345bb8cc93ef7186fd09b4ae1abdd13bc020c7e424a941d3 +dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.gz=d875d0e34057c77c34e2020310f33a56f08f3b063b202f513be8de96319e9e4b +dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.xz=3f489181280332f0d7169f656d03252f7de43b84a6fd6de9fb9c6906c09f7b72 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=072503fd29be4101f8e1f75bad03a5b2486fd2e8e2f217f651d6cee2e0b2f032 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=b96a542616a05b2ccaad49d9e22273341df7000ca63e4eb91ee219e8b931f4b0 +dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.gz=ccae6a247c76bbe08216faad0faff0d2052982baa1cba8d403f3182bd3d92e46 +dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.xz=ceb781289ab079bbab947f366eeb4087b04082326c4f935c78b3887351fe6c89 +dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.gz=ed888cc3847b8616d50e80d6c3c0116c8c0e73c6b7fc3b39bb04bced9fb8d9fa +dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.xz=51ef73968d5e9ae2b7d857befa8827aac37c490f2051f526ad1b5089ee9fa550 +dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=226d46a2cf4e5c58f1ad1357bfc607d23c195122c7a74a5ddb6636ed35d295a4 +dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=27e68d85bfbc8302e68aea58bc57d1d8ff038a0eee7629f17f479d0ea1a6acaa +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=132be65f60c5d0b7d6293495acf51559b8855c80498befe98d6cef752deb1a71 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=7f938a1bfcea115c99e7e813c9737f86788d78af8f97265ce8f7ebde52dca54b +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=186c252edf1497a5f559dabbd8245491e3fef7caa6a80b5dc989275caeed95af +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=3be2944eee2ec57d7ae3d2eb87b7b1881590adaa68c5c6851fa7c027b4f7c4a1 +dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=ae9bfb56c1be153d29371a75141471f676cdf5ec6e8b6af252f4a6f3a1054712 +dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=1387267e76f332fdfaea426468a45ad5d967f1ee9a211b9b72c6cace0b746ad1 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=ef44a8ad9b1e07d240a00a2bec592d4f19a099ddfd8b2398f4ea2d50216548e0 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=25d0da3cc4616bf6778af8277341b3e436300865245d016a370892d1afcfef31 +dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.gz=d5da4fed34f7c008e6365475e2c9a8ac6b74468839fe017827e3c884fca95b1c +dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.xz=7aeade644917bfb22fe68f427a46e21834d45fcc626755b0af806ae28d018518 +dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.gz=3c5d32303ca72eb469730421945f2d2216f8f96aa160d11d6b2e38c6350763dd +dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.xz=9705313b0e7d696b4e7c4ae6201e1dd2a02c51b5d0caac730591419322462f0a +dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.gz=afc32902cd96bfd1c72e5d2cda240a2275f8b8262a0f952e53b39bdf267ffe18 +dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.xz=8a34c9025601a2ee0dabce89ec195fa3bf990986517955768409f3620ae90efa +dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=dddbace8cce3233b6a906ea75032e21c7f2a07be131ff7c356f9d7d59bf90fee +dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=b833758c5555d8805191527f676a20ba6e902fb4da538df8795c5282f495ab65 +dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.gz=2750fc63254bdb773423483808363048126f20246d8d1a26800d06dc7489807c +dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.xz=ccef9823e93948996965f9ed2e73f9dd1638a840c57ef96e5c8df525ac241af3 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=47ebc0eb1bbfa824df620a73d1253f22dda9a2f0810c9b6c542e4a3ed545e899 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=6b5d87a1de21c15352121a9380449ae1df9e49b983ffa2431e3e2767a1b36501 +dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=6e3adc75a553a2d97214d2147340ce23a09a2cad1f5e411048b17f74cc735128 +dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=473c1a57e19527a5a710b5ee59692a1f9d0759d5163de0337e061b006765f197 +dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.gz=eebbea699b2cd32d14123af5ce49ed2fc81f8b2b8de8a83048bdaaae3d0ddbd9 +dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.xz=2a9591eeebfa1ebb4af31ec8c0929b9bdb353ed92c1f22f4a5651d0578a6a5fb +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=036a0bea6dbf65183a3d772fe2cf79c9ad86100274680b639e23683b5a29aa6a +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ebb328a83ad6cdee2e2b26fce63e6ad57293726a59352eb7bb9ac2d022504c33 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.gz=254ba6539d9c7b3b7d1b7ef92056c8c4dc7a9378da7da2575b4010cdbf9ca718 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.xz=9dfb77901799850f50ae983d05aa9467fbf50d0995b3dd1de880dcb48663706c +dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.gz=d99a69e9dd172506a73412c5d3b338a0df798ef77e20e5d8376989d74ada2289 +dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.xz=35f9022e3aff144157a504e73107cdc4fd7aab4e175eb193d240cdbc539d587f +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=aca1d6e2bafd7a446a52bd5a6b6daddb36a2e76f29ffac3ba17cc47f80c2af9c +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=f967c44f7ed974abf292f4b77ddf1e875f08eecb9f8ad930f7d22ca49253b59e +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.gz=61da28d58e15c845d96ae5c1aa93710c47cc3f1903e001bac55e208ea76693a5 +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.xz=6aae3ee172ed6ea5c4f547841c70bfbf26879698c984c4b94f295846282a8643 +dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=aa7cd934f8d17ed79c1d5e37acd67e3f988a0b727a72960b7d9858f965694c19 +dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=2ab9fe2d4e6679ab880ff27addee27c9efa6c851e4781f20971ce035b5037b86 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.gz=96281c576bbf4a1eb9ce814517040189be4529050af2fbce9d20cdf0549154e1 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.xz=1f37734d1987dd0c58f03ee1374a214ef3d35244d455908ca9b346d5945e3aaa +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=515f28e48b0237144bb4110b15c1dfa9dbbd23167b3798a32cd8cf28e741e2d6 +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=469ee9ef8ec15d8203f07630d72ac32ac262a0708617b712f139f1f3adfc7e62 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=066b9b8550ad7960bf6653bdc762ad5264f697ce2122b6789175d270ed0ff9ae +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=7dcde7ccfd02c980ddc33ebb980b1fc364aab099ffd7698a758a375102d48ed0 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.gz=b54b1fe276bf44c39f55678aa4b5c8d50c44332d8ba515d94d057da2e1e036c1 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.xz=1ed8171e1e957aec55be7410f5f9fd7e1b48473f4bc85d1f81360502ddf562a2 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=b85f3e30dada40bc826daa9f02883924cabcf25dd0738e9f783b4185e5bcd6fb +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=4a5642069ce14b53a0ebedf808e9580cf145e30f0e8e61400a27ed14956ed295 +dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.gz=3296a8cbcbbc8296a28d1f97bf24f0c47142c7524ca83d1e215adc6cf1ae459e +dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.xz=5ff405dfdbc42805f8fadd06323066e2a0aa238517871c65198e0c7eb8f6c210 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.gz=01893bc682d37aa38bff5d41e8b61d23ece07f64f950b2efefa2e67efeb47081 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.xz=fcf60f22fab4d53f0352f98c1def023ec174d4d930b7ec0eef71e4ca6a1315de +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=39feeb9da7f9901db336af32543785fd3b0a587684aabf42254efd763461c820 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=f14b77154f905166c769012e600321f1ff9cf79155f9031d7a05eb7469353569 +dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.gz=49c2f372740848e34c8a60256ffde8c578be529087855e517af27a3f4f440428 +dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.xz=5dfc8fdffd7f502ff05f50b8834424f7129b0f7be80647eac466e9fa19660e12 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.gz=7dcdd118d7f862b7bb532fdbfa94a92d88a035a22310c4c2f6c9fc2230467d6c +dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.xz=dbccad2e2b705f2b38ad2b0a8da9bdd3ab58849818051674c26cf516ad7fb37b +dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=06ad4618876e3c9413fde9763b93271e15451ab91c65b56ad6f8be958d2651ff +dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=079120eec04d3940aa4f96627fd6d9ef8f74662eb132f52f4e5c797f5dd16678 +dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.gz=2b0c040d29177a6a1829b3f4e5f5be9313c70205366707d586f4290e80c081d2 +dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.xz=7487ecd436a99fbea0a968c082b42c6036ea0a7f66e8175e61aa0139ff2f80bd +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=041e08179dd50bf95ca4f66bc5b1a10b958bc696774997139fa6754587c45336 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=4a7e06b730d3e35318690fc2927e4084062754c2256e5ea2bb37014e3c66101b +dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=e0cbee59a29d119616e60766eb68b581e27a661498c6af8b7e3cb8279078ba49 +dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=7a21de0bf78aa43cba18f560bf2668c902ee4755fc74f7fee7128f0fa9ded5f3 +dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.gz=dfd520844463a19cb99dc9c33849d646970166e3424c5dd96fb69c4483bd14f7 +dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.xz=7aa566be6a31bc5ebe6f588f521933d2d30514a3caa29332c91a9bba2f41f37d +dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.gz=70efc840eb8b45f0c4f527165ca87a913d18661cf4996766448c03bacc5ac429 +dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.xz=b19493c7894240666496a4cde38cda7dbcce3977c0014cc531f27fedfaabeb6b +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.gz=ae808e787aa5997f2f6ab0fa4bcd65c3c3724d909738b9f78998796c939c6d83 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.xz=2bb6da4f902a8f1d6725705c16d513478c027cbf82c8ab9948feeeed028f60e3 +dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.gz=f29b6c9b9f507858c08a560569bea2a65a749f3f906caa92a2f78998e3530d25 +dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.xz=7b79450216d0e11e6c3cf241cd57b5064388a8d6d7c0b0e52d29f8373ff97da1 +dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.gz=37b03d9f74ec899fde6ae56eb6af8e6b04c2bf8fdf2de08f14fd576569c7f78f +dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.xz=6d212f421ff3b67ed0c0b205a1c3af1df6c5210d21127faf53f906ddc46f1758 +dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=53d0a088e7e70b333a72a83bd42f57c81c24520bad9ae89ef710bc2ad658984b +dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=f26ac1c83990634235b44e14884307a8cc35ab730747b6e4fc90542a985d164d +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=d8385e3c27433ca0898344dad62a91a5bc29b5cbacc5660cef82db0475ce9a04 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=4478fe4b44978f4000708014802365ff25dde402acdf1546101fa07fef329c9e +dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.gz=ebeb2599218420288ea2b95dc5c1a30f4482a37ff28b06bfc945569f60c8b914 +dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.xz=5610b2b28f534eec0003b848621881d3b0addbefdfd69666dc555124aa6dd600 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=5bed751da30f4ec0d76613ab04b5e7687b0928539215241988ae792e93fc1ac6 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=a46f5557facf0e7fe88cb70a52afe1bf7329836ea3379e9eb3d2823884806f35 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=ae040d65d4a52e5369c212f3f3e8986eb92e903d2661734831d253d24efd9f57 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=5bfc44c33c26cba4d381b3a4ec0821ed6fe7597ba1ea33f53f4ed5b9e883aa88 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=7a85f404f581debe2802c64da4e421eab591a47ca40518249c3293d5f3fa109e +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=02b85ff8b77947f53e0bd70c9a40c5bc55fb820f86efb40c2e985266153553ec +dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.gz=db60e79cb4497d46467de9e2e808ae58ee329e2cfc7a114f97d7455c756ced38 +dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.xz=fd7c3fac452faaadf1f907a270daf4e6b09063d9023d0a00bcfbbeffa66aaba5 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=6ef5201b5b5ddc2c8ea7fb20186f086e0ebba77992b86ee9517973063dde8393 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=32744f5af908ff5c925f5b6fe9f2ddb985b23b3a707aa61c5bfbbc4754838d52 +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=857d39bbcd5b8ea6ecefbbbf5a082b11e0e96e51e85c06b33aebc0b96bc48a5f +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d51e77d6fc82bdbae84d4bb787e4df4167a3bdea6ab211d9b8ddf79c285547c9 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=8b5578ab21645fd5ae11dd8e1c6bcd6ff8f402da94345a5a5c462ebddacdf733 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=d3f1f2821af7ec976fc5f68cdcea77b3b36d0e1f54ca17e86fd92b0083d113fa +dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.gz=09095551ce4bca6bb872b07c4a5d62cf96915fcdb95f6e36884b2f6758464e5c +dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.xz=5ab50b5e63d10c1a2edcb7c60cddb081f2779dfcdb6ddfd1785c282c775c4128 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=85633e33d5c82d99cb59d9ac2cf6811b871db12ca3530293ffdd73870a3ee758 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=cfabeb1cecc122b16ff8c63a09e25c15b4855ae30fb71d631ae106150fa10595 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.gz=79532507392a67355c649f92c575ccacce0c73e5c3bec969b0f501e82c3ed291 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.xz=c47637bcf4a3b031f43c5225daa76bd29bb747104ce34d3020328f677b186246 +dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.gz=b64d6b7272689d68074fc15779bb2dd625a897b2afdcc400d6b21f3d64aea45d +dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.xz=54688000828eda67b5761e405f3318f97f58616ecc0fd4b67a3da1ad5fe24471 +dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.gz=6ba9d6456afab0e61593e12a34bb50cbdb8bd78def16eece0f0c79703fd31499 +dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.xz=4b88c220a125af0d7c3a8b50c2edb3acbac9f5a3d54630e5aa926a898c8c5ee4 +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=194780953225139f9c3ca0ed92106a34fd7466aeae3b92aece0fbed31c22ae7c +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=7907a4234a8cd358df1ef1e462136d1c31435461806b7581e621698afce8f1a4 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.gz=faa185048776def01bd11870e2d1d0bde2fca0654ffe01614f36a2602523f261 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.xz=07a424016f695d47ceacb6966983a2fec1414caa9ef5bf84d72540283686c639 +dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=c083674853c3412de578f469e50a367bff77f5f3f8e85bff082200f769150bb4 +dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=2e29b73c2942fad3f2a79ad294e16b124c7c271ce26c6e2b65d5cfadb9709c3e +dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f5e0be0aa0ce467db0bf18fb9d306f88efa36786ea28539fec841300f13fc926 +dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=e7c5d53eeb250006c2ff5c90bdc3a31fd19edde7f9022b96f86655889a2ffe43 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.gz=d78c22fb8862dd3bd258e7982dcce54b859756b8f3bede42097873dd7239e14b +dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.xz=bb1ca2a1bf420f5feb10133ac208f1be8fe54927af236855202758959d933019 +dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=3bc49069aaba38a7ac627181b73f6249d707be590d77bd410a90a59c9ae98378 +dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a66a7b99c95b600abba03330e9f26fdcf87860259f81d41ab629643663c188e3 +dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c17554b2eeaf0af3115fbf3659ca22be0ca1ef7b4c64c831a18466db04cc8d02 +dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=f4b21bf361ffcab4abc8ecbcc0c671788f4f2df058a24334d0aa0c2567c86fbc +dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=1e99b060eb7686203e8b49a2ead224ae3a28456b14a7db89585fe547673ab0c2 +dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=dca7426cdc98b799cade30c8adb4386c4fd0be2d1e6fd055615a0d0350dfe396 +dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.gz=2d683687edd6df5f650979fe8d4ded9c813a695033f11be7444fec7599f58225 +dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.xz=f14f1f132b28d67737fd7d2eaa740a74bce2f19443f0e938c26e182be97404c0 +dist/2024-05-24/rust-std-beta-i686-linux-android.tar.gz=3b812e866ad74e542fe32c625ffac712ee1bf3d101f73828cd938bdbc688b7dd +dist/2024-05-24/rust-std-beta-i686-linux-android.tar.xz=6cd72f9ae6b0459f57e8cc7c5161efb0b0477bbac33339951c9b4ca4f4512de0 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=cf0436b2a84bdb83af01a9383dadb2d0bdb43edbcb959c28d20d8874a4b6bc3c +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=afd01da46d82692d8bea9eefa31000ca10372ee7bdc5a9d8c6b5c4bcecd930cd +dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=3f90c703dd67cee0972536caccc6641dbe5bf38eb8dc822937ff3c98abc97710 +dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=a79012cb247484db2df607a63e451cb6748be1a103d6e368883d95e92fd5ee8f +dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=8df8df9a6eb55bc9b63dbb4b1fbf3e15ba6f95b0ae1e901d4f3d2e594d4fbaef +dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=f110b657611fd530af1fdb20b06384a41db126832ff9a0b8e3e53b508addf1ff +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f89ad7191d2eb0c5d8b01892e61e68747e66d18214152cdef5c5b191a1606981 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=729057537bb4494e3d060c26867bd6695f62a096eaf33582010d583c7234a313 +dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=ea83d20d4dc99b7e9eeef69eeba2224015fc1bd0b0ad4695ca6dcb537a5f610b +dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=b3615738d1c067d22327b62e416e06cc57c08c2141c0a478f265fd888ce6f655 +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=7915fd0662c2cc9724395745bb23d6589e48b74c11151b5674fdd7834483c54a +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=d868ffc4f8b60bd61d862e83f445c783b9b98b11041ba9d284354d1c7c5c81b3 +dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d4ec9d659228b86780d29f183b7b1d8d9087290d9602659d985b5a4adaefe52 +dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.xz=315ef515146f4de92935fd02a458bf71cbfa967d426b7d781b361f650752fb0d +dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.gz=c3cfe615737af46a5de0c0c71cd530d8f1b8fe5d8c9c89865ba5d127c71ebbed +dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.xz=fb375bcafb3d35146ee387772440921cf1ec737f48e035bb34a6772ed6f98435 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=0b5253ef9d9d1298423e6fbc1170e3a7173717ebfc57653debdeceb80df74d8f +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=f1ca8bde4ca0621bba03e94de67167c01a2cc5b37f5b77e600986c67cb477ad8 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=9eaa5a78691b16244bb8d2d4f1e22b3548243967b49572a276a66997a04733a1 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=f4919dd99711b1b0c7c533a2301423a3c6b01534fb8dfb7811356ea827b43b3e +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=9c5156e544557ba6cdc366407cac81b90255b0759c7e9ecf19d15560f8da0338 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=8f9841d0d6bf623330e497304efed6bffb96f081208be5b5952c493884d803f7 +dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.gz=6fbf1ea31e37333c52e2c28d92baadac89bdb2c53fabe18b3977c2a837f69606 +dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.xz=e1b656df5f54c6317ebbe660ca9488a6c93e1516e4d8cd13d4d601d98e18cc71 +dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.gz=d5831bd26c24ee90134178a0877944ebfc5fa743e4b6644308f2e6f9480cbb94 +dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.xz=3441e45c78e670b2cbb5becd10fb1a20232adfba8a3b27534b364fad47a8b14f +dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=3ca6068a2b62dc715fba00c8f8c231465a8cb918bcc0ec28ba5eefd6322509ae +dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=3674d1fb506ee0237f8dc359ebce38aaa1f302e0cfda1a23ca083596aa6ed1cc +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6150c318589db8d2243619b85e0bdbf4433dedd1f6bdaf8ab5a0c48d0fd9a62f +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=3a03e4ee500596e03335f7d01e666727ca35f861a82dad214ca06c09c11246a0 +dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.gz=39998995295e1c03bf81c2f384d871a0270e3b87ca87b23c61642e6455c83287 +dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.xz=4a837a5313c2b7c340c1df32f37679975abb7263966d90f755e87c4925262065 +dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.gz=6f6b434451c5e08e89feaab897d6d70445b380e12ad398453ec36425954c1d09 +dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.xz=183082bd9b3ecb97831d22a1f88820a9622cef480db113695907fd00eac25602 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7d500984773dea88db82653b5565f6d73a622cbaf9da2db942b3453f0b965296 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.xz=9e9a890b7314a731ce63d57c325cd6476c6fa50e0364b4c7b8e2e5620c83ae05 +dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.gz=5a3bd87bf129c826ec705b94f0ebca06fc2b3629d191b76fafc09cff8c59adc3 +dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.xz=24fcbcea1863cf45eadef4fa575d3ec1faded48ddd9aa02f45d199a4b09c136c +dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=6a844b4584ea5c89556518ad063ff6298e6c47853d23f7d8f96a07774b0329e3 +dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=4f20df4cd9832304e4a5963b27f7caa3d5cf7d1d8ca7a203db3c3f30552bf2e5 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=d986028f54153318e862d42bc6f6858b88dfb32089d1039e7cf1bba384ccae1e +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a6ecc5e601620ce896f4371487a7cd9ae529dd20f760d44c498fd705fc4140d0 +dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.gz=59f6d05082f4feb8d1fdedc513c27f4d1680280daa40889aeada106c8d363678 +dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.xz=820c078d60cf6530f1c67111c99ecfc492b564e4f48113770c684677a553864a +dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=8c89e03e9c8f41f2efc8c0c05397051dc67505b634d9b9b7a076471b334a6b8c +dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=592c740d96a1d78711c8a861b3ea17c36a806ca2dc1d869d51dc6e5de456ee60 +dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.gz=9db89655fecd5169d7cfe6869bd901abd621f6f5ccc9c2928ca52a666ef11eb8 +dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.xz=9a37c1efbc17ee392784109db3d5674d95b68829ef87895c2f7dcdedc2271952 +dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.gz=0b6e0cde1312e5294efd1f9ff94a7448e8025b755d02fb36b0e15b2642069cde +dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.xz=5b96820f5ef0f04afeda2fc4052788a0a5c17f24a73680abe265d4a52a27d266 +dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.gz=42a56ca6639895afcc379daa674270aafed270ed3698ac7a16d2180b67d78da3 +dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.xz=9dc792621d33faaf4c5b779df0b72eeb87ff2756bd7347517f50ae0a41d067ac +dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.gz=e30d1feb140198a1cccba94f1f4f12a1e5446c6925c4bc35a82dd8fed54be079 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.xz=b754bb31b01483bbb92b14f1fb7de241295223c58a84059f36b2237c93963bad +dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=de99b7e5b35a756f4d3ae4f780a154310c6062dbcb9c9ab0083d061976634d0e +dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=224f4a46d4cc3ea797fd7cf70f80e2c16ee758cec23aa1816964d9128264928e +dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=0e3907c9e2d11bcf9ae9739c01608f66048a63c343cb006374ddec08d6ea7c78 +dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=981ce940535a7684952299c1be88378c6763ee91d3765b014330aca0fbc65ce9 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ae0074711a8ee88061859789dbe7c7ba9f4f306d5d99fbcdf1a4fb0aef7ec2a8 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.xz=40de1cd1454bb99a8c3ff18bbf2950fcf480152536dba1bc20576e3cb42b62e2 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.gz=1f849b69e086fde12e342aa935bdde649cc3b18ab9f372c1decdc6ab52ecae77 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.xz=75e6ca1b2b75de206ae4c6c8b98f36872e00cb92151c064e29bbb9a5bf47d441 +dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.gz=fb6a694dc1dd5c0f8e0749354b54ec213ae62977d2293b76806da8cf6b4db18a +dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.xz=5d2bdce7e5ee3be7a46bc55614ff6b35c996eb95cc6348fe982207f183237b47 +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=551b70fc54e177ee31a33d79ea7c8ae19b81cf3bbbc767e23455f3da4d1d440a +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=3ceac72674b7ebc33ed3b73057ff93c4569f9bb47d15c743a9ed2775a51d9eb3 +dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=b38fdb21440650b6cbecd6c2e049b95519f60e37af48d1a98d38ea82fe27d908 +dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=74be24ebefc943be201b114d9eb49e15fda0880eb03c0df60ee382f2a48dd0d0 +dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.gz=70d1d27a68f084c133fa0b3c110d43be37de2446a81e27e92fac5678283fa26f +dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.xz=d02feba93e984c5d5aba5018499c830954f3b49f68c9885f11bd04b48b277f0b +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f4eab6af2e369b32879a97446c962c67b8733aaccfbfdc60e04f72e2baf6ab82 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=a34c6b4298c5b8fdd266b6035b6a3c5b0458fbb64a853830fc6f9df2c1a0bca3 +dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=b6fac94136e6fab6c0b6425890060f20481bffaa98bebde52f99564afe8e2c3e +dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=6dc5ebd5e03441015655d5929825364b9bebe0659df42ddef09fc489fe22155e +dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.gz=f08d91646163be427447b11fe7e1214df4444c98c99070d5f154ba79e47cafa1 +dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.xz=ac86b164e6a95388510c6cd5ef6fc82cf9794d5f3ebd12f1bc94f16ca2c85ff4 +dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.gz=07e962b44908356b427c350f1208a9c017ebdbf4bb6d5f952b1625833b552068 +dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.xz=6e0173c30b8087e9ff2a4d7b46d178d380ec4a1443034d5706dcfeb8dcd8ecfc +dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.gz=ebaa62ae3e7191bc5be56f93b47493641e705ea312071e723a9e03bf9fb487ab +dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.xz=3d9c9ecbbbfd2d475d4bec4141e5da4559f092d5167127fd4eb13f5397abc693 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=ea1d746dfe195065e8d387ee06db4f0d2615814b9c6ef6246f85d1073c471b06 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=86387463578f29dbdbb79257ea973a247df4c6774e88df6b38fcf52b79c99e02 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.gz=383a5528ac4ac0524fadad6e2bb7fef0b3a03d795250057cc816533728fbb4a7 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6f796fc9a9039815692dc5e127fe83c5fb71f208f0876a5c6324bfa9953899bb +dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=4538a4c73464791275fb0eb49ef96356966521131a33ed74c5de1ff587b57e3e +dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=e16fd33e2788bfe6d7dfdaf2692b21bf61edf3d34197cd7d32b1ea998ae03000 +dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=61e5c68a5eb0b7ec35b2353dcf19a54e8fd63a4cc8be1e1651138aa8193cd0d6 +dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=6e2a98ffecd48aae032540eaa0c9573317ffa920d6a21e2e2f2e512d8eb3b991 +dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=ae6406baa95d37a95afec6c3cfde8b1fc5b811fa824785ebd6b17d5f1f31d329 +dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=fe98fd0b83763a2b73622ec3ba849ef2e0e31656010b2be3b2ee31875b19a826 +dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.gz=3a4eba33496cf3c1b116524b3f5466426148b5bf84bce2d1b3865c4429277ba6 +dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.xz=17a5a7e10a8821c12a5930fd1ed85e3a545d16471d7948d09fcfe536fb6556a9 +dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.gz=176239e95b1efaa8d12a41792d008ffc4919ce49a86cecc1b5a83fbd94983c9c +dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.xz=0e4abffe1c361b54572572633cdb57ba4b5e43aba01b1af9298532de8201a2bd +dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=1b36ea0173144992dbef9bfbe7117454b7d4bc3a717bd04c6b8470f9f3feb38d +dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=43371fd91a35451213a5b082190bb18178ad712627f7243feb1acbdcf5b01c21 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.gz=9ae71ea9dfe0b56882b949321e4a2820bec4883614bb052cd71d9cce3b203ecd +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.xz=92e23034c6287754a5c7d49c3e53313a614addb220fe0eac36d39b2883b445b6 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2076ed6ef91cd8febcf7daa894d110a2acb8a5b48a60f050c5e126c9378624a2 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.xz=e32790707ddd05624a7066c6185283476aafd7a304fe7528587765102d0fb63e +dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=f47378feae7c5b4d15693ce8b170152237e5adfe027e53e4f017dece19da9f68 +dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=af17738279b4acc3c75974b070c63de6385a62e7cb2ced3d445cb2c7d9928653 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1fa14738518c68f24668fe42ed6653b4a80ac12ac121f36b488215901ea49349 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=f636b9d9628b5be5cc873b0698bc8d1a8487ca81309e359e60d6065c3771f8c0 +dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.gz=14084cadcf4e71259a3a7e2189e648bcc8f8f044b5abf027079ebc140f3593ae +dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.xz=6226dbc6d0e180eb7e946606cd7a5879ce558846334bfd79105ae23cfb7eee63 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=6c58a39182997f07a7391e069ae6f141af8a2964f8c5583bedd70039a759c52f +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=a4c33cdb8711b784f533a685c3a6491f4c841fffcf573b1832315360788833d0 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.gz=f12a529b11e68e8dcbaeefc13e98935171bab78d5aaca0e6ea6d5fccc71b23ab +dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.xz=b060a3285527311eda126adc0f70aa6f361718ef397e89d488a58be7ff70d316 +dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=a7a455d8a0f102d83c07987045beae1a9f633adcbb1752a6c338a0056183cf06 +dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=47869852cf4b215d71ffbb67decee05aa4627041353daa9acd36dd6f2cc8ca71 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=99c4401de28a11dc31d868d01d8de661f45f6238ab7fa36bc203868bf9977efd +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=828ffcd6fae6e48d9af7eca3017eec88b5d79ad5f892dc72ec598d908c23a7d8 +dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.gz=dfe75e08d07df8e2d2f8b7e1d7840a505e42b2267b0f3b63c4cc8356dc3f4519 +dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.xz=83270728dc14957c00a8801a5a187b9247b7c7bac7347f71eaec5e2fc59e17fa +dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.gz=7bef578957e857cb38b6cdc126bd055b95b5dff54d11d73f68413425cb4cae3e +dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.xz=9492aa7f12aa1f38afaab16f4c1ef4d3fc45169e25575a3c691ef13b0389c2d0 +dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.gz=e325ee40a680aba2e413ea314e15fd4f9b5394705f72d652d9914b4fbb16e253 +dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.xz=c499d0bdc755156a058c32d4d9be8e2b358197aa89a161804ccf87b0ce8c90f1 +dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ef245e8ebc4e598ab68b5bd8fbbeaa311e4b4e0471bab961b39c4d5218655712 +dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.xz=55ce153227cecea3a6f05807a156bfbea3c7d7aee72fdfa055fb9ddcbabd041f +dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.gz=d2378b267bf3d0e58300d21dd302161eaea8f8e38b7439731a054597970f7195 +dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.xz=87e337e9a584908d6397987b89756a30e6cd4b537fbe5dfe9d4752d9ae17dd51 +dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9ce0c27f91a3d3a99a0b32d72284827add678b4e6b1377e2fc978397dc897bbd +dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2c314fcfeed780a18fef9835266a50a8bfd4c63f66033c7a2cb589243d0dea8d +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=a1691b9a1629b0ab09505c80ef510fba462f41296b45b04bea52aa66e0314cef +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6d36402ae66f53c24db57f37e3f78a2bd5a07a238d59d4b4b8c000202e6e6714 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=e54ac8103de0de2c4166da6149c0f3da1db29cbf3909844b5fab43e1f56d943f +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=986bc361afa619b299f1c6674651aa56a344374ab8731c9cb702a651132841bc +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=0ee19412859c424304a8e2d66798896ab3be24057a6f12383fadd9c8283e5825 +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=01ff0f61731da21c55618fff0aca2f900c8b1473b7efc12cd8f1d1e49b51ba8a +dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9d29a9809633b98851a5de84d37cb0b37b4f9e9223b42841ee11e4288dfafd90 +dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=122e2f607f59dbbd82693ece7610d9f9a92c1640e3501921d0f6069d0eaf4ac0 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5d8d0ed9f63eb0f2b8eb43c47f0a6858702cd5e9c8f1b308b570981f54a45ba9 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=203c63f477369ce5a6464d0e11a10c5ed11b2e510e6190d6e0ac9993c43f3ffe +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=cee4cab103bf4c2b244a91c1d7578d5c807307a3367291ef1efd072f975e27ca +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=813a55dba22fea0203e43339f95ed1ce8b7406d57b5d75cb0d11ed2638402280 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=c9a941b5c05972c0fc875b052728dd5a83dbdcc8437c5509fbc4ca82cefd5866 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=3bb87c7cdfd0b942d8051de34d068d3fe6b4d5c8b52534ff43d6ffd802112d99 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=2bc18cd1444098b36ba3eb0648944caccac1515495c7180d2258bb29c4dbba71 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=a5e49cd58fbe857a2e99dbd9b68aec300dea92a9f840dc564f6f61d71a291cbe +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=7b270dfdcc65d11d0741adf11f62fff5839b4262ca87a84c273c4f54ccdcf404 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=3cfb7ff6d106ee2ca996a7e5790981648e4bca92ae424c780e6d6831dbe5d521 +dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=82ef339de90bd1eb99bdee0ed4ff0431358706cb826c0810c6a05aa7432c56fe +dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=d4332d61ca86a3c561bef17474110dd96fe73789c1fa43ba216be9a0c3690192 +dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5505cd69abfb7cf00ddd32936067088cc4448cfa09e5571516fa2e61d6593e51 +dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.xz=0c7cc98f9534c691dcba913b5d40fded47b33ca549ac75098c84d900d8452f01 +dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.gz=734c21a4018bf0e5ab561e8e485fd15f9ee38c01685aaf620808edb9a218b476 +dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.xz=69e6408ba329925f38522050f84adb20a299960c04ed3012bf075a10c4ad60c0 +dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=d759046124506b761f0d628681e7f5ac73fc23a04f1bab5097e0796b7197097d +dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=fb07a6adc006753ce09457b032d6e1ce06934aa8c009f5d586d3b317dde6ce21 +dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=c7f7195f7c80e9d6afac4fd6cb6f54b4f1c53116cfbbaa06d185bbca4ef2b4d6 +dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=5acb271b43e1f1c186666c33f322b9d3c253b929710eb73000e2eb61b3978dc9 +dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=7aea051dfd13311ef4a95845b6cfb390c6f502ac2bf46fea335abdbcda05a2e4 +dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=832f664b6508735fc91491fef9eca137ea6707cec000ae483d4c8b5ce9abadb4 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=a5f79e10a34ad8d02645d1e6ae758812ff16e1c74b63c775c5f840fce5569ed0 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=837e8d335322a4d0efb86bf6d6dd65b815548faa9e40135e8cf3b197f6e03960 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=c0d3c4786cf4b4c4cf0b8c26d89d6009e3e9d9c1e69092f4b55f0087b08204f2 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=0d8a1f390b09f8550c38cd1b74e4e8f7cccc496b86e6f2d6f74291c34cc31bd8 +dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=56ccaaba20445959702503d1aedac87b8a9995bcd8619dd120273d0795859705 +dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=201932eba6521c04367eb682f96a54fec10830fe954bc271ce2766db2afe30a1 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=e8c2324aca7fe35e47088d8c317c7f97d88830629e871987faa197d545ef644f +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=51985f7c0530eb59dce830e1508bc270e1bb3fe7b33a95eb93142611e651a7d5 +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=a4fa6bcf4c4b9c446236d710c1878efaf1dfdb95a2f5f3c4c374d8fbf49b792e +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=af0f2443e34c9d6f5d85ff8cb0c0c52fa46b64275c26b57528c1e815edb8f59e +dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=59bd9ccde4722b24b5b746d7e3dfdd48ae8f9c8b142b8c175750b8bdb2c05411 +dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=91dcec67d9382548f89dcaf7c2c6dcaa47f9e04b777f7b8cf047ca0895fd7958 +dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d16ac0c789f0c79867ca74161214a902f97647d2b448ec510d48b254092ea05b +dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=065d796ed384f07116903ae75dcb4accabb3cd81849a0083fa26b42e5ee3027a +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=bd673c6d23377af5158565bcc48048d5a8febf346d200920e8ca8e661149f600 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7f630e63ea697c95bdd2ea2edd678e8cf999c5ed9e7760c2b631ed6ecc4f112d +dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.gz=1f418de895c28fb684035c38f5f1ad45993ccab9bdbd247958083043ec2904ff +dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.xz=a762ad9b084a4221f5e24ba7cc99bfa20dfba935d267efd36ecf371de5fa6261 +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=6fc6f1ee02ac5562da863213924a43b8cc914b54b7a7df7c0fa65b51c0cec2ec +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=3e4343551874ebd6a41912937784938572706896f7b64b246b7630eb2de81e32 +dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=225dfdb7af532a1de12c04bfb4ad41756db6b0c342e3e974a1587b74ac942cc4 +dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ef45d12cf6c0a00bd62bde5143bace4b9f4dc3d27d0e66274698fd4c12aa644e +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=cd5c25154d3a24f9fa14bea66c149c8547179e28307989276b3450411db94f1a +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=07473937fbe50012d4472e283bedb8fa239a02fedc880e8d3cdf96e449a7a237 +dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=3c96788305ae61feba692d7c254c68486e6caa0a7851dc6ee545338260e195bb +dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f5789e53bd82a6e7593f51248342bea26014770d86b171d1e6182039e96cd008 +dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c7960546ecaf8e190e0e0a6bf21d3259b6098b440e9f8efd455c0e207db14100 +dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.xz=dcbd4e5a41496ec3a76a492b6f48a0913f3174f192b0dce38886580fe5866806 +dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=201d715fc46c3b97c6ba56ed89b45870089ead21b5dbe107fc9c11d4e409b594 +dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=5660fc1ea7228b156b070766d568bd27222245f4a8bbd3fa55d53646320594ac +dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=ba5a31b8f6fe6b55976ce3fb7075cf0c539b83b86c029e1dee9259e76eee90c7 +dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=1494876804a4eae08e22a586295d5c75fe611e90e35e98e9d4fd4ce7f08e1648 +dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=e83d8ad735b0c2213613882affea611db0453f2d83dddcdc325100d94ecb8be4 +dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=c41af42429b2322b140d99049fef6a2bfc6950847601ce5daf5e789939ef8383 +dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.gz=4fd2063d10fb4ea166c684edb9b790a0decdc602c600208cad2c378cb5b5f04a +dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.xz=522f49079f90b469a7580f3cbc8f7ec88f2267a5df9cb0fc06a40fa21a778b1d +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=622d58678e2aeca83bfa7172c9cd0fc21128917067b6492fc6a966f0715843e0 +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=2e021443798286eb5bdc855112970862b58bd12ea3b1a3ef7aad178f757004ef +dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.gz=a14a5f1c16f8ac231083b11075aae0970370f29b7f8a6b952c945c8b4a99a1c4 +dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.xz=5a389561f37d446433dc4e4d0ac1259fdfa4bb5728863a0b2e00b6575acc8851 +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=95e73ffa458449089b753f85aaf71581d6229d1fef10f57aa6ac0a9a15f5e2dc +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=b678c5d611324ced9ec61e36cb2ac53d595ed0d9024e987b658d3708714137d0 +dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=07d9e8f300835045ae9bc9350aaebb0c7994398e92e43ca0baf4d491d5e06a51 +dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=7d40e53082177294ee09d59730526586ee973b9d0aac24b4c9116db306a926e1 +dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.gz=e88718e456cfc8892fcdafc1c522b67c53ba5faedf80f43f007222a8bec00a01 +dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.xz=b8320cdfa66421593610eb7299d57ba20381f10bb6f2f82ef5475f86c454c2c7 +dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=65ddf18ce7489b1bcc0d110fbd645326b960230702f6c9ad45680e44e0c1890e +dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=f64735396de921f8b65fd74a3f2c179094770e39549d057e5222085b17976832 +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=cdacc2d990089859fe21fd779d24b186101bcd03f91b8f9c595ddf26af9ced5b +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=74c673001e8794afbf085bde1b5e010420458230fa9eadf7f5f76e5ad11f1c8d +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=76c0a333525099ec78351d29deb0f0c7b72d8a48860c1595442e574bc454ac5a +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=5ff07cf9292c0ba7e3860e9ec2c1de9810e932dc12d9711ba6f1795a5c90875f +dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.gz=32e4afe3e4dd9f64c69da73af0c4a1e6e4c8264640b142de6bb9494c567fdfe4 +dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.xz=f6d8be59445080cc278a152387e47a98d3b371758bc7f36932343d0caa5896e0 +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=caeefbab1a93f119669078ba91aa821e5aaff5811fb3d0a6b0ec482d7bc1a404 +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=7032353ac8ba628f8a2648c106c7a3248ebb1f03bc9036cfca61007f9acc3a0b +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ca53d272b136d5fa112ede10627880a58f51d99a40a490b2c9fff6c996f9aabf +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=d24dcd68c9426f1463c60d5075a9a0ecbc494cdc34a434f377a0b09fdeabf914 +dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=c6a05ee622261a0f4b41b1cf26b5461e1247c00376ac61a0fc4faa16ce478140 +dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=c317af1e4bb1551edc046c426da84ad122379e5829b5e97033c94b6844b18e2c +dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.gz=3efbcc6e74d9cd4ff86803410bbdce0f1e64741870c32f33e28c660c68155851 +dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.xz=3cb7acb1bf66ba39becc6df1cf2727de424ca3ba90e74f0fd7c76f586f868a89 +dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.gz=427b795b94eb4e4e2bd150e98055c5a9a414937ebef7e586bcaf8a1988eb5214 +dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.xz=405b2a99f9a34c1d1195ab88bf6fb696fadb6c2988a3d83555e2ac4de80ba4e5 \ No newline at end of file From 02eada8f8dca08f42560063d99d87fc1c258fd7f Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 24 May 2024 08:08:41 +0200 Subject: [PATCH 061/101] Remove now outdated comment since we bumped stage0 --- library/alloc/Cargo.toml | 1 - library/core/Cargo.toml | 1 - library/std/Cargo.toml | 1 - 3 files changed, 3 deletions(-) diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 3960f7168126..4646eaced018 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -45,7 +45,6 @@ optimize_for_size = ["core/optimize_for_size"] level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_global_oom_handling)', diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 0c2642341235..cf9fddd269aa 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -41,7 +41,6 @@ debug_refcell = [] level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index e56f03808b31..bc78c63c577c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -102,7 +102,6 @@ test = true level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(target_arch, values("xtensa"))', From 9dc76207ffdb225c4f4615dd59bce356b25eeab8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 23 May 2024 13:37:39 +0000 Subject: [PATCH 062/101] Fail relating constants of different types --- .../rustc_infer/src/infer/relate/combine.rs | 13 +++---- tests/crashes/121585-1.rs | 13 ------- tests/crashes/121585-2.rs | 30 ---------------- tests/crashes/121858-2.rs | 20 ----------- tests/crashes/124151.rs | 14 -------- .../ui/const-generics/bad-subst-const-kind.rs | 2 +- .../bad-subst-const-kind.stderr | 15 +++----- .../generic_const_exprs/type_mismatch.rs | 2 +- .../generic_const_exprs/type_mismatch.stderr | 14 +++----- .../consts/eval_type_mismatch.rs} | 7 ++-- tests/ui/consts/eval_type_mismatch.stderr | 34 ++++++++++++++++++ .../bad-const-wf-doesnt-specialize.rs | 3 +- .../bad-const-wf-doesnt-specialize.stderr | 36 ++++++++++++++----- 13 files changed, 84 insertions(+), 119 deletions(-) delete mode 100644 tests/crashes/121585-1.rs delete mode 100644 tests/crashes/121585-2.rs delete mode 100644 tests/crashes/121858-2.rs delete mode 100644 tests/crashes/124151.rs rename tests/{crashes/121858.rs => ui/consts/eval_type_mismatch.rs} (53%) create mode 100644 tests/ui/consts/eval_type_mismatch.stderr diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 101598c59512..fa5b9179c888 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -168,7 +168,7 @@ impl<'tcx> InferCtxt<'tcx> { // ourselves with a check to find bugs being required for code to compile because it made inference progress. self.probe(|_| { if a.ty() == b.ty() { - return; + return Ok(()); } // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the @@ -178,18 +178,15 @@ impl<'tcx> InferCtxt<'tcx> { relation.param_env().and((a.ty(), b.ty())), &mut OriginalQueryValues::default(), ); - self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| { + self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { // The error will only be reported later. If we emit an ErrorGuaranteed // here, then we will never get to the code that actually emits the error. self.tcx.dcx().delayed_bug(format!( "cannot relate consts of different types (a={a:?}, b={b:?})", )); - // We treat these constants as if they were of the same type, so that any - // such constants being used in impls make these impls match barring other mismatches. - // This helps with diagnostics down the road. - }); - }); - + TypeError::Mismatch + }) + })?; match (a.kind(), b.kind()) { ( ty::ConstKind::Infer(InferConst::Var(a_vid)), diff --git a/tests/crashes/121585-1.rs b/tests/crashes/121585-1.rs deleted file mode 100644 index 2a4638efcabd..000000000000 --- a/tests/crashes/121585-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #121585 -#![feature(generic_const_exprs)] - -trait Trait {} - -struct HasCastInTraitImpl; -impl Trait for HasCastInTraitImpl {} - -pub fn use_trait_impl() { - fn assert_impl() {} - - assert_impl::>(); -} diff --git a/tests/crashes/121585-2.rs b/tests/crashes/121585-2.rs deleted file mode 100644 index 99cc8f791955..000000000000 --- a/tests/crashes/121585-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ known-bug: #121585 -//@ check-pass -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -trait Trait {} -pub struct EvaluatableU128; - -struct HasCastInTraitImpl; -impl Trait for HasCastInTraitImpl {} - -pub fn use_trait_impl() where EvaluatableU128<{N as u128}>:, { - fn assert_impl() {} - - assert_impl::>(); - assert_impl::>(); - assert_impl::>(); - assert_impl::>(); -} -pub fn use_trait_impl_2() where EvaluatableU128<{N as _}>:, { - fn assert_impl() {} - - assert_impl::>(); - assert_impl::>(); - assert_impl::>()const NUM: u8 = xyz(); - assert_impl::>(); -} - - -fn main() {} diff --git a/tests/crashes/121858-2.rs b/tests/crashes/121858-2.rs deleted file mode 100644 index cb80c081cffa..000000000000 --- a/tests/crashes/121858-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #121858 -#![allow(named_arguments_used_positionally)] -#![feature(generic_const_exprs)] -struct Inner; -impl Inner where [(); N + M]: { - fn i() -> Self { - Self - } -} - -struct Outer(Inner) where [(); A + (B * 2)]:; -impl Outer where [(); A + (B * 2)]: { - fn o() -> Union { - Self(Inner::i()) - } -} - -fn main() { - Outer::<1, 1>::o(); -} diff --git a/tests/crashes/124151.rs b/tests/crashes/124151.rs deleted file mode 100644 index 5e55ac2aa943..000000000000 --- a/tests/crashes/124151.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #124151 -#![feature(generic_const_exprs)] - -use std::ops::Add; - -pub struct Dimension; - -pub struct Quantity(S); - -impl Add for Quantity {} - -pub fn add(x: Quantity) -> Quantity { - x + y -} diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs index ca5522a2ddf3..88f98a54b6e6 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.rs +++ b/tests/ui/const-generics/bad-subst-const-kind.rs @@ -11,4 +11,4 @@ impl Q for [u8; N] { } pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } -//~^ ERROR: the constant `13` is not of type `u64` +//~^ ERROR: `[u8; 13]: Q` is not satisfied diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index c04a05573bed..6cf9fa743b34 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -1,16 +1,10 @@ -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/bad-subst-const-kind.rs:13:24 | LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/bad-subst-const-kind.rs:8:20 - | -LL | impl Q for [u8; N] { - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/bad-subst-const-kind.rs:8:31 @@ -20,4 +14,5 @@ LL | impl Q for [u8; N] { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs index 6b0d9e047dbc..285f9dee6c27 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs @@ -10,7 +10,7 @@ impl Q for [u8; N] {} //~| ERROR mismatched types pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} -//~^ ERROR the constant `13` is not of type `u64` +//~^ ERROR `[u8; 13]: Q` is not satisfied //~| ERROR mismatched types pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index bb6d650b7ab2..a63a56dd6753 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -7,19 +7,13 @@ LL | const ASSOC: usize; LL | impl Q for [u8; N] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/type_mismatch.rs:12:26 | LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/type_mismatch.rs:8:20 - | -LL | impl Q for [u8; N] {} - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:12:20 @@ -37,5 +31,5 @@ LL | impl Q for [u8; N] {} error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0308. +Some errors have detailed explanations: E0046, E0277, E0308. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/crashes/121858.rs b/tests/ui/consts/eval_type_mismatch.rs similarity index 53% rename from tests/crashes/121858.rs rename to tests/ui/consts/eval_type_mismatch.rs index 7d5bae37f846..3d821ab538ec 100644 --- a/tests/crashes/121858.rs +++ b/tests/ui/consts/eval_type_mismatch.rs @@ -1,14 +1,17 @@ -//@ known-bug: #121858 #![feature(generic_const_exprs)] +#![allow(incomplete_features)] struct Outer(); impl Outer +//~^ ERROR: `A` is not of type `i64` +//~| ERROR: mismatched types where [(); A + (B * 2)]:, { - fn o() -> Union {} + fn o() {} } fn main() { Outer::<1, 1>::o(); + //~^ ERROR: no function or associated item named `o` found } diff --git a/tests/ui/consts/eval_type_mismatch.stderr b/tests/ui/consts/eval_type_mismatch.stderr new file mode 100644 index 000000000000..38d6e33d4067 --- /dev/null +++ b/tests/ui/consts/eval_type_mismatch.stderr @@ -0,0 +1,34 @@ +error: the constant `A` is not of type `i64` + --> $DIR/eval_type_mismatch.rs:5:38 + | +LL | impl Outer + | ^^^^^^^^^^^ expected `i64`, found `usize` + | +note: required by a bound in `Outer` + --> $DIR/eval_type_mismatch.rs:4:14 + | +LL | struct Outer(); + | ^^^^^^^^^^^^ required by this bound in `Outer` + +error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope + --> $DIR/eval_type_mismatch.rs:15:20 + | +LL | struct Outer(); + | ------------------------------------------ function or associated item `o` not found for this struct +... +LL | Outer::<1, 1>::o(); + | ^ function or associated item not found in `Outer<1, 1>` + | + = note: the function or associated item was found for + - `Outer` + +error[E0308]: mismatched types + --> $DIR/eval_type_mismatch.rs:5:44 + | +LL | impl Outer + | ^ expected `i64`, found `usize` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs index f89a463bc580..4d1cd4332fee 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -7,7 +7,8 @@ struct S; impl Copy for S {} //~^ ERROR: mismatched types +//~| ERROR: the trait bound `S: Clone` is not satisfied +//~| ERROR: the constant `N` is not of type `usize` impl Copy for S {} -//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>` fn main() {} diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr index 1dac58e1f694..716a47879482 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -1,11 +1,29 @@ -error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` - --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1 +error[E0277]: the trait bound `S: Clone` is not satisfied + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 | LL | impl Copy for S {} - | -------------------------------- first implementation here -LL | -LL | impl Copy for S {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` + | ^^^^ the trait `Clone` is not implemented for `S` + | + = help: the trait `Clone` is implemented for `S` +note: required by a bound in `Copy` + --> $SRC_DIR/core/src/marker.rs:LL:COL +help: consider annotating `S` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct S; + | + +error: the constant `N` is not of type `usize` + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 + | +LL | impl Copy for S {} + | ^^^^ expected `usize`, found `i32` + | +note: required by a bound in `S` + --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10 + | +LL | struct S; + | ^^^^^^^^^^^^^^ required by this bound in `S` error[E0308]: mismatched types --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31 @@ -13,7 +31,7 @@ error[E0308]: mismatched types LL | impl Copy for S {} | ^ expected `usize`, found `i32` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0308. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From d5eb7a71b3c869eb9e15f10da6eb92303b96dfb5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 23 May 2024 16:23:41 +0000 Subject: [PATCH 063/101] Use regular type equating instead of a custom query --- .../rustc_infer/src/infer/relate/combine.rs | 36 ++++--------------- compiler/rustc_middle/src/query/mod.rs | 9 ----- .../rustc_trait_selection/src/traits/misc.rs | 21 +---------- .../rustc_trait_selection/src/traits/mod.rs | 1 - tests/crashes/119381.rs | 6 ---- .../generic_const_type_mismatch.rs | 12 +++++++ .../generic_const_type_mismatch.stderr | 15 ++++++++ .../ui/const-generics/issues/issue-105821.rs | 8 ++++- .../const-generics/issues/issue-105821.stderr | 8 +++++ 9 files changed, 50 insertions(+), 66 deletions(-) delete mode 100644 tests/crashes/119381.rs create mode 100644 tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs create mode 100644 tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr create mode 100644 tests/ui/const-generics/issues/issue-105821.stderr diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index fa5b9179c888..7e7d4f43c7cc 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -22,11 +22,11 @@ use super::glb::Glb; use super::lub::Lub; use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; -use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::bug; -use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::EffectVarValue; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; @@ -159,34 +159,12 @@ impl<'tcx> InferCtxt<'tcx> { let a = self.shallow_resolve_const(a); let b = self.shallow_resolve_const(b); - // We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the - // correct type for the generic param they are an argument for. However there have been a number of cases - // historically where asserting that the types are equal has found bugs in the compiler so this is valuable - // to check even if it is a bit nasty impl wise :( - // - // This probe is probably not strictly necessary but it seems better to be safe and not accidentally find - // ourselves with a check to find bugs being required for code to compile because it made inference progress. - self.probe(|_| { - if a.ty() == b.ty() { - return Ok(()); - } + // It is always an error if the types of two constants that are related are not equal. + let InferOk { value: (), obligations } = self + .at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env()) + .eq(DefineOpaqueTypes::No, a.ty(), b.ty())?; + relation.register_obligations(obligations); - // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the - // two const param's types are able to be equal has to go through a canonical query with the actual logic - // in `rustc_trait_selection`. - let canonical = self.canonicalize_query( - relation.param_env().and((a.ty(), b.ty())), - &mut OriginalQueryValues::default(), - ); - self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { - // The error will only be reported later. If we emit an ErrorGuaranteed - // here, then we will never get to the code that actually emits the error. - self.tcx.dcx().delayed_bug(format!( - "cannot relate consts of different types (a={a:?}, b={b:?})", - )); - TypeError::Mismatch - }) - })?; match (a.kind(), b.kind()) { ( ty::ConstKind::Infer(InferConst::Var(a_vid)), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5a6decc4f949..8ca7a465c2a8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2218,15 +2218,6 @@ rustc_queries! { separate_provide_extern } - /// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being - /// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if - /// the types might be equal. - query check_tys_might_be_eq( - arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>> - ) -> Result<(), NoSolution> { - desc { "check whether two const param are definitely not equal to eachother"} - } - /// Get all item paths that were stripped by a `#[cfg]` in a particular crate. /// Should not be called for the local crate before the resolver outputs are created, as it /// is only fed there. diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index da2b004761fc..a1094d982768 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,17 +1,14 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::regions::InferCtxtRegionExt; -use crate::traits::{self, ObligationCause, ObligationCtxt}; +use crate::traits::{self, ObligationCause}; use hir::LangItem; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; -use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; @@ -207,19 +204,3 @@ pub fn all_fields_implement_trait<'tcx>( if infringing.is_empty() { Ok(()) } else { Err(infringing) } } - -pub fn check_tys_might_be_eq<'tcx>( - tcx: TyCtxt<'tcx>, - canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, -) -> Result<(), NoSolution> { - let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical); - let (param_env, (ty_a, ty_b)) = key.into_parts(); - let ocx = ObligationCtxt::new(&infcx); - - let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b); - // use `select_where_possible` instead of `select_all_or_error` so that - // we don't get errors from obligations being ambiguous. - let errors = ocx.select_where_possible(); - - if errors.len() > 0 || result.is_err() { Err(NoSolution) } else { Ok(()) } -} diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 204bb487c860..f6003a250281 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -551,7 +551,6 @@ pub fn provide(providers: &mut Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, instantiate_and_check_impossible_predicates, - check_tys_might_be_eq: misc::check_tys_might_be_eq, is_impossible_associated_item, ..*providers }; diff --git a/tests/crashes/119381.rs b/tests/crashes/119381.rs deleted file mode 100644 index 51d1d084ba2b..000000000000 --- a/tests/crashes/119381.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #119381 - -#![feature(with_negative_coherence)] -trait Trait {} -impl Trait for [(); N] {} -impl Trait for [(); N] {} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs new file mode 100644 index 000000000000..89d0b74d4030 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs @@ -0,0 +1,12 @@ +//! This test used to ICE (#119381), because relating the `u8` and `i8` generic +//! const with the array length of the `Self` type was succeeding under the +//! assumption that an error had already been reported. + +#![feature(with_negative_coherence)] +trait Trait {} +impl Trait for [(); N] {} +//~^ ERROR: mismatched types +impl Trait for [(); N] {} +//~^ ERROR: mismatched types + +fn main() {} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr new file mode 100644 index 000000000000..d19502546602 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:7:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `u8` + +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:9:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `i8` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs index a0a98103b2cd..282cbe9249d9 100644 --- a/tests/ui/const-generics/issues/issue-105821.rs +++ b/tests/ui/const-generics/issues/issue-105821.rs @@ -1,4 +1,10 @@ -//@ check-pass +//@ failure-status: 101 +//@ known-bug: unknown +//@ normalize-stderr-test "note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test "delayed at .*" -> "" +//@ rustc-env:RUST_BACKTRACE=0 #![allow(incomplete_features)] #![feature(adt_const_params, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-105821.stderr b/tests/ui/const-generics/issues/issue-105821.stderr new file mode 100644 index 000000000000..1f0fc0f33ce4 --- /dev/null +++ b/tests/ui/const-generics/issues/issue-105821.stderr @@ -0,0 +1,8 @@ +error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid + +query stack during panic: +#0 [mir_borrowck] borrow-checking `::R` +#1 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to 1 previous error + From 99c9b0775fba00de9a114be430506f30d65a34de Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 24 May 2024 11:25:46 -0400 Subject: [PATCH 064/101] Update rustc-perf --- src/tools/rustc-perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf index 4f313add609f..cc81f9654dac 160000 --- a/src/tools/rustc-perf +++ b/src/tools/rustc-perf @@ -1 +1 @@ -Subproject commit 4f313add609f43e928e98132358e8426ed3969ae +Subproject commit cc81f9654dac3fe08de286907dba747538417afd From b7b350cff7e2b893517f5924c2c7c7f8ae9eb2ac Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 23 May 2024 14:48:27 +0100 Subject: [PATCH 065/101] docs --- compiler/rustc_middle/src/ty/region.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 958e7e401684..4dcd9952f1d7 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -352,6 +352,12 @@ impl std::fmt::Debug for EarlyParamRegion { #[derive(HashStable)] /// The parameter representation of late-bound function parameters, "some region /// at least as big as the scope `fr.scope`". +/// +/// Similar to a placeholder region as we create `LateParam` regions when entering a binder +/// except they are always in the root universe and instead of using a boundvar to distinguish +/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field +/// should basically always be `BoundRegionKind::BrNamed` as otherwise there is no way of telling +/// different parameters apart. pub struct LateParamRegion { pub scope: DefId, pub bound_region: BoundRegionKind, From bd6344d829a9917298b73253ee0c3ecd0eb1460d Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 23 May 2024 23:53:56 +0100 Subject: [PATCH 066/101] Remove `DefId` from `EarlyParamRegion` (type system) --- .../rustc_hir_analysis/src/check/check.rs | 15 +++++--------- .../src/check/compare_impl_item.rs | 13 +++++------- .../rustc_hir_analysis/src/check/wfcheck.rs | 16 +++++++-------- .../rustc_lint/src/impl_trait_overcaptures.rs | 18 +++++------------ compiler/rustc_middle/src/ty/region.rs | 20 +++++++++++++++---- 5 files changed, 38 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b5c067514059..8f21d8269259 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -538,11 +538,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe // the cases that were stabilized with the `impl_trait_projection` // feature -- see . if let DefKind::LifetimeParam = tcx.def_kind(def_id) - && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) = *tcx.map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + && let Some(def_id) = tcx + .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id())) { shadowed_captures.insert(def_id); } @@ -585,12 +583,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe // Check if the lifetime param was captured but isn't named in the precise captures list. if variances[param.index as usize] == ty::Invariant { if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id)) - && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) = *tcx + && let Some(def_id) = tcx .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()) + .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id())) { tcx.dcx().emit_err(errors::LifetimeNotCaptured { opaque_span, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 44bf8fd2d93e..fedaf3268868 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -876,7 +876,8 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { ty::ReLateParam(_) => {} // Remap early-bound regions as long as they don't come from the `impl` itself, // in which case we don't really need to renumber them. - ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {} + ty::ReEarlyParam(ebr) + if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {} _ => return Ok(region), } @@ -889,12 +890,8 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { ); } } else { - let guar = match region.kind() { - ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) => { + let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) { + Some(def_id) => { let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() { self.tcx.def_span(opaque_ty.def_id) } else { @@ -914,7 +911,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { .with_note(format!("hidden type inferred to be `{}`", self.ty)) .emit() } - _ => { + None => { // This code path is not reached in any tests, but may be // reachable. If this is triggered, it should be converted // to `delayed_bug` and the triggering case turned into a diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e8ede804c3f3..460269ae41f4 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2101,16 +2101,14 @@ fn lint_redundant_lifetimes<'tcx>( } for &victim in &lifetimes[(idx + 1)..] { - // We should only have late-bound lifetimes of the `BrNamed` variety, - // since we get these signatures straight from `hir_lowering`. And any - // other regions (ReError/ReStatic/etc.) shouldn't matter, since we + // All region parameters should have a `DefId` available as: + // - Late-bound parameters should be of the`BrNamed` variety, + // since we get these signatures straight from `hir_lowering`. + // - Early-bound parameters unconditionally have a `DefId` available. + // + // Any other regions (ReError/ReStatic/etc.) shouldn't matter, since we // can't really suggest to remove them. - let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - })) = victim.kind() - else { + let Some(def_id) = victim.opt_param_def_id(tcx, owner_id.to_def_id()) else { continue; }; diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 30bf80b915b8..c473b74b4105 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -5,11 +5,11 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::LintDiagnostic; +use rustc_middle::bug; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_middle::{bug, span_bug}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{sym, BytePos, Span}; @@ -303,20 +303,12 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { ResolvedArg::EarlyBound(def_id) | ResolvedArg::LateBound(_, _, def_id), ) => { if self.tcx.def_kind(self.tcx.parent(def_id)) == DefKind::OpaqueTy { - let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - })) = self + let def_id = self .tcx .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) - .kind() - else { - span_bug!( - self.tcx.def_span(def_id), - "variable should have been duplicated from a parent" - ); - }; + .opt_param_def_id(self.tcx, self.parent_def_id.to_def_id()) + .expect("variable should have been duplicated from parent"); + explicitly_captured.insert(def_id); } else { explicitly_captured.insert(def_id); diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 4dcd9952f1d7..0e07ef31c26c 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -321,6 +321,21 @@ impl<'tcx> Region<'tcx> { _ => bug!("expected region {:?} to be of kind ReVar", self), } } + + /// Given some item `binding_item`, check if this region is a generic parameter introduced by it + /// or one of the parent generics. Returns the `DefId` of the parameter definition if so. + pub fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId) -> Option { + match self.kind() { + ty::ReEarlyParam(ebr) => { + Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id) + } + ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + }) => Some(def_id), + _ => None, + } + } } impl<'tcx> Deref for Region<'tcx> { @@ -335,16 +350,13 @@ impl<'tcx> Deref for Region<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct EarlyParamRegion { - pub def_id: DefId, pub index: u32, pub name: Symbol, } impl std::fmt::Debug for EarlyParamRegion { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // FIXME(BoxyUwU): self.def_id goes first because of `erased-regions-in-hidden-ty.rs` being impossible to write - // error annotations for otherwise. :). Ideally this would be `self.name, self.index, self.def_id`. - write!(f, "{:?}_{}/#{}", self.def_id, self.name, self.index) + write!(f, "{}/#{}", self.name, self.index) } } From fe2d7794ca189f9ec5e7f7fd9b059e7a2e785944 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 24 May 2024 01:57:06 +0100 Subject: [PATCH 067/101] Remove `DefId` from `EarlyParamRegion` (tedium/diagnostics) --- .../src/diagnostics/bound_region_errors.rs | 36 ++++--- .../src/diagnostics/region_errors.rs | 39 ++++--- .../src/diagnostics/region_name.rs | 8 +- .../src/check/compare_impl_item.rs | 1 - .../rustc_hir_analysis/src/check/wfcheck.rs | 18 +--- compiler/rustc_hir_analysis/src/collect.rs | 1 - .../src/collect/predicates_of.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_infer/src/errors/mod.rs | 5 +- .../src/errors/note_and_explain.rs | 20 +++- .../src/infer/error_reporting/mod.rs | 100 +++++++++++++----- .../nice_region_error/different_lifetimes.rs | 31 ++++-- .../nice_region_error/find_anon_type.rs | 4 +- .../mismatched_static_lifetime.rs | 1 + .../error_reporting/nice_region_error/mod.rs | 18 +++- .../nice_region_error/named_anon_conflict.rs | 6 +- .../nice_region_error/static_impl_trait.rs | 4 +- .../error_reporting/nice_region_error/util.rs | 8 +- .../src/infer/error_reporting/note.rs | 45 +++++++- compiler/rustc_lint/src/builtin.rs | 18 +++- compiler/rustc_middle/src/ty/context.rs | 14 +-- compiler/rustc_middle/src/ty/generics.rs | 2 +- compiler/rustc_middle/src/ty/region.rs | 27 ----- .../rustc_smir/src/rustc_smir/convert/ty.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 1 + compiler/rustc_ty_utils/src/implied_bounds.rs | 6 +- .../ty-outlives/impl-trait-captures.stderr | 4 +- 27 files changed, 266 insertions(+), 157 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 9b8b7e8ddda6..5e10f14f31b5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,4 +1,5 @@ use rustc_errors::Diag; +use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::region_constraints::Constraint; @@ -241,7 +242,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_prove_predicate_with_cause(&ocx, key, cause); - try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -287,7 +288,7 @@ where let (param_env, value) = key.into_parts(); let _ = ocx.normalize(&cause, param_env, value.value); - try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -318,7 +319,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; - try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -342,6 +343,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, + mbcx.mir_def_id(), placeholder_region, error_region, self.region_constraints.as_ref().unwrap(), @@ -358,6 +360,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { #[instrument(skip(ocx), level = "debug")] fn try_extract_error_from_fulfill_cx<'tcx>( ocx: &ObligationCtxt<'_, 'tcx>, + generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { @@ -368,6 +371,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); try_extract_error_from_region_constraints( ocx.infcx, + generic_param_scope, placeholder_region, error_region, ®ion_constraints, @@ -379,6 +383,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] fn try_extract_error_from_region_constraints<'tcx>( infcx: &InferCtxt<'tcx>, + generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, @@ -452,15 +457,18 @@ fn try_extract_error_from_region_constraints<'tcx>( RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region) } }; - NiceRegionError::new(&infcx.err_ctxt(), error).try_report_from_nll().or_else(|| { - if let SubregionOrigin::Subtype(trace) = cause { - Some( - infcx - .err_ctxt() - .report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch), - ) - } else { - None - } - }) + NiceRegionError::new(&infcx.err_ctxt(), generic_param_scope, error) + .try_report_from_nll() + .or_else(|| { + if let SubregionOrigin::Subtype(trace) = cause { + Some( + infcx.err_ctxt().report_and_explain_type_error( + *trace, + TypeError::RegionsPlaceholderMismatch, + ), + ) + } else { + None + } + }) } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 8112fb7b89c6..e11e4a7247c2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -361,6 +361,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let diag = unexpected_hidden_region_diagnostic( self.infcx.tcx, + self.mir_def_id(), span, named_ty, named_region, @@ -453,7 +454,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let infer_err = self.infcx.err_ctxt(); - let nice = NiceRegionError::new_from_span(&infer_err, cause.span, o, f); + let nice = + NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), cause.span, o, f); if let Some(diag) = nice.try_report_from_nll() { self.buffer_error(diag); return; @@ -843,14 +845,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if *outlived_f != ty::ReStatic { return; } - let suitable_region = self.infcx.tcx.is_suitable_region(f); + let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f); let Some(suitable_region) = suitable_region else { return; }; let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id); - let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) { + let param = if let Some(param) = + find_param_with_region(self.infcx.tcx, self.mir_def_id(), f, outlived_f) + { param } else { return; @@ -959,7 +963,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { return; }; - let param = match find_param_with_region(tcx, f, o) { + let param = match find_param_with_region(tcx, self.mir_def_id(), f, o) { Some(param) => param, None => return, }; @@ -1022,25 +1026,30 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { return; }; - let Some((ty_sub, _)) = self - .infcx - .tcx - .is_suitable_region(sub) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.bound_region)) + let Some((ty_sub, _)) = + self.infcx.tcx.is_suitable_region(self.mir_def_id(), sub).and_then(|anon_reg| { + find_anon_type(self.infcx.tcx, self.mir_def_id(), sub, &anon_reg.bound_region) + }) else { return; }; - let Some((ty_sup, _)) = self - .infcx - .tcx - .is_suitable_region(sup) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.bound_region)) + let Some((ty_sup, _)) = + self.infcx.tcx.is_suitable_region(self.mir_def_id(), sup).and_then(|anon_reg| { + find_anon_type(self.infcx.tcx, self.mir_def_id(), sup, &anon_reg.bound_region) + }) else { return; }; - suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag); + suggest_adding_lifetime_params( + self.infcx.tcx, + diag, + self.mir_def_id(), + sub, + ty_sup, + ty_sub, + ); } #[allow(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 46011c1f43ec..c2db64e77025 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -289,7 +289,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { debug!("give_region_a_name: error_region = {:?}", error_region); match *error_region { ty::ReEarlyParam(ebr) => ebr.has_name().then(|| { - let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); + let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id; + let span = tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP); RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) } }), @@ -912,7 +913,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }; let tcx = self.infcx.tcx; - let region_parent = tcx.parent(region.def_id); + let region_def = tcx.generics_of(self.mir_def_id()).region_param(region, tcx).def_id; + let region_parent = tcx.parent(region_def); let DefKind::Impl { .. } = tcx.def_kind(region_parent) else { return None; }; @@ -925,7 +927,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { Some(RegionName { name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromImplSignature( - tcx.def_span(region.def_id), + tcx.def_span(region_def), // FIXME(compiler-errors): Does this ever actually show up // anywhere other than the self type? I couldn't create an // example of a `'_` in the impl's trait being referenceable. diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index fedaf3268868..39ced1c803f7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -925,7 +925,6 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { Ok(ty::Region::new_early_param( self.tcx, ty::EarlyParamRegion { - def_id: e.def_id, name: e.name, index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32, }, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 460269ae41f4..81e3d8c7ece2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -675,11 +675,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( let region_param = gat_generics.param_at(*region_a_idx, tcx); let region_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_param.def_id, - index: region_param.index, - name: region_param.name, - }, + ty::EarlyParamRegion { index: region_param.index, name: region_param.name }, ); // The predicate we expect to see. (In our example, // `Self: 'me`.) @@ -708,21 +704,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( let region_a_param = gat_generics.param_at(*region_a_idx, tcx); let region_a_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_a_param.def_id, - index: region_a_param.index, - name: region_a_param.name, - }, + ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name }, ); // Same for the region. let region_b_param = gat_generics.param_at(*region_b_idx, tcx); let region_b_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_b_param.def_id, - index: region_b_param.index, - name: region_b_param.name, - }, + ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name }, ); // The predicate we expect to see. bounds.insert( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b760b86a7bfb..40cd65b899e2 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -453,7 +453,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { poly_trait_ref, |_| { ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion { - def_id: item_def_id, index: 0, name: Symbol::intern(<_name), }) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index db36aba7edf4..45f06e59be85 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -323,7 +323,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>( if let ty::ReEarlyParam(..) = *orig_lifetime { let dup_lifetime = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name }, + ty::EarlyParamRegion { index: param.index, name: param.name }, ); let span = tcx.def_span(param.def_id); predicates.push(( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 4b1c0da6ce11..83a23de16543 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -280,7 +280,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name }) + ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name }) } Some(rbv::ResolvedArg::Free(scope, id)) => { diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 8bb0dc39143c..a801001eaf98 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -5,6 +5,7 @@ use rustc_errors::{ MultiSpan, SubdiagMessageOp, Subdiagnostic, }; use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::FnRetTy; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -344,6 +345,7 @@ impl Subdiagnostic for LifetimeMismatchLabels { pub struct AddLifetimeParamsSuggestion<'a> { pub tcx: TyCtxt<'a>, + pub generic_param_scope: LocalDefId, pub sub: Region<'a>, pub ty_sup: &'a hir::Ty<'a>, pub ty_sub: &'a hir::Ty<'a>, @@ -357,7 +359,8 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { _f: &F, ) { let mut mk_suggestion = || { - let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else { + let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub) + else { return false; }; diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index f0b336ca0461..4fbeb0ec1024 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,6 +1,7 @@ use crate::fluent_generated as fluent; use crate::infer::error_reporting::nice_region_error::find_anon_type; use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic}; +use rustc_hir::def_id::LocalDefId; use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; @@ -14,12 +15,15 @@ struct DescriptionCtx<'a> { impl<'a> DescriptionCtx<'a> { fn new<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, ) -> Option { let (span, kind, arg) = match *region { - ty::ReEarlyParam(ref br) => { - let scope = region.free_region_binding_scope(tcx).expect_local(); + ty::ReEarlyParam(br) => { + let scope = tcx + .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) + .expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { @@ -35,11 +39,12 @@ impl<'a> DescriptionCtx<'a> { } ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() - && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) + && let Some((ty, _)) = + find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) { (Some(ty.span), "defined_here", String::new()) } else { - let scope = region.free_region_binding_scope(tcx).expect_local(); + let scope = fr.scope.expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { let span = if let Some(param) = tcx @@ -143,12 +148,17 @@ pub struct RegionExplanation<'a> { impl RegionExplanation<'_> { pub fn new<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, prefix: PrefixKind, suffix: SuffixKind, ) -> Option { - Some(Self { desc: DescriptionCtx::new(tcx, region, alt_span)?, prefix, suffix }) + Some(Self { + desc: DescriptionCtx::new(tcx, generic_param_scope, region, alt_span)?, + prefix, + suffix, + }) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e0894ed31bfc..7ab148e70a13 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -161,6 +161,7 @@ impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> { pub(super) fn note_and_explain_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, + generic_param_scope: LocalDefId, prefix: &str, region: ty::Region<'tcx>, suffix: &str, @@ -168,7 +169,7 @@ pub(super) fn note_and_explain_region<'tcx>( ) { let (description, span) = match *region { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { - msg_span_from_named_region(tcx, region, alt_span) + msg_span_from_named_region(tcx, generic_param_scope, region, alt_span) } ty::ReError(_) => return, @@ -187,23 +188,27 @@ pub(super) fn note_and_explain_region<'tcx>( fn explain_free_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, + generic_param_scope: LocalDefId, prefix: &str, region: ty::Region<'tcx>, suffix: &str, ) { - let (description, span) = msg_span_from_named_region(tcx, region, None); + let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None); label_msg_span(err, prefix, description, span, suffix); } fn msg_span_from_named_region<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, ) -> (String, Option) { match *region { - ty::ReEarlyParam(ref br) => { - let scope = region.free_region_binding_scope(tcx).expect_local(); + ty::ReEarlyParam(br) => { + let scope = tcx + .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) + .expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { @@ -220,21 +225,21 @@ fn msg_span_from_named_region<'tcx>( } ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() - && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) + && let Some((ty, _)) = + find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) { ("the anonymous lifetime defined here".to_string(), Some(ty.span)) } else { - let scope = region.free_region_binding_scope(tcx).expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { let span = if let Some(param) = tcx .hir() - .get_generics(scope) + .get_generics(generic_param_scope) .and_then(|generics| generics.get_named(name)) { param.span } else { - tcx.def_span(scope) + tcx.def_span(generic_param_scope) }; let text = if name == kw::UnderscoreLifetime { "the anonymous lifetime as defined here".to_string() @@ -245,11 +250,11 @@ fn msg_span_from_named_region<'tcx>( } ty::BrAnon => ( "the anonymous lifetime as defined here".to_string(), - Some(tcx.def_span(scope)), + Some(tcx.def_span(generic_param_scope)), ), _ => ( format!("the lifetime `{region}` as defined here"), - Some(tcx.def_span(scope)), + Some(tcx.def_span(generic_param_scope)), ), } } @@ -302,6 +307,7 @@ fn label_msg_span( #[instrument(level = "trace", skip(tcx))] pub fn unexpected_hidden_region_diagnostic<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, @@ -327,11 +333,12 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( explain_free_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", ); - if let Some(reg_info) = tcx.is_suitable_region(hidden_region) { + if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) { let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id); nice_region_error::suggest_new_region_bound( tcx, @@ -349,6 +356,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( explain_free_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{}` captures ", hidden_ty), hidden_region, "", @@ -376,6 +384,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( note_and_explain_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", @@ -450,7 +459,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for error in errors { debug!("report_region_errors: error = {:?}", error); - guar = Some(if let Some(guar) = self.try_report_nice_region_error(&error) { + let e = if let Some(guar) = + self.try_report_nice_region_error(generic_param_scope, &error) + { guar } else { match error.clone() { @@ -463,9 +474,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // general bit of code that displays the error information RegionResolutionError::ConcreteFailure(origin, sub, sup) => { if sub.is_placeholder() || sup.is_placeholder() { - self.report_placeholder_failure(origin, sub, sup).emit() + self.report_placeholder_failure(generic_param_scope, origin, sub, sup) + .emit() } else { - self.report_concrete_failure(origin, sub, sup).emit() + self.report_concrete_failure(generic_param_scope, origin, sub, sup) + .emit() } } @@ -488,12 +501,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _, ) => { if sub_r.is_placeholder() { - self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sub_origin, + sub_r, + sup_r, + ) + .emit() } else if sup_r.is_placeholder() { - self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() } else { self.report_sub_sup_conflict( - var_origin, sub_origin, sub_r, sup_origin, sup_r, + generic_param_scope, + var_origin, + sub_origin, + sub_r, + sup_origin, + sup_r, ) } } @@ -514,7 +544,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // value. let sub_r = self.tcx.lifetimes.re_erased; - self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() } RegionResolutionError::CannotNormalize(clause, origin) => { @@ -526,7 +562,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .emit() } } - }) + }; + + guar = Some(e) } guar.unwrap() @@ -2347,7 +2385,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { '_explain: { let (description, span) = match sub.kind() { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { - msg_span_from_named_region(self.tcx, sub, Some(span)) + msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span)) } _ => (format!("lifetime `{sub}`"), Some(span)), }; @@ -2398,7 +2436,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let suggestion_scope = { let lifetime_scope = match sub.kind() { ty::ReStatic => hir::def_id::CRATE_DEF_ID, - _ => match self.tcx.is_suitable_region(sub) { + _ => match self.tcx.is_suitable_region(generic_param_scope, sub) { Some(info) => info.def_id, None => generic_param_scope, }, @@ -2410,7 +2448,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut suggs = vec![]; - let lt_name = self.suggest_name_region(sub, &mut suggs); + let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs); if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span && suggestion_scope == type_scope @@ -2455,6 +2493,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub fn suggest_name_region( &self, + generic_param_scope: LocalDefId, lifetime: Region<'tcx>, add_lt_suggs: &mut Vec<(Span, String)>, ) -> String { @@ -2501,12 +2540,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime) { - Some(info) if !lifetime.has_name() => { - (info.bound_region.get_id().unwrap().expect_local(), info.def_id) - } - _ => return lifetime.get_name_or_anon().to_string(), - }; + let (lifetime_def_id, lifetime_scope) = + match self.tcx.is_suitable_region(generic_param_scope, lifetime) { + Some(info) if !lifetime.has_name() => { + (info.bound_region.get_id().unwrap().expect_local(), info.def_id) + } + _ => return lifetime.get_name_or_anon().to_string(), + }; let new_lt = { let generics = self.tcx.generics_of(lifetime_scope); @@ -2557,6 +2597,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn report_sub_sup_conflict( &self, + generic_param_scope: LocalDefId, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, sub_region: Region<'tcx>, @@ -2568,6 +2609,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "first, the lifetime cannot outlive ", sup_region, "...", @@ -2590,6 +2632,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "...but the lifetime must also be valid for ", sub_region, "...", @@ -2613,6 +2656,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "but, the lifetime must be valid for ", sub_region, "...", diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 84bfa5b5af7f..cbeec591960b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -13,6 +13,7 @@ use crate::infer::TyCtxt; use rustc_errors::Subdiagnostic; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::Ty; use rustc_middle::ty::Region; @@ -66,17 +67,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } // Determine whether the sub and sup consist of both anonymous (elided) regions. - let anon_reg_sup = self.tcx().is_suitable_region(sup)?; + let anon_reg_sup = self.tcx().is_suitable_region(self.generic_param_scope, sup)?; - let anon_reg_sub = self.tcx().is_suitable_region(sub)?; + let anon_reg_sub = self.tcx().is_suitable_region(self.generic_param_scope, sub)?; let scope_def_id_sup = anon_reg_sup.def_id; let bregion_sup = anon_reg_sup.bound_region; let scope_def_id_sub = anon_reg_sub.def_id; let bregion_sub = anon_reg_sub.bound_region; - let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?; + let ty_sup = find_anon_type(self.tcx(), self.generic_param_scope, sup, &bregion_sup)?; - let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?; + let ty_sub = find_anon_type(self.tcx(), self.generic_param_scope, sub, &bregion_sub)?; debug!( "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}", @@ -127,8 +128,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }, }; - let suggestion = - AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true }; + let suggestion = AddLifetimeParamsSuggestion { + tcx: self.tcx(), + sub, + ty_sup, + ty_sub, + add_note: true, + generic_param_scope: self.generic_param_scope, + }; let err = LifetimeMismatch { span, labels, suggestion }; let reported = self.tcx().dcx().emit_err(err); Some(reported) @@ -139,11 +146,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// removed in favour of public_errors::AddLifetimeParamsSuggestion pub fn suggest_adding_lifetime_params<'tcx>( tcx: TyCtxt<'tcx>, + err: &mut Diag<'_>, + generic_param_scope: LocalDefId, sub: Region<'tcx>, ty_sup: &'tcx Ty<'_>, ty_sub: &'tcx Ty<'_>, - err: &mut Diag<'_>, ) { - let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false }; + let suggestion = AddLifetimeParamsSuggestion { + tcx, + sub, + ty_sup, + ty_sub, + add_note: false, + generic_param_scope, + }; suggestion.add_to_diag(err); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 265a315a5597..b91b755d6837 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,5 +1,6 @@ use core::ops::ControlFlow; use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; @@ -23,10 +24,11 @@ use rustc_middle::ty::{self, Region, TyCtxt}; /// for e.g., `&u8` and `Vec<&u8>`. pub fn find_anon_type<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: Region<'tcx>, br: &ty::BoundRegionKind, ) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> { - let anon_reg = tcx.is_suitable_region(region)?; + let anon_reg = tcx.is_suitable_region(generic_param_scope, region)?; let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?; fn_sig diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 45dce0a0e330..7996b4bf65b4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -57,6 +57,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let expl = note_and_explain::RegionExplanation::new( self.tcx(), + self.generic_param_scope, sup, Some(binding_span), note_and_explain::PrefixKind::Empty, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 62c163f0b7f6..cffdfa887523 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -2,6 +2,7 @@ use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::lexical_region_resolve::RegionResolutionError::*; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; @@ -23,30 +24,39 @@ pub use util::find_param_with_region; impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> { pub fn try_report_nice_region_error( &'cx self, + generic_param_scope: LocalDefId, error: &RegionResolutionError<'tcx>, ) -> Option { - NiceRegionError::new(self, error.clone()).try_report() + NiceRegionError::new(self, generic_param_scope, error.clone()).try_report() } } pub struct NiceRegionError<'cx, 'tcx> { cx: &'cx TypeErrCtxt<'cx, 'tcx>, + /// The innermost definition that introduces generic parameters that may be involved in + /// the region errors we are dealing with. + generic_param_scope: LocalDefId, error: Option>, regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>, } impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { - pub fn new(cx: &'cx TypeErrCtxt<'cx, 'tcx>, error: RegionResolutionError<'tcx>) -> Self { - Self { cx, error: Some(error), regions: None } + pub fn new( + cx: &'cx TypeErrCtxt<'cx, 'tcx>, + generic_param_scope: LocalDefId, + error: RegionResolutionError<'tcx>, + ) -> Self { + Self { cx, error: Some(error), regions: None, generic_param_scope } } pub fn new_from_span( cx: &'cx TypeErrCtxt<'cx, 'tcx>, + generic_param_scope: LocalDefId, span: Span, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, ) -> Self { - Self { cx, error: None, regions: Some((span, sub, sup)) } + Self { cx, error: None, regions: Some((span, sub, sup)), generic_param_scope } } fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 239c2db30e2d..29da12e7d151 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -27,12 +27,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // version new_ty of its type where the anonymous region is replaced // with the named one. let (named, anon, anon_param_info, region_info) = if sub.has_name() - && let Some(region_info) = self.tcx().is_suitable_region(sup) + && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sup) && let Some(anon_param_info) = self.find_param_with_region(sup, sub) { (sub, sup, anon_param_info, region_info) } else if sup.has_name() - && let Some(region_info) = self.tcx().is_suitable_region(sub) + && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sub) && let Some(anon_param_info) = self.find_param_with_region(sub, sup) { (sup, sub, anon_param_info, region_info) @@ -72,7 +72,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; } - if find_anon_type(self.tcx(), anon, &br).is_some() + if find_anon_type(self.tcx(), self.generic_param_scope, anon, &br).is_some() && self.is_self_anon(is_first, scope_def_id) { return None; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 8a1e3a7ac71b..71a86683c212 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() { // This may have a closure and it would cause ICE // through `find_param_with_region` (#78262). - let anon_reg_sup = tcx.is_suitable_region(*sup_r)?; + let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?; let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); if fn_returns.is_empty() { return None; @@ -92,7 +92,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})", var_origin, sub_origin, sub_r, sup_origin, sup_r ); - let anon_reg_sup = tcx.is_suitable_region(*sup_r)?; + let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?; debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup); let sp = var_origin.span(); let return_sp = sub_origin.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index f1f8314661f3..5f3f1081ca8f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -37,13 +37,15 @@ pub struct AnonymousParamInfo<'tcx> { #[instrument(skip(tcx), level = "debug")] pub fn find_param_with_region<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, anon_region: Region<'tcx>, replace_region: Region<'tcx>, ) -> Option> { let (id, bound_region) = match *anon_region { ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region), ty::ReEarlyParam(ebr) => { - (tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name)) + let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id; + (tcx.parent(region_def), ty::BoundRegionKind::BrNamed(region_def, ebr.name)) } _ => return None, // not a free region }; @@ -53,7 +55,7 @@ pub fn find_param_with_region<'tcx>( // FIXME: use def_kind // Don't perform this on closures - match tcx.hir_node_by_def_id(def_id) { + match tcx.hir_node_by_def_id(generic_param_scope) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { return None; } @@ -110,7 +112,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { anon_region: Region<'tcx>, replace_region: Region<'tcx>, ) -> Option> { - find_param_with_region(self.tcx(), anon_region, replace_region) + find_param_with_region(self.tcx(), self.generic_param_scope, anon_region, replace_region) } // Here, we check for the case where the anonymous region diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 00dd20a2cc27..acb74f8a82ce 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -75,6 +75,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn report_concrete_failure( &self, + generic_param_scope: LocalDefId, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -89,6 +90,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "", sup, " doesn't meet the lifetime requirements", @@ -99,6 +101,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "the required lifetime does not necessarily outlive ", sub, "", @@ -106,10 +109,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } _ => { - note_and_explain_region(self.tcx, &mut err, "", sup, "...", None); note_and_explain_region( self.tcx, &mut err, + generic_param_scope, + "", + sup, + "...", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, "...does not necessarily outlive ", sub, "", @@ -122,6 +134,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Reborrow(span) => { let reference_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::RefValidFor, @@ -129,6 +142,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let content_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::ContentValidFor, @@ -142,6 +156,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::RelateObjectBound(span) => { let object_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::TypeObjValidFor, @@ -149,6 +164,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::SourcePointerValidFor, @@ -170,7 +186,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain::SuffixKind::Empty }; let note = note_and_explain::RegionExplanation::new( - self.tcx, sub, opt_span, prefix, suffix, + self.tcx, + generic_param_scope, + sub, + opt_span, + prefix, + suffix, ); self.dcx().create_err(FulfillReqLifetime { span, @@ -181,6 +202,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::RelateRegionParamBound(span) => { let param_instantiated = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::LfParamInstantiatedWith, @@ -188,6 +210,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let param_must_outlive = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::LfParamMustOutlive, @@ -201,6 +224,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::ReferenceOutlivesReferent(ty, span) => { let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::PointerValidFor, @@ -208,6 +232,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let data_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::DataValidFor, @@ -239,7 +264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { - let mut err = self.report_concrete_failure(*parent, sub, sup); + let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup); // Don't mention the item name if it's an RPITIT, since that'll just confuse // folks. @@ -262,6 +287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::AscribeUserTypeProvePredicate(span) => { let instantiated = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::LfInstantiatedWith, @@ -269,6 +295,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let must_outlive = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::LfMustOutlive, @@ -347,6 +374,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn report_placeholder_failure( &self, + generic_param_scope: LocalDefId, placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -368,7 +396,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && !span.is_dummy() { let span = *span; - self.report_concrete_failure(placeholder_origin, sub, sup) + self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( @@ -380,7 +408,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let terr = TypeError::RegionsPlaceholderMismatch; return self.report_and_explain_type_error(trace, terr); } - _ => return self.report_concrete_failure(placeholder_origin, sub, sup), + _ => { + return self.report_concrete_failure( + generic_param_scope, + placeholder_origin, + sub, + sup, + ); + } } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 85d54ce563d2..0129b8f842f0 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1950,14 +1950,22 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( + tcx: TyCtxt<'tcx>, inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], - def_id: DefId, + item: DefId, + lifetime: DefId, ) -> Vec> { + let item_generics = tcx.generics_of(item); + inferred_outlives .iter() .filter_map(|(clause, _)| match clause.kind().skip_binder() { ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { - ty::ReEarlyParam(ebr) if ebr.def_id == def_id => Some(b), + ty::ReEarlyParam(ebr) + if item_generics.region_param(ebr, tcx).def_id == lifetime => + { + Some(b) + } _ => None, }, _ => None, @@ -1986,6 +1994,7 @@ impl ExplicitOutlivesRequirements { bounds: &hir::GenericBounds<'_>, inferred_outlives: &[ty::Region<'tcx>], predicate_span: Span, + item: DefId, ) -> Vec<(usize, Span)> { use rustc_middle::middle::resolve_bound_vars::ResolvedArg; @@ -2000,7 +2009,7 @@ impl ExplicitOutlivesRequirements { let is_inferred = match tcx.named_bound_var(lifetime.hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives .iter() - .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { ebr.def_id == def_id })), + .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { tcx.generics_of(item).region_param(ebr, tcx).def_id == def_id })), _ => false, }; @@ -2109,7 +2118,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { { ( Self::lifetimes_outliving_lifetime( + cx.tcx, inferred_outlives, + item.owner_id.to_def_id(), region_def_id, ), &predicate.bounds, @@ -2152,6 +2163,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { bounds, &relevant_lifetimes, predicate_span, + item.owner_id.to_def_id(), ); bound_count += bound_spans.len(); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6e53b5bb5206..318a18715e49 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1488,13 +1488,14 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region. - pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option { + pub fn is_suitable_region( + self, + generic_param_scope: LocalDefId, + mut region: Region<'tcx>, + ) -> Option { let (suitable_region_binding_scope, bound_region) = loop { - let def_id = match region.kind() { - ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?, - ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?, - _ => return None, // not a free region - }; + let def_id = + region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?; let scope = self.local_parent(def_id); if self.def_kind(scope) == DefKind::OpaqueTy { // Lifetime params of opaque types are synthetic and thus irrelevant to @@ -2633,7 +2634,6 @@ impl<'tcx> TyCtxt<'tcx> { return ty::Region::new_early_param( self, ty::EarlyParamRegion { - def_id: ebv, index: generics .param_def_id_to_index(self, ebv) .expect("early-bound var should be present in fn generics"), diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 870e4865aeab..8fdff40024bb 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -66,7 +66,7 @@ pub struct GenericParamDef { impl GenericParamDef { pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion { if let GenericParamDefKind::Lifetime = self.kind { - ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name } + ty::EarlyParamRegion { index: self.index, name: self.name } } else { bug!("cannot convert a non-lifetime parameter def to an early bound region") } diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 0e07ef31c26c..0807cbf91d16 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -265,33 +265,6 @@ impl<'tcx> Region<'tcx> { flags } - /// Given an early-bound or free region, returns the `DefId` where it was bound. - /// For example, consider the regions in this snippet of code: - /// - /// ```ignore (illustrative) - /// impl<'a> Foo { - /// // ^^ -- early bound, declared on an impl - /// - /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c - /// // ^^ ^^ ^ anonymous, late-bound - /// // | early-bound, appears in where-clauses - /// // late-bound, appears only in fn args - /// {..} - /// } - /// ``` - /// - /// Here, `free_region_binding_scope('a)` would return the `DefId` - /// of the impl, and for all the other highlighted regions, it - /// would return the `DefId` of the function. In other cases (not shown), this - /// function might return the `DefId` of a closure. - pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { - match *self { - ty::ReEarlyParam(br) => tcx.parent(br.def_id), - ty::ReLateParam(fr) => fr.scope, - _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), - } - } - /// True for free regions other than `'static`. pub fn is_param(self) -> bool { matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_)) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index be20924670c3..233cfd792880 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -771,7 +771,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; match self { ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { - def_id: tables.region_def(early_reg.def_id), + def_id: tables.region_def(todo!()), index: early_reg.index, name: early_reg.name.to_string(), }), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 204bb487c860..e35b8e9fe7d8 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -185,6 +185,7 @@ fn do_normalize_predicates<'tcx>( predicates: Vec>, ) -> Result>, ErrorGuaranteed> { let span = cause.span; + // FIXME. We should really... do something with these region // obligations. But this call just continues the older // behavior (i.e., doesn't cause any new bugs), and it would diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index e87058f9ba48..6f71951b5162 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -79,11 +79,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' orig_lt, ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: param.def_id, - index: param.index, - name: param.name, - }, + ty::EarlyParamRegion { index: param.index, name: param.name }, ), ); } diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr index 3893cdf482e6..48569d1446dd 100644 --- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,4 +1,4 @@ -error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` captures lifetime that does not appear in bounds --> $DIR/impl-trait-captures.rs:11:5 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { @@ -8,7 +8,7 @@ LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { LL | x | ^ | -help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:14 ~ impl_trait_captures[aeb9]::foo::{opaque#0}::'a)_'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound +help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From f856ee357c1d40eb51e2a545ed30063c55b24c32 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 24 May 2024 17:25:50 +0100 Subject: [PATCH 068/101] Remove `DefId` from `EarlyParamRegion` (clippy/smir) --- .../rustc_smir/src/rustc_smir/convert/ty.rs | 1 - compiler/stable_mir/src/ty.rs | 1 - src/tools/clippy/clippy_lints/src/ptr.rs | 19 +++++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 233cfd792880..a511989d972c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -771,7 +771,6 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; match self { ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { - def_id: tables.region_def(todo!()), index: early_reg.index, name: early_reg.name.to_string(), }), diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index f3ac2bfcdb01..d62054eff609 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -190,7 +190,6 @@ pub(crate) type DebruijnIndex = u32; #[derive(Clone, Debug, Eq, PartialEq)] pub struct EarlyParamRegion { - pub def_id: RegionDef, pub index: u32, pub name: Symbol, } diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 65929cd5fea9..38580dc58226 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -460,13 +460,19 @@ fn check_fn_args<'cx, 'tcx: 'cx>( } None }) { - if !lifetime.is_anonymous() + if let LifetimeName::Param(param_def_id) = lifetime.res + && !lifetime.is_anonymous() && fn_sig .output() .walk() .filter_map(|arg| { arg.as_region().and_then(|lifetime| match lifetime.kind() { - ty::ReEarlyParam(r) => Some(r.def_id), + ty::ReEarlyParam(r) => Some( + cx.tcx + .generics_of(cx.tcx.parent(param_def_id.to_def_id())) + .region_param(r, cx.tcx) + .def_id, + ), ty::ReBound(_, r) => r.kind.get_id(), ty::ReLateParam(r) => r.bound_region.get_id(), ty::ReStatic @@ -476,14 +482,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( | ty::ReError(_) => None, }) }) - .any(|def_id| { - matches!( - lifetime.res, - LifetimeName::Param(param_def_id) if def_id - .as_local() - .is_some_and(|def_id| def_id == param_def_id), - ) - }) + .any(|def_id| def_id.as_local().is_some_and(|def_id| def_id == param_def_id)) { // `&Cow<'a, T>` when the return type uses 'a is okay return None; From 796cb8031d4b3a12bceb95c8b029e90fd5d4e568 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 24 May 2024 17:31:01 +0100 Subject: [PATCH 069/101] Remove failing tests --- tests/crashes/118403.rs | 8 -------- tests/crashes/121574-2.rs | 8 -------- tests/crashes/121574.rs | 6 ------ 3 files changed, 22 deletions(-) delete mode 100644 tests/crashes/118403.rs delete mode 100644 tests/crashes/121574-2.rs delete mode 100644 tests/crashes/121574.rs diff --git a/tests/crashes/118403.rs b/tests/crashes/118403.rs deleted file mode 100644 index 21ab15f9ffd0..000000000000 --- a/tests/crashes/118403.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #118403 -#![feature(generic_const_exprs)] -pub struct X {} -impl X { - pub fn y<'a, U: 'a>(&'a self) -> impl Iterator + '_> { - (0..1).map(move |_| (0..1).map(move |_| loop {})) - } -} diff --git a/tests/crashes/121574-2.rs b/tests/crashes/121574-2.rs deleted file mode 100644 index a08f3f063974..000000000000 --- a/tests/crashes/121574-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #121574 -#![feature(generic_const_exprs)] -pub struct DimName {} -impl X { - pub fn y<'a, U: 'a>(&'a self) -> impl Iterator + '_> { - "0".as_bytes(move |_| (0..1).map(move |_| loop {})) - } -} diff --git a/tests/crashes/121574.rs b/tests/crashes/121574.rs deleted file mode 100644 index 53eec829c5f3..000000000000 --- a/tests/crashes/121574.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #121574 -#![feature(generic_const_exprs)] - -impl X { - pub fn y<'a, U: 'a>(&'a self) -> impl Iterator + '_> {} -} From 3fe3157858ca1cb038ec5f9eb627ade385a5461a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 24 May 2024 17:35:58 +0200 Subject: [PATCH 070/101] Stop using the avx512er and avx512pf x86 target features They are no longer supported by LLVM 19. Fixes #125492 --- compiler/rustc_target/src/target_features.rs | 2 -- library/std/tests/run-time-detect.rs | 2 -- tests/ui/check-cfg/mix.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 1b507bb2a155..d9812540e497 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -199,11 +199,9 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ ("avx512bw", Unstable(sym::avx512_target_feature)), ("avx512cd", Unstable(sym::avx512_target_feature)), ("avx512dq", Unstable(sym::avx512_target_feature)), - ("avx512er", Unstable(sym::avx512_target_feature)), ("avx512f", Unstable(sym::avx512_target_feature)), ("avx512fp16", Unstable(sym::avx512_target_feature)), ("avx512ifma", Unstable(sym::avx512_target_feature)), - ("avx512pf", Unstable(sym::avx512_target_feature)), ("avx512vbmi", Unstable(sym::avx512_target_feature)), ("avx512vbmi2", Unstable(sym::avx512_target_feature)), ("avx512vl", Unstable(sym::avx512_target_feature)), diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index c9b9c54e3d49..694867056566 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -121,10 +121,8 @@ fn x86_all() { println!("avx512bw: {:?}", is_x86_feature_detected!("avx512bw")); println!("avx512cd: {:?}", is_x86_feature_detected!("avx512cd")); println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq")); - println!("avx512er: {:?}", is_x86_feature_detected!("avx512er")); println!("avx512f: {:?}", is_x86_feature_detected!("avx512f")); println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma")); - println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf")); println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2")); println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi")); println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl")); diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 8c1bf5a11607..b3d0046fc178 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, and `bmi2` and 188 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, and `bulk-memory` and 186 more = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index c13446bb9f89..0c50ec1abba9 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From ebd9f355e2b34e36bd5b326c24a5c0eb0b40a371 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 24 May 2024 18:23:24 +0000 Subject: [PATCH 071/101] remove proof tree formatter, make em shallow --- compiler/rustc_interface/src/tests.rs | 5 +- compiler/rustc_middle/src/arena.rs | 5 +- .../rustc_middle/src/traits/solve/cache.rs | 6 +- compiler/rustc_middle/src/ty/context.rs | 3 +- compiler/rustc_session/src/config.rs | 10 - compiler/rustc_session/src/options.rs | 26 +- .../src/solve/eval_ctxt/mod.rs | 27 +-- .../src/solve/fulfill.rs | 6 +- .../src/solve/inspect/analyse.rs | 13 +- .../src/solve/inspect/build.rs | 226 ++++++------------ .../src/solve/search_graph.rs | 20 +- .../src/traits/error_reporting/mod.rs | 17 -- .../error_reporting/type_err_ctxt_ext.rs | 18 +- compiler/rustc_type_ir/src/interner.rs | 8 +- compiler/rustc_type_ir/src/solve/inspect.rs | 77 ++---- .../rustc_type_ir/src/solve/inspect/format.rs | 173 -------------- 16 files changed, 135 insertions(+), 505 deletions(-) delete mode 100644 compiler/rustc_type_ir/src/solve/inspect/format.rs diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 36f9dda7250c..c6cf7cf4f3f7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -799,10 +799,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); - tracked!( - next_solver, - Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() }) - ); + tracked!(next_solver, Some(NextSolverConfig { coherence: true, globally: false })); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); tracked!(no_link, true); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 7392eb6c2bb4..b0e72eaf5a4c 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -61,7 +61,10 @@ macro_rules! arena_types { [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, - [] canonical_goal_evaluation: rustc_next_trait_solver::solve::inspect::GoalEvaluationStep>, + [] canonical_goal_evaluation: + rustc_next_trait_solver::solve::inspect::CanonicalGoalEvaluationStep< + rustc_middle::ty::TyCtxt<'tcx> + >, [] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, [] type_op_subtype: rustc_middle::infer::canonical::Canonical<'tcx, diff --git a/compiler/rustc_middle/src/traits/solve/cache.rs b/compiler/rustc_middle/src/traits/solve/cache.rs index 2ff4ade21d08..dc31114b2c45 100644 --- a/compiler/rustc_middle/src/traits/solve/cache.rs +++ b/compiler/rustc_middle/src/traits/solve/cache.rs @@ -17,7 +17,7 @@ pub struct EvaluationCache<'tcx> { #[derive(Debug, PartialEq, Eq)] pub struct CacheData<'tcx> { pub result: QueryResult<'tcx>, - pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, pub additional_depth: usize, pub encountered_overflow: bool, } @@ -28,7 +28,7 @@ impl<'tcx> EvaluationCache<'tcx> { &self, tcx: TyCtxt<'tcx>, key: CanonicalInput<'tcx>, - proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, additional_depth: usize, encountered_overflow: bool, cycle_participants: FxHashSet>, @@ -107,7 +107,7 @@ struct Success<'tcx> { #[derive(Clone, Copy)] pub struct QueryData<'tcx> { pub result: QueryResult<'tcx>, - pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, } /// The cache entry for a goal `CanonicalInput`. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6e53b5bb5206..d138cd9ceb9d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -103,7 +103,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; type DefiningOpaqueTypes = &'tcx ty::List; type ExternalConstraints = ExternalConstraints<'tcx>; - type GoalEvaluationSteps = &'tcx [solve::inspect::GoalEvaluationStep>]; + type CanonicalGoalEvaluationStepRef = + &'tcx solve::inspect::CanonicalGoalEvaluationStep>; type Ty = Ty<'tcx>; type Tys = &'tcx List>; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5ac4d194e872..c90da966e708 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -796,16 +796,6 @@ pub struct NextSolverConfig { /// Whether the new trait solver should be enabled everywhere. /// This is only `true` if `coherence` is also enabled. pub globally: bool, - /// Whether to dump proof trees after computing a proof tree. - pub dump_tree: DumpSolverProofTree, -} - -#[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum DumpSolverProofTree { - Always, - OnError, - #[default] - Never, } #[derive(Clone)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 65660286dd73..6309fcdd2db3 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -399,7 +399,8 @@ mod desc { pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; - pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error"; + pub const parse_next_solver_config: &str = + "a comma separated list of solver configurations: `globally` (default), and `coherence`"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -1058,7 +1059,6 @@ mod parse { if let Some(config) = v { let mut coherence = false; let mut globally = true; - let mut dump_tree = None; for c in config.split(',') { match c { "globally" => globally = true, @@ -1066,31 +1066,13 @@ mod parse { globally = false; coherence = true; } - "dump-tree" => { - if dump_tree.replace(DumpSolverProofTree::Always).is_some() { - return false; - } - } - "dump-tree-on-error" => { - if dump_tree.replace(DumpSolverProofTree::OnError).is_some() { - return false; - } - } _ => return false, } } - *slot = Some(NextSolverConfig { - coherence: coherence || globally, - globally, - dump_tree: dump_tree.unwrap_or_default(), - }); + *slot = Some(NextSolverConfig { coherence: coherence || globally, globally }); } else { - *slot = Some(NextSolverConfig { - coherence: true, - globally: true, - dump_tree: Default::default(), - }); + *slot = Some(NextSolverConfig { coherence: true, globally: true }); } true diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 7e1d7d73e0b3..ce408ddea378 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -1,6 +1,3 @@ -use std::io::Write; -use std::ops::ControlFlow; - use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; @@ -20,10 +17,10 @@ use rustc_middle::ty::{ self, InferCtxtLike, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_session::config::DumpSolverProofTree; use rustc_span::DUMMY_SP; use rustc_type_ir::{self as ir, CanonicalVarValues, Interner}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use std::ops::ControlFlow; use crate::traits::coherence; use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment}; @@ -135,8 +132,7 @@ impl NestedGoals { #[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)] pub enum GenerateProofTree { Yes, - IfEnabled, - Never, + No, } #[extension(pub trait InferCtxtEvalExt<'tcx>)] @@ -182,7 +178,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { infcx, search_graph: &mut search_graph, nested_goals: NestedGoals::new(), - inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree), + inspect: ProofTreeBuilder::new_maybe_root(generate_proof_tree), // Only relevant when canonicalizing the response, // which we don't do within this evaluation context. @@ -197,23 +193,14 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { }; let result = f(&mut ecx); - let tree = ecx.inspect.finalize(); - if let (Some(tree), DumpSolverProofTree::Always) = ( - &tree, - infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(), - ) { - let mut lock = std::io::stdout().lock(); - let _ = lock.write_fmt(format_args!("{tree:?}\n")); - let _ = lock.flush(); - } - + let proof_tree = ecx.inspect.finalize(); assert!( ecx.nested_goals.is_empty(), "root `EvalCtxt` should not have any goals added to it" ); assert!(search_graph.is_empty()); - (result, tree) + (result, proof_tree) } /// Creates a nested evaluation context that shares the same search graph as the @@ -483,7 +470,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { // the certainty of all the goals. #[instrument(level = "trace", skip(self))] pub(super) fn try_evaluate_added_goals(&mut self) -> Result { - self.inspect.start_evaluate_added_goals(); let mut response = Ok(Certainty::overflow(false)); for _ in 0..FIXPOINT_STEP_LIMIT { // FIXME: This match is a bit ugly, it might be nice to change the inspect @@ -501,8 +487,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } } - self.inspect.evaluate_added_goals_result(response); - if response.is_err() { self.tainted = Err(NoSolution); } @@ -515,7 +499,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. fn evaluate_added_goals_step(&mut self) -> Result, NoSolution> { let tcx = self.tcx(); - self.inspect.start_evaluate_added_goals_step(); let mut goals = core::mem::take(&mut self.nested_goals); // If this loop did not result in any progress, what's our final certainty. diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 7291eb00e727..d28cf834032d 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -79,7 +79,7 @@ impl<'tcx> ObligationStorage<'tcx> { // change. self.overflowed.extend(self.pending.extract_if(|o| { let goal = o.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::Never).0; + let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; match result { Ok((has_changed, _)) => has_changed, _ => false, @@ -159,7 +159,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { let mut has_changed = false; for obligation in self.obligations.unstalled_for_select() { let goal = obligation.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0; + let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; self.inspect_evaluated_obligation(infcx, &obligation, &result); let (changed, certainty) = match result { Ok(result) => result, @@ -246,7 +246,7 @@ fn fulfillment_error_for_stalled<'tcx>( root_obligation: PredicateObligation<'tcx>, ) -> FulfillmentError<'tcx> { let (code, refine_obligation) = infcx.probe(|_| { - match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::Never).0 { + match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::No).0 { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { (FulfillmentErrorCode::Ambiguity { overflow: None }, true) } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 737d03f73f00..447357f8b3f6 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -317,7 +317,6 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeStep::RecordImplArgs { impl_args: i } => { assert_eq!(impl_args.replace(i), None); } - inspect::ProbeStep::EvaluateGoals(_) => (), } } @@ -359,13 +358,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { warn!("unexpected root evaluation: {:?}", self.evaluation_kind); return vec![]; } - inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } => { - if let Some(last) = revisions.last() { - last - } else { - return vec![]; - } - } + inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision } => final_revision, }; let mut nested_goals = vec![]; @@ -392,9 +385,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { normalizes_to_term_hack: Option>, source: GoalSource, ) -> Self { - let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root; - let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() }; - + let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root; let result = evaluation.result.and_then(|ok| { if let Some(term_hack) = normalizes_to_term_hack { infcx diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 803300c5196c..3c6333626483 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -5,20 +5,17 @@ //! see the comment on [ProofTreeBuilder]. use std::mem; +use crate::solve::eval_ctxt::canonical; +use crate::solve::{self, inspect, GenerateProofTree}; use rustc_infer::infer::InferCtxt; use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarValues; -use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, TyCtxt}; use rustc_next_trait_solver::solve::{ CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, }; -use rustc_session::config::DumpSolverProofTree; use rustc_type_ir::Interner; -use crate::solve::eval_ctxt::canonical; -use crate::solve::{self, inspect, GenerateProofTree}; - /// The core data structure when building proof trees. /// /// In case the current evaluation does not generate a proof @@ -53,7 +50,7 @@ enum DebugSolver { Root, GoalEvaluation(WipGoalEvaluation), CanonicalGoalEvaluation(WipCanonicalGoalEvaluation), - GoalEvaluationStep(WipGoalEvaluationStep), + CanonicalGoalEvaluationStep(WipCanonicalGoalEvaluationStep), } impl From> for DebugSolver { @@ -68,9 +65,9 @@ impl From> for DebugSolver { } } -impl From> for DebugSolver { - fn from(g: WipGoalEvaluationStep) -> DebugSolver { - DebugSolver::GoalEvaluationStep(g) +impl From> for DebugSolver { + fn from(g: WipCanonicalGoalEvaluationStep) -> DebugSolver { + DebugSolver::CanonicalGoalEvaluationStep(g) } } @@ -78,7 +75,7 @@ impl From> for DebugSolver { #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] struct WipGoalEvaluation { pub uncanonicalized_goal: Goal, - pub kind: WipGoalEvaluationKind, + pub orig_values: Vec, pub evaluation: Option>, } @@ -86,31 +83,19 @@ impl WipGoalEvaluation { fn finalize(self) -> inspect::GoalEvaluation { inspect::GoalEvaluation { uncanonicalized_goal: self.uncanonicalized_goal, - kind: match self.kind { - WipGoalEvaluationKind::Root { orig_values } => { - inspect::GoalEvaluationKind::Root { orig_values } - } - WipGoalEvaluationKind::Nested => inspect::GoalEvaluationKind::Nested, - }, + orig_values: self.orig_values, evaluation: self.evaluation.unwrap().finalize(), } } } -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -pub(in crate::solve) enum WipGoalEvaluationKind { - Root { orig_values: Vec }, - Nested, -} - #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""))] pub(in crate::solve) enum WipCanonicalGoalEvaluationKind { Overflow, CycleInStack, ProvisionalCacheHit, - Interned { revisions: I::GoalEvaluationSteps }, + Interned { final_revision: I::CanonicalGoalEvaluationStepRef }, } impl std::fmt::Debug for WipCanonicalGoalEvaluationKind { @@ -119,7 +104,9 @@ impl std::fmt::Debug for WipCanonicalGoalEvaluationKind { Self::Overflow => write!(f, "Overflow"), Self::CycleInStack => write!(f, "CycleInStack"), Self::ProvisionalCacheHit => write!(f, "ProvisionalCacheHit"), - Self::Interned { revisions: _ } => f.debug_struct("Interned").finish_non_exhaustive(), + Self::Interned { final_revision: _ } => { + f.debug_struct("Interned").finish_non_exhaustive() + } } } } @@ -131,13 +118,15 @@ struct WipCanonicalGoalEvaluation { kind: Option>, /// Only used for uncached goals. After we finished evaluating /// the goal, this is interned and moved into `kind`. - revisions: Vec>, + final_revision: Option>, result: Option>, } impl WipCanonicalGoalEvaluation { fn finalize(self) -> inspect::CanonicalGoalEvaluation { - assert!(self.revisions.is_empty()); + // We've already interned the final revision in + // `fn finalize_canonical_goal_evaluation`. + assert!(self.final_revision.is_none()); let kind = match self.kind.unwrap() { WipCanonicalGoalEvaluationKind::Overflow => { inspect::CanonicalGoalEvaluationKind::Overflow @@ -148,8 +137,8 @@ impl WipCanonicalGoalEvaluation { WipCanonicalGoalEvaluationKind::ProvisionalCacheHit => { inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit } - WipCanonicalGoalEvaluationKind::Interned { revisions } => { - inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } + WipCanonicalGoalEvaluationKind::Interned { final_revision } => { + inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision } } }; @@ -159,29 +148,7 @@ impl WipCanonicalGoalEvaluation { #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -struct WipAddedGoalsEvaluation { - evaluations: Vec>>, - result: Option>, -} - -impl WipAddedGoalsEvaluation { - fn finalize(self) -> inspect::AddedGoalsEvaluation { - inspect::AddedGoalsEvaluation { - evaluations: self - .evaluations - .into_iter() - .map(|evaluations| { - evaluations.into_iter().map(WipGoalEvaluation::finalize).collect() - }) - .collect(), - result: self.result.unwrap(), - } - } -} - -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -struct WipGoalEvaluationStep { +struct WipCanonicalGoalEvaluationStep { /// Unlike `EvalCtxt::var_values`, we append a new /// generic arg here whenever we create a new inference /// variable. @@ -194,7 +161,7 @@ struct WipGoalEvaluationStep { evaluation: WipProbe, } -impl WipGoalEvaluationStep { +impl WipCanonicalGoalEvaluationStep { fn current_evaluation_scope(&mut self) -> &mut WipProbe { let mut current = &mut self.evaluation; for _ in 0..self.probe_depth { @@ -206,24 +173,16 @@ impl WipGoalEvaluationStep { current } - fn added_goals_evaluation(&mut self) -> &mut WipAddedGoalsEvaluation { - let mut current = &mut self.evaluation; - loop { - match current.steps.last_mut() { - Some(WipProbeStep::NestedProbe(p)) => current = p, - Some(WipProbeStep::EvaluateGoals(evaluation)) => return evaluation, - _ => bug!(), - } - } - } - - fn finalize(self) -> inspect::GoalEvaluationStep { + fn finalize(self) -> inspect::CanonicalGoalEvaluationStep { let evaluation = self.evaluation.finalize(); match evaluation.kind { inspect::ProbeKind::Root { .. } => (), _ => unreachable!("unexpected root evaluation: {evaluation:?}"), } - inspect::GoalEvaluationStep { instantiated_goal: self.instantiated_goal, evaluation } + inspect::CanonicalGoalEvaluationStep { + instantiated_goal: self.instantiated_goal, + evaluation, + } } } @@ -250,7 +209,6 @@ impl WipProbe { #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] enum WipProbeStep { AddGoal(GoalSource, inspect::CanonicalState>), - EvaluateGoals(WipAddedGoalsEvaluation), NestedProbe(WipProbe), MakeCanonicalResponse { shallow_certainty: Certainty }, RecordImplArgs { impl_args: inspect::CanonicalState }, @@ -260,7 +218,6 @@ impl WipProbeStep { fn finalize(self) -> inspect::ProbeStep { match self { WipProbeStep::AddGoal(source, goal) => inspect::ProbeStep::AddGoal(source, goal), - WipProbeStep::EvaluateGoals(eval) => inspect::ProbeStep::EvaluateGoals(eval.finalize()), WipProbeStep::NestedProbe(probe) => inspect::ProbeStep::NestedProbe(probe.finalize()), WipProbeStep::RecordImplArgs { impl_args } => { inspect::ProbeStep::RecordImplArgs { impl_args } @@ -278,6 +235,15 @@ impl<'tcx> ProofTreeBuilder> { ProofTreeBuilder { state: Some(Box::new(state.into())) } } + fn opt_nested>>>( + &self, + state: impl FnOnce() -> Option, + ) -> Self { + ProofTreeBuilder { + state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new), + } + } + fn nested>>>(&self, state: impl FnOnce() -> T) -> Self { ProofTreeBuilder { state: self.state.as_ref().map(|_| Box::new(state().into())) } } @@ -302,22 +268,10 @@ impl<'tcx> ProofTreeBuilder> { } pub fn new_maybe_root( - tcx: TyCtxt<'tcx>, generate_proof_tree: GenerateProofTree, ) -> ProofTreeBuilder> { match generate_proof_tree { - GenerateProofTree::Never => ProofTreeBuilder::new_noop(), - GenerateProofTree::IfEnabled => { - let opts = &tcx.sess.opts.unstable_opts; - match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() { - DumpSolverProofTree::Always => ProofTreeBuilder::new_root(), - // `OnError` is handled by reevaluating goals in error - // reporting with `GenerateProofTree::Yes`. - DumpSolverProofTree::OnError | DumpSolverProofTree::Never => { - ProofTreeBuilder::new_noop() - } - } - } + GenerateProofTree::No => ProofTreeBuilder::new_noop(), GenerateProofTree::Yes => ProofTreeBuilder::new_root(), } } @@ -340,15 +294,13 @@ impl<'tcx> ProofTreeBuilder> { orig_values: &[ty::GenericArg<'tcx>], kind: solve::GoalEvaluationKind, ) -> ProofTreeBuilder> { - self.nested(|| WipGoalEvaluation { - uncanonicalized_goal: goal, - kind: match kind { - solve::GoalEvaluationKind::Root => { - WipGoalEvaluationKind::Root { orig_values: orig_values.to_vec() } - } - solve::GoalEvaluationKind::Nested => WipGoalEvaluationKind::Nested, - }, - evaluation: None, + self.opt_nested(|| match kind { + solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation { + uncanonicalized_goal: goal, + orig_values: orig_values.to_vec(), + evaluation: None, + }), + solve::GoalEvaluationKind::Nested => None, }) } @@ -359,24 +311,22 @@ impl<'tcx> ProofTreeBuilder> { self.nested(|| WipCanonicalGoalEvaluation { goal, kind: None, - revisions: vec![], + final_revision: None, result: None, }) } - pub fn finalize_evaluation( + pub fn finalize_canonical_goal_evaluation( &mut self, tcx: TyCtxt<'tcx>, - ) -> Option<&'tcx [inspect::GoalEvaluationStep>]> { + ) -> Option<&'tcx inspect::CanonicalGoalEvaluationStep>> { self.as_mut().map(|this| match this { DebugSolver::CanonicalGoalEvaluation(evaluation) => { - let revisions = mem::take(&mut evaluation.revisions) - .into_iter() - .map(WipGoalEvaluationStep::finalize); - let revisions = &*tcx.arena.alloc_from_iter(revisions); - let kind = WipCanonicalGoalEvaluationKind::Interned { revisions }; + let final_revision = mem::take(&mut evaluation.final_revision).unwrap(); + let final_revision = &*tcx.arena.alloc(final_revision.finalize()); + let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision }; assert_eq!(evaluation.kind.replace(kind), None); - revisions + final_revision } _ => unreachable!(), }) @@ -400,7 +350,10 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind>) { + pub fn canonical_goal_evaluation_kind( + &mut self, + kind: WipCanonicalGoalEvaluationKind>, + ) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { @@ -413,17 +366,11 @@ impl<'tcx> ProofTreeBuilder> { pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder>) { if let Some(this) = self.as_mut() { - match (this, *goal_evaluation.state.unwrap()) { - ( - DebugSolver::GoalEvaluationStep(state), - DebugSolver::GoalEvaluation(goal_evaluation), - ) => state - .added_goals_evaluation() - .evaluations - .last_mut() - .unwrap() - .push(goal_evaluation), - (this @ DebugSolver::Root, goal_evaluation) => *this = goal_evaluation, + match this { + DebugSolver::Root => *this = *goal_evaluation.state.unwrap(), + DebugSolver::CanonicalGoalEvaluationStep(_) => { + assert!(goal_evaluation.state.is_none()) + } _ => unreachable!(), } } @@ -434,7 +381,7 @@ impl<'tcx> ProofTreeBuilder> { var_values: CanonicalVarValues<'tcx>, instantiated_goal: QueryInput, ty::Predicate<'tcx>>, ) -> ProofTreeBuilder> { - self.nested(|| WipGoalEvaluationStep { + self.nested(|| WipCanonicalGoalEvaluationStep { var_values: var_values.var_values.to_vec(), instantiated_goal, evaluation: WipProbe { @@ -452,9 +399,9 @@ impl<'tcx> ProofTreeBuilder> { match (this, *goal_evaluation_step.state.unwrap()) { ( DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluations), - DebugSolver::GoalEvaluationStep(goal_evaluation_step), + DebugSolver::CanonicalGoalEvaluationStep(goal_evaluation_step), ) => { - canonical_goal_evaluations.revisions.push(goal_evaluation_step); + canonical_goal_evaluations.final_revision = Some(goal_evaluation_step); } _ => unreachable!(), } @@ -464,7 +411,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn add_var_value>>(&mut self, arg: T) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { state.var_values.push(arg.into()); } Some(s) => bug!("tried to add var values to {s:?}"), @@ -474,7 +421,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn enter_probe(&mut self) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let initial_num_var_values = state.var_values.len(); state.current_evaluation_scope().steps.push(WipProbeStep::NestedProbe(WipProbe { initial_num_var_values, @@ -491,7 +438,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind>) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let prev = state.current_evaluation_scope().kind.replace(probe_kind); assert_eq!(prev, None); } @@ -506,7 +453,7 @@ impl<'tcx> ProofTreeBuilder> { ) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let final_state = canonical::make_canonical_state( infcx, &state.var_values, @@ -543,7 +490,7 @@ impl<'tcx> ProofTreeBuilder> { ) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let goal = canonical::make_canonical_state( infcx, &state.var_values, @@ -563,7 +510,7 @@ impl<'tcx> ProofTreeBuilder> { impl_args: ty::GenericArgsRef<'tcx>, ) { match self.as_mut() { - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let impl_args = canonical::make_canonical_state( infcx, &state.var_values, @@ -582,7 +529,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn make_canonical_response(&mut self, shallow_certainty: Certainty) { match self.as_mut() { - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { state .current_evaluation_scope() .steps @@ -596,7 +543,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn finish_probe(mut self) -> ProofTreeBuilder> { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { assert_ne!(state.probe_depth, 0); let num_var_values = state.current_evaluation_scope().initial_num_var_values; state.var_values.truncate(num_var_values); @@ -608,46 +555,13 @@ impl<'tcx> ProofTreeBuilder> { self } - pub fn start_evaluate_added_goals(&mut self) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - state.current_evaluation_scope().steps.push(WipProbeStep::EvaluateGoals( - WipAddedGoalsEvaluation { evaluations: vec![], result: None }, - )); - } - _ => bug!(), - } - } - - pub fn start_evaluate_added_goals_step(&mut self) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - state.added_goals_evaluation().evaluations.push(vec![]); - } - _ => bug!(), - } - } - - pub fn evaluate_added_goals_result(&mut self, result: Result) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - let prev = state.added_goals_evaluation().result.replace(result); - assert_eq!(prev, None); - } - _ => bug!(), - } - } - pub fn query_result(&mut self, result: QueryResult>) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { assert_eq!(canonical_goal_evaluation.result.replace(result), None); } - DebugSolver::GoalEvaluationStep(evaluation_step) => { + DebugSolver::CanonicalGoalEvaluationStep(evaluation_step) => { assert_eq!( evaluation_step .evaluation diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index bcd210f789bf..6be623b6044f 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -274,7 +274,8 @@ impl<'tcx> SearchGraph> { last.encountered_overflow = true; } - inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); + inspect + .canonical_goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); return Self::response_no_constraints(tcx, input, Certainty::overflow(true)); }; @@ -302,8 +303,9 @@ impl<'tcx> SearchGraph> { // We have a nested goal which is already in the provisional cache, use // its result. We do not provide any usage kind as that should have been // already set correctly while computing the cache entry. - inspect - .goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::ProvisionalCacheHit); + inspect.canonical_goal_evaluation_kind( + inspect::WipCanonicalGoalEvaluationKind::ProvisionalCacheHit, + ); Self::tag_cycle_participants(&mut self.stack, HasBeenUsed::empty(), entry.head); return entry.result; } else if let Some(stack_depth) = cache_entry.stack_depth { @@ -314,7 +316,9 @@ impl<'tcx> SearchGraph> { // // Finally we can return either the provisional response or the initial response // in case we're in the first fixpoint iteration for this goal. - inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CycleInStack); + inspect.canonical_goal_evaluation_kind( + inspect::WipCanonicalGoalEvaluationKind::CycleInStack, + ); let is_coinductive_cycle = Self::stack_coinductive_from(tcx, &self.stack, stack_depth); let usage_kind = if is_coinductive_cycle { HasBeenUsed::COINDUCTIVE_CYCLE @@ -371,7 +375,7 @@ impl<'tcx> SearchGraph> { (current_entry, result) }); - let proof_tree = inspect.finalize_evaluation(tcx); + let proof_tree = inspect.finalize_canonical_goal_evaluation(tcx); // We're now done with this goal. In case this goal is involved in a larger cycle // do not remove it from the provisional cache and update its provisional result. @@ -433,9 +437,9 @@ impl<'tcx> SearchGraph> { // the goal. We simply overwrite the existing entry once we're done, // caching the proof tree. if !inspect.is_noop() { - if let Some(revisions) = proof_tree { - let kind = inspect::WipCanonicalGoalEvaluationKind::Interned { revisions }; - inspect.goal_evaluation_kind(kind); + if let Some(final_revision) = proof_tree { + let kind = inspect::WipCanonicalGoalEvaluationKind::Interned { final_revision }; + inspect.canonical_goal_evaluation_kind(kind); } else { return None; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index e50edfdc656c..633d488f7be5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -7,15 +7,11 @@ pub mod suggestions; mod type_err_ctxt_ext; use super::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; -use crate::infer::InferCtxt; -use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -use std::io::Write; use std::ops::ControlFlow; pub use self::infer_ctxt_ext::*; @@ -184,16 +180,3 @@ pub enum DefIdOrName { DefId(DefId), Name(&'static str), } - -pub fn dump_proof_tree<'tcx>(o: &Obligation<'tcx, ty::Predicate<'tcx>>, infcx: &InferCtxt<'tcx>) { - infcx.probe(|_| { - let goal = Goal { predicate: o.predicate, param_env: o.param_env }; - let tree = infcx - .evaluate_root_goal(goal, GenerateProofTree::Yes) - .1 - .expect("proof tree should have been generated"); - let mut lock = std::io::stdout().lock(); - let _ = lock.write_fmt(format_args!("{tree:?}\n")); - let _ = lock.flush(); - }); -} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 494fca0336cc..46953a61296a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -46,7 +46,6 @@ use rustc_middle::ty::{ TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; -use rustc_session::config::DumpSolverProofTree; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -56,8 +55,8 @@ use std::fmt; use std::iter; use super::{ - dump_proof_tree, ArgKind, CandidateSimilarity, FindExprBySpan, FindTypeParam, - GetSafeTransmuteErrorAndReason, HasNumericInferVisitor, ImplCandidate, UnsatisfiedConst, + ArgKind, CandidateSimilarity, FindExprBySpan, FindTypeParam, GetSafeTransmuteErrorAndReason, + HasNumericInferVisitor, ImplCandidate, UnsatisfiedConst, }; pub use rustc_infer::traits::error_reporting::*; @@ -369,13 +368,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { error: &SelectionError<'tcx>, ) -> ErrorGuaranteed { let tcx = self.tcx; - - if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() - == DumpSolverProofTree::OnError - { - dump_proof_tree(root_obligation, self.infcx); - } - let mut span = obligation.cause.span; let mut err = match *error { @@ -1529,12 +1521,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[instrument(skip(self), level = "debug")] fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { - if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() - == DumpSolverProofTree::OnError - { - dump_proof_tree(&error.root_obligation, self.infcx); - } - match error.code { FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( error.obligation.clone(), diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 9b8bb210ff42..c77414afc52c 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,7 +5,7 @@ use std::ops::Deref; use crate::inherent::*; use crate::ir_print::IrPrint; -use crate::solve::inspect::GoalEvaluationStep; +use crate::solve::inspect::CanonicalGoalEvaluationStep; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate, @@ -55,7 +55,11 @@ pub trait Interner: type PredefinedOpaques: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type ExternalConstraints: Copy + Debug + Hash + Eq; - type GoalEvaluationSteps: Copy + Debug + Hash + Eq + Deref]>; + type CanonicalGoalEvaluationStepRef: Copy + + Debug + + Hash + + Eq + + Deref>; // Kinds of tys type Ty: Ty; diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index c4f6ee2669be..0733c730064b 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -1,36 +1,29 @@ //! Data structure used to inspect trait solver behavior. //! //! During trait solving we optionally build "proof trees", the root of -//! which is a [GoalEvaluation] with [GoalEvaluationKind::Root]. These -//! trees are used to improve the debug experience and are also used by -//! the compiler itself to provide necessary context for error messages. +//! which is a [GoalEvaluation]. These trees are used by the compiler +//! to inspect the behavior of the trait solver and to access its internal +//! state, e.g. for diagnostics and when selecting impls during codegen. //! //! Because each nested goal in the solver gets [canonicalized] separately //! and we discard inference progress via "probes", we cannot mechanically //! use proof trees without somehow "lifting up" data local to the current -//! `InferCtxt`. Any data used mechanically is therefore canonicalized and -//! stored as [CanonicalState]. As printing canonicalized data worsens the -//! debugging dumps, we do not simply canonicalize everything. +//! `InferCtxt`. To use the data from evaluation we therefore canonicalize +//! it and store it as a [CanonicalState]. //! -//! This means proof trees contain inference variables and placeholders -//! local to a different `InferCtxt` which must not be used with the -//! current one. +//! Proof trees are only shallow, we do not compute the proof tree for nested +//! goals. Visiting proof trees instead recomputes nested goals in the parents +//! inference context when necessary. //! //! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html -mod format; - -use std::fmt::{Debug, Write}; -use std::hash::Hash; - -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; - -use self::format::ProofTreeFormatter; use crate::solve::{ - CandidateSource, CanonicalInput, Certainty, Goal, GoalSource, NoSolution, QueryInput, - QueryResult, + CandidateSource, CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, }; use crate::{Canonical, CanonicalVarValues, Interner}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use std::fmt::Debug; +use std::hash::Hash; /// Some `data` together with information about how they relate to the input /// of the canonical query. @@ -55,23 +48,15 @@ pub struct State { pub type CanonicalState = Canonical>; -/// When evaluating the root goals we also store the -/// original values for the `CanonicalVarValues` of the -/// canonicalized goal. We use this to map any [CanonicalState] -/// from the local `InferCtxt` of the solver query to -/// the `InferCtxt` of the caller. -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub enum GoalEvaluationKind { - Root { orig_values: Vec }, - Nested, -} - +/// When evaluating a goal we also store the original values +/// for the `CanonicalVarValues` of the canonicalized goal. +/// We use this to map any [CanonicalState] from the local `InferCtxt` +/// of the solver query to the `InferCtxt` of the caller. #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] pub struct GoalEvaluation { pub uncanonicalized_goal: Goal, - pub kind: GoalEvaluationKind, + pub orig_values: Vec, pub evaluation: CanonicalGoalEvaluation, } @@ -89,24 +74,12 @@ pub enum CanonicalGoalEvaluationKind { Overflow, CycleInStack, ProvisionalCacheHit, - Evaluation { revisions: I::GoalEvaluationSteps }, -} -impl Debug for GoalEvaluation { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - ProofTreeFormatter::new(f).format_goal_evaluation(self) - } + Evaluation { final_revision: I::CanonicalGoalEvaluationStepRef }, } #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub struct AddedGoalsEvaluation { - pub evaluations: Vec>>, - pub result: Result, -} - -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub struct GoalEvaluationStep { +pub struct CanonicalGoalEvaluationStep { pub instantiated_goal: QueryInput, /// The actual evaluation of the goal, always `ProbeKind::Root`. @@ -117,7 +90,7 @@ pub struct GoalEvaluationStep { /// corresponds to a `EvalCtxt::probe(_X)` call or the root evaluation /// of a goal. #[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] +#[derivative(Debug(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] pub struct Probe { /// What happened inside of this probe in chronological order. pub steps: Vec>, @@ -125,23 +98,15 @@ pub struct Probe { pub final_state: CanonicalState, } -impl Debug for Probe { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - ProofTreeFormatter::new(f).format_probe(self) - } -} - #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] pub enum ProbeStep { /// We added a goal to the `EvalCtxt` which will get proven /// the next time `EvalCtxt::try_evaluate_added_goals` is called. AddGoal(GoalSource, CanonicalState>), - /// The inside of a `EvalCtxt::try_evaluate_added_goals` call. - EvaluateGoals(AddedGoalsEvaluation), /// A call to `probe` while proving the current goal. This is /// used whenever there are multiple candidates to prove the - /// current goalby . + /// current goal. NestedProbe(Probe), /// A trait goal was satisfied by an impl candidate. RecordImplArgs { impl_args: CanonicalState }, diff --git a/compiler/rustc_type_ir/src/solve/inspect/format.rs b/compiler/rustc_type_ir/src/solve/inspect/format.rs deleted file mode 100644 index 44ade04cf98c..000000000000 --- a/compiler/rustc_type_ir/src/solve/inspect/format.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::marker::PhantomData; - -use super::*; - -pub(super) struct ProofTreeFormatter<'a, 'b, I> { - f: &'a mut (dyn Write + 'b), - _interner: PhantomData, -} - -enum IndentorState { - StartWithNewline, - OnNewline, - Inline, -} - -/// A formatter which adds 4 spaces of indentation to its input before -/// passing it on to its nested formatter. -/// -/// We can use this for arbitrary levels of indentation by nesting it. -struct Indentor<'a, 'b> { - f: &'a mut (dyn Write + 'b), - state: IndentorState, -} - -impl Write for Indentor<'_, '_> { - fn write_str(&mut self, s: &str) -> std::fmt::Result { - for line in s.split_inclusive('\n') { - match self.state { - IndentorState::StartWithNewline => self.f.write_str("\n ")?, - IndentorState::OnNewline => self.f.write_str(" ")?, - IndentorState::Inline => {} - } - self.state = - if line.ends_with('\n') { IndentorState::OnNewline } else { IndentorState::Inline }; - self.f.write_str(line)?; - } - - Ok(()) - } -} - -impl<'a, 'b, I: Interner> ProofTreeFormatter<'a, 'b, I> { - pub(super) fn new(f: &'a mut (dyn Write + 'b)) -> Self { - ProofTreeFormatter { f, _interner: PhantomData } - } - - fn nested(&mut self, func: F) -> std::fmt::Result - where - F: FnOnce(&mut ProofTreeFormatter<'_, '_, I>) -> std::fmt::Result, - { - write!(self.f, " {{")?; - func(&mut ProofTreeFormatter { - f: &mut Indentor { f: self.f, state: IndentorState::StartWithNewline }, - _interner: PhantomData, - })?; - writeln!(self.f, "}}") - } - - pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation) -> std::fmt::Result { - let goal_text = match eval.kind { - GoalEvaluationKind::Root { orig_values: _ } => "ROOT GOAL", - GoalEvaluationKind::Nested => "GOAL", - }; - write!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?; - self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation)) - } - - pub(super) fn format_canonical_goal_evaluation( - &mut self, - eval: &CanonicalGoalEvaluation, - ) -> std::fmt::Result { - writeln!(self.f, "GOAL: {:?}", eval.goal)?; - - match &eval.kind { - CanonicalGoalEvaluationKind::Overflow => { - writeln!(self.f, "OVERFLOW: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::CycleInStack => { - writeln!(self.f, "CYCLE IN STACK: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::ProvisionalCacheHit => { - writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::Evaluation { revisions } => { - for (n, step) in revisions.iter().enumerate() { - write!(self.f, "REVISION {n}")?; - self.nested(|this| this.format_evaluation_step(step))?; - } - writeln!(self.f, "RESULT: {:?}", eval.result) - } - } - } - - pub(super) fn format_evaluation_step( - &mut self, - evaluation_step: &GoalEvaluationStep, - ) -> std::fmt::Result { - writeln!(self.f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?; - self.format_probe(&evaluation_step.evaluation) - } - - pub(super) fn format_probe(&mut self, probe: &Probe) -> std::fmt::Result { - match &probe.kind { - ProbeKind::Root { result } => { - write!(self.f, "ROOT RESULT: {result:?}") - } - ProbeKind::TryNormalizeNonRigid { result } => { - write!(self.f, "TRY NORMALIZE NON-RIGID: {result:?}") - } - ProbeKind::NormalizedSelfTyAssembly => { - write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:") - } - ProbeKind::UnsizeAssembly => { - write!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:") - } - ProbeKind::UpcastProjectionCompatibility => { - write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:") - } - ProbeKind::OpaqueTypeStorageLookup { result } => { - write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}") - } - ProbeKind::TraitCandidate { source, result } => { - write!(self.f, "CANDIDATE {source:?}: {result:?}") - } - ProbeKind::ShadowedEnvProbing => { - write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:") - } - }?; - - self.nested(|this| { - for step in &probe.steps { - match step { - ProbeStep::AddGoal(source, goal) => { - let source = match source { - GoalSource::Misc => "misc", - GoalSource::ImplWhereBound => "impl where-bound", - GoalSource::InstantiateHigherRanked => "higher-ranked goal", - }; - writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")? - } - ProbeStep::EvaluateGoals(eval) => this.format_added_goals_evaluation(eval)?, - ProbeStep::NestedProbe(probe) => this.format_probe(probe)?, - ProbeStep::MakeCanonicalResponse { shallow_certainty } => { - writeln!(this.f, "EVALUATE GOALS AND MAKE RESPONSE: {shallow_certainty:?}")? - } - ProbeStep::RecordImplArgs { impl_args } => { - writeln!(this.f, "RECORDED IMPL ARGS: {impl_args:?}")? - } - } - } - Ok(()) - }) - } - - pub(super) fn format_added_goals_evaluation( - &mut self, - added_goals_evaluation: &AddedGoalsEvaluation, - ) -> std::fmt::Result { - writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?; - - for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() { - write!(self.f, "ITERATION {n}")?; - self.nested(|this| { - for goal_evaluation in iterations { - this.format_goal_evaluation(goal_evaluation)?; - } - Ok(()) - })?; - } - - Ok(()) - } -} From ed8e43691632645d7ca3cf0583a1a822d2eb3c48 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 24 May 2024 20:15:54 +0100 Subject: [PATCH 072/101] move generics_of call outside of iter --- compiler/rustc_lint/src/builtin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 0129b8f842f0..ba42eae34415 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1998,6 +1998,8 @@ impl ExplicitOutlivesRequirements { ) -> Vec<(usize, Span)> { use rustc_middle::middle::resolve_bound_vars::ResolvedArg; + let item_generics = tcx.generics_of(item); + bounds .iter() .enumerate() @@ -2009,7 +2011,7 @@ impl ExplicitOutlivesRequirements { let is_inferred = match tcx.named_bound_var(lifetime.hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives .iter() - .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { tcx.generics_of(item).region_param(ebr, tcx).def_id == def_id })), + .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id })), _ => false, }; From 1af490de424ac07fbeb3b1a0a1268cad43fdf49d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 May 2024 15:47:50 -0400 Subject: [PATCH 073/101] Better ICE message for unresolved upvars --- .../rustc_mir_build/src/build/expr/as_place.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 93d0d4e59ba9..4b62afa61bbd 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -4,7 +4,6 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; use rustc_hir::def_id::LocalDefId; -use rustc_middle::bug; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; @@ -13,6 +12,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::AdtDef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use tracing::{debug, instrument, trace}; @@ -252,7 +252,18 @@ fn strip_prefix<'a, 'tcx>( impl<'tcx> PlaceBuilder<'tcx> { pub(in crate::build) fn to_place(&self, cx: &Builder<'_, 'tcx>) -> Place<'tcx> { - self.try_to_place(cx).unwrap() + self.try_to_place(cx).unwrap_or_else(|| match self.base { + PlaceBase::Local(local) => span_bug!( + cx.local_decls[local].source_info.span, + "could not resolve local: {local:#?} + {:?}", + self.projection + ), + PlaceBase::Upvar { var_hir_id, closure_def_id: _ } => span_bug!( + cx.tcx.hir().span(var_hir_id.0), + "could not resolve upvar: {var_hir_id:?} + {:?}", + self.projection + ), + }) } /// Creates a `Place` or returns `None` if an upvar cannot be resolved From 9185ddb019259883db1d5c2625f4ecb42d3aa77b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 24 May 2024 15:20:20 -0400 Subject: [PATCH 074/101] bootstrap: support target specific config overrides --- src/bootstrap/src/core/config/config.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 19119a073c5f..7eb42ad32f53 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -644,7 +644,20 @@ impl Merge for TomlConfig { do_merge(&mut self.llvm, llvm, replace); do_merge(&mut self.rust, rust, replace); do_merge(&mut self.dist, dist, replace); - assert!(target.is_none(), "merging target-specific config is not currently supported"); + + match (self.target.as_mut(), target) { + (_, None) => {} + (None, Some(target)) => self.target = Some(target), + (Some(original_target), Some(new_target)) => { + for (triple, new) in new_target { + if let Some(original) = original_target.get_mut(&triple) { + original.merge(new, replace); + } else { + original_target.insert(triple, new); + } + } + } + } } } From d1f0bc7562043f2d34c77aadc5263cee89d0ee80 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 24 May 2024 15:25:44 -0400 Subject: [PATCH 075/101] bootstrap: test target specific config overrides Debug, PartialEq, and Eq are derived for testing purposes. --- src/bootstrap/src/core/config/config.rs | 8 ++--- src/bootstrap/src/core/config/tests.rs | 41 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 7eb42ad32f53..d13dc9d1d177 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -360,7 +360,7 @@ pub enum RustfmtState { LazyEvaluated, } -#[derive(Debug, Default, Clone, Copy, PartialEq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum LlvmLibunwind { #[default] No, @@ -381,7 +381,7 @@ impl FromStr for LlvmLibunwind { } } -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum SplitDebuginfo { Packed, Unpacked, @@ -542,7 +542,7 @@ impl PartialEq<&str> for TargetSelection { } /// Per-target configuration stored in the global configuration structure. -#[derive(Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct Target { /// Some(path to llvm-config) if using an external LLVM. pub llvm_config: Option, @@ -912,7 +912,7 @@ define_config! { } } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum StringOrBool { String(String), diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 59e16b654272..c4073910623a 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -1,5 +1,7 @@ use super::{flags::Flags, ChangeIdWrapper, Config}; use crate::core::build_steps::clippy::get_clippy_rules_in_order; +use crate::core::config::Target; +use crate::core::config::TargetSelection; use crate::core::config::{LldMode, TomlConfig}; use clap::CommandFactory; @@ -124,6 +126,10 @@ fn override_toml() { "--set=build.gdb=\"bar\"".to_owned(), "--set=build.tools=[\"cargo\"]".to_owned(), "--set=llvm.build-config={\"foo\" = \"bar\"}".to_owned(), + "--set=target.x86_64-unknown-linux-gnu.runner=bar".to_owned(), + "--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(), + "--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(), + "--set=target.aarch64-apple-darwin.runner=apple".to_owned(), ], |&_| { toml::from_str( @@ -140,6 +146,17 @@ tools = [] [llvm] download-ci-llvm = false build-config = {} + +[target.aarch64-unknown-linux-gnu] +sanitizers = true +rpath = true +runner = "aarch64-runner" + +[target.x86_64-unknown-linux-gnu] +sanitizers = true +rpath = true +runner = "x86_64-runner" + "#, ) .unwrap() @@ -163,6 +180,30 @@ build-config = {} [("foo".to_string(), "bar".to_string())].into_iter().collect(), "setting dictionary value" ); + + let x86_64 = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let x86_64_values = Target { + sanitizers: Some(true), + rpath: Some(false), + runner: Some("bar".into()), + ..Default::default() + }; + let aarch64 = TargetSelection::from_user("aarch64-unknown-linux-gnu"); + let aarch64_values = Target { + sanitizers: Some(false), + rpath: Some(true), + runner: Some("aarch64-runner".into()), + ..Default::default() + }; + let darwin = TargetSelection::from_user("aarch64-apple-darwin"); + let darwin_values = Target { runner: Some("apple".into()), ..Default::default() }; + assert_eq!( + config.target_config, + [(x86_64, x86_64_values), (aarch64, aarch64_values), (darwin, darwin_values)] + .into_iter() + .collect(), + "setting dictionary value" + ); } #[test] From 61aac551b81573d160f19bafbf6deb83f8f0b2be Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 May 2024 15:49:17 -0400 Subject: [PATCH 076/101] Structurally resolve before builtin_index in EUV --- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 6 +++++- .../next-solver/typeck/index-of-projection.rs | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/next-solver/typeck/index-of-projection.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 89f62577506f..0ba4bd090f5e 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1741,7 +1741,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } PatKind::Slice(before, ref slice, after) => { - let Some(element_ty) = place_with_id.place.ty().builtin_index() else { + let Some(element_ty) = self + .cx + .try_structurally_resolve_type(pat.span, place_with_id.place.ty()) + .builtin_index() + else { debug!("explicit index of non-indexable type {:?}", place_with_id); return Err(self .cx diff --git a/tests/ui/traits/next-solver/typeck/index-of-projection.rs b/tests/ui/traits/next-solver/typeck/index-of-projection.rs new file mode 100644 index 000000000000..5023be0bb148 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/index-of-projection.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Fixes a regression in `rustc_attr` where we weren't normalizing the +// output type of a index operator performing a `Ty::builtin_index` call, +// leading to an ICE. + +fn main() { + let mut vec = [1, 2, 3]; + let x = || { + let [..] = &vec[..]; + }; +} From f1a18da4bb6a976cefea5f0341f6898fec436660 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 May 2024 17:43:02 -0400 Subject: [PATCH 077/101] Exit the process a short time after entering our ctrl-c handler --- compiler/rustc_driver_impl/src/lib.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5532eff7be66..2bd58680eef5 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -57,7 +57,7 @@ use std::process::{self, Command, Stdio}; use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; -use std::time::{Instant, SystemTime}; +use std::time::{Duration, Instant, SystemTime}; use time::OffsetDateTime; use tracing::trace; @@ -1502,14 +1502,13 @@ pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) { pub fn install_ctrlc_handler() { #[cfg(not(target_family = "wasm"))] ctrlc::set_handler(move || { - // Indicate that we have been signaled to stop. If we were already signaled, exit - // immediately. In our interpreter loop we try to consult this value often, but if for - // whatever reason we don't get to that check or the cleanup we do upon finding that - // this bool has become true takes a long time, the exit here will promptly exit the - // process on the second Ctrl-C. - if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { - std::process::exit(1); - } + // Indicate that we have been signaled to stop, then give the rest of the compiler a bit of + // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount + // of time exit the process. This sleep+exit ensures that even if nobody is checking + // CTRL_C_RECEIVED, the compiler exits reasonably promptly. + CTRL_C_RECEIVED.store(true, Ordering::Relaxed); + std::thread::sleep(Duration::from_millis(100)); + std::process::exit(1); }) .expect("Unable to install ctrlc handler"); } From 2d9a4c71c852e78c6579ea11fdd97b84ab85d239 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 24 May 2024 17:49:48 -0400 Subject: [PATCH 078/101] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 84dc5dc11a90..a8d72c675ee5 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 84dc5dc11a9007a08f27170454da6097265e510e +Subproject commit a8d72c675ee52dd57f0d8f2bae6655913c15b2fb From f4b9ac68f306f630b5167959d5ee90626a9d7d84 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 24 May 2024 16:17:19 -0700 Subject: [PATCH 079/101] Add manual Sync impl for ReentrantLockGuard Fixes: #125526 --- library/std/src/sync/reentrant_lock.rs | 3 +++ tests/ui/sync/reentrantlockguard-sync.rs | 15 +++++++++++++++ tests/ui/sync/reentrantlockguard-sync.stderr | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 tests/ui/sync/reentrantlockguard-sync.rs create mode 100644 tests/ui/sync/reentrantlockguard-sync.stderr diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index 80b9e0cf1521..f7fe8eb1c7fd 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -116,6 +116,9 @@ pub struct ReentrantLockGuard<'a, T: ?Sized + 'a> { #[unstable(feature = "reentrant_lock", issue = "121440")] impl !Send for ReentrantLockGuard<'_, T> {} +#[unstable(feature = "reentrant_lock", issue = "121440")] +unsafe impl Sync for ReentrantLockGuard<'_, T> {} + #[unstable(feature = "reentrant_lock", issue = "121440")] impl ReentrantLock { /// Creates a new re-entrant lock in an unlocked state ready for use. diff --git a/tests/ui/sync/reentrantlockguard-sync.rs b/tests/ui/sync/reentrantlockguard-sync.rs new file mode 100644 index 000000000000..84d5b1834a88 --- /dev/null +++ b/tests/ui/sync/reentrantlockguard-sync.rs @@ -0,0 +1,15 @@ +#![feature(reentrant_lock)] +use std::sync::ReentrantLock; +use std::cell::Cell; + +// ReentrantLockGuard> must not be Sync, that would be unsound. + +fn test_sync(_t: T) {} + +fn main() +{ + let m = ReentrantLock::new(Cell::new(0i32)); + let guard = m.lock(); + test_sync(guard); + //~^ ERROR `Cell` cannot be shared between threads safely [E0277] +} diff --git a/tests/ui/sync/reentrantlockguard-sync.stderr b/tests/ui/sync/reentrantlockguard-sync.stderr new file mode 100644 index 000000000000..ed2e3e2f1124 --- /dev/null +++ b/tests/ui/sync/reentrantlockguard-sync.stderr @@ -0,0 +1,20 @@ +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/reentrantlockguard-sync.rs:13:15 + | +LL | test_sync(guard); + | --------- ^^^^^ `Cell` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `Cell`, which is required by `ReentrantLockGuard<'_, Cell>: Sync` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead + = note: required for `ReentrantLockGuard<'_, Cell>` to implement `Sync` +note: required by a bound in `test_sync` + --> $DIR/reentrantlockguard-sync.rs:7:17 + | +LL | fn test_sync(_t: T) {} + | ^^^^ required by this bound in `test_sync` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 9763222f592dad3e3fdda987491da3878f1c1410 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 May 2024 16:14:40 -0400 Subject: [PATCH 080/101] Move the checks for Arguments constructors to inline const --- library/core/src/fmt/mod.rs | 18 +-- ...mes.foo.ScalarReplacementOfAggregates.diff | 130 ++++++++---------- tests/pretty/issue-4264.pp | 2 +- .../run-make/symbol-mangling-hashed/Makefile | 4 +- tests/ui/consts/const-eval/format.rs | 4 +- tests/ui/consts/const-eval/format.stderr | 4 +- 6 files changed, 75 insertions(+), 87 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 1324fb6e056b..c25bc5a1b13c 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -338,23 +338,19 @@ pub struct Arguments<'a> { impl<'a> Arguments<'a> { #[inline] #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] - pub const fn new_const(pieces: &'a [&'static str]) -> Self { - if pieces.len() > 1 { - // Since panic!() expands to panic_fmt(format_args!()), using panic! here is both a - // bit silly and also significantly increases the amount of MIR generated by panics. - crate::panicking::panic_nounwind("invalid args"); - } + pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { + const { assert!(N <= 1) }; Arguments { pieces, fmt: None, args: &[] } } /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[inline] - pub fn new_v1(pieces: &'a [&'static str], args: &'a [rt::Argument<'a>]) -> Arguments<'a> { - if pieces.len() < args.len() || pieces.len() > args.len() + 1 { - // See Arguments::new_const for why we don't use panic!. - crate::panicking::panic_nounwind("invalid args"); - } + pub fn new_v1( + pieces: &'a [&'static str; P], + args: &'a [rt::Argument<'a>; A], + ) -> Arguments<'a> { + const { assert!(P >= A && P <= A + 1, "invalid args") } Arguments { pieces, fmt: None, args } } diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 0d518f78f6b5..819f3f86d145 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -11,30 +11,28 @@ let _9: (); let _10: (); let mut _11: std::fmt::Arguments<'_>; - let mut _12: &[&str]; - let mut _13: &[&str; 3]; - let _14: &[&str; 3]; - let _15: [&str; 3]; - let mut _16: &[core::fmt::rt::Argument<'_>]; - let mut _17: &[core::fmt::rt::Argument<'_>; 2]; - let _18: &[core::fmt::rt::Argument<'_>; 2]; - let _19: [core::fmt::rt::Argument<'_>; 2]; - let mut _20: core::fmt::rt::Argument<'_>; - let mut _21: &std::boxed::Box; - let _22: &std::boxed::Box; - let mut _23: core::fmt::rt::Argument<'_>; - let mut _24: &u32; - let _25: &u32; - let mut _27: bool; + let mut _12: &[&str; 3]; + let _13: &[&str; 3]; + let _14: [&str; 3]; + let mut _15: &[core::fmt::rt::Argument<'_>; 2]; + let _16: &[core::fmt::rt::Argument<'_>; 2]; + let _17: [core::fmt::rt::Argument<'_>; 2]; + let mut _18: core::fmt::rt::Argument<'_>; + let mut _19: &std::boxed::Box; + let _20: &std::boxed::Box; + let mut _21: core::fmt::rt::Argument<'_>; + let mut _22: &u32; + let _23: &u32; + let mut _25: bool; + let mut _26: isize; + let mut _27: isize; let mut _28: isize; - let mut _29: isize; - let mut _30: isize; -+ let _31: std::result::Result, ::Err>; -+ let _32: u32; ++ let _29: std::result::Result, ::Err>; ++ let _30: u32; scope 1 { - debug foo => _1; -+ debug ((foo: Foo).0: std::result::Result, ::Err>) => _31; -+ debug ((foo: Foo).1: u32) => _32; ++ debug ((foo: Foo).0: std::result::Result, ::Err>) => _29; ++ debug ((foo: Foo).1: u32) => _30; let _5: std::result::Result, ::Err>; scope 2 { debug x => _5; @@ -44,17 +42,17 @@ scope 4 { debug x => _8; let _8: std::boxed::Box; - let mut _26: &[&str; 3]; + let mut _24: &[&str; 3]; } } } } bb0: { - _27 = const false; + _25 = const false; - StorageLive(_1); -+ StorageLive(_31); -+ StorageLive(_32); ++ StorageLive(_29); ++ StorageLive(_30); + nop; StorageLive(_2); StorageLive(_3); @@ -68,83 +66,77 @@ _2 = Result::, ::Err>::Ok(move _3); StorageDead(_3); - _1 = Foo:: { x: move _2, y: const 7_u32 }; -+ _31 = move _2; -+ _32 = const 7_u32; ++ _29 = move _2; ++ _30 = const 7_u32; + nop; StorageDead(_2); StorageLive(_5); - _27 = const true; + _25 = const true; - _5 = move (_1.0: std::result::Result, ::Err>); -+ _5 = move _31; ++ _5 = move _29; StorageLive(_6); - _6 = (_1.1: u32); -+ _6 = _32; ++ _6 = _30; _7 = discriminant(_5); switchInt(move _7) -> [0: bb2, otherwise: bb7]; } bb2: { StorageLive(_8); - _27 = const false; + _25 = const false; _8 = move ((_5 as Ok).0: std::boxed::Box); StorageLive(_9); StorageLive(_10); StorageLive(_11); StorageLive(_12); StorageLive(_13); - StorageLive(_14); - _26 = const foo::::promoted[0]; - _14 = &(*_26); - _13 = &(*_14); - _12 = move _13 as &[&str] (PointerCoercion(Unsize)); - StorageDead(_13); + _24 = const foo::::promoted[0]; + _13 = &(*_24); + _12 = &(*_13); + StorageLive(_15); StorageLive(_16); StorageLive(_17); StorageLive(_18); StorageLive(_19); StorageLive(_20); - StorageLive(_21); - StorageLive(_22); - _22 = &_8; - _21 = &(*_22); - _20 = core::fmt::rt::Argument::<'_>::new_display::>(move _21) -> [return: bb3, unwind unreachable]; + _20 = &_8; + _19 = &(*_20); + _18 = core::fmt::rt::Argument::<'_>::new_display::>(move _19) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_21); + StorageDead(_19); + StorageLive(_21); + StorageLive(_22); StorageLive(_23); - StorageLive(_24); - StorageLive(_25); - _25 = &_6; - _24 = &(*_25); - _23 = core::fmt::rt::Argument::<'_>::new_display::(move _24) -> [return: bb4, unwind unreachable]; + _23 = &_6; + _22 = &(*_23); + _21 = core::fmt::rt::Argument::<'_>::new_display::(move _22) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_24); - _19 = [move _20, move _23]; - StorageDead(_23); - StorageDead(_20); - _18 = &_19; - _17 = &(*_18); - _16 = move _17 as &[core::fmt::rt::Argument<'_>] (PointerCoercion(Unsize)); - StorageDead(_17); - _11 = Arguments::<'_>::new_v1(move _12, move _16) -> [return: bb5, unwind unreachable]; + StorageDead(_22); + _17 = [move _18, move _21]; + StorageDead(_21); + StorageDead(_18); + _16 = &_17; + _15 = &(*_16); + _11 = Arguments::<'_>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_16); + StorageDead(_15); StorageDead(_12); _10 = _eprint(move _11) -> [return: bb6, unwind unreachable]; } bb6: { StorageDead(_11); - StorageDead(_25); - StorageDead(_22); - StorageDead(_19); - StorageDead(_18); - StorageDead(_14); + StorageDead(_23); + StorageDead(_20); + StorageDead(_17); + StorageDead(_16); + StorageDead(_13); StorageDead(_10); _9 = const (); StorageDead(_9); @@ -164,22 +156,22 @@ bb9: { StorageDead(_6); - _28 = discriminant(_5); - switchInt(move _28) -> [0: bb11, otherwise: bb13]; + _26 = discriminant(_5); + switchInt(move _26) -> [0: bb11, otherwise: bb13]; } bb10: { - _27 = const false; + _25 = const false; StorageDead(_5); - StorageDead(_1); -+ StorageDead(_31); -+ StorageDead(_32); ++ StorageDead(_29); ++ StorageDead(_30); + nop; return; } bb11: { - switchInt(_27) -> [0: bb10, otherwise: bb12]; + switchInt(_25) -> [0: bb10, otherwise: bb12]; } bb12: { diff --git a/tests/pretty/issue-4264.pp b/tests/pretty/issue-4264.pp index 4d43db5716e3..018ccf82daeb 100644 --- a/tests/pretty/issue-4264.pp +++ b/tests/pretty/issue-4264.pp @@ -34,7 +34,7 @@ fn bar() ({ ((::alloc::fmt::format as for<'a> fn(Arguments<'a>) -> String {format})(((format_arguments::new_const as - fn(&[&'static str]) -> Arguments<'_> {Arguments::<'_>::new_const})((&([("test" + fn(&[&'static str; 1]) -> Arguments<'_> {Arguments::<'_>::new_const::<1>})((&([("test" as &str)] as [&str; 1]) as &[&str; 1])) as Arguments<'_>)) as String); (res as String) diff --git a/tests/run-make/symbol-mangling-hashed/Makefile b/tests/run-make/symbol-mangling-hashed/Makefile index 68894b2192ab..c95036ead958 100644 --- a/tests/run-make/symbol-mangling-hashed/Makefile +++ b/tests/run-make/symbol-mangling-hashed/Makefile @@ -35,10 +35,10 @@ all: # Check hashed symbol name [ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep -c hello)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "2" ] [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep b_dylib | grep -c hello)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "1" ] + [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "2" ] [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ] [ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC6a_rlib | grep -c ' U ')" -eq "1" ] diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs index 5bdb2bf19543..b12df824a337 100644 --- a/tests/ui/consts/const-eval/format.rs +++ b/tests/ui/consts/const-eval/format.rs @@ -1,13 +1,13 @@ const fn failure() { panic!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions + //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions } const fn print() { println!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions + //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions //~| ERROR cannot call non-const fn `_print` in constant functions } diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 434b07443044..ce3f9f2190e5 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -7,7 +7,7 @@ LL | panic!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions +error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions --> $DIR/format.rs:2:5 | LL | panic!("{:?}", 0); @@ -25,7 +25,7 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions +error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions --> $DIR/format.rs:8:5 | LL | println!("{:?}", 0); From 18cb2fa851e13879f182b19883541f66719b714f Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 May 2024 21:23:12 -0400 Subject: [PATCH 081/101] Stabilize the runtime of libtest-padding The body of these benchmarks is close to empty but not literally empty. This was making the runtime of the benchmarks (which are compiled without optimizations!) flicker between 9 ns and 10 ns runtime, which changes the padding and breaks the test. Recent changes to the standard library have pushed the runtime closer to 10 ns when unoptimized, which is why we haven't seen such failures before in CI. Contributors can also induce such failures before this PR by running the run-make tests while the system is under heavy load. --- tests/run-make/libtest-padding/tests.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/run-make/libtest-padding/tests.rs b/tests/run-make/libtest-padding/tests.rs index cadf07237e95..97a99b47b5c7 100644 --- a/tests/run-make/libtest-padding/tests.rs +++ b/tests/run-make/libtest-padding/tests.rs @@ -8,11 +8,7 @@ fn short_test_name() {} fn this_is_a_really_long_test_name() {} #[bench] -fn short_bench_name(b: &mut test::Bencher) { - b.iter(|| 1); -} +fn short_bench_name(b: &mut test::Bencher) {} #[bench] -fn this_is_a_really_long_bench_name(b: &mut test::Bencher) { - b.iter(|| 1); -} +fn this_is_a_really_long_bench_name(b: &mut test::Bencher) {} From 045f448e26257c7b19bf6d68c8e5e9d09ab4df79 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 May 2024 15:17:34 -0400 Subject: [PATCH 082/101] Don't eagerly monomorphize drop for types that are impossible to instantiate --- compiler/rustc_monomorphize/src/collector.rs | 9 +++++++++ tests/ui/codegen/mono-impossible-drop.rs | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/ui/codegen/mono-impossible-drop.rs diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 76972ff2263d..9487692662bb 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1434,6 +1434,15 @@ impl<'v> RootCollector<'_, 'v> { { debug!("RootCollector: ADT drop-glue for `{id:?}`",); + // This type is impossible to instantiate, so we should not try to + // generate a `drop_in_place` instance for it. + if self.tcx.instantiate_and_check_impossible_predicates(( + id.owner_id.to_def_id(), + ty::List::empty(), + )) { + return; + } + let ty = self.tcx.type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } diff --git a/tests/ui/codegen/mono-impossible-drop.rs b/tests/ui/codegen/mono-impossible-drop.rs new file mode 100644 index 000000000000..dec013cfe54b --- /dev/null +++ b/tests/ui/codegen/mono-impossible-drop.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -Clink-dead-code=on --crate-type=lib +//@ build-pass + +#![feature(trivial_bounds)] +#![allow(trivial_bounds)] + +// Make sure we don't monomorphize the drop impl for `Baz`, since it has predicates +// that don't hold under a reveal-all param env. + +trait Foo { + type Assoc; +} + +struct Bar; + +struct Baz(::Assoc) +where + Bar: Foo; From d7248d7b71fd756bef62e98b52ee1110f8d3a3c4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 24 May 2024 00:40:39 -0700 Subject: [PATCH 083/101] Stop SRoA'ing `DynMetadata` in MIR --- compiler/rustc_mir_transform/src/sroa.rs | 5 +++++ tests/ui/mir/dyn_metadata_sroa.rs | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/ui/mir/dyn_metadata_sroa.rs diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index cdf3305b5609..f19c34cae7a7 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -70,6 +70,11 @@ fn escaping_locals<'tcx>( // Exclude #[repr(simd)] types so that they are not de-optimized into an array return true; } + if Some(def.did()) == tcx.lang_items().dyn_metadata() { + // codegen wants to see the `DynMetadata`, + // not the inner reference-to-opaque-type. + return true; + } // We already excluded unions and enums, so this ADT must have one variant let variant = def.variant(FIRST_VARIANT); if variant.fields.len() > 1 { diff --git a/tests/ui/mir/dyn_metadata_sroa.rs b/tests/ui/mir/dyn_metadata_sroa.rs new file mode 100644 index 000000000000..1a00c0f0a3e3 --- /dev/null +++ b/tests/ui/mir/dyn_metadata_sroa.rs @@ -0,0 +1,19 @@ +//@ run-pass +//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir + +#![feature(ptr_metadata)] + +// Regression for , +// which failed because of SRoA would project into `DynMetadata`. + +trait Foo {} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + let a: *mut dyn Foo = &mut Bar; + + let _d = a.to_raw_parts().0 as usize; +} From bebcb4e4b85f0414da3aef50dfc5abded1ad9f55 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 25 May 2024 13:56:19 +0200 Subject: [PATCH 084/101] Also mention my-self for check-cfg docs changes --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2e45b257f812..303c2fccc075 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -794,6 +794,9 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/rustc/src/check-cfg.md"] cc = ["@Urgau"] +[mentions."src/doc/rustc/src/check-cfg"] +cc = ["@Urgau"] + [mentions."src/doc/rustc/src/platform-support"] cc = ["@Nilstrieb"] From 2315c6b764ca75b8bf1e778ebea386e57787a0f2 Mon Sep 17 00:00:00 2001 From: Jonas Rinke Date: Sat, 25 May 2024 16:53:01 +0200 Subject: [PATCH 085/101] Use correct format for setting environment variables when debugging with cpptools --- src/tools/rust-analyzer/editors/code/src/debug.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index 855e8b082ae8..3e4446e5668f 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -194,7 +194,9 @@ function getCCppDebugConfig( args: runnable.args.executableArgs, cwd: runnable.args.cwd || runnable.args.workspaceRoot || ".", sourceFileMap, - env, + environment: Object.entries(env).map(entry => { + return { "name": entry[0], "value": entry[1] } + }), // See https://github.com/rust-lang/rust-analyzer/issues/16901#issuecomment-2024486941 osx: { MIMode: "lldb", From 78fe45e273b38e3770bb738a524c227996248cae Mon Sep 17 00:00:00 2001 From: Jonas Rinke Date: Sat, 25 May 2024 17:04:48 +0200 Subject: [PATCH 086/101] Semicolon --- src/tools/rust-analyzer/editors/code/src/debug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index 3e4446e5668f..91b07aed0171 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -195,7 +195,7 @@ function getCCppDebugConfig( cwd: runnable.args.cwd || runnable.args.workspaceRoot || ".", sourceFileMap, environment: Object.entries(env).map(entry => { - return { "name": entry[0], "value": entry[1] } + return { "name": entry[0], "value": entry[1] }; }), // See https://github.com/rust-lang/rust-analyzer/issues/16901#issuecomment-2024486941 osx: { From 09677b03ddbe2f1357a03d0f96c991e930df9176 Mon Sep 17 00:00:00 2001 From: Jonas Rinke Date: Sat, 25 May 2024 17:08:17 +0200 Subject: [PATCH 087/101] Formatting --- src/tools/rust-analyzer/editors/code/src/debug.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index 91b07aed0171..3de8cb9c2920 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -194,8 +194,8 @@ function getCCppDebugConfig( args: runnable.args.executableArgs, cwd: runnable.args.cwd || runnable.args.workspaceRoot || ".", sourceFileMap, - environment: Object.entries(env).map(entry => { - return { "name": entry[0], "value": entry[1] }; + environment: Object.entries(env).map((entry) => { + return { name: entry[0], value: entry[1] }; }), // See https://github.com/rust-lang/rust-analyzer/issues/16901#issuecomment-2024486941 osx: { From afa8dfc51faa9304e03cb79c84c7e99bd7cf2f42 Mon Sep 17 00:00:00 2001 From: Mathew Horner Date: Sat, 25 May 2024 15:00:15 -0500 Subject: [PATCH 088/101] Avoid clone when constructing runnable label. --- src/tools/rust-analyzer/crates/ide/src/runnables.rs | 2 +- .../rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 64ffa5910176..2feea09840fa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -79,7 +79,7 @@ impl RunnableKind { impl Runnable { // test package::module::testname - pub fn label(&self, target: Option) -> String { + pub fn label(&self, target: Option<&str>) -> String { match &self.kind { RunnableKind::Test { test_id, .. } => format!("test {test_id}"), RunnableKind::TestMod { path } => format!("test-mod {path}"), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 1d7062c98977..86368c9eea87 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1364,10 +1364,10 @@ pub(crate) fn runnable( ide::RunnableKind::Bin { .. } => workspace_root.clone().map(|it| it.into()), _ => spec.as_ref().map(|it| it.cargo_toml.parent().into()), }; - let target = spec.as_ref().map(|s| s.target.clone()); + let target = spec.as_ref().map(|s| s.target.as_str()); + let label = runnable.label(target); let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(snap, spec, &runnable.kind, &runnable.cfg); - let label = runnable.label(target); let location = location_link(snap, None, runnable.nav)?; Ok(lsp_ext::Runnable { From eb9894f3c9ea2ec18b36de46db417659fbe3aa9e Mon Sep 17 00:00:00 2001 From: Jonas Rinke Date: Sat, 25 May 2024 22:42:39 +0200 Subject: [PATCH 089/101] Removed return --- src/tools/rust-analyzer/editors/code/src/debug.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index 3de8cb9c2920..4b96e4d5c8ef 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -194,9 +194,10 @@ function getCCppDebugConfig( args: runnable.args.executableArgs, cwd: runnable.args.cwd || runnable.args.workspaceRoot || ".", sourceFileMap, - environment: Object.entries(env).map((entry) => { - return { name: entry[0], value: entry[1] }; - }), + environment: Object.entries(env).map((entry) => ({ + name: entry[0], + value: entry[1], + })), // See https://github.com/rust-lang/rust-analyzer/issues/16901#issuecomment-2024486941 osx: { MIMode: "lldb", From 0c843613423cdd6fdf8d8efe462bfc66640c14f2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 25 May 2024 15:58:26 -0700 Subject: [PATCH 090/101] Simplify the `unchecked_sh[lr]` ub-checks a bit --- library/core/src/num/int_macros.rs | 6 ++---- library/core/src/num/uint_macros.rs | 6 ++---- ...s.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff | 2 +- ....unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff | 2 +- ...ifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff | 2 +- ...fts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index b8b4f581a7e6..c9c6e34eaad8 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1282,8 +1282,7 @@ macro_rules! int_impl { concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), ( rhs: u32 = rhs, - bits: u32 = Self::BITS, - ) => rhs < bits, + ) => rhs < <$ActualT>::BITS, ); // SAFETY: this is guaranteed to be safe by the caller. @@ -1381,8 +1380,7 @@ macro_rules! int_impl { concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), ( rhs: u32 = rhs, - bits: u32 = Self::BITS, - ) => rhs < bits, + ) => rhs < <$ActualT>::BITS, ); // SAFETY: this is guaranteed to be safe by the caller. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 141d164de14a..f70c34199ace 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1369,8 +1369,7 @@ macro_rules! uint_impl { concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), ( rhs: u32 = rhs, - bits: u32 = Self::BITS, - ) => rhs < bits, + ) => rhs < <$ActualT>::BITS, ); // SAFETY: this is guaranteed to be safe by the caller. @@ -1468,8 +1467,7 @@ macro_rules! uint_impl { concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), ( rhs: u32 = rhs, - bits: u32 = Self::BITS, - ) => rhs < bits, + ) => rhs < <$ActualT>::BITS, ); // SAFETY: this is guaranteed to be safe by the caller. diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff index 652e24a5f8ec..0d9d58316ea1 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -29,7 +29,7 @@ } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ _6 = core::num::::unchecked_shl::precondition_check(_4) -> [return: bb2, unwind unreachable]; + } + + bb2: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff index dbcae605f769..82f7eceaa180 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff @@ -29,7 +29,7 @@ } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ _6 = core::num::::unchecked_shl::precondition_check(_4) -> [return: bb2, unwind unreachable]; + } + + bb2: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff index 88d0621c2877..6894b2466990 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff @@ -29,7 +29,7 @@ } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ _6 = core::num::::unchecked_shr::precondition_check(_4) -> [return: bb2, unwind unreachable]; + } + + bb2: { diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff index 6d4c73cf576a..070f4a1c5c83 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff @@ -29,7 +29,7 @@ } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(_4, const core::num::::BITS) -> [return: bb2, unwind unreachable]; ++ _6 = core::num::::unchecked_shr::precondition_check(_4) -> [return: bb2, unwind unreachable]; + } + + bb2: { From c81a40bbc02bb44aa99b3a94322dbf07e7a62ce1 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 23 May 2024 23:56:17 -0400 Subject: [PATCH 091/101] opt-dist: dont overrwite config.toml when verifying This is another step toward making opt-dist work in sandboxed environments opt-dist verifies the final built rustc against a subset of rustc test suite. However it overwrote the pre-existing `config.toml` [^1], and that results in ./vendor/ directory removed [^2]. Instead of overwriting, this patch use `--set ` to override paths to rustc / cargo / llvm-config. [^1]: https://github.com/rust-lang/rust/blob/606afbb617a2949a4e35c4b0258ff94c980b9451/src/tools/opt-dist/src/tests.rs#L62-L77 [^2]: https://github.com/rust-lang/rust/blob/8679004993f08807289911d9f400f4ac4391d2bc/src/bootstrap/bootstrap.py#L1057 --- src/tools/opt-dist/src/tests.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 46b0a5438025..d03d1936e086 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -59,26 +59,17 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> { .join(format!("llvm-config{}", executable_extension())); assert!(llvm_config.is_file()); - let config_content = format!( - r#"profile = "user" -change-id = 115898 + let rustc = format!("build.rustc={}", rustc_path.to_string().replace('\\', "/")); + let cargo = format!("build.cargo={}", cargo_path.to_string().replace('\\', "/")); + let llvm_config = + format!("target.{host_triple}.llvm-config={}", llvm_config.to_string().replace('\\', "/")); -[build] -rustc = "{rustc}" -cargo = "{cargo}" - -[target.{host_triple}] -llvm-config = "{llvm_config}" -"#, - rustc = rustc_path.to_string().replace('\\', "/"), - cargo = cargo_path.to_string().replace('\\', "/"), - llvm_config = llvm_config.to_string().replace('\\', "/") - ); - log::info!("Using following `config.toml` for running tests:\n{config_content}"); + log::info!("Set the following configurations for running tests:"); + log::info!("\t{rustc}"); + log::info!("\t{cargo}"); + log::info!("\t{llvm_config}"); // Simulate a stage 0 compiler with the extracted optimized dist artifacts. - std::fs::write("config.toml", config_content)?; - let x_py = env.checkout_path().join("x.py"); let mut args = vec![ env.python_binary(), @@ -97,6 +88,12 @@ llvm-config = "{llvm_config}" "tests/run-pass-valgrind", "tests/ui", "tests/crashes", + "--set", + &rustc, + "--set", + &cargo, + "--set", + &llvm_config, ]; for test_path in env.skipped_tests() { args.extend(["--skip", test_path]); From 824ffd29eeaf6581eefdce2a1c462c8ab6339bf4 Mon Sep 17 00:00:00 2001 From: Cyborus Date: Sat, 25 May 2024 20:14:18 -0400 Subject: [PATCH 092/101] Stabilize `slice_flatten` --- library/alloc/src/vec/mod.rs | 4 +--- library/alloc/tests/lib.rs | 1 - library/core/src/slice/mod.rs | 9 +++------ library/core/tests/lib.rs | 1 - 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index b2e22d8715a8..aa9b632cbed9 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2643,15 +2643,13 @@ impl Vec<[T; N], A> { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// let mut vec = vec![[1, 2, 3], [4, 5, 6], [7, 8, 9]]; /// assert_eq!(vec.pop(), Some([7, 8, 9])); /// /// let mut flattened = vec.into_flattened(); /// assert_eq!(flattened.pop(), Some(6)); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub fn into_flattened(self) -> Vec { let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc(); let (new_len, new_cap) = if T::IS_ZST { diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 0eae4ca4b8ba..8451be63c2b9 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -36,7 +36,6 @@ #![feature(const_str_from_utf8)] #![feature(panic_update_hook)] #![feature(pointer_is_aligned_to)] -#![feature(slice_flatten)] #![feature(thin_box)] #![feature(strict_provenance)] #![feature(drain_keep_rest)] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f82f965e67cf..503107c74803 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4531,8 +4531,6 @@ impl [[T; N]] { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]); /// /// assert_eq!( @@ -4546,7 +4544,8 @@ impl [[T; N]] { /// let empty_slice_of_arrays: &[[u32; 10]] = &[]; /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] pub const fn as_flattened(&self) -> &[T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") @@ -4572,8 +4571,6 @@ impl [[T; N]] { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// fn add_5_to_all(slice: &mut [i32]) { /// for i in slice { /// *i += 5; @@ -4584,7 +4581,7 @@ impl [[T; N]] { /// add_5_to_all(array.as_flattened_mut()); /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub fn as_flattened_mut(&mut self) -> &mut [T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 797108a8425d..6937780bcefe 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -112,7 +112,6 @@ #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] #![feature(waker_getters)] -#![feature(slice_flatten)] #![feature(error_generic_member_access)] #![feature(error_in_core)] #![feature(trait_upcasting)] From 91b3ef5b4a36e16347dbf128b4da64078babae70 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 25 May 2024 22:55:50 -0700 Subject: [PATCH 093/101] Notify T-rustdoc for beta-accepted and stable-accepted too Otherwise, it's unclear when the nomination label is removed whether the backport was accepted, thus nomination removed, or if the backport was rejected, thus nomination removed. --- triagebot.toml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2e45b257f812..877f6af4ec73 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -452,6 +452,19 @@ message_on_remove = "PR #{number}'s beta-nomination has been removed." message_on_close = "PR #{number} has been closed. Thanks for participating!" message_on_reopen = "PR #{number} has been reopened. Pinging @*T-rustdoc*." +# FIXME: Patch triagebot to support `notify-zulip.