From d8980d3e2828fb29ad2ebdd14f5fdae07961eee1 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Sat, 17 Oct 2026 13:59:03 +0000 Subject: [PATCH] Remap local def ids for deterministic metadata encoding --- compiler/rustc_hir_id/src/definitions.rs | 19 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 7 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 60 +++-- compiler/rustc_metadata/src/rmeta/mod.rs | 207 +++++++++++++++--- .../rustc_metadata/src/rmeta/parameterized.rs | 2 +- compiler/rustc_metadata/src/rmeta/table.rs | 8 +- .../src/offload/manifest.rs | 7 +- .../async-fns-issue-162202.rs | 3 + .../parallel-reproducible-build/rmake.rs | 33 +++ .../rpit-issue-162202.rs | 19 ++ .../static-muts-lib-issue-162203.rs | 4 + 11 files changed, 308 insertions(+), 61 deletions(-) create mode 100644 tests/run-make/parallel-reproducible-build/async-fns-issue-162202.rs create mode 100644 tests/run-make/parallel-reproducible-build/rpit-issue-162202.rs create mode 100644 tests/run-make/parallel-reproducible-build/static-muts-lib-issue-162203.rs diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 92c8aeb43f283..557b87bedff85 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -98,6 +98,9 @@ pub struct Definitions { def_id_to_key: IndexVec, // We do only store the local hash, as all the definitions are from the current crate. def_path_hashes: IndexVec, + // 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, 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. diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 5705831bcfaee..f68cfcc0d388b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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)>` /// through transmuting or somehow else, as `LocalDefId` here should be `DefIndex`, /// as it is from external crate. - trait_impls: FxIndexMap)>>, + trait_impls: FxIndexMap)>>, /// 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 { + fn reverse_translate_def_id(&self, did: DefId) -> Option { 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())); } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f9f4c52b79d3b..2970bc0b7ed78 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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>, // Used for both `Symbol`s and `ByteSymbol`s. symbol_index_table: FxHashMap, + 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,7 +463,8 @@ 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); }}; } @@ -464,7 +472,8 @@ 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, LazyValue) { 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. diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index eef513382b57e..e0356d75c0a85 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -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, } -/// 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, + + /// 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 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 + 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::>(); + + 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)>, } @@ -397,14 +552,14 @@ macro_rules! define_tables { ) => { #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct LazyTables { - $($name1: LazyTable,)+ - $($name2: LazyTable>,)+ + $($name1: LazyTable,)+ + $($name2: LazyTable>,)+ } #[derive(Default)] struct TableBuilders { - $($name1: TableBuilder,)+ - $($name2: TableBuilder>,)+ + $($name1: TableBuilder,)+ + $($name2: TableBuilder>,)+ } impl TableBuilders { @@ -481,7 +636,7 @@ define_tables! { mir_coroutine_witnesses: Table>>, promoted_mir: Table>>>, thir_abstract_const: Table>>>, - impl_parent: Table, + impl_parent: Table, const_conditions: Table>>, // FIXME(eddyb) perhaps compute this on the fly if cheap enough? coerce_unsized_info: Table>, @@ -490,10 +645,10 @@ define_tables! { rendered_precise_capturing_args: Table>>, fn_arg_idents: Table>>, coroutine_kind: Table, - coroutine_for_closure: Table, + coroutine_for_closure: Table, adt_destructor: Table>, adt_async_destructor: Table>, - coroutine_by_move_body_def_id: Table, + coroutine_by_move_body_def_id: Table, eval_static_initializer: Table>>, trait_def: Table>, expn_that_defined: Table>, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index 24177e4f83de8..299a5ca906ea1 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -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, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index bbac0b5ad5435..2844b7c26a550 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -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 { +impl FixedSizeEncoding for Option { type ByteArray = [u8; 8]; #[inline] @@ -265,14 +266,15 @@ impl FixedSizeEncoding for Option { } 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(); diff --git a/compiler/rustc_monomorphize/src/offload/manifest.rs b/compiler/rustc_monomorphize/src/offload/manifest.rs index a6f5d1228082e..8fdd8e10ab419 100644 --- a/compiler/rustc_monomorphize/src/offload/manifest.rs +++ b/compiler/rustc_monomorphize/src/offload/manifest.rs @@ -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 { diff --git a/tests/run-make/parallel-reproducible-build/async-fns-issue-162202.rs b/tests/run-make/parallel-reproducible-build/async-fns-issue-162202.rs new file mode 100644 index 0000000000000..1e959cfd62543 --- /dev/null +++ b/tests/run-make/parallel-reproducible-build/async-fns-issue-162202.rs @@ -0,0 +1,3 @@ +async fn test1(_: &'_ u8) {} +async fn test2<'s>(_: &'s u8) {} +fn main() {} diff --git a/tests/run-make/parallel-reproducible-build/rmake.rs b/tests/run-make/parallel-reproducible-build/rmake.rs index caaee1b47c583..01de08e0551f3 100644 --- a/tests/run-make/parallel-reproducible-build/rmake.rs +++ b/tests/run-make/parallel-reproducible-build/rmake.rs @@ -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 { diff --git a/tests/run-make/parallel-reproducible-build/rpit-issue-162202.rs b/tests/run-make/parallel-reproducible-build/rpit-issue-162202.rs new file mode 100644 index 0000000000000..1147f4d450d7d --- /dev/null +++ b/tests/run-make/parallel-reproducible-build/rpit-issue-162202.rs @@ -0,0 +1,19 @@ +trait Foo { + fn test() -> impl IntoIterator + Send; +} + +struct A; +impl Foo for A { + fn test() -> impl IntoIterator + Send { + [] + } +} + +struct B; +impl Foo for B { + fn test() -> impl IntoIterator + Send { + [] + } +} + +fn main() {} diff --git a/tests/run-make/parallel-reproducible-build/static-muts-lib-issue-162203.rs b/tests/run-make/parallel-reproducible-build/static-muts-lib-issue-162203.rs new file mode 100644 index 0000000000000..adda309c8cd39 --- /dev/null +++ b/tests/run-make/parallel-reproducible-build/static-muts-lib-issue-162203.rs @@ -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() {}