diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index cd6614a54a4..211f5cb0a2a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -58,7 +58,7 @@ use rustc_errors::{ use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::{Idx, IndexSlice, IndexVec}; @@ -435,6 +435,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_with_value().output_filenames(()); tcx.ensure_with_value().early_lint_checks(()); + tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE); let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal(); let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 66bdc9d2a3e..d5642ec3e0e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -572,12 +572,6 @@ fn resolver_for_lowering<'tcx>( // Make sure we don't mutate the cstore from here on. tcx.untracked().cstore.leak(); - { - let debugger_visualizers = rustc_passes::debugger_visualizer::collect(tcx.sess, &krate); - let feed = tcx.feed_local_crate(); - feed.debugger_visualizers(debugger_visualizers); - } - let ty::ResolverOutputs { global_ctxt: untracked_resolutions, ast_lowering: untracked_resolver_for_lowering, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index effa38dc2dc..276538c7ef2 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1165,6 +1165,11 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { source_file_names.sort_unstable(); + // We have to take care of debugger visualizers explicitly. The HIR (and + // thus `hir_body_hash`) contains the #[debugger_visualizer] attributes but + // these attributes only store the file path to the visualizer file, not + // their content. Yet that content is exported into crate metadata, so any + // changes to it need to be reflected in the crate hash. let debugger_visualizers: Vec<_> = tcx .debugger_visualizers(LOCAL_CRATE) .iter() diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3bf62db3135..a3877bff85f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1790,13 +1790,18 @@ rustc_queries! { desc { "looking at the source for a crate" } separate_provide_extern } + /// Returns the debugger visualizers defined for this crate. + /// NOTE: This query has to be marked `eval_always` because it reads data + /// directly from disk that is not tracked anywhere else. I.e. it + /// represents a genuine input to the query system. query debugger_visualizers(_: CrateNum) -> &'tcx Vec { arena_cache desc { "looking up the debugger visualizers for this crate" } separate_provide_extern - feedable + eval_always } + query postorder_cnums(_: ()) -> &'tcx [CrateNum] { eval_always desc { "generating a postorder list of CrateNums" } diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index d75258c0511..a55dad9ee43 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -3,6 +3,10 @@ use rustc_ast::Attribute; use rustc_data_structures::sync::Lrc; use rustc_expand::base::resolve_path; +use rustc_middle::{ + query::{LocalCrate, Providers}, + ty::TyCtxt, +}; use rustc_session::Session; use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType}; @@ -12,7 +16,7 @@ impl DebuggerVisualizerCollector<'_> { fn check_for_debugger_visualizer(&mut self, attr: &Attribute) { if attr.has_name(sym::debugger_visualizer) { let Some(hints) = attr.meta_item_list() else { - self.sess.emit_err(DebugVisualizerInvalid { span: attr.span }); + self.sess.emit_err(DebugVisualizerInvalid { span: attr.span }); return; }; @@ -82,12 +86,18 @@ impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> { } /// Traverses and collects the debugger visualizers for a specific crate. -pub fn collect(sess: &Session, krate: &rustc_ast::ast::Crate) -> Vec { - // Initialize the collector. - let mut visitor = DebuggerVisualizerCollector { sess, visualizers: Vec::new() }; +fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec { + let resolver_and_krate = tcx.resolver_for_lowering(()).borrow(); + let krate = &*resolver_and_krate.1; + + let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() }; rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate); // Sort the visualizers so we always get a deterministic query result. visitor.visualizers.sort_unstable(); visitor.visualizers } + +pub fn provide(providers: &mut Providers) { + providers.debugger_visualizers = debugger_visualizers; +} diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 5b1ed7f3fa4..0da4b294648 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -27,7 +27,7 @@ use rustc_middle::query::Providers; mod check_attr; mod check_const; pub mod dead; -pub mod debugger_visualizer; +mod debugger_visualizer; mod diagnostic_items; pub mod entry; mod errors; @@ -50,6 +50,7 @@ pub fn provide(providers: &mut Providers) { check_attr::provide(providers); check_const::provide(providers); dead::provide(providers); + debugger_visualizer::provide(providers); diagnostic_items::provide(providers); entry::provide(providers); lang_items::provide(providers);