rust-lang/rust · #162809

Remap local def ids for deterministic metadata encoding

aerooneqq · merged Oct 17, 202611 files · 308 + / 61 −
compiler/rustc_hir_id/src/definitions.rs14 + / 5 −
@@ -98,6 +98,9 @@ pub struct Definitions {     def_id_to_key: IndexVec<LocalDefId, DefKey>,     // We do only store the local hash, as all the definitions are from the current crate.     def_path_hashes: IndexVec<LocalDefId, Hash64>,+    // The first non deterministic def index, may correspond to non-allocated+    // def id, in this case `first_non_det_index.as_usize() == num_definitions`.+    first_non_det_index: Option<DefIndex>,     def_path_hash_to_index: DefPathToIndexMap, } @@ -302,13 +305,18 @@ pub enum DefPathData { }  impl Definitions {-    /// This function indicates that the order of def id allocations+    /// This function indicates that the def id allocations     /// may be non-deterministic after it was called.     pub fn commit_end_of_determinism(&mut self) {-        assert!(-            self.def_path_hash_to_index.after_parallel_alloc.replace(Default::default()).is_none(),-            "this function should be called only once"-        )+        let prev = self.def_path_hash_to_index.after_parallel_alloc.replace(Default::default());+        assert!(prev.is_none(), "this function should be called only once");++        let def_index = DefIndex::from_usize(self.def_id_to_key.len());+        self.first_non_det_index.replace(def_index);+    }++    pub fn first_non_det_index(&self) -> DefIndex {+        self.first_non_det_index.expect("must contain index")     }      #[inline(always)]@@ -362,6 +370,7 @@ impl Definitions {             def_path_hashes: Default::default(),             def_id_to_key: Default::default(),             def_path_hash_to_index: Default::default(),+            first_non_det_index: Default::default(),         };          // Create the root definition.
compiler/rustc_metadata/src/rmeta/decoder.rs4 + / 3 −
@@ -41,6 +41,7 @@ use tracing::debug;  use crate::creader::CStore; use crate::eii::EiiMapEncodedKeyValue;+use crate::rmeta::remapped_def_id::RemappedRawDefId; use crate::rmeta::table::IsDefault; use crate::rmeta::*; @@ -103,7 +104,7 @@ pub(crate) struct CrateMetadata {     /// FIXME: make type of the value `LazyArray<(DefIndex, Option<SimplifiedType>)>`     /// through transmuting or somehow else, as `LocalDefId` here should be `DefIndex`,     /// as it is from external crate.-    trait_impls: FxIndexMap<RawDefId, LazyArray<(LocalDefId, Option<SimplifiedType>)>>,+    trait_impls: FxIndexMap<RemappedRawDefId, LazyArray<(LocalDefId, Option<SimplifiedType>)>>,     /// Inherent impls which do not follow the normal coherence rules.     ///     /// These can be introduced using either `#![rustc_coherence_is_core]`@@ -2163,10 +2164,10 @@ impl CrateMetadata {      // Translate a DefId from the current compilation environment to a DefId     // for an external crate.-    fn reverse_translate_def_id(&self, did: DefId) -> Option<RawDefId> {+    fn reverse_translate_def_id(&self, did: DefId) -> Option<RemappedRawDefId> {         for (local, &global) in self.cnum_map.iter_enumerated() {             if global == did.krate {-                return Some(RawDefId { krate: local.as_u32(), index: did.index.as_u32() });+                return Some(RemappedRawDefId::new_unchecked(local.as_u32(), did.index.as_u32()));             }         } 
compiler/rustc_metadata/src/rmeta/encoder.rs41 + / 19 −
@@ -47,6 +47,7 @@ use twox_hash::XxHash3_128;  use crate::diagnostics::{FailCreateFileEncoder, FailWriteFile}; use crate::eii::EiiMapEncodedKeyValue;+use crate::rmeta::remapped_def_id::RemappedRawDefId; use crate::rmeta::*;  pub(super) struct EncodeContext<'a, 'tcx> {@@ -78,6 +79,7 @@ pub(super) struct EncodeContext<'a, 'tcx> {     hygiene_ctxt: Rc<RefCell<HygieneEncodeContext>>,     // Used for both `Symbol`s and `ByteSymbol`s.     symbol_index_table: FxHashMap<u32, usize>,+    local_defs_remapping: LocalDefsRemapping, }  /// If the current crate is a proc-macro, returns early with `LazyArray::default()`.@@ -164,6 +166,8 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {     }      fn encode_def_id(&mut self, def_id: DefId) {+        let def_id = self.local_defs_remapping.map_def_id(def_id);+         def_id.krate.encode(self);         self.emit_u32(def_id.index.as_u32());     }@@ -235,7 +239,7 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {     /// `LocalDefId` as a wrapper around def index we want to encode     /// def index only, so we override the encode implementation.     fn encode_local_def_id(&mut self, def_id: LocalDefId) {-        self.emit_u32(def_id.local_def_index.as_u32());+        self.emit_u32(self.local_defs_remapping.map_local_def_id(def_id).index.as_u32());     }      /// We override encoding logic for `DefKey` during metadata encoding,@@ -434,20 +438,23 @@ macro_rules! record_some_lazy {     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{         let value = $value;         let lazy = $self.lazy(value);-        $self.$tables.$table.set_some($def_id, lazy);+        let def_id = $self.local_defs_remapping.map_local_def_id($def_id);+        $self.$tables.$table.set_some(def_id, lazy);     }}; }  macro_rules! record_some {-    ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {-        $self.$tables.$table.set_some($def_id, $value)-    };+    ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{+        let def_id = $self.local_defs_remapping.map_local_def_id($def_id);+        $self.$tables.$table.set_some(def_id, $value)+    }}; }  macro_rules! record_value {-    ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {-        $self.$tables.$table.set($def_id, $value)-    };+    ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{+        let def_id = $self.local_defs_remapping.map_local_def_id($def_id);+        $self.$tables.$table.set(def_id, $value)+    }}; }  // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_array($value))`, which would@@ -456,15 +463,17 @@ macro_rules! record_array {     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{         let value = $value;         let lazy = $self.lazy_array(value);-        $self.$tables.$table.set_some($def_id, lazy);+        let def_id = $self.local_defs_remapping.map_local_def_id($def_id);+        $self.$tables.$table.set_some(def_id, lazy);     }}; }  macro_rules! record_defaulted_array {     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{         let value = $value;         let lazy = $self.lazy_array(value);-        $self.$tables.$table.set($def_id, lazy);+        let def_id = $self.local_defs_remapping.map_local_def_id($def_id);+        $self.$tables.$table.set(def_id, lazy);     }}; } @@ -566,10 +575,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {                 record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64())             }         } else {-            for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() {-                let def_id = LocalDefId { local_def_index: def_index };+            for def_id in self.local_defs_remapping.iter_sorted_local_ids() {+                let def_key = defs.def_key(def_id);+                let hash = defs.def_path_hash(def_id).local_hash().as_u64();+                 record_some_lazy!(self.tables.def_keys[def_id] <- def_key);-                record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64())+                record_value!(self.tables.def_path_hashes[def_id] <- hash);             }         }     }@@ -650,6 +661,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {      fn encode_crate_root(&mut self) -> (LazyValue<CrateRoot>, LazyValue<CrateRootUnhashed>) {         let tcx = self.tcx;++        // We set it here as we need it only for metadata encoding,+        // while `with_encode_metadata_header` is used in some other places too.+        self.local_defs_remapping = LocalDefsRemapping::new(tcx);+         let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32);          macro_rules! stat {@@ -1489,8 +1505,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {         }          let tcx = self.tcx;--        for local_id in tcx.iter_local_def_id() {+        for local_id in self.local_defs_remapping.iter_sorted_local_ids() {             let def_id = local_id.to_def_id();             let def_kind = tcx.def_kind(local_id);             record_some!(self.tables.def_kind[local_id] <- def_kind);@@ -1630,13 +1645,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {                 && tcx.type_of(def_id).skip_binder().is_coroutine_closure()             {                 let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id);-                record_some!(self.tables.coroutine_for_closure[local_id] <- coroutine_for_closure.into());+                let remapped_id =+                    RemappedRawDefId::create(coroutine_for_closure, &self.local_defs_remapping);++                record_some!(self.tables.coroutine_for_closure[local_id] <- remapped_id);                  // If this async closure has a by-move body, record it too.                 if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) {                     let id = self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure);+                    let id = RemappedRawDefId::create(id, &self.local_defs_remapping);+                     record_some!(-                        self.tables.coroutine_by_move_body_def_id[coroutine_for_closure.expect_local()] <- id.into()+                        self.tables.coroutine_by_move_body_def_id[coroutine_for_closure.expect_local()] <- id                     )                 }             }@@ -2325,7 +2345,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {                 if let Ok(mut an) = trait_def.ancestors(tcx, local_id.to_def_id())                     && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1)                 {-                    record_some!(self.tables.impl_parent[local_id] <- parent.into());+                    let parent = RemappedRawDefId::create(parent, &self.local_defs_remapping);+                    record_some!(self.tables.impl_parent[local_id] <- parent);                 }                  // if this is an impl of `CoerceUnsized`, create its@@ -2340,7 +2361,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {         let trait_impls: Vec<_> = trait_impls             .into_iter()             .map(|(trait_def_id, impls)| TraitImpls {-                trait_id: trait_def_id.into(),+                trait_id: RemappedRawDefId::create(trait_def_id, &self.local_defs_remapping),                 impls: self.lazy_array(&impls),             })             .collect();@@ -2734,6 +2755,7 @@ fn with_encode_metadata_header(         is_proc_macro: tcx.crate_types().contains(&CrateType::ProcMacro),         hygiene_ctxt: Default::default(),         symbol_index_table: Default::default(),+        local_defs_remapping: Default::default(),     };      // Encode the rustc version string in a predictable location.
compiler/rustc_metadata/src/rmeta/mod.rs181 + / 26 −
@@ -1,6 +1,7 @@ use std::marker::PhantomData; use std::mem::size_of; use std::num::NonZero;+use std::rc::Rc;  use decoder::LazyDecoder; pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers};@@ -22,11 +23,12 @@ use rustc_hir as hir; use rustc_hir::PreciseCapturingArgKind; use rustc_hir::def::{CtorKind, DefKind, MacroKinds}; use rustc_hir::def_id::{-    CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, LocalDefId, StableCrateId,+    CRATE_DEF_INDEX, CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, LOCAL_CRATE, LocalDefId,+    StableCrateId, }; use rustc_hir::definitions::DefKey;-use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet;+use rustc_index::{Idx, IndexVec}; use rustc_macros::{     BlobDecodable, Decodable, Encodable, LazyDecodable, MetadataEncodable, TyDecodable, TyEncodable, };@@ -52,6 +54,7 @@ use rustc_target::spec::{PanicStrategy, TargetTuple}; use table::TableBuilder;  use crate::eii::EiiMapEncodedKeyValue;+use crate::rmeta::remapped_def_id::RemappedRawDefId;  mod decoder; mod def_path_hash_map;@@ -340,27 +343,179 @@ pub(crate) struct CrateRootUnhashed {     dep_extra_filenames: IndexVec<CrateNum, String>, } -/// On-disk representation of `DefId`.-/// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk-/// representation and the compilation session.-#[derive(Copy, Clone, Hash, PartialEq, Eq, Encodable, BlobDecodable)]-pub(crate) struct RawDefId {-    krate: u32,-    index: u32,+#[derive(Default)]+pub(crate) struct LocalDefsRemapping {+    /// See `Definitions::first_non_det_index`, it is just cached version of it.+    pub first_non_det_index: u32,++    /// The map where for each non-det local def id the remapped def index+    /// is stored. It can be accessed by+    /// `remapping[id.local_def_index - first_non_det_index]`, the caller should+    /// ensure that `id.local_def_index >= first_non_det_index`.+    pub remapping: Vec<DefIndex>,++    /// The ordered list of NON-remapped non-det local def ids. This+    /// list is used when we need to iterate over all local defs in a+    /// stable order.+    pub sorted_non_det_ids: Rc<[LocalDefId]>, } -impl From<DefId> for RawDefId {-    fn from(val: DefId) -> Self {-        RawDefId { krate: val.krate.as_u32(), index: val.index.as_u32() }+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]+pub(crate) struct RemappedLocalDefId {+    pub index: DefIndex,+}++impl Idx for RemappedLocalDefId {+    #[inline]+    fn new(idx: usize) -> Self {+        RemappedLocalDefId { index: DefIndex::from_usize(idx) }+    }++    #[inline]+    fn index(self) -> usize {+        self.index.as_usize()+    }+}++impl LocalDefsRemapping {+    /// This method should be used whenever the `LocalDefId` is encoded, as it remaps+    /// it's `local_def_index` for deterministic metadata encoding, this+    /// remapping needs to be applied to all `LocalDefId`s during metadata encoding.+    /// Note that when implementing custom structs that represent `LocalDefId` the+    /// remapping should also be applied (see `RawDefId`).+    #[inline]+    fn map_local_def_id(&self, local_def_id: LocalDefId) -> RemappedLocalDefId {+        RemappedLocalDefId { index: self.map_index(local_def_id.local_def_index) }+    }++    /// Remaps `DefId` only if it local for deterministic metadata encoding. External+    /// def ids are not needed to be remapped as they are already deterministic.+    /// Whenever a `DefId` is encoded this method should be called.+    /// Note that when implementing custom structs that represent `DefId` the+    /// remapping should also be applied (see `RawDefId`).+    #[inline]+    fn map_def_id(&self, def_id: DefId) -> DefId {+        if def_id.is_local() {+            DefId { krate: LOCAL_CRATE, index: self.map_index(def_id.index) }+        } else {+            def_id+        }+    }++    /// Shared part of `map_local_def_id` and `map_def_id` which remaps a def index.+    /// Given only def index we do not know whether it belongs to local or external+    /// def id, so this method should not be called on `DefIndex`es whose origin is unknown.+    /// Prefer to use above-mentioned methods instead or use it when it is clear that+    /// `DefIndex` is local.+    #[inline]+    fn map_index(&self, def_index: DefIndex) -> DefIndex {+        let index = def_index.as_u32();++        if index < self.first_non_det_index {+            def_index+        } else {+            let shifted_idx = index - self.first_non_det_index;+            self.remapping[shifted_idx as usize]+        }+    }++    fn iter_sorted_local_ids(&self) -> impl Iterator<Item = LocalDefId> + use<> {+        let first_non_det_index = self.first_non_det_index;+        let non_det_part = Rc::clone(&self.sorted_non_det_ids);++        gen move {+            for i in 0..first_non_det_index {+                yield LocalDefId { local_def_index: DefIndex::from_u32(i) }+            }++            let len = non_det_part.len();+            for i in 0..len {+                yield non_det_part[i]+            }+        }+    }++    fn new(tcx: TyCtxt<'_>) -> LocalDefsRemapping {+        let defs = tcx.definitions();++        let mut non_det_ids = vec![];+        let start = defs.first_non_det_index().as_usize();+        let num_defs = defs.num_definitions();++        for idx in start..num_defs {+            let def_id_level = |mut id| {+                let mut level = 0;+                while let Some(parent) = tcx.opt_local_parent(id) {+                    level += 1;+                    id = parent;+                }++                level+            };++            let def_id = LocalDefId { local_def_index: idx.into() };+            non_det_ids.push((+                def_id,+                def_id_level(def_id),+                defs.def_path_hash(def_id).local_hash(),+            ));+        }++        // Sort by level first in order to satisfy the invariant that child def id+        // always has a higher def index than its parent (see `def_id_partial_cmp`),+        // in context of one level sort by stable hash. Ids from higher level will+        // get higher remapped def index.+        non_det_ids.sort_by_key(|(_, level, hash)| (*level, *hash));++        let mut remapping = vec![CRATE_DEF_INDEX; non_det_ids.len()];+        for (idx, (id, ..)) in non_det_ids.into_iter().enumerate() {+            remapping[id.local_def_index.as_usize() - start] = DefIndex::from_usize(start + idx);+        }++        let mut sorted_non_det_ids = (start..num_defs)+            .into_iter()+            .map(|idx| LocalDefId { local_def_index: DefIndex::from(idx) })+            .collect::<Vec<_>>();++        sorted_non_det_ids.sort_by_key(|id| remapping[id.local_def_index.as_usize() - start]);++        let sorted_non_det_ids = Rc::from(sorted_non_det_ids);+        LocalDefsRemapping { first_non_det_index: start as u32, remapping, sorted_non_det_ids }     } } -impl RawDefId {-    /// This exists so that `provide_one!` is happy-    fn decode(self, meta: (&CrateMetadata, TyCtxt<'_>)) -> DefId {-        let krate = CrateNum::from_u32(self.krate);-        let krate = meta.0.map_encoded_cnum_to_current(krate);-        DefId { krate, index: DefIndex::from_u32(self.index) }+pub(crate) mod remapped_def_id {+    use super::*;++    /// On-disk representation of `DefId`.+    /// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk+    /// representation and the compilation session.+    #[derive(Copy, Clone, Hash, PartialEq, Eq, Encodable, BlobDecodable)]+    pub(crate) struct RemappedRawDefId {+        krate: u32,+        index: u32,+    }++    impl RemappedRawDefId {+        pub(crate) fn new_unchecked(krate: u32, index: u32) -> RemappedRawDefId {+            RemappedRawDefId { krate, index }+        }++        pub(crate) fn create(def_id: DefId, remapping: &LocalDefsRemapping) -> RemappedRawDefId {+            let def_id = remapping.map_def_id(def_id);+            RemappedRawDefId { krate: def_id.krate.as_u32(), index: def_id.index.as_u32() }+        }++        /// This exists so that `provide_one!` is happy+        pub(crate) fn decode(self, meta: (&CrateMetadata, TyCtxt<'_>)) -> DefId {+            let krate = CrateNum::from_u32(self.krate);+            let krate = meta.0.map_encoded_cnum_to_current(krate);+            DefId { krate, index: DefIndex::from_u32(self.index) }+        }++        pub(crate) fn decompose(&self) -> (u32, u32) {+            (self.krate, self.index)+        }     } } @@ -379,7 +534,7 @@ pub(crate) struct CrateDep {  #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct TraitImpls {-    trait_id: RawDefId,+    trait_id: RemappedRawDefId,     impls: LazyArray<(LocalDefId, Option<SimplifiedType>)>, } @@ -397,14 +552,14 @@ macro_rules! define_tables {     ) => {         #[derive(MetadataEncodable, LazyDecodable)]         pub(crate) struct LazyTables {-            $($name1: LazyTable<LocalDefId, DefIndex, $T1>,)+-            $($name2: LazyTable<LocalDefId, DefIndex, Option<$T2>>,)++            $($name1: LazyTable<RemappedLocalDefId, DefIndex, $T1>,)++            $($name2: LazyTable<RemappedLocalDefId, DefIndex, Option<$T2>>,)+         }          #[derive(Default)]         struct TableBuilders {-            $($name1: TableBuilder<LocalDefId, DefIndex, $T1>,)+-            $($name2: TableBuilder<LocalDefId, DefIndex, Option<$T2>>,)++            $($name1: TableBuilder<RemappedLocalDefId, DefIndex, $T1>,)++            $($name2: TableBuilder<RemappedLocalDefId, DefIndex, Option<$T2>>,)+         }          impl TableBuilders {@@ -481,7 +636,7 @@ define_tables! {     mir_coroutine_witnesses: Table<LazyValue<mir::CoroutineLayout<'static>>>,     promoted_mir: Table<LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,     thir_abstract_const: Table<LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,-    impl_parent: Table<RawDefId>,+    impl_parent: Table<RemappedRawDefId>,     const_conditions: Table<LazyValue<ty::ConstConditions<'static>>>,     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?     coerce_unsized_info: Table<LazyValue<ty::adjustment::CoerceUnsizedInfo>>,@@ -490,10 +645,10 @@ define_tables! {     rendered_precise_capturing_args: Table<LazyArray<PreciseCapturingArgKind<Symbol, Symbol>>>,     fn_arg_idents: Table<LazyArray<Option<Ident>>>,     coroutine_kind: Table<hir::CoroutineKind>,-    coroutine_for_closure: Table<RawDefId>,+    coroutine_for_closure: Table<RemappedRawDefId>,     adt_destructor: Table<LazyValue<ty::Destructor>>,     adt_async_destructor: Table<LazyValue<ty::AsyncDestructor>>,-    coroutine_by_move_body_def_id: Table<RawDefId>,+    coroutine_by_move_body_def_id: Table<RemappedRawDefId>,     eval_static_initializer: Table<LazyValue<mir::interpret::ConstAllocation<'static>>>,     trait_def: Table<LazyValue<ty::TraitDef>>,     expn_that_defined: Table<LazyValue<ExpnId>>,
compiler/rustc_metadata/src/rmeta/parameterized.rs1 + / 1 −
@@ -81,9 +81,9 @@ trivially_parameterized_over_tcx! {     crate::rmeta::IncoherentImpls,     crate::rmeta::LocalDefId,     crate::rmeta::ProcMacroKind,-    crate::rmeta::RawDefId,     crate::rmeta::TraitImpls,     crate::rmeta::VariantData,+    crate::rmeta::remapped_def_id::RemappedRawDefId,     rustc_abi::ReprOptions,     rustc_ast::DelimArgs,     rustc_attr_ir::Attribute,
compiler/rustc_metadata/src/rmeta/table.rs5 + / 3 −
@@ -2,6 +2,7 @@ use rustc_hir::def::CtorOf; use rustc_index::Idx;  use crate::rmeta::decoder::MetaBlob;+use crate::rmeta::remapped_def_id::RemappedRawDefId; use crate::rmeta::*;  pub(super) trait IsDefault: Default {@@ -253,7 +254,7 @@ fixed_size_enum! { }  // We directly encode RawDefId because using a `LazyValue` would incur a 50% overhead in the worst case.-impl FixedSizeEncoding for Option<RawDefId> {+impl FixedSizeEncoding for Option<RemappedRawDefId> {     type ByteArray = [u8; 8];      #[inline]@@ -265,14 +266,15 @@ impl FixedSizeEncoding for Option<RawDefId> {         }         let index = u32::from_le_bytes(index); -        Some(RawDefId { krate: krate - 1, index })+        Some(RemappedRawDefId::new_unchecked(krate - 1, index))     }      #[inline]     fn write_to_bytes(self, dest: &mut [u8; 8]) {         match self {             None => unreachable!(),-            Some(RawDefId { krate, index }) => {+            Some(id) => {+                let (krate, index) = id.decompose();                 debug_assert!(krate < u32::MAX);                 // CrateNum is less than `CrateNum::MAX_AS_U32`.                 let krate = (krate + 1).to_le_bytes();
compiler/rustc_monomorphize/src/offload/manifest.rs3 + / 4 −
@@ -119,8 +119,8 @@ impl<'a, 'tcx> SpanEncoder for OffloadManifestEncoder<'a, 'tcx> {         self.tcx.stable_crate_id(crate_num).encode(self);     } -    fn encode_def_index(&mut self, def_index: rustc_span::def_id::DefIndex) {-        def_index.as_u32().encode(self);+    fn encode_def_index(&mut self, _: rustc_span::def_id::DefIndex) {+        panic!("encode def id instead")     }      fn encode_def_id(&mut self, def_id: rustc_span::def_id::DefId) {@@ -287,8 +287,7 @@ impl<'a, 'tcx> BlobDecoder for OffloadManifestDecoder<'a, 'tcx> {     }      fn decode_def_index(&mut self) -> rustc_span::def_id::DefIndex {-        let v = self.read_u32();-        rustc_span::def_id::DefIndex::from_u32(v)+        panic!("can't decode def indices as we do not encode them")     }      fn decode_local_def_id(&mut self) -> rustc_hir::def_id::LocalDefId {
tests/run-make/parallel-reproducible-build/async-fns-issue-162202.rsadded3 + / 0 −
@@ -0,0 +1,3 @@+async fn test1(_: &'_ u8) {}+async fn test2<'s>(_: &'s u8) {}+fn main() {}
tests/run-make/parallel-reproducible-build/rmake.rs33 + / 0 −
@@ -14,6 +14,39 @@ fn main() {     const TESTS: &[(&str, &[&str])] = &[         ("static-muts-issue-140413", &["-Zthreads=50"]),         ("derives-issue-129094", &["-Zthreads=16", "-Copt-level=3"]),+        (+            "async-fns-issue-162202",+            &[+                "-Zthreads=30",+                "--crate-type=lib",+                "--crate-name=test",+                "-Ccodegen-units=1",+                "-Zremap-cwd-prefix=reproducible_dir",+                "--edition=2024",+            ],+        ),+        (+            "rpit-issue-162202",+            &[+                "-Zthreads=30",+                "--crate-type=lib",+                "--crate-name=test",+                "-Ccodegen-units=1",+                "-Zremap-cwd-prefix=reproducible_dir",+                "--edition=2024",+            ],+        ),+        (+            "static-muts-lib-issue-162203",+            &[+                "-Zthreads=30",+                "--edition=2024",+                "-Zremap-cwd-prefix=reproducible_dir",+                "--cap-lints=warn",+                "-Ccodegen-units=1",+                "-Clink-dead-code=true",+            ],+        ),     ];      for (file, args) in TESTS {
tests/run-make/parallel-reproducible-build/rpit-issue-162202.rsadded19 + / 0 −
@@ -0,0 +1,19 @@+trait Foo {+    fn test() -> impl IntoIterator<Item = ()> + Send;+}++struct A;+impl Foo for A {+    fn test() -> impl IntoIterator<Item = ()> + Send {+        []+    }+}++struct B;+impl Foo for B {+    fn test() -> impl IntoIterator<Item = ()> + Send {+        []+    }+}++fn main() {}
tests/run-make/parallel-reproducible-build/static-muts-lib-issue-162203.rsadded4 + / 0 −
@@ -0,0 +1,4 @@+#![crate_type = "lib"]+static mut TEST: &'static mut [isize] = &mut [1];+static mut TEST_RAW: *mut [isize] = &mut [1isize] as *mut _;+pub fn main() {}