Skip to content

Commit 8437cef

Browse files
authored
Rollup merge of rust-lang#89476 - cjgillot:expn-id, r=petrochenkov
Correct decoding of foreign expansions during incr. comp. Fixes rust-lang#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.
2 parents 30fa4ad + 4028b09 commit 8437cef

File tree

5 files changed

+51
-19
lines changed

5 files changed

+51
-19
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
16321632
self.def_path_hash_map.def_path_hash_to_def_index(&hash)
16331633
}
16341634

1635-
fn expn_hash_to_expn_id(&self, index_guess: u32, hash: ExpnHash) -> ExpnId {
1635+
fn expn_hash_to_expn_id(&self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId {
16361636
debug_assert_eq!(ExpnId::from_hash(hash), None);
16371637
let index_guess = ExpnIndex::from_u32(index_guess);
16381638
let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self));
@@ -1654,16 +1654,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
16541654
let i = ExpnIndex::from_u32(i);
16551655
if let Some(hash) = self.root.expn_hashes.get(self, i) {
16561656
map.insert(hash.decode(self), i);
1657-
} else {
1658-
panic!("Missing expn_hash entry for {:?}", i);
16591657
}
16601658
}
16611659
map
16621660
});
16631661
map[&hash]
16641662
};
16651663

1666-
let data = self.root.expn_data.get(self, index).unwrap().decode(self);
1664+
let data = self.root.expn_data.get(self, index).unwrap().decode((self, sess));
16671665
rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash)
16681666
}
16691667

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,13 @@ impl CrateStore for CStore {
506506
DefId { krate: cnum, index: def_index }
507507
}
508508

509-
fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId {
510-
self.get_crate_data(cnum).expn_hash_to_expn_id(index_guess, hash)
509+
fn expn_hash_to_expn_id(
510+
&self,
511+
sess: &Session,
512+
cnum: CrateNum,
513+
index_guess: u32,
514+
hash: ExpnHash,
515+
) -> ExpnId {
516+
self.get_crate_data(cnum).expn_hash_to_expn_id(sess, index_guess, hash)
511517
}
512518
}

compiler/rustc_query_impl/src/on_disk_cache.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -664,22 +664,32 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
664664

665665
let data: ExpnData = decoder
666666
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))?;
667-
rustc_span::hygiene::register_local_expn_id(data, hash)
667+
let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);
668+
669+
#[cfg(debug_assertions)]
670+
{
671+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
672+
let mut hcx = decoder.tcx.create_stable_hashing_context();
673+
let mut hasher = StableHasher::new();
674+
hcx.while_hashing_spans(true, |hcx| {
675+
expn_id.expn_data().hash_stable(hcx, &mut hasher)
676+
});
677+
let local_hash: u64 = hasher.finish();
678+
debug_assert_eq!(hash.local_hash(), local_hash);
679+
}
680+
681+
expn_id
668682
} else {
669683
let index_guess = decoder.foreign_expn_data[&hash];
670-
decoder.tcx.cstore_untracked().expn_hash_to_expn_id(krate, index_guess, hash)
684+
decoder.tcx.cstore_untracked().expn_hash_to_expn_id(
685+
decoder.tcx.sess,
686+
krate,
687+
index_guess,
688+
hash,
689+
)
671690
};
672691

673-
#[cfg(debug_assertions)]
674-
{
675-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
676-
let mut hcx = decoder.tcx.create_stable_hashing_context();
677-
let mut hasher = StableHasher::new();
678-
hcx.while_hashing_spans(true, |hcx| expn_id.expn_data().hash_stable(hcx, &mut hasher));
679-
let local_hash: u64 = hasher.finish();
680-
debug_assert_eq!(hash.local_hash(), local_hash);
681-
}
682-
692+
debug_assert_eq!(expn_id.krate, krate);
683693
Ok(expn_id)
684694
}
685695
}

compiler/rustc_session/src/cstore.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
use crate::search_paths::PathKind;
66
use crate::utils::NativeLibKind;
7+
use crate::Session;
78
use rustc_ast as ast;
89
use rustc_data_structures::sync::{self, MetadataRef};
910
use rustc_hir::def_id::{CrateNum, DefId, StableCrateId, LOCAL_CRATE};
@@ -193,7 +194,13 @@ pub trait CrateStore: std::fmt::Debug {
193194

194195
/// Fetch a DefId from a DefPathHash for a foreign crate.
195196
fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId;
196-
fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId;
197+
fn expn_hash_to_expn_id(
198+
&self,
199+
sess: &Session,
200+
cnum: CrateNum,
201+
index_guess: u32,
202+
hash: ExpnHash,
203+
) -> ExpnId;
197204
}
198205

199206
pub type CrateStoreDyn = dyn CrateStore + sync::Sync;

src/test/incremental/mir-opt.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// MIR optimizations can create expansions after the TyCtxt has been created.
2+
// This test verifies that those expansions can be decoded correctly.
3+
4+
// revisions:rpass1 rpass2
5+
// compile-flags: -Z query-dep-graph -Z mir-opt-level=3
6+
7+
fn main() {
8+
if std::env::var("a").is_ok() {
9+
println!("b");
10+
}
11+
}

0 commit comments

Comments
 (0)