Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dependency tracking for debugger visualizers #111641

Merged
merged 6 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -37,7 +38,6 @@ use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT
use rustc_session::cstore::{self, CrateSource};
use rustc_session::utils::NativeLibKind;
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 @@ -486,6 +486,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 @@ -18,6 +18,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 @@ -961,7 +962,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 @@ -1852,7 +1851,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 @@ -246,7 +247,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();
michaelwoerister marked this conversation as resolved.
Show resolved Hide resolved

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 @@ -1790,12 +1791,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