From ce21756ed3acdd6bb4c222725214c24e1bc70915 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Oct 2021 17:35:27 +0200 Subject: [PATCH 1/3] Access Session while decoding expn_id. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 ++-- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 10 ++++++++-- compiler/rustc_query_impl/src/on_disk_cache.rs | 7 ++++++- compiler/rustc_session/src/cstore.rs | 9 ++++++++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 08fc11f21d94e..ffb7fdacd2275 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1624,7 +1624,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.def_path_hash_map.def_path_hash_to_def_index(&hash) } - fn expn_hash_to_expn_id(&self, index_guess: u32, hash: ExpnHash) -> ExpnId { + fn expn_hash_to_expn_id(&self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId { debug_assert_eq!(ExpnId::from_hash(hash), None); let index_guess = ExpnIndex::from_u32(index_guess); let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self)); @@ -1655,7 +1655,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { map[&hash] }; - let data = self.root.expn_data.get(self, index).unwrap().decode(self); + let data = self.root.expn_data.get(self, index).unwrap().decode((self, sess)); rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 292ef03d856d9..4e7f85d2c3727 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -506,7 +506,13 @@ impl CrateStore for CStore { DefId { krate: cnum, index: def_index } } - fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId { - self.get_crate_data(cnum).expn_hash_to_expn_id(index_guess, hash) + fn expn_hash_to_expn_id( + &self, + sess: &Session, + cnum: CrateNum, + index_guess: u32, + hash: ExpnHash, + ) -> ExpnId { + self.get_crate_data(cnum).expn_hash_to_expn_id(sess, index_guess, hash) } } diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index d8cff0bd1880f..f93623e445c22 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -667,7 +667,12 @@ impl<'a, 'tcx> Decodable> for ExpnId { rustc_span::hygiene::register_local_expn_id(data, hash) } else { let index_guess = decoder.foreign_expn_data[&hash]; - decoder.tcx.cstore_untracked().expn_hash_to_expn_id(krate, index_guess, hash) + decoder.tcx.cstore_untracked().expn_hash_to_expn_id( + decoder.tcx.sess, + krate, + index_guess, + hash, + ) }; #[cfg(debug_assertions)] diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 9d6bd20103989..59e7abc2ea3bd 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -4,6 +4,7 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; +use crate::Session; use rustc_ast as ast; use rustc_data_structures::sync::{self, MetadataRef}; use rustc_hir::def_id::{CrateNum, DefId, StableCrateId, LOCAL_CRATE}; @@ -193,7 +194,13 @@ pub trait CrateStore: std::fmt::Debug { /// Fetch a DefId from a DefPathHash for a foreign crate. fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId; - fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId; + fn expn_hash_to_expn_id( + &self, + sess: &Session, + cnum: CrateNum, + index_guess: u32, + hash: ExpnHash, + ) -> ExpnId; } pub type CrateStoreDyn = dyn CrateStore + sync::Sync; From daf8903e8ed1f4704077e02479f841b84ebc82d3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Oct 2021 21:14:52 +0200 Subject: [PATCH 2/3] Do not re-hash foreign spans. --- .../rustc_query_impl/src/on_disk_cache.rs | 27 +++++++++++-------- src/test/incremental/mir-opt.rs | 11 ++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 src/test/incremental/mir-opt.rs diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index f93623e445c22..48eb488792d89 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -664,7 +664,21 @@ impl<'a, 'tcx> Decodable> for ExpnId { let data: ExpnData = decoder .with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))?; - rustc_span::hygiene::register_local_expn_id(data, hash) + let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash); + + #[cfg(debug_assertions)] + { + use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; + let mut hcx = decoder.tcx.create_stable_hashing_context(); + let mut hasher = StableHasher::new(); + hcx.while_hashing_spans(true, |hcx| { + expn_id.expn_data().hash_stable(hcx, &mut hasher) + }); + let local_hash: u64 = hasher.finish(); + debug_assert_eq!(hash.local_hash(), local_hash); + } + + expn_id } else { let index_guess = decoder.foreign_expn_data[&hash]; decoder.tcx.cstore_untracked().expn_hash_to_expn_id( @@ -675,16 +689,7 @@ impl<'a, 'tcx> Decodable> for ExpnId { ) }; - #[cfg(debug_assertions)] - { - use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; - let mut hcx = decoder.tcx.create_stable_hashing_context(); - let mut hasher = StableHasher::new(); - hcx.while_hashing_spans(true, |hcx| expn_id.expn_data().hash_stable(hcx, &mut hasher)); - let local_hash: u64 = hasher.finish(); - debug_assert_eq!(hash.local_hash(), local_hash); - } - + debug_assert_eq!(expn_id.krate, krate); Ok(expn_id) } } diff --git a/src/test/incremental/mir-opt.rs b/src/test/incremental/mir-opt.rs new file mode 100644 index 0000000000000..5bd863439df5d --- /dev/null +++ b/src/test/incremental/mir-opt.rs @@ -0,0 +1,11 @@ +// MIR optimizations can create expansions after the TyCtxt has been created. +// This test verifies that those expansions can be decoded correctly. + +// revisions:rpass1 rpass2 +// compile-flags: -Z query-dep-graph -Z mir-opt-level=3 + +fn main() { + if std::env::var("a").is_ok() { + println!("b"); + } +} From 4028b093e468afad4896a1658924e3e3f3b8f57c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Oct 2021 22:55:04 +0200 Subject: [PATCH 3/3] Do not ICE if some foreign expansions were not encoded. The metadata encoder does not necessarily encode all expansions, only those which are referenced in other metadata fields. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ffb7fdacd2275..9b97d1a476210 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1646,8 +1646,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let i = ExpnIndex::from_u32(i); if let Some(hash) = self.root.expn_hashes.get(self, i) { map.insert(hash.decode(self), i); - } else { - panic!("Missing expn_hash entry for {:?}", i); } } map