Skip to content

Commit 4171895

Browse files
Convert crate hash to use metadata instead of HIR
1 parent 4c42051 commit 4171895

10 files changed

Lines changed: 354 additions & 190 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
@@ -950,8 +950,13 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
950950
let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
951951

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

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

0 commit comments

Comments
 (0)