Rollup merge of #89476 - cjgillot:expn-id, r=petrochenkov
Correct decoding of foreign expansions during incr. comp. Fixes https://github.com/rust-lang/rust/issues/74946 The original issue was due to a wrong assertion in `expn_hash_to_expn_id`. The secondary issue was due to a mismatch between the encoding and decoding paths for expansions that are created after the TyCtxt is created.
This commit is contained in:
commit
aed1801841
5 changed files with 51 additions and 19 deletions
|
@ -1632,7 +1632,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
self.def_path_hash_map.def_path_hash_to_def_index(&hash)
|
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);
|
debug_assert_eq!(ExpnId::from_hash(hash), None);
|
||||||
let index_guess = ExpnIndex::from_u32(index_guess);
|
let index_guess = ExpnIndex::from_u32(index_guess);
|
||||||
let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self));
|
let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self));
|
||||||
|
@ -1654,8 +1654,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
let i = ExpnIndex::from_u32(i);
|
let i = ExpnIndex::from_u32(i);
|
||||||
if let Some(hash) = self.root.expn_hashes.get(self, i) {
|
if let Some(hash) = self.root.expn_hashes.get(self, i) {
|
||||||
map.insert(hash.decode(self), i);
|
map.insert(hash.decode(self), i);
|
||||||
} else {
|
|
||||||
panic!("Missing expn_hash entry for {:?}", i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
|
@ -1663,7 +1661,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
map[&hash]
|
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)
|
rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -506,7 +506,13 @@ impl CrateStore for CStore {
|
||||||
DefId { krate: cnum, index: def_index }
|
DefId { krate: cnum, index: def_index }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId {
|
fn expn_hash_to_expn_id(
|
||||||
self.get_crate_data(cnum).expn_hash_to_expn_id(index_guess, hash)
|
&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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,22 +664,32 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
||||||
|
|
||||||
let data: ExpnData = decoder
|
let data: ExpnData = decoder
|
||||||
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))?;
|
.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 {
|
} else {
|
||||||
let index_guess = decoder.foreign_expn_data[&hash];
|
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)]
|
debug_assert_eq!(expn_id.krate, krate);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(expn_id)
|
Ok(expn_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use crate::search_paths::PathKind;
|
use crate::search_paths::PathKind;
|
||||||
use crate::utils::NativeLibKind;
|
use crate::utils::NativeLibKind;
|
||||||
|
use crate::Session;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::sync::{self, MetadataRef};
|
use rustc_data_structures::sync::{self, MetadataRef};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, StableCrateId, LOCAL_CRATE};
|
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.
|
/// Fetch a DefId from a DefPathHash for a foreign crate.
|
||||||
fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId;
|
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;
|
pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
|
||||||
|
|
11
src/test/incremental/mir-opt.rs
Normal file
11
src/test/incremental/mir-opt.rs
Normal file
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue