From f2eb25e8c0aa2a364d13c42f40f1606cc58cb3dd Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 29 Oct 2025 17:07:54 +0000 Subject: [PATCH 1/8] rustc_public: Make Id types !Send / !Sync These types are Id's to a table stored in TLS, so using them from another tread will either panic, or give wrong results. Therefor, I've added a `ReferencesTls` marker type, which ensures types arn't `Send`/`Sync`. This is a breaking change for users of the `rustc_public` crate. It also changes how `DefId` and similar are `Serialize`d. Zulip Discussion: https://rust-lang.zulipchat.com/#narrow/channel/320896-project-stable-mir/topic/WDYM.20.22should.20not.20.20be.20shared.20across.20threads.22/with/547374171 --- compiler/rustc_public/src/abi.rs | 16 ++------ .../rustc_public/src/compiler_interface.rs | 4 +- compiler/rustc_public/src/crate_def.rs | 7 ++-- compiler/rustc_public/src/lib.rs | 40 ++++++++++++++----- compiler/rustc_public/src/mir/alloc.rs | 16 ++------ compiler/rustc_public/src/mir/mono.rs | 16 ++------ compiler/rustc_public/src/ty.rs | 15 +++---- 7 files changed, 55 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 7b0882caf1b3e..051566538e29d 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -7,8 +7,8 @@ use serde::Serialize; use crate::compiler_interface::with; use crate::mir::FieldIdx; use crate::target::{MachineInfo, MachineSize as Size}; -use crate::ty::{Align, Ty, VariantIdx}; -use crate::{Error, Opaque, error}; +use crate::ty::{index_impl, Align, Ty, VariantIdx}; +use crate::{error, Error, Opaque, ReferencesTls}; /// A function ABI definition. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] @@ -110,7 +110,8 @@ impl LayoutShape { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct Layout(usize); +pub struct Layout(usize, ReferencesTls); +index_impl!(Layout); impl Layout { pub fn shape(self) -> LayoutShape { @@ -118,15 +119,6 @@ impl Layout { } } -impl crate::IndexedVal for Layout { - fn to_val(index: usize) -> Self { - Layout(index) - } - fn to_index(&self) -> usize { - self.0 - } -} - /// Describes how the fields of a type are shaped in memory. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum FieldsShape { diff --git a/compiler/rustc_public/src/compiler_interface.rs b/compiler/rustc_public/src/compiler_interface.rs index 5a09c3b24f0f1..b09bb2dfe3ece 100644 --- a/compiler/rustc_public/src/compiler_interface.rs +++ b/compiler/rustc_public/src/compiler_interface.rs @@ -25,7 +25,7 @@ use crate::ty::{ use crate::unstable::{RustcInternal, Stable, new_item_kind}; use crate::{ AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, - ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, + ImplTraitDecls, ItemKind, ReferencesTls, Symbol, TraitDecls, alloc, mir, }; pub struct BridgeTys; @@ -1095,5 +1095,5 @@ fn smir_crate<'tcx>( let is_local = cx.crate_is_local(crate_num); let id = cx.crate_num_id(crate_num); debug!(?name, ?crate_num, "smir_crate"); - Crate { id, name, is_local } + Crate { id, name, is_local, references_tls: ReferencesTLS } } diff --git a/compiler/rustc_public/src/crate_def.rs b/compiler/rustc_public/src/crate_def.rs index 75228135e4cb3..e86ba332db85e 100644 --- a/compiler/rustc_public/src/crate_def.rs +++ b/compiler/rustc_public/src/crate_def.rs @@ -3,12 +3,13 @@ use serde::Serialize; -use crate::ty::{GenericArgs, Span, Ty}; -use crate::{AssocItems, Crate, Symbol, with}; +use crate::ty::{GenericArgs, Span, Ty, index_impl}; +use crate::{AssocItems, Crate, ReferencesTls, Symbol, with}; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct DefId(pub(crate) usize); +pub struct DefId(pub(crate) usize, ReferencesTls); +index_impl!(DefId); impl DefId { /// Return fully qualified name of this definition diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 958b3b2647889..a1a79c9675a93 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -20,11 +20,12 @@ //! [crates.io](https://crates.io). use std::fmt::Debug; +use std::marker::PhantomData; use std::{fmt, io}; +use rustc_public_bridge::context::CompilerCtxt; pub(crate) use rustc_public_bridge::IndexedVal; use rustc_public_bridge::Tables; -use rustc_public_bridge::context::CompilerCtxt; /// Export the rustc_internal APIs. Note that this module has no stability /// guarantees and it is not taken into account for semver. #[cfg(feature = "rustc_internal")] @@ -56,6 +57,7 @@ pub mod visitor; pub type Symbol = String; /// The number that identifies a crate. +// FIXME: Make this a newtype, so it can have a `ReferencesTls` pub type CrateNum = usize; impl Debug for DefId { @@ -64,16 +66,6 @@ impl Debug for DefId { } } -impl IndexedVal for DefId { - fn to_val(index: usize) -> Self { - DefId(index) - } - - fn to_index(&self) -> usize { - self.0 - } -} - /// A list of crate items. pub type CrateItems = Vec; @@ -92,6 +84,9 @@ pub struct Crate { pub id: CrateNum, pub name: Symbol, pub is_local: bool, + // FIXME: Remove this when `CrateNum` holds `ReferencesTLS` + #[serde(skip)] + references_tls: ReferencesTls, } impl Crate { @@ -300,3 +295,26 @@ impl rustc_public_bridge::bridge::Allocation } } } + +#[derive(Clone, Copy, Hash, PartialEq, Eq, Default)] +#[derive(serde::Serialize)] // TODO: Don't. +/// Marker type for indexes into [`TLV`]. +/// +/// Makes things `!Send`/`!Sync`, so users don't move `rustc_public`` types to +/// thread with no (or worse, different) `rustc_public` pointer. +/// +/// Note. This doens't make it impossible to confuse TLS. You could return a +/// `DefId` from one `run!` invocation, and then use it inside a different +/// `run!` invocation with different tables. +pub(crate) struct ReferencesTls { + _phantom: PhantomData<*const ()>, +} +#[expect(non_upper_case_globals)] +/// Emulating unit struct `struct ReferencesTLS`; +pub(crate) const ReferencesTLS: ReferencesTls = ReferencesTls { _phantom: PhantomData }; + +impl fmt::Debug for ReferencesTls { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("ReferencesTLS").finish() + } +} diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs index 07a979f3811e4..0a6ad2dbe5928 100644 --- a/compiler/rustc_public/src/mir/alloc.rs +++ b/compiler/rustc_public/src/mir/alloc.rs @@ -6,8 +6,8 @@ use serde::Serialize; use crate::mir::mono::{Instance, StaticDef}; use crate::target::{Endian, MachineInfo}; -use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty}; -use crate::{Error, IndexedVal, with}; +use crate::ty::{index_impl, Allocation, Binder, ExistentialTraitRef, Ty}; +use crate::{with, Error, ReferencesTls}; /// An allocation in the rustc_public's IR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. @@ -48,16 +48,8 @@ impl GlobalAlloc { /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] -pub struct AllocId(usize); - -impl IndexedVal for AllocId { - fn to_val(index: usize) -> Self { - AllocId(index) - } - fn to_index(&self) -> usize { - self.0 - } -} +pub struct AllocId(usize, ReferencesTls); +index_impl!(AllocId); /// Utility function used to read an allocation data into a unassigned integer. pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result { diff --git a/compiler/rustc_public/src/mir/mono.rs b/compiler/rustc_public/src/mir/mono.rs index d488f5a25c7d9..d13b35c1dfbc7 100644 --- a/compiler/rustc_public/src/mir/mono.rs +++ b/compiler/rustc_public/src/mir/mono.rs @@ -7,8 +7,8 @@ use serde::Serialize; use crate::abi::FnAbi; use crate::crate_def::CrateDef; use crate::mir::Body; -use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty}; -use crate::{CrateItem, DefId, Error, IndexedVal, ItemKind, Opaque, Symbol, with}; +use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty, index_impl}; +use crate::{CrateItem, DefId, Error, ItemKind, Opaque, ReferencesTls, Symbol, with}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum MonoItem { @@ -242,7 +242,8 @@ impl From for CrateItem { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct InstanceDef(usize); +pub struct InstanceDef(usize, ReferencesTls); +index_impl!(InstanceDef); impl CrateDef for InstanceDef { fn def_id(&self) -> DefId { @@ -294,12 +295,3 @@ impl StaticDef { with(|cx| cx.eval_static_initializer(*self)) } } - -impl IndexedVal for InstanceDef { - fn to_val(index: usize) -> Self { - InstanceDef(index) - } - fn to_index(&self) -> usize { - self.0 - } -} diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 0afb94c18d7b9..bcabf6308eb5b 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -11,10 +11,10 @@ use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType}; use crate::mir::alloc::{AllocId, read_target_int, read_target_uint}; use crate::mir::mono::StaticDef; use crate::target::MachineInfo; -use crate::{Filename, IndexedVal, Opaque}; +use crate::{Filename, IndexedVal, Opaque, ReferencesTls}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] -pub struct Ty(usize); +pub struct Ty(usize, ReferencesTls); impl Debug for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -152,7 +152,7 @@ pub enum TyConstKind { } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] -pub struct TyConstId(usize); +pub struct TyConstId(usize, ReferencesTls); /// Represents a constant in MIR #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] @@ -213,7 +213,7 @@ impl MirConst { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct MirConstId(usize); +pub struct MirConstId(usize, ReferencesTls); type Ident = Opaque; @@ -256,7 +256,7 @@ pub struct Placeholder { } #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct Span(usize); +pub struct Span(usize, ReferencesTls); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -1560,7 +1560,7 @@ macro_rules! index_impl { ($name:ident) => { impl crate::IndexedVal for $name { fn to_val(index: usize) -> Self { - $name(index) + $name(index, $crate::ReferencesTLS) } fn to_index(&self) -> usize { self.0 @@ -1568,6 +1568,7 @@ macro_rules! index_impl { } }; } +pub(crate) use index_impl; index_impl!(TyConstId); index_impl!(MirConstId); @@ -1588,7 +1589,7 @@ index_impl!(Span); /// `c` is in the variant with the `VariantIdx` of `1`, and /// `g` is in the variant with the `VariantIdx` of `0`. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct VariantIdx(usize); +pub struct VariantIdx(usize, ReferencesTls); index_impl!(VariantIdx); From 8b3ee9fb2efdf3fc332cb7da0dbb2fa2593a022e Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 00:17:39 +0000 Subject: [PATCH 2/8] rustc_public: Make `CrateNum` a newtype. --- compiler/rustc_public/src/compiler_interface.rs | 6 +++--- compiler/rustc_public/src/lib.rs | 9 +++------ compiler/rustc_public/src/rustc_internal/mod.rs | 2 +- compiler/rustc_public/src/unstable/convert/internal.rs | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_public/src/compiler_interface.rs b/compiler/rustc_public/src/compiler_interface.rs index b09bb2dfe3ece..e599d49553095 100644 --- a/compiler/rustc_public/src/compiler_interface.rs +++ b/compiler/rustc_public/src/compiler_interface.rs @@ -25,7 +25,7 @@ use crate::ty::{ use crate::unstable::{RustcInternal, Stable, new_item_kind}; use crate::{ AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, - ImplTraitDecls, ItemKind, ReferencesTls, Symbol, TraitDecls, alloc, mir, + ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, }; pub struct BridgeTys; @@ -1093,7 +1093,7 @@ fn smir_crate<'tcx>( ) -> Crate { let name = cx.crate_name(crate_num); let is_local = cx.crate_is_local(crate_num); - let id = cx.crate_num_id(crate_num); + let id = CrateNum(cx.crate_num_id(crate_num)); debug!(?name, ?crate_num, "smir_crate"); - Crate { id, name, is_local, references_tls: ReferencesTLS } + Crate { id, name, is_local } } diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index a1a79c9675a93..d19308c3a5b16 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -23,9 +23,9 @@ use std::fmt::Debug; use std::marker::PhantomData; use std::{fmt, io}; -use rustc_public_bridge::context::CompilerCtxt; pub(crate) use rustc_public_bridge::IndexedVal; use rustc_public_bridge::Tables; +use rustc_public_bridge::context::CompilerCtxt; /// Export the rustc_internal APIs. Note that this module has no stability /// guarantees and it is not taken into account for semver. #[cfg(feature = "rustc_internal")] @@ -57,8 +57,8 @@ pub mod visitor; pub type Symbol = String; /// The number that identifies a crate. -// FIXME: Make this a newtype, so it can have a `ReferencesTls` -pub type CrateNum = usize; +#[derive(Clone, Copy, Serialize, PartialEq, Eq, Debug)] +pub struct CrateNum(pub(crate) usize, ThreadLocalIndex); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -84,9 +84,6 @@ pub struct Crate { pub id: CrateNum, pub name: Symbol, pub is_local: bool, - // FIXME: Remove this when `CrateNum` holds `ReferencesTLS` - #[serde(skip)] - references_tls: ReferencesTls, } impl Crate { diff --git a/compiler/rustc_public/src/rustc_internal/mod.rs b/compiler/rustc_public/src/rustc_internal/mod.rs index 225c811ab3a54..6c7dbd4d32ca9 100644 --- a/compiler/rustc_public/src/rustc_internal/mod.rs +++ b/compiler/rustc_public/src/rustc_internal/mod.rs @@ -53,7 +53,7 @@ where } pub fn crate_num(item: &crate::Crate) -> CrateNum { - item.id.into() + CrateNum::from_u32(item.id.0) } // A thread local variable that stores a pointer to the tables mapping between TyCtxt diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index 064fb6c6803a5..d9f314a8e29cc 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -40,7 +40,7 @@ impl RustcInternal for CrateNum { _tables: &mut Tables<'_, BridgeTys>, _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - rustc_span::def_id::CrateNum::from_usize(*self) + rustc_span::def_id::CrateNum::from_usize(self.0) } } From 421857f11261d0be45f0e683bbe8df253598ea8a Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 00:18:18 +0000 Subject: [PATCH 3/8] [SQUASH BEFORE MERGE] ./x fmt Somehow VSCode's format-on-save is formatting differently to ./x. Maybe to do with 2024 edition?? --- compiler/rustc_public/src/abi.rs | 4 ++-- compiler/rustc_public/src/mir/alloc.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 051566538e29d..01becbbf870b3 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -7,8 +7,8 @@ use serde::Serialize; use crate::compiler_interface::with; use crate::mir::FieldIdx; use crate::target::{MachineInfo, MachineSize as Size}; -use crate::ty::{index_impl, Align, Ty, VariantIdx}; -use crate::{error, Error, Opaque, ReferencesTls}; +use crate::ty::{Align, Ty, VariantIdx, index_impl}; +use crate::{Error, Opaque, ReferencesTls, error}; /// A function ABI definition. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs index 0a6ad2dbe5928..dc537d675c83d 100644 --- a/compiler/rustc_public/src/mir/alloc.rs +++ b/compiler/rustc_public/src/mir/alloc.rs @@ -6,8 +6,8 @@ use serde::Serialize; use crate::mir::mono::{Instance, StaticDef}; use crate::target::{Endian, MachineInfo}; -use crate::ty::{index_impl, Allocation, Binder, ExistentialTraitRef, Ty}; -use crate::{with, Error, ReferencesTls}; +use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty, index_impl}; +use crate::{Error, ReferencesTls, with}; /// An allocation in the rustc_public's IR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. From b1e3bd42f60067ec1a2883ee093bfc7770375e3b Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 00:27:41 +0000 Subject: [PATCH 4/8] [SQUASH BEFORE MERGE] s/ReferencesTls/ThreadLocalIndex --- compiler/rustc_public/src/abi.rs | 4 ++-- compiler/rustc_public/src/compiler_interface.rs | 4 ++-- compiler/rustc_public/src/crate_def.rs | 4 ++-- compiler/rustc_public/src/lib.rs | 10 +++++----- compiler/rustc_public/src/mir/alloc.rs | 4 ++-- compiler/rustc_public/src/mir/mono.rs | 4 ++-- compiler/rustc_public/src/ty.rs | 14 +++++++------- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 01becbbf870b3..bea983095a920 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -8,7 +8,7 @@ use crate::compiler_interface::with; use crate::mir::FieldIdx; use crate::target::{MachineInfo, MachineSize as Size}; use crate::ty::{Align, Ty, VariantIdx, index_impl}; -use crate::{Error, Opaque, ReferencesTls, error}; +use crate::{Error, Opaque, ThreadLocalIndex, error}; /// A function ABI definition. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] @@ -110,7 +110,7 @@ impl LayoutShape { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct Layout(usize, ReferencesTls); +pub struct Layout(usize, ThreadLocalIndex); index_impl!(Layout); impl Layout { diff --git a/compiler/rustc_public/src/compiler_interface.rs b/compiler/rustc_public/src/compiler_interface.rs index e599d49553095..2af66fcaa5a48 100644 --- a/compiler/rustc_public/src/compiler_interface.rs +++ b/compiler/rustc_public/src/compiler_interface.rs @@ -25,7 +25,7 @@ use crate::ty::{ use crate::unstable::{RustcInternal, Stable, new_item_kind}; use crate::{ AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, - ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, + ImplTraitDecls, ItemKind, Symbol, ThreadLocalIndex, TraitDecls, alloc, mir, }; pub struct BridgeTys; @@ -1093,7 +1093,7 @@ fn smir_crate<'tcx>( ) -> Crate { let name = cx.crate_name(crate_num); let is_local = cx.crate_is_local(crate_num); - let id = CrateNum(cx.crate_num_id(crate_num)); + let id = CrateNum(cx.crate_num_id(crate_num), ThreadLocalIndex); debug!(?name, ?crate_num, "smir_crate"); Crate { id, name, is_local } } diff --git a/compiler/rustc_public/src/crate_def.rs b/compiler/rustc_public/src/crate_def.rs index e86ba332db85e..5a076c733d053 100644 --- a/compiler/rustc_public/src/crate_def.rs +++ b/compiler/rustc_public/src/crate_def.rs @@ -4,11 +4,11 @@ use serde::Serialize; use crate::ty::{GenericArgs, Span, Ty, index_impl}; -use crate::{AssocItems, Crate, ReferencesTls, Symbol, with}; +use crate::{AssocItems, Crate, Symbol, ThreadLocalIndex, with}; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct DefId(pub(crate) usize, ReferencesTls); +pub struct DefId(pub(crate) usize, ThreadLocalIndex); index_impl!(DefId); impl DefId { diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index d19308c3a5b16..74f17fec77154 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -303,15 +303,15 @@ impl rustc_public_bridge::bridge::Allocation /// Note. This doens't make it impossible to confuse TLS. You could return a /// `DefId` from one `run!` invocation, and then use it inside a different /// `run!` invocation with different tables. -pub(crate) struct ReferencesTls { +pub(crate) struct ThreadLocalIndex { _phantom: PhantomData<*const ()>, } #[expect(non_upper_case_globals)] -/// Emulating unit struct `struct ReferencesTLS`; -pub(crate) const ReferencesTLS: ReferencesTls = ReferencesTls { _phantom: PhantomData }; +/// Emulating unit struct `struct ThreadLocalIndex`; +pub(crate) const ThreadLocalIndex: ThreadLocalIndex = ThreadLocalIndex { _phantom: PhantomData }; -impl fmt::Debug for ReferencesTls { +impl fmt::Debug for ThreadLocalIndex { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("ReferencesTLS").finish() + f.debug_tuple("ThreadLocalIndex").finish() } } diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs index dc537d675c83d..44c59b8711221 100644 --- a/compiler/rustc_public/src/mir/alloc.rs +++ b/compiler/rustc_public/src/mir/alloc.rs @@ -7,7 +7,7 @@ use serde::Serialize; use crate::mir::mono::{Instance, StaticDef}; use crate::target::{Endian, MachineInfo}; use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty, index_impl}; -use crate::{Error, ReferencesTls, with}; +use crate::{Error, ThreadLocalIndex, with}; /// An allocation in the rustc_public's IR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. @@ -48,7 +48,7 @@ impl GlobalAlloc { /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] -pub struct AllocId(usize, ReferencesTls); +pub struct AllocId(usize, ThreadLocalIndex); index_impl!(AllocId); /// Utility function used to read an allocation data into a unassigned integer. diff --git a/compiler/rustc_public/src/mir/mono.rs b/compiler/rustc_public/src/mir/mono.rs index d13b35c1dfbc7..0899c582e8679 100644 --- a/compiler/rustc_public/src/mir/mono.rs +++ b/compiler/rustc_public/src/mir/mono.rs @@ -8,7 +8,7 @@ use crate::abi::FnAbi; use crate::crate_def::CrateDef; use crate::mir::Body; use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty, index_impl}; -use crate::{CrateItem, DefId, Error, ItemKind, Opaque, ReferencesTls, Symbol, with}; +use crate::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, ThreadLocalIndex, with}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum MonoItem { @@ -242,7 +242,7 @@ impl From for CrateItem { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct InstanceDef(usize, ReferencesTls); +pub struct InstanceDef(usize, ThreadLocalIndex); index_impl!(InstanceDef); impl CrateDef for InstanceDef { diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index bcabf6308eb5b..2c1153d6343ab 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -11,10 +11,10 @@ use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType}; use crate::mir::alloc::{AllocId, read_target_int, read_target_uint}; use crate::mir::mono::StaticDef; use crate::target::MachineInfo; -use crate::{Filename, IndexedVal, Opaque, ReferencesTls}; +use crate::{Filename, IndexedVal, Opaque, ThreadLocalIndex}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] -pub struct Ty(usize, ReferencesTls); +pub struct Ty(usize, ThreadLocalIndex); impl Debug for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -152,7 +152,7 @@ pub enum TyConstKind { } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] -pub struct TyConstId(usize, ReferencesTls); +pub struct TyConstId(usize, ThreadLocalIndex); /// Represents a constant in MIR #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] @@ -213,7 +213,7 @@ impl MirConst { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct MirConstId(usize, ReferencesTls); +pub struct MirConstId(usize, ThreadLocalIndex); type Ident = Opaque; @@ -256,7 +256,7 @@ pub struct Placeholder { } #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct Span(usize, ReferencesTls); +pub struct Span(usize, ThreadLocalIndex); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -1560,7 +1560,7 @@ macro_rules! index_impl { ($name:ident) => { impl crate::IndexedVal for $name { fn to_val(index: usize) -> Self { - $name(index, $crate::ReferencesTLS) + $name(index, $crate::ThreadLocalIndex) } fn to_index(&self) -> usize { self.0 @@ -1589,7 +1589,7 @@ index_impl!(Span); /// `c` is in the variant with the `VariantIdx` of `1`, and /// `g` is in the variant with the `VariantIdx` of `0`. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct VariantIdx(usize, ReferencesTls); +pub struct VariantIdx(usize, ThreadLocalIndex); index_impl!(VariantIdx); From 97e6df40bdfd4cb406a703f27377af1f11f983aa Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 00:46:58 +0000 Subject: [PATCH 5/8] rustc_public: Don't `impl Serialize for ThreadLocalIndex`. It meant that `DefId(0, ThreadLocalIndex)` would go to json as `[0, null]`, instead of just `0` (like before this PR). Now it's back to going to `0`, so this PR won't effect JSON consumers. This can't be achieved with just `#[serde(skip)]`: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=b4aafe4ff5312c4ddedd5e17ee361d5a --- compiler/rustc_public/src/abi.rs | 2 +- compiler/rustc_public/src/crate_def.rs | 4 +-- compiler/rustc_public/src/lib.rs | 9 ++++--- compiler/rustc_public/src/mir/alloc.rs | 2 +- compiler/rustc_public/src/mir/mono.rs | 2 +- .../rustc_public/src/rustc_internal/mod.rs | 2 +- compiler/rustc_public/src/ty.rs | 26 ++++++++++++++----- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index bea983095a920..820c41acf5b23 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -109,7 +109,7 @@ impl LayoutShape { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct Layout(usize, ThreadLocalIndex); index_impl!(Layout); diff --git a/compiler/rustc_public/src/crate_def.rs b/compiler/rustc_public/src/crate_def.rs index 5a076c733d053..95a7908b19bdd 100644 --- a/compiler/rustc_public/src/crate_def.rs +++ b/compiler/rustc_public/src/crate_def.rs @@ -1,13 +1,11 @@ //! Module that define a common trait for things that represent a crate definition, //! such as, a function, a trait, an enum, and any other definitions. -use serde::Serialize; - use crate::ty::{GenericArgs, Span, Ty, index_impl}; use crate::{AssocItems, Crate, Symbol, ThreadLocalIndex, with}; /// A unique identification number for each item accessible for the current compilation unit. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct DefId(pub(crate) usize, ThreadLocalIndex); index_impl!(DefId); diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 74f17fec77154..5183dbad2a507 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -37,7 +37,10 @@ pub use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId}; pub use crate::error::*; use crate::mir::mono::StaticDef; use crate::mir::{Body, Mutability}; -use crate::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, ProvenanceMap, Span, TraitDef, Ty}; +use crate::ty::{ + AssocItem, FnDef, ForeignModuleDef, ImplDef, ProvenanceMap, Span, TraitDef, Ty, + serialize_index_impl, +}; use crate::unstable::Stable; pub mod abi; @@ -57,8 +60,9 @@ pub mod visitor; pub type Symbol = String; /// The number that identifies a crate. -#[derive(Clone, Copy, Serialize, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct CrateNum(pub(crate) usize, ThreadLocalIndex); +serialize_index_impl!(CrateNum); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -294,7 +298,6 @@ impl rustc_public_bridge::bridge::Allocation } #[derive(Clone, Copy, Hash, PartialEq, Eq, Default)] -#[derive(serde::Serialize)] // TODO: Don't. /// Marker type for indexes into [`TLV`]. /// /// Makes things `!Send`/`!Sync`, so users don't move `rustc_public`` types to diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs index 44c59b8711221..b267e3612d808 100644 --- a/compiler/rustc_public/src/mir/alloc.rs +++ b/compiler/rustc_public/src/mir/alloc.rs @@ -47,7 +47,7 @@ impl GlobalAlloc { } /// A unique identification number for each provenance -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub struct AllocId(usize, ThreadLocalIndex); index_impl!(AllocId); diff --git a/compiler/rustc_public/src/mir/mono.rs b/compiler/rustc_public/src/mir/mono.rs index 0899c582e8679..ab939a5535149 100644 --- a/compiler/rustc_public/src/mir/mono.rs +++ b/compiler/rustc_public/src/mir/mono.rs @@ -241,7 +241,7 @@ impl From for CrateItem { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct InstanceDef(usize, ThreadLocalIndex); index_impl!(InstanceDef); diff --git a/compiler/rustc_public/src/rustc_internal/mod.rs b/compiler/rustc_public/src/rustc_internal/mod.rs index 6c7dbd4d32ca9..dc8afb89d949e 100644 --- a/compiler/rustc_public/src/rustc_internal/mod.rs +++ b/compiler/rustc_public/src/rustc_internal/mod.rs @@ -53,7 +53,7 @@ where } pub fn crate_num(item: &crate::Crate) -> CrateNum { - CrateNum::from_u32(item.id.0) + item.id.0.into() } // A thread local variable that stores a pointer to the tables mapping between TyCtxt diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 2c1153d6343ab..f24d98f7e5521 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -13,7 +13,7 @@ use crate::mir::mono::StaticDef; use crate::target::MachineInfo; use crate::{Filename, IndexedVal, Opaque, ThreadLocalIndex}; -#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct Ty(usize, ThreadLocalIndex); impl Debug for Ty { @@ -151,7 +151,7 @@ pub enum TyConstKind { ZSTValue(Ty), } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct TyConstId(usize, ThreadLocalIndex); /// Represents a constant in MIR @@ -212,7 +212,7 @@ impl MirConst { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct MirConstId(usize, ThreadLocalIndex); type Ident = Opaque; @@ -255,7 +255,7 @@ pub struct Placeholder { pub bound: T, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Span(usize, ThreadLocalIndex); impl Debug for Span { @@ -1566,9 +1566,23 @@ macro_rules! index_impl { self.0 } } + $crate::ty::serialize_index_impl!($name); + }; +} +macro_rules! serialize_index_impl { + ($name:ident) => { + impl ::serde::Serialize for $name { + fn serialize(&self, serializer: S) -> Result + where + S: ::serde::Serializer, + { + let n: usize = self.0; // Make sure we're serializing an int. + ::serde::Serialize::serialize(&n, serializer) + } + } }; } -pub(crate) use index_impl; +pub(crate) use {index_impl, serialize_index_impl}; index_impl!(TyConstId); index_impl!(MirConstId); @@ -1588,7 +1602,7 @@ index_impl!(Span); /// `a` is in the variant with the `VariantIdx` of `0`, /// `c` is in the variant with the `VariantIdx` of `1`, and /// `g` is in the variant with the `VariantIdx` of `0`. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct VariantIdx(usize, ThreadLocalIndex); index_impl!(VariantIdx); From 3c0a9cecf15a1473b59e2c29922400ad9c50bb98 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 00:56:52 +0000 Subject: [PATCH 6/8] typos --- compiler/rustc_public/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 5183dbad2a507..70959bd930297 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -303,7 +303,7 @@ impl rustc_public_bridge::bridge::Allocation /// Makes things `!Send`/`!Sync`, so users don't move `rustc_public`` types to /// thread with no (or worse, different) `rustc_public` pointer. /// -/// Note. This doens't make it impossible to confuse TLS. You could return a +/// Note. This doesn't make it impossible to confuse TLS. You could return a /// `DefId` from one `run!` invocation, and then use it inside a different /// `run!` invocation with different tables. pub(crate) struct ThreadLocalIndex { From 63087382b5cb2e59aebfb324d4813bc6891553b2 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Thu, 30 Oct 2025 01:16:36 +0000 Subject: [PATCH 7/8] remove stray backtick --- compiler/rustc_public/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 70959bd930297..b0a58767ccfa1 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -300,7 +300,7 @@ impl rustc_public_bridge::bridge::Allocation #[derive(Clone, Copy, Hash, PartialEq, Eq, Default)] /// Marker type for indexes into [`TLV`]. /// -/// Makes things `!Send`/`!Sync`, so users don't move `rustc_public`` types to +/// Makes things `!Send`/`!Sync`, so users don't move `rustc_public` types to /// thread with no (or worse, different) `rustc_public` pointer. /// /// Note. This doesn't make it impossible to confuse TLS. You could return a From 3716afa40898bf869d0147535cac9313863d6006 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 31 Oct 2025 18:08:43 +0000 Subject: [PATCH 8/8] Don't intra-doc-link to TLV. It didn't resolve, and it turns out there's two TLV's in rustc_public. This is used for both, so it's better to just describe in terms on what it's doing, rather than which specic statics it cares about. --- compiler/rustc_public/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index b0a58767ccfa1..ffdd34b4a3e75 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -298,7 +298,7 @@ impl rustc_public_bridge::bridge::Allocation } #[derive(Clone, Copy, Hash, PartialEq, Eq, Default)] -/// Marker type for indexes into [`TLV`]. +/// Marker type for indexes into thread local structures. /// /// Makes things `!Send`/`!Sync`, so users don't move `rustc_public` types to /// thread with no (or worse, different) `rustc_public` pointer.