Rollup merge of #147075 - Lysxia:no-panic-def-path-hash, r=petrochenkov
Make `def_path_hash_to_def_id` not panic when passed an invalid hash I'm using this function in a third-party application (Creusot) to access private items (by reverse engineering their hash). This works in the happy path, but it panics when an item does not exist. There is no way to hack it downstream because the hook `def_path_hash_to_def_id_extern` must always return a `DefId` and its implementation uses `def_path_hash_to_def_index` which is internal and which is where the panic happens.
This commit is contained in:
commit
a2b77d09d7
5 changed files with 10 additions and 9 deletions
|
|
@ -1555,7 +1555,7 @@ impl<'a> CrateMetadataRef<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn def_path_hash_to_def_index(self, hash: DefPathHash) -> DefIndex {
|
||||
fn def_path_hash_to_def_index(self, hash: DefPathHash) -> Option<DefIndex> {
|
||||
self.def_path_hash_map.def_path_hash_to_def_index(&hash)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -691,8 +691,8 @@ fn provide_cstore_hooks(providers: &mut Providers) {
|
|||
.get(&stable_crate_id)
|
||||
.unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"));
|
||||
assert_ne!(cnum, LOCAL_CRATE);
|
||||
let def_index = cstore.get_crate_data(cnum).def_path_hash_to_def_index(hash);
|
||||
DefId { krate: cnum, index: def_index }
|
||||
let def_index = cstore.get_crate_data(cnum).def_path_hash_to_def_index(hash)?;
|
||||
Some(DefId { krate: cnum, index: def_index })
|
||||
};
|
||||
|
||||
providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@ pub(crate) enum DefPathHashMapRef<'tcx> {
|
|||
|
||||
impl DefPathHashMapRef<'_> {
|
||||
#[inline]
|
||||
pub(crate) fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
|
||||
pub(crate) fn def_path_hash_to_def_index(
|
||||
&self,
|
||||
def_path_hash: &DefPathHash,
|
||||
) -> Option<DefIndex> {
|
||||
match *self {
|
||||
DefPathHashMapRef::OwnedFromMetadata(ref map) => {
|
||||
map.get(&def_path_hash.local_hash()).unwrap()
|
||||
}
|
||||
DefPathHashMapRef::OwnedFromMetadata(ref map) => map.get(&def_path_hash.local_hash()),
|
||||
DefPathHashMapRef::BorrowedFromTcx(_) => {
|
||||
panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ declare_hooks! {
|
|||
/// session, if it still exists. This is used during incremental compilation to
|
||||
/// turn a deserialized `DefPathHash` into its current `DefId`.
|
||||
/// Will fetch a DefId from a DefPathHash for a foreign crate.
|
||||
hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId;
|
||||
hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> Option<DefId>;
|
||||
|
||||
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
|
||||
/// can just link to the upstream crate and therefore don't need a mono item.
|
||||
|
|
|
|||
|
|
@ -2012,7 +2012,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
|
||||
Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
|
||||
} else {
|
||||
Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
|
||||
self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue