Skip to content

Commit

Permalink
Auto merge of rust-lang#111641 - michaelwoerister:debugger-visualizer…
Browse files Browse the repository at this point in the history
…-fixes, r=cjgillot

Fix dependency tracking for debugger visualizers

This PR fixes dependency tracking for debugger visualizer files by changing the `debugger_visualizers` query to an `eval_always` query that scans the AST while it is still available. This way the set of visualizer files is already available when dep-info is emitted. Since the query is turned into an `eval_always` query, dependency tracking will now reliably detect changes to the visualizer script files themselves.

TODO:
 - [x] perf.rlo
 - [x] Needs a bit more documentation in some places
 - [x] Needs regression test for the incr. comp. case

Fixes rust-lang#111226
Fixes rust-lang#111227
Fixes rust-lang#111295

r? `@wesleywiser`
cc `@gibbyfree`
  • Loading branch information
bors committed May 19, 2023
2 parents 2d17294 + 987655a commit 17a6810
Show file tree
Hide file tree
Showing 27 changed files with 246 additions and 145 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use rustc_ast::attr;
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_middle::{bug, middle::debugger_visualizer::DebuggerVisualizerType};
use rustc_session::config::{CrateType, DebugInfo};
use rustc_span::symbol::sym;
use rustc_span::DebuggerVisualizerType;

/// Inserts a side-effect free instruction sequence that makes sure that the
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
Expand All @@ -21,7 +22,6 @@ use rustc_session::utils::NativeLibKind;
/// need out of the shared crate context before we get rid of it.
use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy};
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_metadata::EncodedMetadata;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_middle::middle::exported_symbols;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::middle::lang_items;
Expand All @@ -35,7 +36,6 @@ use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_target::abi::{Align, FIRST_VARIANT};

use std::collections::BTreeSet;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
use rustc_hir::def_id::CrateNum;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::query::{ExternProviders, Providers};
Expand All @@ -38,7 +39,6 @@ use rustc_session::cstore::{self, CrateSource};
use rustc_session::utils::NativeLibKind;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
use std::collections::BTreeSet;
use std::io;
use std::path::{Path, PathBuf};
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,11 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
files.push(normalize_path(profile_sample.as_path().to_path_buf()));
}

// Debugger visualizer files
for debugger_visualizer in tcx.debugger_visualizers(LOCAL_CRATE) {
files.push(normalize_path(debugger_visualizer.path.clone().unwrap()));
}

if sess.binary_dep_depinfo() {
if let Some(ref backend) = sess.opts.unstable_opts.codegen_backend {
if backend.contains('.') {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc_hir::diagnostic_items::DiagnosticItems;
use rustc_index::{Idx, IndexVec};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::ty::codec::TyDecoder;
Expand Down Expand Up @@ -958,7 +959,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess))
}

fn get_debugger_visualizers(self) -> Vec<rustc_span::DebuggerVisualizerFile> {
fn get_debugger_visualizers(self) -> Vec<DebuggerVisualizerFile> {
self.root.debugger_visualizers.decode(self).collect::<Vec<_>>()
}

Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::lang_items::LangItem;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo,
Expand All @@ -36,9 +37,7 @@ use rustc_session::config::{CrateType, OptLevel};
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
};
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::hash::Hash;
Expand Down Expand Up @@ -1855,7 +1854,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

fn encode_debugger_visualizers(&mut self) -> LazyArray<DebuggerVisualizerFile> {
empty_proc_macro!(self);
self.lazy_array(self.tcx.debugger_visualizers(LOCAL_CRATE).iter())
self.lazy_array(
self.tcx
.debugger_visualizers(LOCAL_CRATE)
.iter()
// Erase the path since it may contain privacy sensitive data
// that we don't want to end up in crate metadata.
// The path is only needed for the local crate because of
// `--emit dep-info`.
.map(DebuggerVisualizerFile::path_erased),
)
}

fn encode_crate_deps(&mut self) -> LazyArray<CrateDep> {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::creader::CrateMetadataRef;
use decoder::Metadata;
use def_path_hash_map::DefPathHashMapRef;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use table::TableBuilder;

use rustc_ast as ast;
Expand Down Expand Up @@ -245,7 +246,7 @@ pub(crate) struct CrateRoot {
proc_macro_data: Option<ProcMacroData>,

tables: LazyTables,
debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,
debugger_visualizers: LazyArray<DebuggerVisualizerFile>,

exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,

Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::hir::{ModuleItems, Owner};
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate;
use crate::ty::TyCtxt;
use rustc_ast as ast;
Expand Down Expand Up @@ -1165,11 +1166,26 @@ 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()
// We ignore the path to the visualizer file since it's not going to be
// encoded in crate metadata and we already hash the full contents of
// the file.
.map(DebuggerVisualizerFile::path_erased)
.collect();

let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
let mut stable_hasher = StableHasher::new();
hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher);
if tcx.sess.opts.incremental_relative_spans() {
let definitions = tcx.definitions_untracked();
let mut owner_spans: Vec<_> = krate
Expand Down
38 changes: 38 additions & 0 deletions compiler/rustc_middle/src/middle/debugger_visualizer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use rustc_data_structures::sync::Lrc;
use std::path::PathBuf;

#[derive(HashStable)]
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
pub enum DebuggerVisualizerType {
Natvis,
GdbPrettyPrinter,
}

/// A single debugger visualizer file.
#[derive(HashStable)]
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)]
pub struct DebuggerVisualizerFile {
/// The complete debugger visualizer source.
pub src: Lrc<[u8]>,
/// Indicates which visualizer type this targets.
pub visualizer_type: DebuggerVisualizerType,
/// The file path to the visualizer file. This is used for reporting
/// visualizer files in dep-info. Before it is written to crate metadata,
/// the path is erased to `None`, so as not to emit potentially privacy
/// sensitive data.
pub path: Option<PathBuf>,
}

