From 84140cf4e10409b54bdbaeef21751d8b6276640f Mon Sep 17 00:00:00 2001 From: LaneAsade Date: Sun, 8 Feb 2026 23:06:35 +0530 Subject: [PATCH 01/12] gate defaulted type consts with associated_type_defaults --- compiler/rustc_ast_passes/src/feature_gate.rs | 13 ++++++++++++- .../const_evaluatable_unchecked.rs | 2 +- .../mgca/type-const-associated-default.rs | 9 +++++++++ .../mgca/type-const-associated-default.stderr | 13 +++++++++++++ .../assoc-const-no-infer-ice-115806.rs | 1 + .../assoc-const-no-infer-ice-115806.stderr | 2 +- .../cfi/assoc-const-projection-issue-151878.rs | 2 +- 7 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 tests/ui/const-generics/mgca/type-const-associated-default.rs create mode 100644 tests/ui/const-generics/mgca/type-const-associated-default.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index eac7f03d8450c..f22c10949d1ed 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -431,7 +431,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { false } ast::AssocItemKind::Const(box ast::ConstItem { - rhs_kind: ast::ConstItemRhsKind::TypeConst { .. }, + rhs_kind: ast::ConstItemRhsKind::TypeConst { rhs }, .. }) => { // Make sure this is only allowed if the feature gate is enabled. @@ -442,6 +442,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { i.span, "associated `type const` are unstable" ); + // Make sure associated `type const` defaults in traits are only allowed + // if the feature gate is enabled. + // #![feature(associated_type_defaults)] + if ctxt == AssocCtxt::Trait && rhs.is_some() { + gate!( + &self, + associated_type_defaults, + i.span, + "associated type defaults are unstable" + ); + } false } _ => false, diff --git a/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs index 578904ea18918..54ba1093325a3 100644 --- a/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs +++ b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs @@ -4,7 +4,7 @@ // // issue: //@ check-pass -#![feature(min_generic_const_args)] +#![feature(min_generic_const_args, associated_type_defaults)] #![allow(incomplete_features)] pub trait TraitA { diff --git a/tests/ui/const-generics/mgca/type-const-associated-default.rs b/tests/ui/const-generics/mgca/type-const-associated-default.rs new file mode 100644 index 0000000000000..7492ccbc60af5 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-associated-default.rs @@ -0,0 +1,9 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] +trait Trait { + type const N: usize = 10; + //~^ ERROR associated type defaults are unstable +} + +fn main(){ +} diff --git a/tests/ui/const-generics/mgca/type-const-associated-default.stderr b/tests/ui/const-generics/mgca/type-const-associated-default.stderr new file mode 100644 index 0000000000000..a1d635801513e --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-associated-default.stderr @@ -0,0 +1,13 @@ +error[E0658]: associated type defaults are unstable + --> $DIR/type-const-associated-default.rs:4:5 + | +LL | type const N: usize = 10; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #29661 for more information + = help: add `#![feature(associated_type_defaults)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index df680f30fed98..354880e6d573e 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,7 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 #![feature(adt_const_params, min_generic_const_args, unsized_const_params)] +#![feature(associated_type_defaults)] #![allow(incomplete_features)] pub struct NoPin; diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index b719ebe0664f2..f57fd74ad99df 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` - --> $DIR/assoc-const-no-infer-ice-115806.rs:16:1 + --> $DIR/assoc-const-no-infer-ice-115806.rs:17:1 | LL | impl Pins for NoPin {} | --------------------------- first implementation here diff --git a/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs index 6bd995449fc64..ec7a6d1605588 100644 --- a/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs +++ b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs @@ -4,7 +4,7 @@ //@ build-pass //@ no-prefer-dynamic -#![feature(min_generic_const_args)] +#![feature(min_generic_const_args, associated_type_defaults)] #![expect(incomplete_features)] trait Trait { From 751b7d5bda0676f55f14a1451c58b6c9cb92bfd3 Mon Sep 17 00:00:00 2001 From: Paul Mabileau Date: Fri, 16 May 2025 13:06:27 +0200 Subject: [PATCH 02/12] Build: Add `stdenv.cc.cc.lib` to Nix dependencies Otherwise, it systematically fails on: ``` error: process didn't exit successfully: `[...]/rust/build/bootstrap/debug/rustc [...]/rust/build/bootstrap/debug/rustc -vV` (exit status: 127) --- stderr [...]/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory ``` for us at least. Signed-off-by: Paul Mabileau --- src/bootstrap/src/core/download.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 6177233bc04e5..389956f145994 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -675,6 +675,7 @@ fn fix_bin_or_dylib(out: &Path, fname: &Path, exec_ctx: &ExecutionContext) { // the `.nix-deps` location. // // bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`). + // cc.lib: Needed similarly for `libstdc++.so.6`. // zlib: Needed as a system dependency of `libLLVM-*.so`. // patchelf: Needed for patching ELF binaries (see doc comment above). let nix_deps_dir = out.join(".nix-deps"); @@ -686,6 +687,7 @@ fn fix_bin_or_dylib(out: &Path, fname: &Path, exec_ctx: &ExecutionContext) { zlib patchelf stdenv.cc.bintools + stdenv.cc.cc.lib ]; } "; From 7df748542c53e937613ce0f85ab813467ed62eaa Mon Sep 17 00:00:00 2001 From: Brent Kerby Date: Fri, 20 Feb 2026 09:24:06 -0700 Subject: [PATCH 03/12] Add build.rustdoc option to bootstrap config --- bootstrap.example.toml | 5 +++++ src/bootstrap/src/core/config/config.rs | 6 ++++++ src/bootstrap/src/core/config/toml/build.rs | 1 + src/bootstrap/src/lib.rs | 4 +--- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index e0cbb0c0e747c..662bcc5d61e75 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -302,6 +302,11 @@ # If you set this, you likely want to set `cargo` as well. #build.rustc = "/path/to/rustc" +# Use this rustdoc binary as the stage0 snapshot rustdoc. +# If unspecified, then the binary "rustdoc" (with platform-specific extension, e.g. ".exe") +# in the same directory as "rustc" will be used. +#build.rustdoc = "/path/to/rustdoc" + # Instead of downloading the src/stage0 version of rustfmt specified, # use this rustfmt binary instead as the stage0 snapshot rustfmt. #build.rustfmt = "/path/to/rustfmt" diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index bc68bfe396425..e975d71c8c70b 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -298,6 +298,7 @@ pub struct Config { // These are either the stage0 downloaded binaries or the locally installed ones. pub initial_cargo: PathBuf, pub initial_rustc: PathBuf, + pub initial_rustdoc: PathBuf, pub initial_cargo_clippy: Option, pub initial_sysroot: PathBuf, pub initial_rustfmt: Option, @@ -456,6 +457,7 @@ impl Config { build_dir: build_build_dir, cargo: mut build_cargo, rustc: mut build_rustc, + rustdoc: build_rustdoc, rustfmt: build_rustfmt, cargo_clippy: build_cargo_clippy, docs: build_docs, @@ -751,6 +753,9 @@ impl Config { default_stage0_rustc_path(&out) }); + let initial_rustdoc = build_rustdoc + .unwrap_or_else(|| initial_rustc.with_file_name(exe("rustdoc", host_target))); + let initial_sysroot = t!(PathBuf::from_str( command(&initial_rustc) .args(["--print", "sysroot"]) @@ -1348,6 +1353,7 @@ impl Config { initial_cargo, initial_cargo_clippy: build_cargo_clippy, initial_rustc, + initial_rustdoc, initial_rustfmt, initial_sysroot, jemalloc: rust_jemalloc.unwrap_or(false), diff --git a/src/bootstrap/src/core/config/toml/build.rs b/src/bootstrap/src/core/config/toml/build.rs index 192f875587209..27bf753f6914d 100644 --- a/src/bootstrap/src/core/config/toml/build.rs +++ b/src/bootstrap/src/core/config/toml/build.rs @@ -25,6 +25,7 @@ define_config! { build_dir: Option = "build-dir", cargo: Option = "cargo", rustc: Option = "rustc", + rustdoc: Option = "rustdoc", rustfmt: Option = "rustfmt", cargo_clippy: Option = "cargo-clippy", docs: Option = "docs", diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ec5c6fbe1d01d..b9a914f53cec1 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -535,9 +535,7 @@ impl Build { initial_lld, initial_relative_libdir, initial_rustc: config.initial_rustc.clone(), - initial_rustdoc: config - .initial_rustc - .with_file_name(exe("rustdoc", config.host_target)), + initial_rustdoc: config.initial_rustdoc.clone(), initial_cargo: config.initial_cargo.clone(), initial_sysroot: config.initial_sysroot.clone(), local_rebuild: config.local_rebuild, From ae4fd170937af54b2b459a0631ce090e6f307d6b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 18 Feb 2026 08:17:53 +1100 Subject: [PATCH 04/12] Streamline query modifier macros. There are six small macros used in `define_callbacks` that all expand to one thing if a particular query modifier is present, and to another thing otherwise. One of these macros looks for the `arena_cache` modifier: - `query_if_arena` Two of these macros look for the `return_result_from_ensure_ok` modifier: - `query_ensure_select` - `ensure_ok_result` Three of these macros look for the `separate_provide_extern` modifier: - `local_key_if_separate_extern` - `separate_provide_extern_decl` - `separate_provide_extern_default` (There is also `query_helper_param_ty!`, but it follows a different pattern, and I will deal with it later.) The "one thing"/"another thing" is different for every macro. For most of them you can't see at the macro call site what the expansion will be; you have to look at the macro definition. This is annoying. This commit reduces the six macros into three macros: - `if_arena_cache` - `if_return_result_from_ensure_ok` - `if_separate_provide_extern` They all have the same form: they look for a modifier and then expand to one *given* thing or the other *given* thing. You can see at the call site the two possible expansions, which is much nicer. (Note: `query_if_arena` already had this form.) Ideally there would be a single macro instead of three, but I couldn't work out a way to combine them. --- compiler/rustc_middle/src/query/plumbing.rs | 181 +++++++++----------- 1 file changed, 81 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 03618ee6acd46..be368c6012f69 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -262,88 +262,36 @@ impl<'tcx> TyCtxt<'tcx> { } } -/// Calls either `query_ensure` or `query_ensure_error_guaranteed`, depending -/// on whether the list of modifiers contains `return_result_from_ensure_ok`. -macro_rules! query_ensure_select { - ([]$($args:tt)*) => { - crate::query::inner::query_ensure($($args)*) - }; - ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => { - crate::query::inner::query_ensure_error_guaranteed($($args)*) - }; - ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { - query_ensure_select!([$($modifiers)*]$($args)*) - }; -} - macro_rules! query_helper_param_ty { (DefId) => { impl $crate::query::IntoQueryParam }; (LocalDefId) => { impl $crate::query::IntoQueryParam }; ($K:ty) => { $K }; } -macro_rules! query_if_arena { - ([] $arena:tt $no_arena:tt) => { - $no_arena - }; - ([(arena_cache) $($rest:tt)*] $arena:tt $no_arena:tt) => { - $arena - }; - ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { - query_if_arena!([$($modifiers)*]$($args)*) - }; -} - -/// If `separate_provide_extern`, then the key can be projected to its -/// local key via `<$K as AsLocalKey>::LocalKey`. -macro_rules! local_key_if_separate_extern { - ([] $($K:tt)*) => { - $($K)* - }; - ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => { - <$($K)* as $crate::query::AsLocalKey>::LocalKey - }; - ([$other:tt $($modifiers:tt)*] $($K:tt)*) => { - local_key_if_separate_extern!([$($modifiers)*] $($K)*) - }; -} - -macro_rules! separate_provide_extern_decl { - ([][$name:ident]) => { - () - }; - ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - for<'tcx> fn( - TyCtxt<'tcx>, - $name::Key<'tcx>, - ) -> $name::ProvidedValue<'tcx> - }; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - separate_provide_extern_decl!([$($modifiers)*][$($args)*]) +// Expands to `$yes` if the `arena_cache` modifier is present, `$no` otherwise. +macro_rules! if_arena_cache { + ([] $then:tt $no:tt) => { $no }; + ([(arena_cache) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; + ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { + if_arena_cache!([$($modifiers)*] $yes $no) }; } -macro_rules! ensure_ok_result { - ( [] ) => { - () - }; - ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => { - Result<(), ErrorGuaranteed> - }; - ( [$other:tt $($modifiers:tt)*] ) => { - ensure_ok_result!( [$($modifiers)*] ) +// Expands to `$yes` if the `separate_provide_extern` modifier is present, `$no` otherwise. +macro_rules! if_separate_provide_extern { + ([] $then:tt $no:tt) => { $no }; + ([(separate_provide_extern) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; + ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { + if_separate_provide_extern!([$($modifiers)*] $yes $no) }; } -macro_rules! separate_provide_extern_default { - ([][$name:ident]) => { - () - }; - ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key) - }; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - separate_provide_extern_default!([$($modifiers)*][$($args)*]) +// Expands to `$yes` if the `return_result_from_ensure_ok` modifier is present, `$no` otherwise. +macro_rules! if_return_result_from_ensure_ok { + ([] $then:tt $no:tt) => { $no }; + ([(return_result_from_ensure_ok) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; + ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { + if_return_result_from_ensure_ok!([$($modifiers)*] $yes $no) }; } @@ -361,12 +309,16 @@ macro_rules! define_callbacks { pub type Key<'tcx> = $($K)*; pub type Value<'tcx> = $V; - pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*); + pub type LocalKey<'tcx> = if_separate_provide_extern!( + [$($modifiers)*] + (<$($K)* as $crate::query::AsLocalKey>::LocalKey) + ($($K)*) + ); /// This type alias specifies the type returned from query providers and the type /// used for decoding. For regular queries this is the declared returned type `V`, /// but `arena_cache` will use `::Provided` instead. - pub type ProvidedValue<'tcx> = query_if_arena!( + pub type ProvidedValue<'tcx> = if_arena_cache!( [$($modifiers)*] (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) ($V) @@ -383,17 +335,21 @@ macro_rules! define_callbacks { ) -> Erased> { // For queries with the `arena_cache` modifier, store the // provided value in an arena and get a reference to it. - let value: Value<'tcx> = query_if_arena!([$($modifiers)*] { - <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( - tcx, - &tcx.query_system.arenas.$name, - provided_value, - ) - } { - // Otherwise, the provided value is the value (and `tcx` is unused). - let _ = tcx; - provided_value - }); + let value: Value<'tcx> = if_arena_cache!( + [$($modifiers)*] + { + <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( + tcx, + &tcx.query_system.arenas.$name, + provided_value, + ) + } + { + // Otherwise, the provided value is the value (and `tcx` is unused). + let _ = tcx; + provided_value + } + ); erase::erase_val(value) } @@ -436,7 +392,8 @@ macro_rules! define_callbacks { pub struct QueryArenas<'tcx> { $( $(#[$attr])* - pub $name: query_if_arena!([$($modifiers)*] + pub $name: if_arena_cache!( + [$($modifiers)*] // Use the `ArenaCached` helper trait to determine the arena's value type. (TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>) // No arena for this query, so the field type is `()`. @@ -451,21 +408,30 @@ macro_rules! define_callbacks { } impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name( - self, - key: query_helper_param_ty!($($K)*), - ) -> ensure_ok_result!([$($modifiers)*]) { - query_ensure_select!( + $( + $(#[$attr])* + #[inline(always)] + pub fn $name( + self, + key: query_helper_param_ty!($($K)*), + ) -> if_return_result_from_ensure_ok!( [$($modifiers)*] - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - $crate::query::IntoQueryParam::into_query_param(key), - false, - ) - })* + (Result<(), ErrorGuaranteed>) + () + ) { + if_return_result_from_ensure_ok!( + [$($modifiers)*] + (crate::query::inner::query_ensure_error_guaranteed) + (crate::query::inner::query_ensure) + )( + self.tcx, + self.tcx.query_system.fns.engine.$name, + &self.tcx.query_system.caches.$name, + $crate::query::IntoQueryParam::into_query_param(key), + false, + ) + } + )* } impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> { @@ -537,7 +503,13 @@ macro_rules! define_callbacks { } pub struct ExternProviders { - $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)* + $( + pub $name: if_separate_provide_extern!( + [$($modifiers)*] + (for<'tcx> fn(TyCtxt<'tcx>, $name::Key<'tcx>) -> $name::ProvidedValue<'tcx>) + () + ), + )* } impl Default for Providers { @@ -551,7 +523,16 @@ macro_rules! define_callbacks { impl Default for ExternProviders { fn default() -> Self { ExternProviders { - $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)* + $( + $name: if_separate_provide_extern!( + [$($modifiers)*] + (|_, key| $crate::query::plumbing::default_extern_query( + stringify!($name), + &key + )) + () + ), + )* } } } From eefb116cb1e5e3fdffd9912b37c96f65778936ce Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 18 Feb 2026 09:09:06 +1100 Subject: [PATCH 05/12] Reindent `define_callbacks` and `define_feedable`. So that all `$( ... $name ... )*` repetitions are spread across multiple lines, even if they all fit on one line. I find this much easier to read because the `$name` repetition is the main feature of these macros. --- compiler/rustc_middle/src/query/plumbing.rs | 304 +++++++++++--------- 1 file changed, 164 insertions(+), 140 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index be368c6012f69..4e19ebb9016ab 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -299,93 +299,97 @@ macro_rules! define_callbacks { ( $( $(#[$attr:meta])* - [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty, + [$($modifiers:tt)*] + fn $name:ident($($K:tt)*) -> $V:ty, )* ) => { - $(#[allow(unused_lifetimes)] pub mod $name { - use super::*; - use $crate::query::erase::{self, Erased}; - - pub type Key<'tcx> = $($K)*; - pub type Value<'tcx> = $V; - - pub type LocalKey<'tcx> = if_separate_provide_extern!( - [$($modifiers)*] - (<$($K)* as $crate::query::AsLocalKey>::LocalKey) - ($($K)*) - ); - - /// This type alias specifies the type returned from query providers and the type - /// used for decoding. For regular queries this is the declared returned type `V`, - /// but `arena_cache` will use `::Provided` instead. - pub type ProvidedValue<'tcx> = if_arena_cache!( - [$($modifiers)*] - (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) - ($V) - ); - - /// This helper function takes a value returned by the query provider - /// (or loaded from disk, or supplied by query feeding), allocates - /// it in an arena if requested by the `arena_cache` modifier, and - /// then returns an erased copy of it. - #[inline(always)] - pub fn provided_to_erased<'tcx>( - tcx: TyCtxt<'tcx>, - provided_value: ProvidedValue<'tcx>, - ) -> Erased> { - // For queries with the `arena_cache` modifier, store the - // provided value in an arena and get a reference to it. - let value: Value<'tcx> = if_arena_cache!( + $( + #[allow(unused_lifetimes)] + pub mod $name { + use super::*; + use $crate::query::erase::{self, Erased}; + + pub type Key<'tcx> = $($K)*; + pub type Value<'tcx> = $V; + + pub type LocalKey<'tcx> = if_separate_provide_extern!( [$($modifiers)*] - { - <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( - tcx, - &tcx.query_system.arenas.$name, - provided_value, - ) - } - { - // Otherwise, the provided value is the value (and `tcx` is unused). - let _ = tcx; - provided_value - } + (<$($K)* as $crate::query::AsLocalKey>::LocalKey) + ($($K)*) ); - erase::erase_val(value) - } - pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache>; - - // Ensure that keys grow no larger than 88 bytes by accident. - // Increase this limit if necessary, but do try to keep the size low if possible - #[cfg(target_pointer_width = "64")] - const _: () = { - if size_of::>() > 88 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a key type `", - stringify!($($K)*), - "` that is too large" - )); - } - }; - - // Ensure that values grow no larger than 64 bytes by accident. - // Increase this limit if necessary, but do try to keep the size low if possible - #[cfg(target_pointer_width = "64")] - #[cfg(not(feature = "rustc_randomized_layouts"))] - const _: () = { - if size_of::>() > 64 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a value type `", - stringify!($V), - "` that is too large" - )); + /// This type alias specifies the type returned from query providers and the type + /// used for decoding. For regular queries this is the declared returned type `V`, + /// but `arena_cache` will use `::Provided` instead. + pub type ProvidedValue<'tcx> = if_arena_cache!( + [$($modifiers)*] + (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) + ($V) + ); + + /// This helper function takes a value returned by the query provider + /// (or loaded from disk, or supplied by query feeding), allocates + /// it in an arena if requested by the `arena_cache` modifier, and + /// then returns an erased copy of it. + #[inline(always)] + pub fn provided_to_erased<'tcx>( + tcx: TyCtxt<'tcx>, + provided_value: ProvidedValue<'tcx>, + ) -> Erased> { + // For queries with the `arena_cache` modifier, store the + // provided value in an arena and get a reference to it. + let value: Value<'tcx> = if_arena_cache!( + [$($modifiers)*] + { + <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( + tcx, + &tcx.query_system.arenas.$name, + provided_value, + ) + } + { + // Otherwise, the provided value is the value (and `tcx` is unused). + let _ = tcx; + provided_value + } + ); + erase::erase_val(value) } - }; - })* + + pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache>; + + // Ensure that keys grow no larger than 88 bytes by accident. + // Increase this limit if necessary, but do try to keep the size low if possible + #[cfg(target_pointer_width = "64")] + const _: () = { + if size_of::>() > 88 { + panic!("{}", concat!( + "the query `", + stringify!($name), + "` has a key type `", + stringify!($($K)*), + "` that is too large" + )); + } + }; + + // Ensure that values grow no larger than 64 bytes by accident. + // Increase this limit if necessary, but do try to keep the size low if possible + #[cfg(target_pointer_width = "64")] + #[cfg(not(feature = "rustc_randomized_layouts"))] + const _: () = { + if size_of::>() > 64 { + panic!("{}", concat!( + "the query `", + stringify!($name), + "` has a value type `", + stringify!($V), + "` that is too large" + )); + } + }; + } + )* /// Holds per-query arenas for queries with the `arena_cache` modifier. #[derive(Default)] @@ -404,7 +408,9 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryCaches<'tcx> { - $($(#[$attr])* pub $name: $name::Storage<'tcx>,)* + $( + $(#[$attr])* pub $name: $name::Storage<'tcx>, + )* } impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> { @@ -435,44 +441,48 @@ macro_rules! define_callbacks { } impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) { - crate::query::inner::query_ensure( - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - $crate::query::IntoQueryParam::into_query_param(key), - true, - ); - })* + $( + $(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + crate::query::inner::query_ensure( + self.tcx, + self.tcx.query_system.fns.engine.$name, + &self.tcx.query_system.caches.$name, + $crate::query::IntoQueryParam::into_query_param(key), + true, + ); + } + )* } impl<'tcx> TyCtxt<'tcx> { - $($(#[$attr])* - #[inline(always)] - #[must_use] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V - { - self.at(DUMMY_SP).$name(key) - })* + $( + $(#[$attr])* + #[inline(always)] + #[must_use] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + self.at(DUMMY_SP).$name(key) + } + )* } impl<'tcx> $crate::query::TyCtxtAt<'tcx> { - $($(#[$attr])* - #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V - { - use $crate::query::{erase, inner}; - - erase::restore_val::<$V>(inner::query_get_at( - self.tcx, - self.tcx.query_system.fns.engine.$name, - &self.tcx.query_system.caches.$name, - self.span, - $crate::query::IntoQueryParam::into_query_param(key), - )) - })* + $( + $(#[$attr])* + #[inline(always)] + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + use $crate::query::{erase, inner}; + + erase::restore_val::<$V>(inner::query_get_at( + self.tcx, + self.tcx.query_system.fns.engine.$name, + &self.tcx.query_system.caches.$name, + self.span, + $crate::query::IntoQueryParam::into_query_param(key), + )) + } + )* } /// Holds a `QueryVTable` for each query. @@ -515,7 +525,11 @@ macro_rules! define_callbacks { impl Default for Providers { fn default() -> Self { Providers { - $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),* + $( + $name: |_, key| { + $crate::query::plumbing::default_query(stringify!($name), &key) + }, + )* } } } @@ -548,37 +562,47 @@ macro_rules! define_callbacks { } pub struct QueryEngine { - $(pub $name: for<'tcx> fn( - TyCtxt<'tcx>, - Span, - $name::Key<'tcx>, - $crate::query::QueryMode, - ) -> Option<$crate::query::erase::Erased<$V>>,)* + $( + pub $name: for<'tcx> fn( + TyCtxt<'tcx>, + Span, + $name::Key<'tcx>, + $crate::query::QueryMode, + ) -> Option<$crate::query::erase::Erased<$V>>, + )* } }; } macro_rules! define_feedable { - ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - $(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { - $(#[$attr])* - #[inline(always)] - pub fn $name(self, value: $name::ProvidedValue<'tcx>) { - let key = self.key().into_query_param(); - - let tcx = self.tcx; - let erased_value = $name::provided_to_erased(tcx, value); - - $crate::query::inner::query_feed( - tcx, - dep_graph::DepKind::$name, - &tcx.query_system.query_vtables.$name, - &tcx.query_system.caches.$name, - key, - erased_value, - ); + ( + $( + $(#[$attr:meta])* + [$($modifiers:tt)*] + fn $name:ident($($K:tt)*) -> $V:ty, + )* + ) => { + $( + impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { + $(#[$attr])* + #[inline(always)] + pub fn $name(self, value: $name::ProvidedValue<'tcx>) { + let key = self.key().into_query_param(); + + let tcx = self.tcx; + let erased_value = $name::provided_to_erased(tcx, value); + + $crate::query::inner::query_feed( + tcx, + dep_graph::DepKind::$name, + &tcx.query_system.query_vtables.$name, + &tcx.query_system.caches.$name, + key, + erased_value, + ); + } } - })* + )* } } From 5142af7e91c6fec2d50aee85e51d66bef78d74e9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 18 Feb 2026 20:29:49 +1100 Subject: [PATCH 06/12] Remove `$attr` from `QueryArenas`/`QueryCaches`. It doesn't make much sense to put the query doc comments on these structs. (The doc comments *are* put on various query functions, where it makes more sense.) --- compiler/rustc_middle/src/query/plumbing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 4e19ebb9016ab..dfa122510729c 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -395,7 +395,6 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryArenas<'tcx> { $( - $(#[$attr])* pub $name: if_arena_cache!( [$($modifiers)*] // Use the `ArenaCached` helper trait to determine the arena's value type. @@ -409,7 +408,7 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryCaches<'tcx> { $( - $(#[$attr])* pub $name: $name::Storage<'tcx>, + pub $name: $name::Storage<'tcx>, )* } From bc1b6b8b325e9242c1d1fe32a1fa66a246daac0b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Feb 2026 08:11:43 +1100 Subject: [PATCH 07/12] Reduce `$K` and `$V` usage in query macros. Within `define_callbacks!`: - Use `Key<'tcx>` where possible instead of `$($K)*`. - Use `Value<'tcx>` where possible instead of `$V`. In the other `define_*!` macros: - Use `$K:ty` where possible instead of `$($K:tt)*`. - Add comments about unused `$K` and `$V` cases. - Add `()` key types to the special nodes in the `define_dep_nodes!` invocation for consistency with normal queries. --- .../rustc_middle/src/dep_graph/dep_node.rs | 21 ++++++++-------- compiler/rustc_middle/src/query/plumbing.rs | 24 ++++++++++++------- compiler/rustc_query_impl/src/plumbing.rs | 5 ++-- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 1ffbdfbf11875..5b583796c1756 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -324,11 +324,12 @@ impl StableOrd for WorkProductId { const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); } +// Note: `$K` and `$V` are unused but present so this can be called by `rustc_with_all_queries`. macro_rules! define_dep_nodes { ( $( $(#[$attr:meta])* - [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty, + [$($modifiers:tt)*] fn $variant:ident($K:ty) -> $V:ty, )* ) => { @@ -382,20 +383,20 @@ macro_rules! define_dep_nodes { } // Create various data structures for each query, and also for a few things -// that aren't queries. +// that aren't queries. The key and return types aren't used, hence the use of `()`. rustc_with_all_queries!(define_dep_nodes![ /// We use this for most things when incr. comp. is turned off. - [] fn Null() -> (), + [] fn Null(()) -> (), /// We use this to create a forever-red node. - [] fn Red() -> (), + [] fn Red(()) -> (), /// We use this to create a side effect node. - [] fn SideEffect() -> (), + [] fn SideEffect(()) -> (), /// We use this to create the anon node with zero dependencies. - [] fn AnonZeroDeps() -> (), - [] fn TraitSelect() -> (), - [] fn CompileCodegenUnit() -> (), - [] fn CompileMonoItem() -> (), - [] fn Metadata() -> (), + [] fn AnonZeroDeps(()) -> (), + [] fn TraitSelect(()) -> (), + [] fn CompileCodegenUnit(()) -> (), + [] fn CompileMonoItem(()) -> (), + [] fn Metadata(()) -> (), ]); // WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys. diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index dfa122510729c..a48fc8908f498 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -297,6 +297,8 @@ macro_rules! if_return_result_from_ensure_ok { macro_rules! define_callbacks { ( + // You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that + // `query_helper_param_ty!` can match on specific type names. $( $(#[$attr:meta])* [$($modifiers:tt)*] @@ -314,8 +316,8 @@ macro_rules! define_callbacks { pub type LocalKey<'tcx> = if_separate_provide_extern!( [$($modifiers)*] - (<$($K)* as $crate::query::AsLocalKey>::LocalKey) - ($($K)*) + ( as $crate::query::AsLocalKey>::LocalKey) + (Key<'tcx>) ); /// This type alias specifies the type returned from query providers and the type @@ -323,8 +325,8 @@ macro_rules! define_callbacks { /// but `arena_cache` will use `::Provided` instead. pub type ProvidedValue<'tcx> = if_arena_cache!( [$($modifiers)*] - (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) - ($V) + ( as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) + (Value<'tcx>) ); /// This helper function takes a value returned by the query provider @@ -341,7 +343,9 @@ macro_rules! define_callbacks { let value: Value<'tcx> = if_arena_cache!( [$($modifiers)*] { - <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( + as $crate::query::arena_cached::ArenaCached>:: + alloc_in_arena + ( tcx, &tcx.query_system.arenas.$name, provided_value, @@ -356,7 +360,8 @@ macro_rules! define_callbacks { erase::erase_val(value) } - pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache>; + pub type Storage<'tcx> = + as $crate::query::Key>::Cache>>; // Ensure that keys grow no larger than 88 bytes by accident. // Increase this limit if necessary, but do try to keep the size low if possible @@ -496,7 +501,7 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryStates<'tcx> { $( - pub $name: $crate::query::QueryState<'tcx, $($K)*>, + pub $name: $crate::query::QueryState<'tcx, $name::Key<'tcx>>, )* } @@ -573,16 +578,17 @@ macro_rules! define_callbacks { }; } +// Note: `$V` is unused but present so this can be called by `rustc_with_all_queries`. macro_rules! define_feedable { ( $( $(#[$attr:meta])* [$($modifiers:tt)*] - fn $name:ident($($K:tt)*) -> $V:ty, + fn $name:ident($K:ty) -> $V:ty, )* ) => { $( - impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { + impl<'tcx, K: $crate::query::IntoQueryParam<$K> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] pub fn $name(self, value: $name::ProvidedValue<'tcx>) { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 1ed601aae3562..31e81a62d5270 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -471,13 +471,12 @@ pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryF } } -// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros -// invoked by `rustc_with_all_queries`. +// Note: `$K` and `$V` are unused but present so this can be called by `rustc_with_all_queries`. macro_rules! define_queries { ( $( $(#[$attr:meta])* - [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty, + [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty, )* ) => { From b7c28a8471dc1ec7636e6d2f2334f09e845311ac Mon Sep 17 00:00:00 2001 From: Alex Celeste Date: Sat, 21 Feb 2026 01:20:19 +0000 Subject: [PATCH 08/12] Index expressions rendered the index: subexpression as the id, instead of actually showing the content of the subexpression This meant the content of the subexpression was completely missing from tree view (as the id did not reference anything) --- compiler/rustc_mir_build/src/thir/print.rs | 3 +- tests/ui/thir-print/thir-tree-array-index.rs | 22 + .../thir-print/thir-tree-array-index.stdout | 1211 +++++++++++++++++ 3 files changed, 1235 insertions(+), 1 deletion(-) create mode 100644 tests/ui/thir-print/thir-tree-array-index.rs create mode 100644 tests/ui/thir-print/thir-tree-array-index.stdout diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 6905f5c34caa8..27dec99696f5f 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -397,9 +397,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { } Index { lhs, index } => { print_indented!(self, "Index {", depth_lvl); - print_indented!(self, format!("index: {:?}", index), depth_lvl + 1); print_indented!(self, "lhs:", depth_lvl + 1); self.print_expr(*lhs, depth_lvl + 2); + print_indented!(self, "index:", depth_lvl + 1); + self.print_expr(*index, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } VarRef { id } => { diff --git a/tests/ui/thir-print/thir-tree-array-index.rs b/tests/ui/thir-print/thir-tree-array-index.rs new file mode 100644 index 0000000000000..75098f72293e1 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-array-index.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=thir-tree + +fn index(x: usize) -> usize { x } + +fn indexing(x: usize) -> usize { + let a1: [usize; 5] = [1, 2, 3, 4, 5]; + let a2: [usize; 5] = [x; 5]; + + a1[0]; + a2[1]; + + a1[x]; + a2[x + 2]; + + a1[a2[x] + a2[x - 3]]; + a2[index (x + 1) - x]; + + 0 +} + +fn main() {} diff --git a/tests/ui/thir-print/thir-tree-array-index.stdout b/tests/ui/thir-print/thir-tree-array-index.stdout new file mode 100644 index 0000000000000..bbb2fd9578146 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-array-index.stdout @@ -0,0 +1,1211 @@ +DefId(0:3 ~ thir_tree_array_index[2569]::index): +params: [ + Param { + ty: usize + ty_span: Some($DIR/thir-tree-array-index.rs:4:13: 4:18 (#0)) + self_kind: None + hir_id: Some(HirId(DefId(0:3 ~ thir_tree_array_index[2569]::index).1)) + param: Some( + Pat { + ty: usize + span: $DIR/thir-tree-array-index.rs:4:10: 4:11 (#0) + kind: PatKind { + Binding { + name: "x" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:3 ~ thir_tree_array_index[2569]::index).2)) + ty: usize + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + ) + } +] +body: + Expr { + ty: usize + temp_scope_id: 6 + span: $DIR/thir-tree-array-index.rs:4:29: 4:34 (#0) + kind: + Scope { + region_scope: Node(6) + hir_id: HirId(DefId(0:3 ~ thir_tree_array_index[2569]::index).6) + value: + Expr { + ty: usize + temp_scope_id: 6 + span: $DIR/thir-tree-array-index.rs:4:29: 4:34 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-array-index.rs:4:29: 4:34 (#0) + region_scope: Node(3) + safety_mode: Safe + stmts: [] + expr: + Expr { + ty: usize + temp_scope_id: 4 + span: $DIR/thir-tree-array-index.rs:4:31: 4:32 (#0) + kind: + Scope { + region_scope: Node(4) + hir_id: HirId(DefId(0:3 ~ thir_tree_array_index[2569]::index).4) + value: + Expr { + ty: usize + temp_scope_id: 4 + span: $DIR/thir-tree-array-index.rs:4:31: 4:32 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:3 ~ thir_tree_array_index[2569]::index).2)) + } + } + } + } + } + } + } + } + + +DefId(0:4 ~ thir_tree_array_index[2569]::indexing): +params: [ + Param { + ty: usize + ty_span: Some($DIR/thir-tree-array-index.rs:6:16: 6:21 (#0)) + self_kind: None + hir_id: Some(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).1)) + param: Some( + Pat { + ty: usize + span: $DIR/thir-tree-array-index.rs:6:13: 6:14 (#0) + kind: PatKind { + Binding { + name: "x" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + ty: usize + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + ) + } +] +body: + Expr { + ty: usize + temp_scope_id: 90 + span: $DIR/thir-tree-array-index.rs:6:32: 20:2 (#0) + kind: + Scope { + region_scope: Node(90) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).90) + value: + Expr { + ty: usize + temp_scope_id: 90 + span: $DIR/thir-tree-array-index.rs:6:32: 20:2 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-array-index.rs:6:32: 20:2 (#0) + region_scope: Node(3) + safety_mode: Safe + stmts: [ + Stmt { + kind: Let { + remainder_scope: Remainder { block: 3, first_statement_index: 0} + init_scope: Node(4) + pattern: + Pat { + ty: [usize; 5_usize] + span: $DIR/thir-tree-array-index.rs:7:7: 7:9 (#0) + extra: PatExtra { + expanded_const: None + ascriptions: [ + Ascription { annotation: CanonicalUserTypeAnnotation { user_ty: Canonical { value: UserType { kind: Ty([usize; 5_usize]), bounds: [] }, max_universe: U0, var_kinds: [] }, span: $DIR/thir-tree-array-index.rs:7:11: 7:21 (#0), inferred_ty: [usize; 5_usize] }, variance: + } + ] + } + kind: PatKind { + Binding { + name: "a1" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).18)) + ty: [usize; 5_usize] + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + , + initializer: Some( + Expr { + ty: [usize; 5_usize] + temp_scope_id: 11 + span: $DIR/thir-tree-array-index.rs:7:24: 7:39 (#0) + kind: + Scope { + region_scope: Node(11) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).11) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 11 + span: $DIR/thir-tree-array-index.rs:7:24: 7:39 (#0) + kind: + Array { + fields: [ + Expr { + ty: usize + temp_scope_id: 12 + span: $DIR/thir-tree-array-index.rs:7:25: 7:26 (#0) + kind: + Scope { + region_scope: Node(12) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).12) + value: + Expr { + ty: usize + temp_scope_id: 12 + span: $DIR/thir-tree-array-index.rs:7:25: 7:26 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:25: 7:26 (#0) }, neg: false) + + } + } + } + Expr { + ty: usize + temp_scope_id: 13 + span: $DIR/thir-tree-array-index.rs:7:28: 7:29 (#0) + kind: + Scope { + region_scope: Node(13) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).13) + value: + Expr { + ty: usize + temp_scope_id: 13 + span: $DIR/thir-tree-array-index.rs:7:28: 7:29 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(2), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:28: 7:29 (#0) }, neg: false) + + } + } + } + Expr { + ty: usize + temp_scope_id: 14 + span: $DIR/thir-tree-array-index.rs:7:31: 7:32 (#0) + kind: + Scope { + region_scope: Node(14) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).14) + value: + Expr { + ty: usize + temp_scope_id: 14 + span: $DIR/thir-tree-array-index.rs:7:31: 7:32 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(3), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:31: 7:32 (#0) }, neg: false) + + } + } + } + Expr { + ty: usize + temp_scope_id: 15 + span: $DIR/thir-tree-array-index.rs:7:34: 7:35 (#0) + kind: + Scope { + region_scope: Node(15) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).15) + value: + Expr { + ty: usize + temp_scope_id: 15 + span: $DIR/thir-tree-array-index.rs:7:34: 7:35 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(4), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:34: 7:35 (#0) }, neg: false) + + } + } + } + Expr { + ty: usize + temp_scope_id: 16 + span: $DIR/thir-tree-array-index.rs:7:37: 7:38 (#0) + kind: + Scope { + region_scope: Node(16) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).16) + value: + Expr { + ty: usize + temp_scope_id: 16 + span: $DIR/thir-tree-array-index.rs:7:37: 7:38 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(5), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:37: 7:38 (#0) }, neg: false) + + } + } + } + ] + } + } + } + } + ) + else_block: None + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).17) + span: $DIR/thir-tree-array-index.rs:7:3: 7:39 (#0) + } + } + Stmt { + kind: Let { + remainder_scope: Remainder { block: 3, first_statement_index: 1} + init_scope: Node(19) + pattern: + Pat { + ty: [usize; 5_usize] + span: $DIR/thir-tree-array-index.rs:8:7: 8:9 (#0) + extra: PatExtra { + expanded_const: None + ascriptions: [ + Ascription { annotation: CanonicalUserTypeAnnotation { user_ty: Canonical { value: UserType { kind: Ty([usize; 5_usize]), bounds: [] }, max_universe: U0, var_kinds: [] }, span: $DIR/thir-tree-array-index.rs:8:11: 8:21 (#0), inferred_ty: [usize; 5_usize] }, variance: + } + ] + } + kind: PatKind { + Binding { + name: "a2" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + ty: [usize; 5_usize] + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + , + initializer: Some( + Expr { + ty: [usize; 5_usize] + temp_scope_id: 26 + span: $DIR/thir-tree-array-index.rs:8:24: 8:30 (#0) + kind: + Scope { + region_scope: Node(26) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).26) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 26 + span: $DIR/thir-tree-array-index.rs:8:24: 8:30 (#0) + kind: + Repeat { + count: 5_usize + value: + Expr { + ty: usize + temp_scope_id: 27 + span: $DIR/thir-tree-array-index.rs:8:25: 8:26 (#0) + kind: + Scope { + region_scope: Node(27) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).27) + value: + Expr { + ty: usize + temp_scope_id: 27 + span: $DIR/thir-tree-array-index.rs:8:25: 8:26 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + } + } + } + } + ) + else_block: None + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).32) + span: $DIR/thir-tree-array-index.rs:8:3: 8:30 (#0) + } + } + Stmt { + kind: Expr { + scope: Node(38) + expr: + Expr { + ty: usize + temp_scope_id: 34 + span: $DIR/thir-tree-array-index.rs:10:3: 10:8 (#0) + kind: + Scope { + region_scope: Node(34) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).34) + value: + Expr { + ty: usize + temp_scope_id: 34 + span: $DIR/thir-tree-array-index.rs:10:3: 10:8 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 35 + span: $DIR/thir-tree-array-index.rs:10:3: 10:5 (#0) + kind: + Scope { + region_scope: Node(35) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).35) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 35 + span: $DIR/thir-tree-array-index.rs:10:3: 10:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).18)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 37 + span: $DIR/thir-tree-array-index.rs:10:6: 10:7 (#0) + kind: + Scope { + region_scope: Node(37) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).37) + value: + Expr { + ty: usize + temp_scope_id: 37 + span: $DIR/thir-tree-array-index.rs:10:6: 10:7 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(0), Unsuffixed), span: $DIR/thir-tree-array-index.rs:10:6: 10:7 (#0) }, neg: false) + + } + } + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(43) + expr: + Expr { + ty: usize + temp_scope_id: 39 + span: $DIR/thir-tree-array-index.rs:11:3: 11:8 (#0) + kind: + Scope { + region_scope: Node(39) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).39) + value: + Expr { + ty: usize + temp_scope_id: 39 + span: $DIR/thir-tree-array-index.rs:11:3: 11:8 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 40 + span: $DIR/thir-tree-array-index.rs:11:3: 11:5 (#0) + kind: + Scope { + region_scope: Node(40) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).40) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 40 + span: $DIR/thir-tree-array-index.rs:11:3: 11:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 42 + span: $DIR/thir-tree-array-index.rs:11:6: 11:7 (#0) + kind: + Scope { + region_scope: Node(42) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).42) + value: + Expr { + ty: usize + temp_scope_id: 42 + span: $DIR/thir-tree-array-index.rs:11:6: 11:7 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/thir-tree-array-index.rs:11:6: 11:7 (#0) }, neg: false) + + } + } + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(49) + expr: + Expr { + ty: usize + temp_scope_id: 44 + span: $DIR/thir-tree-array-index.rs:13:3: 13:8 (#0) + kind: + Scope { + region_scope: Node(44) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).44) + value: + Expr { + ty: usize + temp_scope_id: 44 + span: $DIR/thir-tree-array-index.rs:13:3: 13:8 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 45 + span: $DIR/thir-tree-array-index.rs:13:3: 13:5 (#0) + kind: + Scope { + region_scope: Node(45) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).45) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 45 + span: $DIR/thir-tree-array-index.rs:13:3: 13:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).18)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 47 + span: $DIR/thir-tree-array-index.rs:13:6: 13:7 (#0) + kind: + Scope { + region_scope: Node(47) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).47) + value: + Expr { + ty: usize + temp_scope_id: 47 + span: $DIR/thir-tree-array-index.rs:13:6: 13:7 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(57) + expr: + Expr { + ty: usize + temp_scope_id: 50 + span: $DIR/thir-tree-array-index.rs:14:3: 14:12 (#0) + kind: + Scope { + region_scope: Node(50) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).50) + value: + Expr { + ty: usize + temp_scope_id: 50 + span: $DIR/thir-tree-array-index.rs:14:3: 14:12 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 51 + span: $DIR/thir-tree-array-index.rs:14:3: 14:5 (#0) + kind: + Scope { + region_scope: Node(51) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).51) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 51 + span: $DIR/thir-tree-array-index.rs:14:3: 14:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 53 + span: $DIR/thir-tree-array-index.rs:14:6: 14:11 (#0) + kind: + Scope { + region_scope: Node(53) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).53) + value: + Expr { + ty: usize + temp_scope_id: 53 + span: $DIR/thir-tree-array-index.rs:14:6: 14:11 (#0) + kind: + Binary { + op: Add + lhs: + Expr { + ty: usize + temp_scope_id: 54 + span: $DIR/thir-tree-array-index.rs:14:6: 14:7 (#0) + kind: + Scope { + region_scope: Node(54) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).54) + value: + Expr { + ty: usize + temp_scope_id: 54 + span: $DIR/thir-tree-array-index.rs:14:6: 14:7 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + rhs: + Expr { + ty: usize + temp_scope_id: 56 + span: $DIR/thir-tree-array-index.rs:14:10: 14:11 (#0) + kind: + Scope { + region_scope: Node(56) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).56) + value: + Expr { + ty: usize + temp_scope_id: 56 + span: $DIR/thir-tree-array-index.rs:14:10: 14:11 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(2), Unsuffixed), span: $DIR/thir-tree-array-index.rs:14:10: 14:11 (#0) }, neg: false) + + } + } + } + } + } + } + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(74) + expr: + Expr { + ty: usize + temp_scope_id: 58 + span: $DIR/thir-tree-array-index.rs:16:3: 16:24 (#0) + kind: + Scope { + region_scope: Node(58) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).58) + value: + Expr { + ty: usize + temp_scope_id: 58 + span: $DIR/thir-tree-array-index.rs:16:3: 16:24 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 59 + span: $DIR/thir-tree-array-index.rs:16:3: 16:5 (#0) + kind: + Scope { + region_scope: Node(59) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).59) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 59 + span: $DIR/thir-tree-array-index.rs:16:3: 16:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).18)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 61 + span: $DIR/thir-tree-array-index.rs:16:6: 16:23 (#0) + kind: + Scope { + region_scope: Node(61) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).61) + value: + Expr { + ty: usize + temp_scope_id: 61 + span: $DIR/thir-tree-array-index.rs:16:6: 16:23 (#0) + kind: + Binary { + op: Add + lhs: + Expr { + ty: usize + temp_scope_id: 62 + span: $DIR/thir-tree-array-index.rs:16:6: 16:11 (#0) + kind: + Scope { + region_scope: Node(62) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).62) + value: + Expr { + ty: usize + temp_scope_id: 62 + span: $DIR/thir-tree-array-index.rs:16:6: 16:11 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 63 + span: $DIR/thir-tree-array-index.rs:16:6: 16:8 (#0) + kind: + Scope { + region_scope: Node(63) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).63) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 63 + span: $DIR/thir-tree-array-index.rs:16:6: 16:8 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 65 + span: $DIR/thir-tree-array-index.rs:16:9: 16:10 (#0) + kind: + Scope { + region_scope: Node(65) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).65) + value: + Expr { + ty: usize + temp_scope_id: 65 + span: $DIR/thir-tree-array-index.rs:16:9: 16:10 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + } + } + } + } + rhs: + Expr { + ty: usize + temp_scope_id: 67 + span: $DIR/thir-tree-array-index.rs:16:14: 16:23 (#0) + kind: + Scope { + region_scope: Node(67) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).67) + value: + Expr { + ty: usize + temp_scope_id: 67 + span: $DIR/thir-tree-array-index.rs:16:14: 16:23 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 68 + span: $DIR/thir-tree-array-index.rs:16:14: 16:16 (#0) + kind: + Scope { + region_scope: Node(68) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).68) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 68 + span: $DIR/thir-tree-array-index.rs:16:14: 16:16 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 70 + span: $DIR/thir-tree-array-index.rs:16:17: 16:22 (#0) + kind: + Scope { + region_scope: Node(70) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).70) + value: + Expr { + ty: usize + temp_scope_id: 70 + span: $DIR/thir-tree-array-index.rs:16:17: 16:22 (#0) + kind: + Binary { + op: Sub + lhs: + Expr { + ty: usize + temp_scope_id: 71 + span: $DIR/thir-tree-array-index.rs:16:17: 16:18 (#0) + kind: + Scope { + region_scope: Node(71) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).71) + value: + Expr { + ty: usize + temp_scope_id: 71 + span: $DIR/thir-tree-array-index.rs:16:17: 16:18 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + rhs: + Expr { + ty: usize + temp_scope_id: 73 + span: $DIR/thir-tree-array-index.rs:16:21: 16:22 (#0) + kind: + Scope { + region_scope: Node(73) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).73) + value: + Expr { + ty: usize + temp_scope_id: 73 + span: $DIR/thir-tree-array-index.rs:16:21: 16:22 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(3), Unsuffixed), span: $DIR/thir-tree-array-index.rs:16:21: 16:22 (#0) }, neg: false) + + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(88) + expr: + Expr { + ty: usize + temp_scope_id: 75 + span: $DIR/thir-tree-array-index.rs:17:3: 17:24 (#0) + kind: + Scope { + region_scope: Node(75) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).75) + value: + Expr { + ty: usize + temp_scope_id: 75 + span: $DIR/thir-tree-array-index.rs:17:3: 17:24 (#0) + kind: + Index { + lhs: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 76 + span: $DIR/thir-tree-array-index.rs:17:3: 17:5 (#0) + kind: + Scope { + region_scope: Node(76) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).76) + value: + Expr { + ty: [usize; 5_usize] + temp_scope_id: 76 + span: $DIR/thir-tree-array-index.rs:17:3: 17:5 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).33)) + } + } + } + } + index: + Expr { + ty: usize + temp_scope_id: 78 + span: $DIR/thir-tree-array-index.rs:17:6: 17:23 (#0) + kind: + Scope { + region_scope: Node(78) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).78) + value: + Expr { + ty: usize + temp_scope_id: 78 + span: $DIR/thir-tree-array-index.rs:17:6: 17:23 (#0) + kind: + Binary { + op: Sub + lhs: + Expr { + ty: usize + temp_scope_id: 79 + span: $DIR/thir-tree-array-index.rs:17:6: 17:19 (#0) + kind: + Scope { + region_scope: Node(79) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).79) + value: + Expr { + ty: usize + temp_scope_id: 79 + span: $DIR/thir-tree-array-index.rs:17:6: 17:19 (#0) + kind: + Call { + ty: FnDef(DefId(0:3 ~ thir_tree_array_index[2569]::index), []) + from_hir_call: true + fn_span: $DIR/thir-tree-array-index.rs:17:6: 17:19 (#0) + fun: + Expr { + ty: FnDef(DefId(0:3 ~ thir_tree_array_index[2569]::index), []) + temp_scope_id: 80 + span: $DIR/thir-tree-array-index.rs:17:6: 17:11 (#0) + kind: + Scope { + region_scope: Node(80) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).80) + value: + Expr { + ty: FnDef(DefId(0:3 ~ thir_tree_array_index[2569]::index), []) + temp_scope_id: 80 + span: $DIR/thir-tree-array-index.rs:17:6: 17:11 (#0) + kind: + ZstLiteral(user_ty: None) + } + } + } + args: [ + Expr { + ty: usize + temp_scope_id: 82 + span: $DIR/thir-tree-array-index.rs:17:13: 17:18 (#0) + kind: + Scope { + region_scope: Node(82) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).82) + value: + Expr { + ty: usize + temp_scope_id: 82 + span: $DIR/thir-tree-array-index.rs:17:13: 17:18 (#0) + kind: + Binary { + op: Add + lhs: + Expr { + ty: usize + temp_scope_id: 83 + span: $DIR/thir-tree-array-index.rs:17:13: 17:14 (#0) + kind: + Scope { + region_scope: Node(83) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).83) + value: + Expr { + ty: usize + temp_scope_id: 83 + span: $DIR/thir-tree-array-index.rs:17:13: 17:14 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + rhs: + Expr { + ty: usize + temp_scope_id: 85 + span: $DIR/thir-tree-array-index.rs:17:17: 17:18 (#0) + kind: + Scope { + region_scope: Node(85) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).85) + value: + Expr { + ty: usize + temp_scope_id: 85 + span: $DIR/thir-tree-array-index.rs:17:17: 17:18 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/thir-tree-array-index.rs:17:17: 17:18 (#0) }, neg: false) + + } + } + } + } + } + } + } + ] + } + } + } + } + rhs: + Expr { + ty: usize + temp_scope_id: 86 + span: $DIR/thir-tree-array-index.rs:17:22: 17:23 (#0) + kind: + Scope { + region_scope: Node(86) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).86) + value: + Expr { + ty: usize + temp_scope_id: 86 + span: $DIR/thir-tree-array-index.rs:17:22: 17:23 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).2)) + } + } + } + } + } + } + } + } + } + } + } + } + } + } + ] + expr: + Expr { + ty: usize + temp_scope_id: 89 + span: $DIR/thir-tree-array-index.rs:19:3: 19:4 (#0) + kind: + Scope { + region_scope: Node(89) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).89) + value: + Expr { + ty: usize + temp_scope_id: 89 + span: $DIR/thir-tree-array-index.rs:19:3: 19:4 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(0), Unsuffixed), span: $DIR/thir-tree-array-index.rs:19:3: 19:4 (#0) }, neg: false) + + } + } + } + } + } + } + } + + +DefId(0:5 ~ thir_tree_array_index[2569]::indexing::{constant#0}): +params: [ +] +body: + Expr { + ty: usize + temp_scope_id: 8 + span: $DIR/thir-tree-array-index.rs:7:19: 7:20 (#0) + kind: + Scope { + region_scope: Node(8) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).8) + value: + Expr { + ty: usize + temp_scope_id: 8 + span: $DIR/thir-tree-array-index.rs:7:19: 7:20 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(5), Unsuffixed), span: $DIR/thir-tree-array-index.rs:7:19: 7:20 (#0) }, neg: false) + + } + } + } + + +DefId(0:7 ~ thir_tree_array_index[2569]::indexing::{constant#2}): +params: [ +] +body: + Expr { + ty: usize + temp_scope_id: 30 + span: $DIR/thir-tree-array-index.rs:8:28: 8:29 (#0) + kind: + Scope { + region_scope: Node(30) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).30) + value: + Expr { + ty: usize + temp_scope_id: 30 + span: $DIR/thir-tree-array-index.rs:8:28: 8:29 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(5), Unsuffixed), span: $DIR/thir-tree-array-index.rs:8:28: 8:29 (#0) }, neg: false) + + } + } + } + + +DefId(0:6 ~ thir_tree_array_index[2569]::indexing::{constant#1}): +params: [ +] +body: + Expr { + ty: usize + temp_scope_id: 23 + span: $DIR/thir-tree-array-index.rs:8:19: 8:20 (#0) + kind: + Scope { + region_scope: Node(23) + hir_id: HirId(DefId(0:4 ~ thir_tree_array_index[2569]::indexing).23) + value: + Expr { + ty: usize + temp_scope_id: 23 + span: $DIR/thir-tree-array-index.rs:8:19: 8:20 (#0) + kind: + Literal( lit: Spanned { node: Int(Pu128(5), Unsuffixed), span: $DIR/thir-tree-array-index.rs:8:19: 8:20 (#0) }, neg: false) + + } + } + } + + +DefId(0:8 ~ thir_tree_array_index[2569]::main): +params: [ +] +body: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-array-index.rs:22:11: 22:13 (#0) + kind: + Scope { + region_scope: Node(2) + hir_id: HirId(DefId(0:8 ~ thir_tree_array_index[2569]::main).2) + value: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-array-index.rs:22:11: 22:13 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-array-index.rs:22:11: 22:13 (#0) + region_scope: Node(1) + safety_mode: Safe + stmts: [] + expr: [] + } + } + } + } + + From 46ccd829eb45012d94bd701d982bb296fb64863b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Feb 2026 16:41:49 +1100 Subject: [PATCH 09/12] Fix bad key names in a couple of queries. Due to a bug, you can currently use `key` within the `desc` block and it'll just work regardless of what actual key name you specified. A subsequent commit will fix this, so let's correct the affected queries first. --- compiler/rustc_middle/src/queries.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index cb922a2ad90bd..e51514f29c254 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -589,7 +589,7 @@ rustc_queries! { } /// Checks whether a type is representable or infinitely sized - query representability(_: LocalDefId) -> rustc_middle::ty::Representability { + query representability(key: LocalDefId) -> rustc_middle::ty::Representability { desc { "checking if `{}` is representable", tcx.def_path_str(key) } // infinitely sized types will cause a cycle cycle_delay_bug @@ -600,7 +600,7 @@ rustc_queries! { } /// An implementation detail for the `representability` query - query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability { + query representability_adt_ty(key: Ty<'tcx>) -> rustc_middle::ty::Representability { desc { "checking if `{}` is representable", key } cycle_delay_bug anon From cb083142f215bf20c05e97a3ecddd15962d89707 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Feb 2026 16:48:05 +1100 Subject: [PATCH 10/12] Remove explicit `tcx` bindings from query `desc`s. Due to a bug they aren't actually necessary! (A few queries already take advantage of this, probably unintentionally.) And the next commit will remove support for explicit `tcx` bindings in favour of implicit. --- compiler/rustc_middle/src/queries.rs | 328 +++++++++++++-------------- 1 file changed, 164 insertions(+), 164 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index e51514f29c254..0cf15bd793a90 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -239,13 +239,13 @@ rustc_queries! { /// Avoid calling this query directly. query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache - desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } + desc { "getting HIR module items in `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } /// Returns HIR ID for the given `LocalDefId`. query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId { - desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } + desc { "getting HIR ID of `{}`", tcx.def_path_str(key) } feedable } @@ -254,7 +254,7 @@ rustc_queries! { /// This can be conveniently accessed by `tcx.hir_*` methods. /// Avoid calling this query directly. query hir_owner_parent_q(key: hir::OwnerId) -> hir::HirId { - desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } + desc { "getting HIR parent of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner. @@ -262,7 +262,7 @@ rustc_queries! { /// This can be conveniently accessed by `tcx.hir_*` methods. /// Avoid calling this query directly. query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> { - desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } + desc { "getting HIR owner items in `{}`", tcx.def_path_str(key) } feedable } @@ -271,7 +271,7 @@ rustc_queries! { /// This can be conveniently accessed by `tcx.hir_*` methods. /// Avoid calling this query directly. query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { - desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } + desc { "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } feedable } @@ -280,14 +280,14 @@ rustc_queries! { /// This can be conveniently accessed by `tcx.hir_*` methods. /// Avoid calling this query directly. query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx hir::lints::DelayedLints> { - desc { |tcx| "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) } + desc { "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) } } /// Returns the *default* of the const pararameter given by `DefId`. /// /// E.g., given `struct Ty;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } + desc { "computing the default for const parameter `{}`", tcx.def_path_str(param) } cache_on_disk_if { param.is_local() } separate_provide_extern } @@ -300,7 +300,7 @@ rustc_queries! { /// /// This query will ICE if given a const that is not marked with `type const`. query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing the type-level value for `{}`", tcx.def_path_str(def_id) } + desc { "computing the type-level value for `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } @@ -324,7 +324,7 @@ rustc_queries! { /// /// [alias type]: rustc_middle::ty::AliasTy query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - desc { |tcx| + desc { "{action} `{path}`", action = match tcx.def_kind(key) { DefKind::TyAlias => "expanding type alias", @@ -349,14 +349,14 @@ rustc_queries! { /// /// This query will panic if the given definition is not an opaque type. query type_of_opaque(key: DefId) -> Result>, CyclePlaceholder> { - desc { |tcx| + desc { "computing type of opaque `{path}`", path = tcx.def_path_str(key), } cycle_stash } query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - desc { |tcx| + desc { "computing type of opaque `{path}` via HIR typeck", path = tcx.def_path_str(key), } @@ -376,7 +376,7 @@ rustc_queries! { /// [free]: rustc_middle::ty::Free /// [alias type]: rustc_middle::ty::AliasTy query type_alias_is_lazy(key: DefId) -> bool { - desc { |tcx| + desc { "computing whether the type alias `{path}` is lazy", path = tcx.def_path_str(key), } @@ -400,7 +400,7 @@ rustc_queries! { query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet { arena_cache - desc { |tcx| + desc { "determining what parameters of `{}` can participate in unsizing", tcx.def_path_str(key), } @@ -409,7 +409,7 @@ rustc_queries! { /// The root query triggering all analysis passes like typeck or borrowck. query analysis(key: ()) { eval_always - desc { |tcx| + desc { "running analysis passes on crate `{}`", tcx.crate_name(LOCAL_CRATE), } @@ -436,7 +436,7 @@ rustc_queries! { /// Returns the *generics* of the definition given by `DefId`. query generics_of(key: DefId) -> &'tcx ty::Generics { - desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } + desc { "computing generics of `{}`", tcx.def_path_str(key) } arena_cache cache_on_disk_if { key.is_local() } separate_provide_extern @@ -451,7 +451,7 @@ rustc_queries! { /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print /// the result of this query for use in UI tests or for debugging purposes. query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } + desc { "computing predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } } @@ -459,7 +459,7 @@ rustc_queries! { key: LocalDefId ) -> &'tcx ty::List { desc { - |tcx| "computing the opaque types defined by `{}`", + "computing the opaque types defined by `{}`", tcx.def_path_str(key.to_def_id()) } } @@ -470,7 +470,7 @@ rustc_queries! { key: LocalDefId ) -> &'tcx ty::List { desc { - |tcx| "computing the coroutines defined within `{}`", + "computing the coroutines defined within `{}`", tcx.def_path_str(key.to_def_id()) } } @@ -494,7 +494,7 @@ rustc_queries! { /// // ^^^^^^^^^^^^^^^ /// ``` query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } + desc { "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable @@ -507,7 +507,7 @@ rustc_queries! { /// /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } + desc { "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable @@ -537,19 +537,19 @@ rustc_queries! { /// ] /// ``` query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } + desc { "elaborating item bounds for `{}`", tcx.def_path_str(key) } } query item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + desc { "elaborating item assumptions for `{}`", tcx.def_path_str(key) } } query item_non_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + desc { "elaborating item assumptions for `{}`", tcx.def_path_str(key) } } query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) } + desc { "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) } } /// Look up all native libraries this crate depends on. @@ -564,7 +564,7 @@ rustc_queries! { query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { arena_cache - desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } + desc { "looking up lint levels for `{}`", tcx.def_path_str(key) } } query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { @@ -578,7 +578,7 @@ rustc_queries! { } query expn_that_defined(key: DefId) -> rustc_span::ExpnId { - desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) } + desc { "getting the expansion that defined `{}`", tcx.def_path_str(key) } separate_provide_extern } @@ -619,7 +619,7 @@ rustc_queries! { query thir_body(key: LocalDefId) -> Result<(&'tcx Steal>, thir::ExprId), ErrorGuaranteed> { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash - desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } + desc { "building THIR for `{}`", tcx.def_path_str(key) } } /// Set of all the `DefId`s in this crate that have MIR associated with @@ -634,7 +634,7 @@ rustc_queries! { /// of the MIR const-checking pass. This is the set of qualifs in /// the final value of a `const`. query mir_const_qualif(key: DefId) -> mir::ConstQualifs { - desc { |tcx| "const checking `{}`", tcx.def_path_str(key) } + desc { "const checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -645,7 +645,7 @@ rustc_queries! { /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html query mir_built(key: LocalDefId) -> &'tcx Steal> { - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } + desc { "building MIR for `{}`", tcx.def_path_str(key) } feedable } @@ -654,20 +654,20 @@ rustc_queries! { key: DefId ) -> Result>>, ErrorGuaranteed> { desc { - |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key), + "building an abstract representation for `{}`", tcx.def_path_str(key), } separate_provide_extern } query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal> { no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } + desc { "elaborating drops for `{}`", tcx.def_path_str(key) } } query mir_for_ctfe( key: DefId ) -> &'tcx mir::Body<'tcx> { - desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) } + desc { "caching mir of `{}` for CTFE", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -677,12 +677,12 @@ rustc_queries! { &'tcx Steal>> ) { no_hash - desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } + desc { "promoting constants in MIR for `{}`", tcx.def_path_str(key) } } query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { desc { - |tcx| "finding symbols for captures of closure `{}`", + "finding symbols for captures of closure `{}`", tcx.def_path_str(key) } } @@ -696,19 +696,19 @@ rustc_queries! { /// For coroutines this only contains upvars that are shared by all states. query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec { arena_cache - desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } + desc { "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> { arena_cache - desc { |tcx| "coroutine witness types for `{}`", tcx.def_path_str(key) } + desc { "coroutine witness types for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) } + desc { "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) } return_result_from_ensure_ok } @@ -723,7 +723,7 @@ rustc_queries! { /// delay a bug if it does not. query check_potentially_region_dependent_goals(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { - |tcx| "reproving potentially region dependent HIR typeck goals for `{}", + "reproving potentially region dependent HIR typeck goals for `{}", tcx.def_path_str(key) } } @@ -731,7 +731,7 @@ rustc_queries! { /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { - desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) } + desc { "optimizing MIR for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -742,7 +742,7 @@ rustc_queries! { /// Returns `false` if `#[coverage(off)]` was found, or `true` if /// either `#[coverage(on)]` or no coverage attribute was found. query coverage_attr_on(key: LocalDefId) -> bool { - desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) } + desc { "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) } feedable } @@ -759,7 +759,7 @@ rustc_queries! { /// /// Returns `None` for functions that were not instrumented. query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> { - desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) } + desc { "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) } arena_cache } @@ -769,7 +769,7 @@ rustc_queries! { /// after inlining a body may refer to promoteds from other bodies. In that case you still /// need to use the `DefId` of the original body. query promoted_mir(key: DefId) -> &'tcx IndexVec> { - desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } + desc { "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -815,7 +815,7 @@ rustc_queries! { /// /// This query will panic if the given definition is not a trait. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } + desc { "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } /// Returns the explicitly user-written *predicates* of the definition given by `DefId` @@ -824,7 +824,7 @@ rustc_queries! { /// You should probably use [`Self::predicates_of`] unless you're looking for /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } + desc { "computing explicit predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable @@ -837,7 +837,7 @@ rustc_queries! { /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the /// result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { - desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } + desc { "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable @@ -851,7 +851,7 @@ rustc_queries! { /// because we must evaluate them even during type conversion, often before the full /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } + desc { "computing the super predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -863,7 +863,7 @@ rustc_queries! { /// associated type bounds. For trait aliases, currently, this includes all of the /// predicates of the trait alias. query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } + desc { "computing the implied predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -874,7 +874,7 @@ rustc_queries! { query explicit_supertraits_containing_assoc_item( key: (DefId, rustc_span::Ident) ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", + desc { "computing the super traits of `{}` with associated type name `{}`", tcx.def_path_str(key.0), key.1 } @@ -892,7 +892,7 @@ rustc_queries! { query const_conditions( key: DefId ) -> ty::ConstConditions<'tcx> { - desc { |tcx| "computing the conditions for `{}` to be considered const", + desc { "computing the conditions for `{}` to be considered const", tcx.def_path_str(key) } separate_provide_extern @@ -906,7 +906,7 @@ rustc_queries! { query explicit_implied_const_bounds( key: DefId ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { - desc { |tcx| "computing the implied `[const]` bounds for `{}`", + desc { "computing the implied `[const]` bounds for `{}`", tcx.def_path_str(key) } separate_provide_extern @@ -917,40 +917,40 @@ rustc_queries! { query type_param_predicates( key: (LocalDefId, LocalDefId, rustc_span::Ident) ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } + desc { "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } } query trait_def(key: DefId) -> &'tcx ty::TraitDef { - desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) } + desc { "computing trait definition for `{}`", tcx.def_path_str(key) } arena_cache cache_on_disk_if { key.is_local() } separate_provide_extern } query adt_def(key: DefId) -> ty::AdtDef<'tcx> { - desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) } + desc { "computing ADT definition for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } query adt_destructor(key: DefId) -> Option { - desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) } + desc { "computing `Drop` impl for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } query adt_async_destructor(key: DefId) -> Option { - desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } + desc { "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } query adt_sizedness_constraint( key: (DefId, SizedTraitKind) ) -> Option>> { - desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } + desc { "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } } query adt_dtorck_constraint( key: DefId ) -> &'tcx DropckConstraint<'tcx> { - desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } + desc { "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } /// Returns the constness of the function-like[^1] definition given by `DefId`. @@ -975,13 +975,13 @@ rustc_queries! { /// /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. query constness(key: DefId) -> hir::Constness { - desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } + desc { "checking if item is const: `{}`", tcx.def_path_str(key) } separate_provide_extern feedable } query asyncness(key: DefId) -> ty::Asyncness { - desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } + desc { "checking if the function is async: `{}`", tcx.def_path_str(key) } separate_provide_extern } @@ -993,7 +993,7 @@ rustc_queries! { /// function does not inspect the bits of any of its arguments (so is essentially just a /// constructor function). query is_promotable_const_fn(key: DefId) -> bool { - desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) } + desc { "checking if item is promotable: `{}`", tcx.def_path_str(key) } } /// The body of the coroutine, modified to take its upvars by move rather than by ref. @@ -1003,19 +1003,19 @@ rustc_queries! { /// is run right after building the initial MIR, and will only be populated for coroutines /// which come out of the async closure desugaring. query coroutine_by_move_body_def_id(def_id: DefId) -> DefId { - desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) } + desc { "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine. query coroutine_kind(def_id: DefId) -> Option { - desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) } + desc { "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) } separate_provide_extern feedable } query coroutine_for_closure(def_id: DefId) -> DefId { - desc { |_tcx| "Given a coroutine-closure def id, return the def id of the coroutine returned by it" } + desc { "Given a coroutine-closure def id, return the def id of the coroutine returned by it" } separate_provide_extern } @@ -1045,7 +1045,7 @@ rustc_queries! { /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the /// result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { - desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } + desc { "computing the variances of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern cycle_delay_bug @@ -1066,14 +1066,14 @@ rustc_queries! { /// Maps from an impl/trait or struct/variant `DefId` /// to a list of the `DefId`s of its associated items or fields. query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) } + desc { "collecting associated items or fields of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } /// Maps from a trait/impl item to the trait/impl item "descriptor". query associated_item(key: DefId) -> ty::AssocItem { - desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) } + desc { "computing associated item data for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable @@ -1082,7 +1082,7 @@ rustc_queries! { /// Collects the associated items defined on a trait or impl. query associated_items(key: DefId) -> &'tcx ty::AssocItems { arena_cache - desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } + desc { "collecting associated items of `{}`", tcx.def_path_str(key) } } /// Maps from associated items on a trait to the corresponding associated @@ -1108,20 +1108,20 @@ rustc_queries! { ///`{ trait_f: impl_f, trait_g: impl_g }` query impl_item_implementor_ids(impl_id: DefId) -> &'tcx DefIdMap { arena_cache - desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } + desc { "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } } /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id /// to its associated type items that correspond to the RPITITs in its signature. query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap> { arena_cache - desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) } + desc { "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) } separate_provide_extern } /// Given an `impl_id`, return the trait it implements along with some header information. query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { - desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } + desc { "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } cache_on_disk_if { impl_id.is_local() } separate_provide_extern } @@ -1130,35 +1130,35 @@ rustc_queries! { /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct /// whose tail is one of those types. query impl_self_is_guaranteed_unsized(impl_def_id: DefId) -> bool { - desc { |tcx| "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) } + desc { "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) } } /// Maps a `DefId` of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. query inherent_impls(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } + desc { "collecting inherent impls for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { - desc { |tcx| "collecting all inherent impls for `{:?}`", key } + desc { "collecting all inherent impls for `{:?}`", key } } /// Unsafety-check this `LocalDefId`. query check_transmutes(key: LocalDefId) { - desc { |tcx| "check transmute calls inside `{}`", tcx.def_path_str(key) } + desc { "check transmute calls inside `{}`", tcx.def_path_str(key) } } /// Unsafety-check this `LocalDefId`. query check_unsafety(key: LocalDefId) { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } + desc { "unsafety-checking `{}`", tcx.def_path_str(key) } } /// Checks well-formedness of tail calls (`become f()`). query check_tail_calls(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { - desc { |tcx| "tail-call-checking `{}`", tcx.def_path_str(key) } + desc { "tail-call-checking `{}`", tcx.def_path_str(key) } return_result_from_ensure_ok } @@ -1167,19 +1167,19 @@ rustc_queries! { /// Note that we've liberated the late bound regions of function signatures, so /// this can not be used to check whether these types are well formed. query assumed_wf_types(key: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] { - desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } + desc { "computing the implied bounds of `{}`", tcx.def_path_str(key) } } /// We need to store the assumed_wf_types for an RPITIT so that impls of foreign /// traits with return-position impl trait in traits can inherit the right wf types. query assumed_wf_types_for_rpitit(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] { - desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } + desc { "computing the implied bounds of `{}`", tcx.def_path_str(key) } separate_provide_extern } /// Computes the signature of the function. query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { - desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) } + desc { "computing function signature of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern cycle_delay_bug @@ -1187,7 +1187,7 @@ rustc_queries! { /// Performs lint checking for the module. query lint_mod(key: LocalModDefId) { - desc { |tcx| "linting {}", describe_as_module(key, tcx) } + desc { "linting {}", describe_as_module(key, tcx) } } query check_unused_traits(_: ()) { @@ -1196,21 +1196,21 @@ rustc_queries! { /// Checks the attributes in the module. query check_mod_attrs(key: LocalModDefId) { - desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } + desc { "checking attributes in {}", describe_as_module(key, tcx) } } /// Checks for uses of unstable APIs in the module. query check_mod_unstable_api_usage(key: LocalModDefId) { - desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } + desc { "checking for unstable API usage in {}", describe_as_module(key, tcx) } } query check_mod_privacy(key: LocalModDefId) { - desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } + desc { "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } } query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet { arena_cache - desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } } @@ -1226,7 +1226,7 @@ rustc_queries! { } query check_mod_deathness(key: LocalModDefId) { - desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } + desc { "checking deathness of variables in {}", describe_as_module(key, tcx) } } query check_type_wf(key: ()) -> Result<(), ErrorGuaranteed> { @@ -1236,24 +1236,24 @@ rustc_queries! { /// Caches `CoerceUnsized` kinds for impls on custom types. query coerce_unsized_info(key: DefId) -> Result { - desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } + desc { "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern return_result_from_ensure_ok } query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } + desc { "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { - desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } + desc { "finding used_trait_imports `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) } + desc { "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) } return_result_from_ensure_ok } @@ -1263,7 +1263,7 @@ rustc_queries! { &'tcx FxIndexMap>, ErrorGuaranteed > { - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } + desc { "borrow-checking `{}`", tcx.def_path_str(key) } } /// Gets a complete map from all types to their inherent impls. @@ -1304,7 +1304,7 @@ rustc_queries! { /// Checks whether all impls in the crate pass the overlap check, returning /// which impls fail it. If all impls are correct, the returned slice is empty. query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| + desc { "checking whether impl `{}` follows the orphan rules", tcx.def_path_str(key), } @@ -1316,7 +1316,7 @@ rustc_queries! { query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option> { cycle_fatal arena_cache - desc { |tcx| + desc { "computing (transitive) callees of `{}` that may recurse", tcx.def_path_str(key), } @@ -1326,7 +1326,7 @@ rustc_queries! { /// Obtain all the calls into other local functions query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] { cycle_fatal - desc { |tcx| + desc { "computing all local function calls in `{}`", tcx.def_path_str(key.def_id()), } @@ -1355,7 +1355,7 @@ rustc_queries! { /// query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { - desc { |tcx| + desc { "const-evaluating + checking `{}`", key.value.display(tcx) } @@ -1364,7 +1364,7 @@ rustc_queries! { /// Evaluate a static's initializer, returning the allocation of the initializer's memory. query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> { - desc { |tcx| + desc { "evaluating initializer of static `{}`", tcx.def_path_str(key) } @@ -1387,7 +1387,7 @@ rustc_queries! { /// [^1]: Such as enum variant explicit discriminants or array lengths. query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { - desc { |tcx| + desc { "simplifying constant for the type system `{}`", key.value.display(tcx) } @@ -1416,7 +1416,7 @@ rustc_queries! { } query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { - desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } + desc { "match-checking `{}`", tcx.def_path_str(key) } return_result_from_ensure_ok } @@ -1426,7 +1426,7 @@ rustc_queries! { desc { "checking effective visibilities" } } query check_private_in_public(module_def_id: LocalModDefId) { - desc { |tcx| + desc { "checking for private elements in public interfaces for {}", describe_as_module(module_def_id, tcx) } @@ -1441,14 +1441,14 @@ rustc_queries! { /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { - desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) } + desc { "computing drop scopes for `{}`", tcx.def_path_str(def_id) } } /// Generates a MIR body for the shim. query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { arena_cache desc { - |tcx| "generating MIR shim for `{}`, instance={:?}", + "generating MIR shim for `{}`, instance={:?}", tcx.def_path_str(key.def_id()), key } @@ -1463,7 +1463,7 @@ rustc_queries! { } query def_kind(def_id: DefId) -> DefKind { - desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } + desc { "looking up definition kind of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern feedable @@ -1471,7 +1471,7 @@ rustc_queries! { /// Gets the span for the definition. query def_span(def_id: DefId) -> Span { - desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) } + desc { "looking up span for `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern feedable @@ -1479,7 +1479,7 @@ rustc_queries! { /// Gets the span for the identifier of the definition. query def_ident_span(def_id: DefId) -> Option { - desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } + desc { "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern feedable @@ -1488,57 +1488,57 @@ rustc_queries! { /// Gets the span for the type of the definition. /// Panics if it is not a definition that has a single type. query ty_span(def_id: LocalDefId) -> Span { - desc { |tcx| "looking up span for `{}`'s type", tcx.def_path_str(def_id) } + desc { "looking up span for `{}`'s type", tcx.def_path_str(def_id) } cache_on_disk_if { true } } query lookup_stability(def_id: DefId) -> Option { - desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) } + desc { "looking up stability of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } query lookup_const_stability(def_id: DefId) -> Option { - desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) } + desc { "looking up const stability of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } query lookup_default_body_stability(def_id: DefId) -> Option { - desc { |tcx| "looking up default body stability of `{}`", tcx.def_path_str(def_id) } + desc { "looking up default body stability of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query should_inherit_track_caller(def_id: DefId) -> bool { - desc { |tcx| "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) } + desc { "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) } } query inherited_align(def_id: DefId) -> Option { - desc { |tcx| "computing inherited_align of `{}`", tcx.def_path_str(def_id) } + desc { "computing inherited_align of `{}`", tcx.def_path_str(def_id) } } query lookup_deprecation_entry(def_id: DefId) -> Option { - desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } + desc { "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } /// Determines whether an item is annotated with `#[doc(hidden)]`. query is_doc_hidden(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } + desc { "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } separate_provide_extern } /// Determines whether an item is annotated with `#[doc(notable_trait)]`. query is_doc_notable_trait(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } + desc { "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } } /// Returns the attributes on the item at `def_id`. /// /// Do not use this directly, use `tcx.get_attrs` instead. query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] { - desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) } + desc { "collecting attributes of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } @@ -1552,7 +1552,7 @@ rustc_queries! { /// Using this query would include the attribute regardless of the actual instance /// kind at the call site. query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs { - desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } + desc { "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } arena_cache cache_on_disk_if { def_id.is_local() } separate_provide_extern @@ -1560,11 +1560,11 @@ rustc_queries! { } query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet { - desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } + desc { "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } } query fn_arg_idents(def_id: DefId) -> &'tcx [Option] { - desc { |tcx| "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) } + desc { "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } @@ -1572,23 +1572,23 @@ rustc_queries! { /// Used by rustdoc. query rendered_const(def_id: DefId) -> &'tcx String { arena_cache - desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) } + desc { "rendering constant initializer of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } /// Gets the rendered precise capturing args for an opaque for use in rustdoc. query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind]> { - desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) } + desc { "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query impl_parent(def_id: DefId) -> Option { - desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } + desc { "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query is_mir_available(key: DefId) -> bool { - desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) } + desc { "checking if item has MIR available: `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -1596,25 +1596,25 @@ rustc_queries! { query own_existential_vtable_entries( key: DefId ) -> &'tcx [DefId] { - desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } + desc { "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } } query vtable_entries(key: ty::TraitRef<'tcx>) -> &'tcx [ty::VtblEntry<'tcx>] { - desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) } + desc { "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) } } query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize { - desc { |tcx| "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() } + desc { "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() } } query supertrait_vtable_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option { - desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable", + desc { "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable", key.1, key.0 } } query vtable_allocation(key: (Ty<'tcx>, Option>)) -> mir::interpret::AllocId { - desc { |tcx| "vtable const allocation for <{} as {}>", + desc { "vtable const allocation for <{} as {}>", key.0, key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or_else(|| "_".to_owned()) } @@ -1624,7 +1624,7 @@ rustc_queries! { key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { cache_on_disk_if { true } - desc { |tcx| "computing candidate for `{}`", key.value } + desc { "computing candidate for `{}`", key.value } } /// Return all `impl` blocks in the current crate. @@ -1640,19 +1640,19 @@ rustc_queries! { /// Given a trait `trait_id`, return all known `impl` blocks. query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls { arena_cache - desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) } + desc { "finding trait impls of `{}`", tcx.def_path_str(trait_id) } } query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { - desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } + desc { "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } cache_on_disk_if { true } return_result_from_ensure_ok } query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { - desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } + desc { "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } } query is_dyn_compatible(trait_id: DefId) -> bool { - desc { |tcx| "checking if trait `{}` is dyn-compatible", tcx.def_path_str(trait_id) } + desc { "checking if trait `{}` is dyn-compatible", tcx.def_path_str(trait_id) } } /// Gets the ParameterEnvironment for a given item; this environment @@ -1664,7 +1664,7 @@ rustc_queries! { /// you should also probably have a `ParamEnv` from when it was built. If you don't, /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly. query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> { - desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } + desc { "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } feedable } @@ -1672,7 +1672,7 @@ rustc_queries! { /// replaced with their hidden type. This is used in the old trait solver /// when in `PostAnalysis` mode and should not be called directly. query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> { - desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } + desc { "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, @@ -1733,7 +1733,7 @@ rustc_queries! { /// those types require drop. If the ADT is known to always need drop /// then `Err(AlwaysRequiresDrop)` is returned. query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` needs drop", tcx.def_path_str(def_id) } + desc { "computing when `{}` needs drop", tcx.def_path_str(def_id) } cache_on_disk_if { true } } @@ -1741,7 +1741,7 @@ rustc_queries! { /// those types require async drop. If the ADT is known to always need async drop /// then `Err(AlwaysRequiresDrop)` is returned. query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) } + desc { "computing when `{}` needs async drop", tcx.def_path_str(def_id) } cache_on_disk_if { true } } @@ -1752,7 +1752,7 @@ rustc_queries! { /// freeing up memory). If the ADT is known to have a significant destructor then /// `Err(AlwaysRequiresDrop)` is returned. query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) } + desc { "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) } } /// Returns a list of types which (a) have a potentially significant destructor @@ -1773,7 +1773,7 @@ rustc_queries! { /// because this query partially depends on that query. /// Otherwise, there is a risk of query cycles. query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List> { - desc { |tcx| "computing when `{}` has a significant destructor", ty.value } + desc { "computing when `{}` has a significant destructor", ty.value } } /// Computes the layout of a type. Note that this implicitly @@ -1849,7 +1849,7 @@ rustc_queries! { separate_provide_extern } query has_ffi_unwind_calls(key: LocalDefId) -> bool { - desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } + desc { "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } cache_on_disk_if { true } } query required_panic_strategy(_: CrateNum) -> Option { @@ -1895,24 +1895,24 @@ rustc_queries! { /// Returns whether the impl or associated function has the `default` keyword. /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`. query defaultness(def_id: DefId) -> hir::Defaultness { - desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) } + desc { "looking up whether `{}` has `default`", tcx.def_path_str(def_id) } separate_provide_extern feedable } /// Returns whether the field corresponding to the `DefId` has a default field value. query default_field(def_id: DefId) -> Option { - desc { |tcx| "looking up the `const` corresponding to the default for `{}`", tcx.def_path_str(def_id) } + desc { "looking up the `const` corresponding to the default for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } + desc { "checking that `{}` is well-formed", tcx.def_path_str(key) } return_result_from_ensure_ok } query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) } + desc { "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) } return_result_from_ensure_ok } @@ -1935,12 +1935,12 @@ rustc_queries! { separate_provide_extern } query is_reachable_non_generic(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } + desc { "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } query is_unreachable_local_definition(def_id: LocalDefId) -> bool { - desc { |tcx| + desc { "checking whether `{}` is reachable from outside the crate", tcx.def_path_str(def_id), } @@ -1968,7 +1968,7 @@ rustc_queries! { query upstream_monomorphizations_for(def_id: DefId) -> Option<&'tcx UnordMap, CrateNum>> { - desc { |tcx| + desc { "collecting available upstream monomorphizations for `{}`", tcx.def_path_str(def_id), } @@ -2086,13 +2086,13 @@ rustc_queries! { /// Do not call this directly, but instead use the `incoherent_impls` query. /// This query is only used to get the data necessary for that query. query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { - desc { |tcx| "collecting all impls for a type in a crate" } + desc { "collecting all impls for a type in a crate" } separate_provide_extern } /// Get the corresponding native library from the `native_libraries` query query native_library(def_id: DefId) -> Option<&'tcx NativeLib> { - desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } + desc { "getting the native library for `{}`", tcx.def_path_str(def_id) } } query inherit_sig_for_delegation_item(def_id: LocalDefId) -> &'tcx [Ty<'tcx>] { @@ -2104,13 +2104,13 @@ rustc_queries! { /// See `rustc_resolve::late::lifetimes` for details. query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars<'tcx> { arena_cache - desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) } + desc { "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) } } query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap { - desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) } + desc { "looking up a named region inside `{}`", tcx.def_path_str(owner_id) } } query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet> { - desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } + desc { "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } } /// Returns the *default lifetime* to be used if a trait object type were to be passed for /// the type parameter given by `DefId`. @@ -2132,7 +2132,7 @@ rustc_queries! { } query late_bound_vars_map(owner_id: hir::OwnerId) -> &'tcx SortedMap>> { - desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) } + desc { "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) } } /// For an opaque type, return the list of (captured lifetime, inner generic param). /// ```ignore (illustrative) @@ -2149,7 +2149,7 @@ rustc_queries! { /// ^^^^^^ captured lifetimes /// ``` query opaque_captured_lifetimes(def_id: LocalDefId) -> &'tcx [(ResolvedArg, LocalDefId)] { - desc { |tcx| "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) } + desc { "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) } } /// Computes the visibility of the provided `def_id`. @@ -2165,7 +2165,7 @@ rustc_queries! { /// /// In here, if you call `visibility` on `T`, it'll panic. query visibility(def_id: DefId) -> ty::Visibility { - desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } + desc { "computing visibility of `{}`", tcx.def_path_str(def_id) } separate_provide_extern feedable } @@ -2192,7 +2192,7 @@ rustc_queries! { separate_provide_extern } query module_children(def_id: DefId) -> &'tcx [ModChild] { - desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) } + desc { "collecting child items of module `{}`", tcx.def_path_str(def_id) } separate_provide_extern } @@ -2230,7 +2230,7 @@ rustc_queries! { } /// Whether the function is an intrinsic query intrinsic_raw(def_id: DefId) -> Option { - desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) } + desc { "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) } separate_provide_extern } /// Returns the lang items defined in another crate by loading it from metadata. @@ -2323,7 +2323,7 @@ rustc_queries! { } query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap> { - desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } + desc { "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } } /// All available crates in the graph, including those that should not be user-facing @@ -2406,7 +2406,7 @@ rustc_queries! { } query is_codegened_item(def_id: DefId) -> bool { - desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) } + desc { "determining whether `{}` needs codegen", tcx.def_path_str(def_id) } } query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> { @@ -2565,14 +2565,14 @@ rustc_queries! { } query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { - desc { |tcx| + desc { "checking impossible instantiated predicates: `{}`", tcx.def_path_str(key.0) } } query is_impossible_associated_item(key: (DefId, DefId)) -> bool { - desc { |tcx| + desc { "checking if `{}` is impossible to reference within `{}`", tcx.def_path_str(key.1), tcx.def_path_str(key.0), @@ -2674,12 +2674,12 @@ rustc_queries! { /// /// Any other def id will ICE. query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } + desc { "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } return_result_from_ensure_ok } query deduced_param_attrs(def_id: DefId) -> &'tcx [DeducedParamAttrs] { - desc { |tcx| "deducing parameter attributes for {}", tcx.def_path_str(def_id) } + desc { "deducing parameter attributes for {}", tcx.def_path_str(def_id) } separate_provide_extern } @@ -2736,12 +2736,12 @@ rustc_queries! { } query anon_const_kind(def_id: DefId) -> ty::AnonConstKind { - desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) } + desc { "looking up anon const kind of `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> { - desc { |tcx| "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } + desc { "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } @@ -2752,7 +2752,7 @@ rustc_queries! { /// /// Returns the sanitizer settings for this def. query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs { - desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } + desc { "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } feedable } @@ -2769,7 +2769,7 @@ rustc_queries! { } query is_rhs_type_const(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is a rhs type const", tcx.def_path_str(def_id) } + desc { "checking whether `{}` is a rhs type const", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern } From ecb778fc61906ea2e94247435e516c8fcbc124c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 20 Feb 2026 17:01:50 +1100 Subject: [PATCH 11/12] Remove explicit `tcx` bindings from `query` entries. As currently written, these have big problems. - `desc` and `cache_on_disk_if` modifiers use different syntaxes to introduce `tcx`. - `desc` is mis-implemented such that the explicit binding isn't even necessary and the key name can be botched, as the previous two commits showed. (It's the `let (#tcx, #key) = (tcx, key);` line that messes things up.) It's simpler and less error-prone to simply not require explicit `tcx` bindings, and instead just make it implicitly available to these code snippets. --- compiler/rustc_macros/src/query.rs | 45 ++++++++-------------------- compiler/rustc_middle/src/queries.rs | 12 +++++--- 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index d81bac4930a63..346604a46ef7d 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -103,13 +103,11 @@ impl Parse for List { struct Desc { modifier: Ident, - tcx_binding: Option, expr_list: Punctuated, } struct CacheOnDiskIf { modifier: Ident, - tcx_binding: Option, block: Block, } @@ -192,35 +190,16 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { if modifier == "desc" { // Parse a description modifier like: - // `desc { |tcx| "foo {}", tcx.item_path(key) }` + // `desc { "foo {}", tcx.item_path(key) }` let attr_content; braced!(attr_content in input); - let tcx_binding = if attr_content.peek(Token![|]) { - attr_content.parse::()?; - let tcx = attr_content.parse()?; - attr_content.parse::()?; - Some(tcx) - } else { - None - }; let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?; - try_insert!(desc = Desc { modifier, tcx_binding, expr_list }); + try_insert!(desc = Desc { modifier, expr_list }); } else if modifier == "cache_on_disk_if" { // Parse a cache-on-disk modifier like: - // - // `cache_on_disk_if { true }` - // `cache_on_disk_if { key.is_local() }` - // `cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }` - let tcx_binding = if input.peek(token::Paren) { - let args; - parenthesized!(args in input); - let tcx = Pat::parse_single(&args)?; - Some(tcx) - } else { - None - }; + // `cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) }` let block = input.parse()?; - try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, tcx_binding, block }); + try_insert!(cache_on_disk_if = CacheOnDiskIf { modifier, block }); } else if modifier == "arena_cache" { try_insert!(arena_cache = modifier); } else if modifier == "cycle_fatal" { @@ -313,24 +292,24 @@ fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) { erased_name.set_span(Span::call_site()); // Generate a function to check whether we should cache the query to disk, for some key. - if let Some(CacheOnDiskIf { tcx_binding, block, .. }) = modifiers.cache_on_disk_if.as_ref() { - let tcx = tcx_binding.as_ref().map(|t| quote! { #t }).unwrap_or_else(|| quote! { _ }); - // we're taking `key` by reference, but some rustc types usually prefer being passed by value + if let Some(CacheOnDiskIf { block, .. }) = modifiers.cache_on_disk_if.as_ref() { + // `pass_by_value`: some keys are marked with `rustc_pass_by_value`, but we take keys by + // reference here. + // FIXME: `pass_by_value` is badly named; `allow(rustc::pass_by_value)` actually means + // "allow pass by reference of `rustc_pass_by_value` types". streams.cache_on_disk_if_fns_stream.extend(quote! { #[allow(unused_variables, rustc::pass_by_value)] #[inline] - pub fn #erased_name<'tcx>(#tcx: TyCtxt<'tcx>, #key_pat: &crate::queries::#name::Key<'tcx>) -> bool + pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: &#key_ty) -> bool #block }); } - let Desc { tcx_binding, expr_list, .. } = &modifiers.desc; - let tcx = tcx_binding.as_ref().map_or_else(|| quote! { _ }, |t| quote! { #t }); + let Desc { expr_list, .. } = &modifiers.desc; let desc = quote! { #[allow(unused_variables)] - pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, key: #key_ty) -> String { - let (#tcx, #key_pat) = (tcx, key); + pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> String { format!(#expr_list) } }; diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 0cf15bd793a90..3a3a2743ec4f8 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -25,9 +25,13 @@ //! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros` //! The main modifiers are: //! -//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query. +//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required +//! for every query. The block should contain a `format!`-style string literal followed by +//! optional arguments. The query key identifier is available for use within the block, as is +//! `tcx`. //! - `arena_cache`: Use an arena for in-memory caching of the query result. -//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true. +//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to +//! true. The query key identifier is available for use within the block, as is `tcx`. //! - `cycle_fatal`: If a dependency cycle is detected, abort compilation with a fatal error. //! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately. //! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling. @@ -1211,7 +1215,7 @@ rustc_queries! { query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet { arena_cache desc { "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } - cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } + cache_on_disk_if { tcx.is_typeck_child(key.to_def_id()) } } /// Return the live symbols in the crate for dead code check. @@ -1244,7 +1248,7 @@ rustc_queries! { query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } + cache_on_disk_if { !tcx.is_typeck_child(key.to_def_id()) } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { From bde075b6f34b06938c4349832a593ef129d00a97 Mon Sep 17 00:00:00 2001 From: Makai Date: Sun, 22 Feb 2026 23:42:15 +0800 Subject: [PATCH 12/12] Fix ICE when an associated type or const is wrongly marked as `final` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr --- compiler/rustc_ast_lowering/src/item.rs | 15 +++++-- .../traits/final/final-on-assoc-type-const.rs | 12 +++++ .../final/final-on-assoc-type-const.stderr | 18 ++++++++ tests/ui/traits/final/positions.rs | 2 - tests/ui/traits/final/positions.stderr | 44 +++++-------------- 5 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 tests/ui/traits/final/final-on-assoc-type-const.rs create mode 100644 tests/ui/traits/final/final-on-assoc-type-const.stderr diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 8ae117f62786f..b63a7b25d197c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1088,9 +1088,18 @@ impl<'hir> LoweringContext<'_, 'hir> { } }; - let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value, || { - hir::Defaultness::Default { has_value } - }); + let defaultness = match i.kind.defaultness() { + // We do not yet support `final` on trait associated items other than functions. + // Even though we reject `final` on non-functions during AST validation, we still + // need to stop propagating it here because later compiler passes do not expect + // and cannot handle such items. + Defaultness::Final(..) if !matches!(i.kind, AssocItemKind::Fn(..)) => { + Defaultness::Implicit + } + defaultness => defaultness, + }; + let (defaultness, _) = self + .lower_defaultness(defaultness, has_value, || hir::Defaultness::Default { has_value }); let item = hir::TraitItem { owner_id: trait_item_def_id, diff --git a/tests/ui/traits/final/final-on-assoc-type-const.rs b/tests/ui/traits/final/final-on-assoc-type-const.rs new file mode 100644 index 0000000000000..9d20c0515476c --- /dev/null +++ b/tests/ui/traits/final/final-on-assoc-type-const.rs @@ -0,0 +1,12 @@ +// This is a regression test for . +#![feature(final_associated_functions)] +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] +trait Uwu { + final type Ovo; + //~^ error: `final` is only allowed on associated functions in traits + final type const QwQ: (); + //~^ error: `final` is only allowed on associated functions in traits +} + +fn main() {} diff --git a/tests/ui/traits/final/final-on-assoc-type-const.stderr b/tests/ui/traits/final/final-on-assoc-type-const.stderr new file mode 100644 index 0000000000000..ac2ab123e1d17 --- /dev/null +++ b/tests/ui/traits/final/final-on-assoc-type-const.stderr @@ -0,0 +1,18 @@ +error: `final` is only allowed on associated functions in traits + --> $DIR/final-on-assoc-type-const.rs:6:5 + | +LL | final type Ovo; + | -----^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/final-on-assoc-type-const.rs:8:5 + | +LL | final type const QwQ: (); + | -----^^^^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/final/positions.rs b/tests/ui/traits/final/positions.rs index 9bf659e12431e..4b8d9536ad4cf 100644 --- a/tests/ui/traits/final/positions.rs +++ b/tests/ui/traits/final/positions.rs @@ -38,11 +38,9 @@ final impl Trait for Foo { final type Foo = (); //~^ ERROR `final` is only allowed on associated functions in traits - //~^^ ERROR cannot override `Foo` because it already has a `final` definition in the trait final const FOO: usize = 1; //~^ ERROR `final` is only allowed on associated functions in traits - //~^^ ERROR cannot override `FOO` because it already has a `final` definition in the trait } diff --git a/tests/ui/traits/final/positions.stderr b/tests/ui/traits/final/positions.stderr index bcb300e49d1a9..ff19c01b39617 100644 --- a/tests/ui/traits/final/positions.stderr +++ b/tests/ui/traits/final/positions.stderr @@ -15,7 +15,7 @@ LL | final trait Trait { = note: only associated functions in traits can be `final` error: a static item cannot be `final` - --> $DIR/positions.rs:67:5 + --> $DIR/positions.rs:65:5 | LL | final static FOO_EXTERN: usize = 0; | ^^^^^ `final` because of this @@ -23,7 +23,7 @@ LL | final static FOO_EXTERN: usize = 0; = note: only associated functions in traits can be `final` error: an extern block cannot be `final` - --> $DIR/positions.rs:58:1 + --> $DIR/positions.rs:56:1 | LL | final unsafe extern "C" { | ^^^^^ `final` because of this @@ -87,7 +87,7 @@ LL | final type Foo = (); | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:43:5 + --> $DIR/positions.rs:42:5 | LL | final const FOO: usize = 1; | -----^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | final const FOO: usize = 1; | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:49:1 + --> $DIR/positions.rs:47:1 | LL | final fn foo() {} | -----^^^^^^^^^ @@ -103,7 +103,7 @@ LL | final fn foo() {} | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:52:1 + --> $DIR/positions.rs:50:1 | LL | final type FooTy = (); | -----^^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | final type FooTy = (); | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:55:1 + --> $DIR/positions.rs:53:1 | LL | final const FOO: usize = 0; | -----^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | final const FOO: usize = 0; | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:61:5 + --> $DIR/positions.rs:59:5 | LL | final fn foo_extern(); | -----^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | final fn foo_extern(); | `final` because of this error: `final` is only allowed on associated functions in traits - --> $DIR/positions.rs:64:5 + --> $DIR/positions.rs:62:5 | LL | final type FooExtern; | -----^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | final type FooExtern; | `final` because of this error: incorrect `static` inside `extern` block - --> $DIR/positions.rs:67:18 + --> $DIR/positions.rs:65:18 | LL | final unsafe extern "C" { | ----------------------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body @@ -159,29 +159,5 @@ note: `method` is marked final here LL | final fn method() {} | ^^^^^^^^^^^^^^^^^ -error: cannot override `Foo` because it already has a `final` definition in the trait - --> $DIR/positions.rs:39:5 - | -LL | final type Foo = (); - | ^^^^^^^^^^^^^^ - | -note: `Foo` is marked final here - --> $DIR/positions.rs:16:5 - | -LL | final type Foo = (); - | ^^^^^^^^^^^^^^ - -error: cannot override `FOO` because it already has a `final` definition in the trait - --> $DIR/positions.rs:43:5 - | -LL | final const FOO: usize = 1; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: `FOO` is marked final here - --> $DIR/positions.rs:19:5 - | -LL | final const FOO: usize = 1; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 21 previous errors +error: aborting due to 19 previous errors