diff --git a/Cargo.lock b/Cargo.lock index 5e9ba9b432793..6f43b9b798eb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4440,6 +4440,7 @@ dependencies = [ "rustc_target", "scoped-tls", "serde", + "serde_json", "tracing", ] diff --git a/compiler/rustc_public/Cargo.toml b/compiler/rustc_public/Cargo.toml index 70af30c1a5f46..c2b00b515adc6 100644 --- a/compiler/rustc_public/Cargo.toml +++ b/compiler/rustc_public/Cargo.toml @@ -13,10 +13,15 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } scoped-tls = "1.0" -serde = { version = "1.0.125", features = [ "derive" ] } +serde = { version = "1.0.125", features = ["derive"] } tracing = "0.1" # tidy-alphabetical-end +[dev-dependencies] +# tidy-alphabetical-start +serde_json = "1.0.142" +# tidy-alphabetical-end + [features] # tidy-alphabetical-start # Provides access to APIs that expose internals of the rust compiler. diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 7b0882caf1b3e..820c41acf5b23 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::{Align, Ty, VariantIdx, index_impl}; +use crate::{Error, Opaque, ThreadLocalIndex, error}; /// A function ABI definition. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] @@ -109,8 +109,9 @@ impl LayoutShape { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct Layout(usize); +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct Layout(usize, ThreadLocalIndex); +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..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 = 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 75228135e4cb3..95a7908b19bdd 100644 --- a/compiler/rustc_public/src/crate_def.rs +++ b/compiler/rustc_public/src/crate_def.rs @@ -1,14 +1,13 @@ //! 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}; -use crate::{AssocItems, Crate, Symbol, with}; +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)] -pub struct DefId(pub(crate) usize); +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct DefId(pub(crate) usize, ThreadLocalIndex); +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..9d64553b7a662 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -20,6 +20,7 @@ //! [crates.io](https://crates.io). use std::fmt::Debug; +use std::marker::PhantomData; use std::{fmt, io}; pub(crate) use rustc_public_bridge::IndexedVal; @@ -36,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; @@ -49,6 +53,8 @@ pub mod compiler_interface; pub mod error; pub mod mir; pub mod target; +#[cfg(test)] +mod tests; pub mod ty; pub mod visitor; @@ -56,7 +62,9 @@ pub mod visitor; pub type Symbol = String; /// The number that identifies a crate. -pub type CrateNum = usize; +#[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 { @@ -64,16 +72,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; @@ -300,3 +298,25 @@ impl rustc_public_bridge::bridge::Allocation } } } + +#[derive(Clone, Copy, Hash, PartialEq, Eq, Default)] +/// 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. +/// +/// 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 { + _phantom: PhantomData<*const ()>, +} +#[expect(non_upper_case_globals)] +/// Emulating unit struct `struct ThreadLocalIndex`; +pub(crate) const ThreadLocalIndex: ThreadLocalIndex = ThreadLocalIndex { _phantom: PhantomData }; + +impl fmt::Debug for ThreadLocalIndex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("ThreadLocalIndex").finish() + } +} diff --git a/compiler/rustc_public/src/mir/alloc.rs b/compiler/rustc_public/src/mir/alloc.rs index 07a979f3811e4..b267e3612d808 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::{Allocation, Binder, ExistentialTraitRef, Ty, index_impl}; +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. @@ -47,17 +47,9 @@ 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 - } -} +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub struct AllocId(usize, ThreadLocalIndex); +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..ab939a5535149 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, Symbol, ThreadLocalIndex, with}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum MonoItem { @@ -241,8 +241,9 @@ impl From for CrateItem { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct InstanceDef(usize); +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct InstanceDef(usize, ThreadLocalIndex); +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/rustc_internal/mod.rs b/compiler/rustc_public/src/rustc_internal/mod.rs index 225c811ab3a54..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 { - item.id.into() + 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/tests.rs b/compiler/rustc_public/src/tests.rs new file mode 100644 index 0000000000000..9c3f956c37df4 --- /dev/null +++ b/compiler/rustc_public/src/tests.rs @@ -0,0 +1,63 @@ +use rustc_public_bridge::IndexedVal; + +use crate::abi::Layout; +use crate::mir::alloc::AllocId; +use crate::mir::mono::InstanceDef; +use crate::ty::{MirConstId, TyConstId, VariantIdx}; +use crate::{CrateNum, DefId, Span, ThreadLocalIndex, Ty}; + +#[track_caller] +fn check_serialize(value: T, expected_json: &str) { + let got_json = serde_json::to_string(&value).unwrap(); + assert_eq!(got_json, expected_json, "didn't get expected json for serializing"); +} + +#[test] +fn serialize_cratenum() { + check_serialize(CrateNum(1, ThreadLocalIndex), "1"); +} + +#[test] +fn serialize_defid() { + check_serialize(DefId::to_val(2), "2"); +} + +#[test] +fn serialize_layout() { + check_serialize(Layout::to_val(3), "3"); +} + +#[test] +fn serialize_allocid() { + check_serialize(AllocId::to_val(4), "4"); +} + +#[test] +fn serialize_ty() { + check_serialize(Ty::to_val(5), "5"); +} + +#[test] +fn serialize_tyconstid() { + check_serialize(TyConstId::to_val(6), "6"); +} + +#[test] +fn serialize_mirconstid() { + check_serialize(MirConstId::to_val(7), "7"); +} + +#[test] +fn serialize_span() { + check_serialize(Span::to_val(8), "8"); +} + +#[test] +fn serialize_variantidx() { + check_serialize(VariantIdx::to_val(9), "9"); +} + +#[test] +fn serialize_instancedef() { + check_serialize(InstanceDef::to_val(10), "10"); +} diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 0afb94c18d7b9..f24d98f7e5521 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, ThreadLocalIndex}; -#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] -pub struct Ty(usize); +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct Ty(usize, ThreadLocalIndex); impl Debug for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -151,8 +151,8 @@ pub enum TyConstKind { ZSTValue(Ty), } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] -pub struct TyConstId(usize); +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct TyConstId(usize, ThreadLocalIndex); /// Represents a constant in MIR #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] @@ -212,8 +212,8 @@ impl MirConst { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] -pub struct MirConstId(usize); +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct MirConstId(usize, ThreadLocalIndex); type Ident = Opaque; @@ -255,8 +255,8 @@ pub struct Placeholder { pub bound: T, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] -pub struct Span(usize); +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct Span(usize, ThreadLocalIndex); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -1560,14 +1560,29 @@ macro_rules! index_impl { ($name:ident) => { impl crate::IndexedVal for $name { fn to_val(index: usize) -> Self { - $name(index) + $name(index, $crate::ThreadLocalIndex) } fn to_index(&self) -> usize { 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, serialize_index_impl}; index_impl!(TyConstId); index_impl!(MirConstId); @@ -1587,8 +1602,8 @@ 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)] -pub struct VariantIdx(usize); +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct VariantIdx(usize, ThreadLocalIndex); index_impl!(VariantIdx); 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) } }