Skip to content

Commit f2eb25e

Browse files
committed
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
1 parent c6d42d7 commit f2eb25e

File tree

7 files changed

+55
-59
lines changed

7 files changed

+55
-59
lines changed

compiler/rustc_public/src/abi.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use serde::Serialize;
77
use crate::compiler_interface::with;
88
use crate::mir::FieldIdx;
99
use crate::target::{MachineInfo, MachineSize as Size};
10-
use crate::ty::{Align, Ty, VariantIdx};
11-
use crate::{Error, Opaque, error};
10+
use crate::ty::{index_impl, Align, Ty, VariantIdx};
11+
use crate::{error, Error, Opaque, ReferencesTls};
1212

1313
/// A function ABI definition.
1414
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
@@ -110,23 +110,15 @@ impl LayoutShape {
110110
}
111111

112112
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
113-
pub struct Layout(usize);
113+
pub struct Layout(usize, ReferencesTls);
114+
index_impl!(Layout);
114115

115116
impl Layout {
116117
pub fn shape(self) -> LayoutShape {
117118
with(|cx| cx.layout_shape(self))
118119
}
119120
}
120121

121-
impl crate::IndexedVal for Layout {
122-
fn to_val(index: usize) -> Self {
123-
Layout(index)
124-
}
125-
fn to_index(&self) -> usize {
126-
self.0
127-
}
128-
}
129-
130122
/// Describes how the fields of a type are shaped in memory.
131123
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
132124
pub enum FieldsShape {

compiler/rustc_public/src/compiler_interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::ty::{
2525
use crate::unstable::{RustcInternal, Stable, new_item_kind};
2626
use crate::{
2727
AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename,
28-
ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir,
28+
ImplTraitDecls, ItemKind, ReferencesTls, Symbol, TraitDecls, alloc, mir,
2929
};
3030

3131
pub struct BridgeTys;
@@ -1095,5 +1095,5 @@ fn smir_crate<'tcx>(
10951095
let is_local = cx.crate_is_local(crate_num);
10961096
let id = cx.crate_num_id(crate_num);
10971097
debug!(?name, ?crate_num, "smir_crate");
1098-
Crate { id, name, is_local }
1098+
Crate { id, name, is_local, references_tls: ReferencesTLS }
10991099
}

compiler/rustc_public/src/crate_def.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
44
use serde::Serialize;
55

6-
use crate::ty::{GenericArgs, Span, Ty};
7-
use crate::{AssocItems, Crate, Symbol, with};
6+
use crate::ty::{GenericArgs, Span, Ty, index_impl};
7+
use crate::{AssocItems, Crate, ReferencesTls, Symbol, with};
88

99
/// A unique identification number for each item accessible for the current compilation unit.
1010
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
11-
pub struct DefId(pub(crate) usize);
11+
pub struct DefId(pub(crate) usize, ReferencesTls);
12+
index_impl!(DefId);
1213

1314
impl DefId {
1415
/// Return fully qualified name of this definition

compiler/rustc_public/src/lib.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@
2020
//! [crates.io](https://crates.io).
2121
2222
use std::fmt::Debug;
23+
use std::marker::PhantomData;
2324
use std::{fmt, io};
2425

26+
use rustc_public_bridge::context::CompilerCtxt;
2527
pub(crate) use rustc_public_bridge::IndexedVal;
2628
use rustc_public_bridge::Tables;
27-
use rustc_public_bridge::context::CompilerCtxt;
2829
/// Export the rustc_internal APIs. Note that this module has no stability
2930
/// guarantees and it is not taken into account for semver.
3031
#[cfg(feature = "rustc_internal")]
@@ -56,6 +57,7 @@ pub mod visitor;
5657
pub type Symbol = String;
5758

5859
/// The number that identifies a crate.
60+
// FIXME: Make this a newtype, so it can have a `ReferencesTls`
5961
pub type CrateNum = usize;
6062

6163
impl Debug for DefId {
@@ -64,16 +66,6 @@ impl Debug for DefId {
6466
}
6567
}
6668

67-
impl IndexedVal for DefId {
68-
fn to_val(index: usize) -> Self {
69-
DefId(index)
70-
}
71-
72-
fn to_index(&self) -> usize {
73-
self.0
74-
}
75-
}
76-
7769
/// A list of crate items.
7870
pub type CrateItems = Vec<CrateItem>;
7971

@@ -92,6 +84,9 @@ pub struct Crate {
9284
pub id: CrateNum,
9385
pub name: Symbol,
9486
pub is_local: bool,
87+
// FIXME: Remove this when `CrateNum` holds `ReferencesTLS`
88+
#[serde(skip)]
89+
references_tls: ReferencesTls,
9590
}
9691

9792
impl Crate {
@@ -300,3 +295,26 @@ impl rustc_public_bridge::bridge::Allocation<compiler_interface::BridgeTys>
300295
}
301296
}
302297
}
298+
299+
#[derive(Clone, Copy, Hash, PartialEq, Eq, Default)]
300+
#[derive(serde::Serialize)] // TODO: Don't.
301+
/// Marker type for indexes into [`TLV`].
302+
///
303+
/// Makes things `!Send`/`!Sync`, so users don't move `rustc_public`` types to
304+
/// thread with no (or worse, different) `rustc_public` pointer.
305+
///
306+
/// Note. This doens't make it impossible to confuse TLS. You could return a
307+
/// `DefId` from one `run!` invocation, and then use it inside a different
308+
/// `run!` invocation with different tables.
309+
pub(crate) struct ReferencesTls {
310+
_phantom: PhantomData<*const ()>,
311+
}
312+
#[expect(non_upper_case_globals)]
313+
/// Emulating unit struct `struct ReferencesTLS`;
314+
pub(crate) const ReferencesTLS: ReferencesTls = ReferencesTls { _phantom: PhantomData };
315+
316+
impl fmt::Debug for ReferencesTls {
317+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318+
f.debug_tuple("ReferencesTLS").finish()
319+
}
320+
}

