Skip to content

Commit 19112b3

Browse files
Convert crate hash to use metadata instead of HIR
1 parent 345a975 commit 19112b3

10 files changed

Lines changed: 357 additions & 192 deletions

File tree

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
324324

325325
tcx.ensure_ok().analysis(());
326326

327-
if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
328-
dump_feature_usage_metrics(tcx, metrics_dir);
329-
}
330-
331327
if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
332328
return early_exit();
333329
}
@@ -340,6 +336,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
340336

341337
let linker = Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend);
342338

339+
if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
340+
dump_feature_usage_metrics(tcx, metrics_dir);
341+
}
342+
343343
tcx.report_unused_features();
344344

345345
Some(linker)

compiler/rustc_interface/src/passes.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,13 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
951951
let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
952952

953953
let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default());
954-
let untracked =
955-
Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids };
954+
let untracked = Untracked {
955+
cstore,
956+
source_span: AppendOnlyIndexVec::new(),
957+
definitions,
958+
stable_crate_ids,
959+
local_crate_hash: OnceLock::new(),
960+
};
956961

957962
// We're constructing the HIR here; we don't care what we will
958963
// read, since we haven't even constructed the *input* to

compiler/rustc_metadata/src/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
5454
None
5555
};
5656

57-
if tcx.needs_metadata() {
57+
if tcx.needs_metadata() || tcx.needs_crate_hash() {
5858
encode_metadata(tcx, &metadata_filename, metadata_stub_filename.as_deref());
5959
} else {
6060
// Always create a file at `metadata_filename`, even if we have nothing to write to it.

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,4 +750,101 @@ fn provide_cstore_hooks(providers: &mut Providers) {
750750
cdata.imported_source_file(tcx, file_index as u32);
751751
}
752752
};
753+
754+
providers.queries.crate_hash = |tcx: TyCtxt<'_>, _: LocalCrate| {
755+
*tcx.untracked()
756+
.local_crate_hash
757+
.get()
758+
.expect("crate_hash(LOCAL_CRATE) called before metadata encoding")
759+
};
753760
}
761+
762+
/*pub(super) fn crate_hash(tcx: TyCtxt<'_>, cnum: rustc_hir::def_id::CrateNum) -> Svh {
763+
let cstore = CStore::from_tcx(tcx);
764+
let crate_data = cstore.get_crate_data(cnum);
765+
crate_data.root.header.hash
766+
767+
let upstream_crates = upstream_crates(tcx);
768+
769+
let resolutions = tcx.resolutions(());
770+
771+
// We hash the final, remapped names of all local source files so we
772+
// don't have to include the path prefix remapping commandline args.
773+
// If we included the full mapping in the SVH, we could only have
774+
// reproducible builds by compiling from the same directory. So we just
775+
// hash the result of the mapping instead of the mapping itself.
776+
let mut source_file_names: Vec<_> = tcx
777+
.sess
778+
.source_map()
779+
.files()
780+
.iter()
781+
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
782+
.map(|source_file| source_file.stable_id)
783+
.collect();
784+
785+
source_file_names.sort_unstable();
786+
787+
// We have to take care of debugger visualizers explicitly. The HIR (and
788+
// thus `hir_body_hash`) contains the #[debugger_visualizer] attributes but
789+
// these attributes only store the file path to the visualizer file, not
790+
// their content. Yet that content is exported into crate metadata, so any
791+
// changes to it need to be reflected in the crate hash.
792+
let debugger_visualizers: Vec<_> = tcx
793+
.debugger_visualizers(LOCAL_CRATE)
794+
.iter()
795+
// We ignore the path to the visualizer file since it's not going to be
796+
// encoded in crate metadata and we already hash the full contents of
797+
// the file.
798+
.map(DebuggerVisualizerFile::path_erased)
799+
.collect();
800+
801+
let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
802+
let mut stable_hasher = StableHasher::new();
803+
metadata_hash.hash_stable(&mut hcx, &mut stable_hasher);
804+
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
805+
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
806+
debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher);
807+
if tcx.sess.opts.incremental.is_some() {
808+
let definitions = tcx.untracked().definitions.freeze();
809+
let mut owner_spans: Vec<_> = tcx
810+
.hir_crate_items(())
811+
.definitions()
812+
.map(|def_id| {
813+
let def_path_hash = definitions.def_path_hash(def_id);
814+
let span = tcx.source_span(def_id);
815+
debug_assert_eq!(span.parent(), None);
816+
(def_path_hash, span)
817+
})
818+
.collect();
819+
owner_spans.sort_unstable_by_key(|bn| bn.0);
820+
owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
821+
}
822+
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
823+
tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
824+
// Hash visibility information since it does not appear in HIR.
825+
// FIXME: Figure out how to remove `visibilities_for_hashing` by hashing visibilities on
826+
// the fly in the resolver, storing only their accumulated hash in `ResolverGlobalCtxt`,
827+
// and combining it with other hashes here.
828+
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
829+
with_metavar_spans(|mspans| {
830+
mspans.freeze_and_get_read_spans().hash_stable(&mut hcx, &mut stable_hasher);
831+
});
832+
stable_hasher.finish()
833+
});
834+
835+
Svh::new(crate_hash)
836+
}
837+
838+
fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
839+
let mut upstream_crates: Vec<_> = tcx
840+
.crates(())
841+
.iter()
842+
.map(|&cnum| {
843+
let stable_crate_id = tcx.stable_crate_id(cnum);
844+
let hash = tcx.crate_hash(cnum);
845+
(stable_crate_id, hash)
846+
})
847+
.collect();
848+
upstream_crates.sort_unstable_by_key(|&(stable_crate_id, _)| stable_crate_id);
849+
upstream_crates
850+
}*/

0 commit comments

Comments
 (0)