impl DebuggerVisualizerFile {
pub fn new(src: Lrc<[u8]>, visualizer_type: DebuggerVisualizerType, path: PathBuf) -> Self {
DebuggerVisualizerFile { src, visualizer_type, path: Some(path) }
}

pub fn path_erased(&self) -> Self {
DebuggerVisualizerFile {
src: self.src.clone(),
visualizer_type: self.visualizer_type,
path: None,
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/middle/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod codegen_fn_attrs;
pub mod debugger_visualizer;
pub mod dependency_format;
pub mod exported_symbols;
pub mod lang_items;
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::infer::canonical::{self, Canonical};
use crate::lint::LintExpectation;
use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::EffectiveVisibilities;
Expand Down Expand Up @@ -1784,12 +1785,18 @@ rustc_queries! {
desc { "looking at the source for a crate" }
separate_provide_extern
}

/// Returns the debugger visualizers defined for this crate.
query debugger_visualizers(_: CrateNum) -> &'tcx Vec<rustc_span::DebuggerVisualizerFile> {
/// 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<DebuggerVisualizerFile> {
arena_cache
desc { "looking up the debugger visualizers for this crate" }
separate_provide_extern
eval_always
}

query postorder_cnums(_: ()) -> &'tcx [CrateNum] {
eval_always
desc { "generating a postorder list of CrateNums" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ trivially_parameterized_over_tcx! {
std::string::String,
crate::metadata::ModChild,
crate::middle::codegen_fn_attrs::CodegenFnAttrs,
crate::middle::debugger_visualizer::DebuggerVisualizerFile,
crate::middle::exported_symbols::SymbolExportInfo,
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
crate::mir::ConstQualifs,
Expand Down Expand Up @@ -91,7 +92,6 @@ trivially_parameterized_over_tcx! {
rustc_session::cstore::ForeignModule,
rustc_session::cstore::LinkagePreference,
rustc_session::cstore::NativeLib,
rustc_span::DebuggerVisualizerFile,
rustc_span::ExpnData,
rustc_span::ExpnHash,
rustc_span::ExpnId,
Expand Down
53 changes: 5 additions & 48 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{errors, fluent_generated as fluent};
use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan};
use rustc_expand::base::resolve_path;
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
Expand Down Expand Up @@ -1916,6 +1915,10 @@ impl CheckAttrVisitor<'_> {

/// Checks if the items on the `#[debugger_visualizer]` attribute are valid.
fn check_debugger_visualizer(&self, attr: &Attribute, target: Target) -> bool {
// Here we only check that the #[debugger_visualizer] attribute is attached
// to nothing other than a module. All other checks are done in the
// `debugger_visualizer` query where they need to be done for decoding
// anyway.
match target {
Target::Mod => {}
_ => {
Expand All @@ -1924,53 +1927,7 @@ impl CheckAttrVisitor<'_> {
}
}

let Some(hints) = attr.meta_item_list() else {
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
return false;
};

let hint = match hints.len() {
1 => &hints[0],
_ => {
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
return false;
}
};

let Some(meta_item) = hint.meta_item() else {
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: attr.span });
return false;
};

let visualizer_path = match (meta_item.name_or_empty(), meta_item.value_str()) {
(sym::natvis_file, Some(value)) => value,
(sym::gdb_script_file, Some(value)) => value,
(_, _) => {
self.tcx.sess.emit_err(errors::DebugVisualizerInvalid { span: meta_item.span });
return false;
}
};

let file =
match resolve_path(&self.tcx.sess.parse_sess, visualizer_path.as_str(), attr.span) {
Ok(file) => file,
Err(mut err) => {
err.emit();
return false;
}
};

match std::fs::File::open(&file) {
Ok(_) => true,
Err(error) => {
self.tcx.sess.emit_err(errors::DebugVisualizerUnreadable {
span: meta_item.span,
file: &file,
error,
});
false
}
}
true
}

/// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
Expand Down
Loading

0 comments on commit 17a6810

Please sign in to comment.