compiler/rustc_public/src/mir/alloc.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use serde::Serialize;
66

77
use crate::mir::mono::{Instance, StaticDef};
88
use crate::target::{Endian, MachineInfo};
9-
use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty};
10-
use crate::{Error, IndexedVal, with};
9+
use crate::ty::{index_impl, Allocation, Binder, ExistentialTraitRef, Ty};
10+
use crate::{with, Error, ReferencesTls};
1111

1212
/// An allocation in the rustc_public's IR global memory can be either a function pointer,
1313
/// a static, or a "real" allocation with some data in it.
@@ -48,16 +48,8 @@ impl GlobalAlloc {
4848

4949
/// A unique identification number for each provenance
5050
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
51-
pub struct AllocId(usize);
52-
53-
impl IndexedVal for AllocId {
54-
fn to_val(index: usize) -> Self {
55-
AllocId(index)
56-
}
57-
fn to_index(&self) -> usize {
58-
self.0
59-
}
60-
}
51+
pub struct AllocId(usize, ReferencesTls);
52+
index_impl!(AllocId);
6153

6254
/// Utility function used to read an allocation data into a unassigned integer.
6355
pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {

compiler/rustc_public/src/mir/mono.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use serde::Serialize;
77
use crate::abi::FnAbi;
88
use crate::crate_def::CrateDef;
99
use crate::mir::Body;
10-
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty};
11-
use crate::{CrateItem, DefId, Error, IndexedVal, ItemKind, Opaque, Symbol, with};
10+
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty, index_impl};
11+
use crate::{CrateItem, DefId, Error, ItemKind, Opaque, ReferencesTls, Symbol, with};
1212

1313
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
1414
pub enum MonoItem {
@@ -242,7 +242,8 @@ impl From<StaticDef> for CrateItem {
242242
}
243243

244244
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
245-
pub struct InstanceDef(usize);
245+
pub struct InstanceDef(usize, ReferencesTls);
246+
index_impl!(InstanceDef);
246247

247248
impl CrateDef for InstanceDef {
248249
fn def_id(&self) -> DefId {
@@ -294,12 +295,3 @@ impl StaticDef {
294295
with(|cx| cx.eval_static_initializer(*self))
295296
}
296297
}
297-
298-
impl IndexedVal for InstanceDef {
299-
fn to_val(index: usize) -> Self {
300-
InstanceDef(index)
301-
}
302-
fn to_index(&self) -> usize {
303-
self.0
304-
}
305-
}

compiler/rustc_public/src/ty.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType};
1111
use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
1212
use crate::mir::mono::StaticDef;
1313
use crate::target::MachineInfo;
14-
use crate::{Filename, IndexedVal, Opaque};
14+
use crate::{Filename, IndexedVal, Opaque, ReferencesTls};
1515

1616
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
17-
pub struct Ty(usize);
17+
pub struct Ty(usize, ReferencesTls);
1818

1919
impl Debug for Ty {
2020
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -152,7 +152,7 @@ pub enum TyConstKind {
152152
}
153153

154154
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
155-
pub struct TyConstId(usize);
155+
pub struct TyConstId(usize, ReferencesTls);
156156

157157
/// Represents a constant in MIR
158158
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
@@ -213,7 +213,7 @@ impl MirConst {
213213
}
214214

215215
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
216-
pub struct MirConstId(usize);
216+
pub struct MirConstId(usize, ReferencesTls);
217217

218218
type Ident = Opaque;
219219

@@ -256,7 +256,7 @@ pub struct Placeholder<T> {
256256
}
257257

258258
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
259-
pub struct Span(usize);
259+
pub struct Span(usize, ReferencesTls);
260260

261261
impl Debug for Span {
262262
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -1560,14 +1560,15 @@ macro_rules! index_impl {
15601560
($name:ident) => {
15611561
impl crate::IndexedVal for $name {
15621562
fn to_val(index: usize) -> Self {
1563-
$name(index)
1563+
$name(index, $crate::ReferencesTLS)
15641564
}
15651565
fn to_index(&self) -> usize {
15661566
self.0
15671567
}
15681568
}
15691569
};
15701570
}
1571+
pub(crate) use index_impl;
15711572

15721573
index_impl!(TyConstId);
15731574
index_impl!(MirConstId);
@@ -1588,7 +1589,7 @@ index_impl!(Span);
15881589
/// `c` is in the variant with the `VariantIdx` of `1`, and
15891590
/// `g` is in the variant with the `VariantIdx` of `0`.
15901591
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1591-
pub struct VariantIdx(usize);
1592+
pub struct VariantIdx(usize, ReferencesTls);
15921593

15931594
index_impl!(VariantIdx);
15941595

0 commit comments

Comments
 (0)