Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d1723f6

Browse files
authoredOct 24, 2023
Rollup merge of rust-lang#117010 - celinval:smir-internal, r=oli-obk
Add method to convert internal to stable constructs This is an alternative implementation to rust-lang#116999. I believe we can still improve the logic a bit here, but I wanted to see which direction we should go first. In this implementation, the API is simpler and we keep Tables somewhat private. The definition is still public though, since we have to expose the Stable trait. However, there's a cost of keeping another thread-local and using `Rc`, but I'm hoping it will be a small cost. r? `@oli-obk` r? `@spastorino`
2 parents edba0cb + ae86f59 commit d1723f6

File tree

7 files changed

+281
-141
lines changed

7 files changed

+281
-141
lines changed
 

‎Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,6 +4525,7 @@ dependencies = [
45254525
"rustc_middle",
45264526
"rustc_span",
45274527
"rustc_target",
4528+
"scoped-tls",
45284529
"stable_mir",
45294530
"tracing",
45304531
]

‎compiler/rustc_smir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rustc_hir = { path = "../rustc_hir" }
99
rustc_middle = { path = "../rustc_middle" }
1010
rustc_span = { path = "../rustc_span" }
1111
rustc_target = { path = "../rustc_target" }
12+
scoped-tls = "1.0"
1213
stable_mir = {path = "../stable_mir" }
1314
tracing = "0.1"
1415

‎compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,32 @@
33
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
44
//! until stable MIR is complete.
55
6-
use crate::rustc_smir::Tables;
6+
use crate::rustc_smir::{Stable, Tables, TablesWrapper};
77
use rustc_data_structures::fx;
88
use rustc_data_structures::fx::FxIndexMap;
99
use rustc_middle::mir::interpret::AllocId;
1010
use rustc_middle::ty;
1111
use rustc_middle::ty::TyCtxt;
1212
use rustc_span::def_id::{CrateNum, DefId};
1313
use rustc_span::Span;
14+
use scoped_tls::scoped_thread_local;
1415
use stable_mir::ty::IndexedVal;
16+
use std::cell::Cell;
17+
use std::cell::RefCell;
1518
use std::fmt::Debug;
1619
use std::hash::Hash;
1720
use std::ops::Index;
1821

1922
mod internal;
2023

24+
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
25+
with_tables(|tables| item.stable(tables))
26+
}
27+
28+
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
29+
with_tables(|tables| item.internal(tables))
30+
}
31+
2132
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2233
type Output = DefId;
2334

@@ -125,18 +136,41 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
125136
item.id.into()
126137
}
127138

139+
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
140+
// datastructures and stable MIR datastructures
141+
scoped_thread_local! (static TLV: Cell<*const ()>);
142+
143+
pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
144+
assert!(!TLV.is_set());
145+
let ptr = tables as *const _ as *const ();
146+
TLV.set(&Cell::new(ptr), || {
147+
f();
148+
});
149+
}
150+
151+
/// Loads the current context and calls a function with it.
152+
/// Do not nest these, as that will ICE.
153+
pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R {
154+
assert!(TLV.is_set());
155+
TLV.with(|tlv| {
156+
let ptr = tlv.get();
157+
assert!(!ptr.is_null());
158+
let wrapper = ptr as *const TablesWrapper<'tcx>;
159+
let mut tables = unsafe { (*wrapper).0.borrow_mut() };
160+
f(&mut *tables)
161+
})
162+
}
163+
128164
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
129-
stable_mir::run(
130-
Tables {
131-
tcx,
132-
def_ids: IndexMap::default(),
133-
alloc_ids: IndexMap::default(),
134-
spans: IndexMap::default(),
135-
types: vec![],
136-
instances: IndexMap::default(),
137-
},
138-
f,
139-
);
165+
let tables = TablesWrapper(RefCell::new(Tables {
166+
tcx,
167+
def_ids: IndexMap::default(),
168+
alloc_ids: IndexMap::default(),
169+
spans: IndexMap::default(),
170+
types: vec![],
171+
instances: IndexMap::default(),
172+
}));
173+
stable_mir::run(&tables, || init(&tables, f));
140174
}
141175

142176
#[macro_export]
@@ -251,7 +285,7 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
251285
/// Trait used to translate a stable construct to its rustc counterpart.
252286
///
253287
/// This is basically a mirror of [crate::rustc_smir::Stable].
254-
pub(crate) trait RustcInternal<'tcx> {
288+
pub trait RustcInternal<'tcx> {
255289
type T;
256290
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
257291
}

‎compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 123 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,31 @@ use stable_mir::ty::{
2323
FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
2424
};
2525
use stable_mir::{self, opaque, Context, Filename};
26+
use std::cell::RefCell;
2627
use tracing::debug;
2728

2829
mod alloc;
2930
mod builder;
3031

31-
impl<'tcx> Context for Tables<'tcx> {
32+
impl<'tcx> Context for TablesWrapper<'tcx> {
3233
fn local_crate(&self) -> stable_mir::Crate {
33-
smir_crate(self.tcx, LOCAL_CRATE)
34+
let tables = self.0.borrow();
35+
smir_crate(tables.tcx, LOCAL_CRATE)
3436
}
3537

3638
fn external_crates(&self) -> Vec<stable_mir::Crate> {
37-
self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect()
39+
let tables = self.0.borrow();
40+
tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
3841
}
3942

4043
fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
44+
let tables = self.0.borrow();
4145
let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
4246
.iter()
43-
.chain(self.tcx.crates(()).iter())
47+
.chain(tables.tcx.crates(()).iter())
4448
.map(|crate_num| {
45-
let crate_name = self.tcx.crate_name(*crate_num).to_string();
46-
(name == crate_name).then(|| smir_crate(self.tcx, *crate_num))
49+
let crate_name = tables.tcx.crate_name(*crate_num).to_string();
50+
(name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
4751
})
4852
.into_iter()
4953
.filter_map(|c| c)
@@ -52,163 +56,197 @@ impl<'tcx> Context for Tables<'tcx> {
5256
}
5357

5458
fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
55-
self.tcx.def_path_str(self[def_id])
59+
let tables = self.0.borrow();
60+
tables.tcx.def_path_str(tables[def_id])
5661
}
5762

5863
fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
59-
self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
64+
let tables = self.0.borrow();
65+
tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
6066
}
6167

6268
fn get_filename(&self, span: &Span) -> Filename {
69+
let tables = self.0.borrow();
6370
opaque(
64-
&self
71+
&tables
6572
.tcx
6673
.sess
6774
.source_map()
68-
.span_to_filename(self[*span])
75+
.span_to_filename(tables[*span])
6976
.display(rustc_span::FileNameDisplayPreference::Local)
7077
.to_string(),
7178
)
7279
}
7380

7481
fn get_lines(&self, span: &Span) -> LineInfo {
75-
let lines = &self.tcx.sess.source_map().span_to_location_info(self[*span]);
82+
let tables = self.0.borrow();
83+
let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
7684
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
7785
}
7886

79-
fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
80-
self.tcx.def_kind(self[def_id]).stable(self)
87+
fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
88+
let mut tables = self.0.borrow_mut();
89+
tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
8190
}
8291

83-
fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
84-
self.tcx.def_span(self[def_id]).stable(self)
92+
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
93+
let mut tables = self.0.borrow_mut();
94+
tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
8595
}
8696

87-
fn all_local_items(&mut self) -> stable_mir::CrateItems {
88-
self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
97+
fn all_local_items(&self) -> stable_mir::CrateItems {
98+
let mut tables = self.0.borrow_mut();
99+
tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
89100
}
90101

91-
fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
92-
Some(self.crate_item(self.tcx.entry_fn(())?.0))
102+
fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
103+
let mut tables = self.0.borrow_mut();
104+
let tcx = tables.tcx;
105+
Some(tables.crate_item(tcx.entry_fn(())?.0))
93106
}
94107

95-
fn all_trait_decls(&mut self) -> stable_mir::TraitDecls {
96-
self.tcx
108+
fn all_trait_decls(&self) -> stable_mir::TraitDecls {
109+
let mut tables = self.0.borrow_mut();
110+
tables
111+
.tcx
97112
.traits(LOCAL_CRATE)
98113
.iter()
99-
.map(|trait_def_id| self.trait_def(*trait_def_id))
114+
.map(|trait_def_id| tables.trait_def(*trait_def_id))
100115
.collect()
101116
}
102117

103-
fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
104-
let def_id = self[trait_def.0];
105-
let trait_def = self.tcx.trait_def(def_id);
106-
trait_def.stable(self)
118+
fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
119+
let mut tables = self.0.borrow_mut();
120+
let def_id = tables[trait_def.0];
121+
let trait_def = tables.tcx.trait_def(def_id);
122+
trait_def.stable(&mut *tables)
107123
}
108124

109-
fn all_trait_impls(&mut self) -> stable_mir::ImplTraitDecls {
110-
self.tcx
125+
fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
126+
let mut tables = self.0.borrow_mut();
127+
tables
128+
.tcx
111129
.trait_impls_in_crate(LOCAL_CRATE)
112130
.iter()
113-
.map(|impl_def_id| self.impl_def(*impl_def_id))
131+
.map(|impl_def_id| tables.impl_def(*impl_def_id))
114132
.collect()
115133
}
116134

117-
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
118-
let def_id = self[impl_def.0];
119-
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
120-
impl_trait.stable(self)
135+
fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
136+
let mut tables = self.0.borrow_mut();
137+
let def_id = tables[impl_def.0];
138+
let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
139+
impl_trait.stable(&mut *tables)
121140
}
122141

123-
fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body {
124-
let def_id = self[item];
125-
self.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(self)
142+
fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
143+
let mut tables = self.0.borrow_mut();
144+
let def_id = tables[item];
145+
tables.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(&mut tables)
126146
}
127147

128-
fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
129-
self.types[ty.0].clone().stable(self)
148+
fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
149+
let mut tables = self.0.borrow_mut();
150+
tables.types[ty.0].clone().stable(&mut *tables)
130151
}
131152

132-
fn mk_ty(&mut self, kind: TyKind) -> stable_mir::ty::Ty {
133-
let n = self.types.len();
134-
self.types.push(MaybeStable::Stable(kind));
153+
fn mk_ty(&self, kind: TyKind) -> stable_mir::ty::Ty {
154+
let mut tables = self.0.borrow_mut();
155+
let n = tables.types.len();
156+
tables.types.push(MaybeStable::Stable(kind));
135157
stable_mir::ty::Ty(n)
136158
}
137159

138-
fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
139-
let def_id = self[def_id];
140-
let generics = self.tcx.generics_of(def_id);
141-
generics.stable(self)
160+
fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
161+
let mut tables = self.0.borrow_mut();
162+
let def_id = tables[def_id];
163+
let generics = tables.tcx.generics_of(def_id);
164+
generics.stable(&mut *tables)
142165
}
143166

144-
fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
145-
let def_id = self[def_id];
146-
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
167+
fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
168+
let mut tables = self.0.borrow_mut();
169+
let def_id = tables[def_id];
170+
let ty::GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
147171
stable_mir::ty::GenericPredicates {
148-
parent: parent.map(|did| self.trait_def(did)),
172+
parent: parent.map(|did| tables.trait_def(did)),
149173
predicates: predicates
150174
.iter()
151175
.map(|(clause, span)| {
152-
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
176+
(
177+
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
178+
span.stable(&mut *tables),
179+
)
153180
})
154181
.collect(),
155182
}
156183
}
157184

158185
fn explicit_predicates_of(
159-
&mut self,
186+
&self,
160187
def_id: stable_mir::DefId,
161188
) -> stable_mir::ty::GenericPredicates {
162-
let def_id = self[def_id];
163-
let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
189+
let mut tables = self.0.borrow_mut();
190+
let def_id = tables[def_id];
191+
let ty::GenericPredicates { parent, predicates } =
192+
tables.tcx.explicit_predicates_of(def_id);
164193
stable_mir::ty::GenericPredicates {
165-
parent: parent.map(|did| self.trait_def(did)),
194+
parent: parent.map(|did| tables.trait_def(did)),
166195
predicates: predicates
167196
.iter()
168197
.map(|(clause, span)| {
169-
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
198+
(
199+
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
200+
span.stable(&mut *tables),
201+
)
170202
})
171203
.collect(),
172204
}
173205
}
174206

175-
fn instance_body(&mut self, def: InstanceDef) -> Body {
176-
let instance = self.instances[def];
177-
builder::BodyBuilder::new(self.tcx, instance).build(self)
207+
fn instance_body(&self, def: InstanceDef) -> Body {
208+
let mut tables = self.0.borrow_mut();
209+
let instance = tables.instances[def];
210+
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
178211
}
179212

180-
fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
181-
let instance = self.instances[def];
182-
let ty = instance.ty(self.tcx, ParamEnv::empty());
183-
self.intern_ty(ty)
213+
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
214+
let mut tables = self.0.borrow_mut();
215+
let instance = tables.instances[def];
216+
let ty = instance.ty(tables.tcx, ParamEnv::empty());
217+
tables.intern_ty(ty)
184218
}
185219

186-
fn instance_def_id(&mut self, def: InstanceDef) -> stable_mir::DefId {
187-
let def_id = self.instances[def].def_id();
188-
self.create_def_id(def_id)
220+
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
221+
let mut tables = self.0.borrow_mut();
222+
let def_id = tables.instances[def].def_id();
223+
tables.create_def_id(def_id)
189224
}
190225

191-
fn mono_instance(&mut self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
192-
let def_id = self[item.0];
193-
Instance::mono(self.tcx, def_id).stable(self)
226+
fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
227+
let mut tables = self.0.borrow_mut();
228+
let def_id = tables[item.0];
229+
Instance::mono(tables.tcx, def_id).stable(&mut *tables)
194230
}
195231

196232
fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
197-
let def_id = self[def_id];
198-
let generics = self.tcx.generics_of(def_id);
199-
let result = generics.requires_monomorphization(self.tcx);
233+
let tables = self.0.borrow();
234+
let def_id = tables[def_id];
235+
let generics = tables.tcx.generics_of(def_id);
236+
let result = generics.requires_monomorphization(tables.tcx);
200237
result
201238
}
202239

203240
fn resolve_instance(
204-
&mut self,
241+
&self,
205242
def: stable_mir::ty::FnDef,
206243
args: &stable_mir::ty::GenericArgs,
207244
) -> Option<stable_mir::mir::mono::Instance> {
208-
let def_id = def.0.internal(self);
209-
let args_ref = args.internal(self);
210-
match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
211-
Ok(Some(instance)) => Some(instance.stable(self)),
245+
let mut tables = self.0.borrow_mut();
246+
let def_id = def.0.internal(&mut *tables);
247+
let args_ref = args.internal(&mut *tables);
248+
match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
249+
Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
212250
Ok(None) | Err(_) => None,
213251
}
214252
}
@@ -241,13 +279,15 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
241279
}
242280
}
243281

282+
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
283+
244284
pub struct Tables<'tcx> {
245-
pub tcx: TyCtxt<'tcx>,
246-
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
247-
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
248-
pub spans: IndexMap<rustc_span::Span, Span>,
249-
pub types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
250-
pub instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
285+
pub(crate) tcx: TyCtxt<'tcx>,
286+
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
287+
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
288+
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
289+
pub(crate) types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
290+
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
251291
}
252292

253293
impl<'tcx> Tables<'tcx> {
@@ -270,7 +310,7 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
270310
}
271311

272312
/// Trait used to convert between an internal MIR type to a Stable MIR type.
273-
pub(crate) trait Stable<'tcx> {
313+
pub trait Stable<'tcx> {
274314
/// The stable representation of the type implementing Stable.
275315
type T;
276316
/// Converts an object to the equivalent Stable MIR representation.

‎compiler/stable_mir/src/lib.rs

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,17 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
175175
}
176176

177177
pub trait Context {
178-
fn entry_fn(&mut self) -> Option<CrateItem>;
178+
fn entry_fn(&self) -> Option<CrateItem>;
179179
/// Retrieve all items of the local crate that have a MIR associated with them.
180-
fn all_local_items(&mut self) -> CrateItems;
181-
fn mir_body(&mut self, item: DefId) -> mir::Body;
182-
fn all_trait_decls(&mut self) -> TraitDecls;
183-
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
184-
fn all_trait_impls(&mut self) -> ImplTraitDecls;
185-
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
186-
fn generics_of(&mut self, def_id: DefId) -> Generics;
187-
fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
188-
fn explicit_predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
180+
fn all_local_items(&self) -> CrateItems;
181+
fn mir_body(&self, item: DefId) -> mir::Body;
182+
fn all_trait_decls(&self) -> TraitDecls;
183+
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
184+
fn all_trait_impls(&self) -> ImplTraitDecls;
185+
fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait;
186+
fn generics_of(&self, def_id: DefId) -> Generics;
187+
fn predicates_of(&self, def_id: DefId) -> GenericPredicates;
188+
fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates;
189189
/// Get information about the local crate.
190190
fn local_crate(&self) -> Crate;
191191
/// Retrieve a list of all external crates.
@@ -207,61 +207,58 @@ pub trait Context {
207207
fn get_lines(&self, span: &Span) -> LineInfo;
208208

209209
/// Returns the `kind` of given `DefId`
210-
fn def_kind(&mut self, def_id: DefId) -> DefKind;
210+
fn def_kind(&self, def_id: DefId) -> DefKind;
211211

212212
/// `Span` of an item
213-
fn span_of_an_item(&mut self, def_id: DefId) -> Span;
213+
fn span_of_an_item(&self, def_id: DefId) -> Span;
214214

215215
/// Obtain the representation of a type.
216-
fn ty_kind(&mut self, ty: Ty) -> TyKind;
216+
fn ty_kind(&self, ty: Ty) -> TyKind;
217217

218218
/// Create a new `Ty` from scratch without information from rustc.
219-
fn mk_ty(&mut self, kind: TyKind) -> Ty;
219+
fn mk_ty(&self, kind: TyKind) -> Ty;
220220

221221
/// Get the body of an Instance.
222222
/// FIXME: Monomorphize the body.
223-
fn instance_body(&mut self, instance: InstanceDef) -> Body;
223+
fn instance_body(&self, instance: InstanceDef) -> Body;
224224

225225
/// Get the instance type with generic substitutions applied and lifetimes erased.
226-
fn instance_ty(&mut self, instance: InstanceDef) -> Ty;
226+
fn instance_ty(&self, instance: InstanceDef) -> Ty;
227227

228228
/// Get the instance.
229-
fn instance_def_id(&mut self, instance: InstanceDef) -> DefId;
229+
fn instance_def_id(&self, instance: InstanceDef) -> DefId;
230230

231231
/// Convert a non-generic crate item into an instance.
232232
/// This function will panic if the item is generic.
233-
fn mono_instance(&mut self, item: CrateItem) -> Instance;
233+
fn mono_instance(&self, item: CrateItem) -> Instance;
234234

235235
/// Item requires monomorphization.
236236
fn requires_monomorphization(&self, def_id: DefId) -> bool;
237237

238238
/// Resolve an instance from the given function definition and generic arguments.
239-
fn resolve_instance(&mut self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
239+
fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
240240
}
241241

242242
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
243243
// datastructures and stable MIR datastructures
244-
scoped_thread_local! (static TLV: Cell<*mut ()>);
244+
scoped_thread_local! (static TLV: Cell<*const ()>);
245245

246-
pub fn run(mut context: impl Context, f: impl FnOnce()) {
246+
pub fn run(context: &dyn Context, f: impl FnOnce()) {
247247
assert!(!TLV.is_set());
248-
fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
249-
let ptr: *mut () = &mut context as *mut &mut _ as _;
250-
TLV.set(&Cell::new(ptr), || {
251-
f();
252-
});
253-
}
254-
g(&mut context, f);
248+
let ptr: *const () = &context as *const &_ as _;
249+
TLV.set(&Cell::new(ptr), || {
250+
f();
251+
});
255252
}
256253

257254
/// Loads the current context and calls a function with it.
258255
/// Do not nest these, as that will ICE.
259-
pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
256+
pub fn with<R>(f: impl FnOnce(&dyn Context) -> R) -> R {
260257
assert!(TLV.is_set());
261258
TLV.with(|tlv| {
262259
let ptr = tlv.get();
263260
assert!(!ptr.is_null());
264-
f(unsafe { *(ptr as *mut &mut dyn Context) })
261+
f(unsafe { *(ptr as *const &dyn Context) })
265262
})
266263
}
267264

‎tests/ui-fulldeps/stable-mir/check_instance.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
2-
// Test that users are able to use stable mir APIs to retrieve monomorphized instances
2+
//! Test that users are able to use stable mir APIs to retrieve monomorphized instances
33
44
// ignore-stage1
55
// ignore-cross-compile
@@ -14,15 +14,15 @@
1414
extern crate rustc_middle;
1515
#[macro_use]
1616
extern crate rustc_smir;
17-
extern crate stable_mir;
1817
extern crate rustc_driver;
1918
extern crate rustc_interface;
19+
extern crate stable_mir;
2020

21-
use rustc_middle::ty::TyCtxt;
2221
use mir::{mono::Instance, TerminatorKind::*};
23-
use stable_mir::ty::{TyKind, RigidTy};
24-
use stable_mir::*;
22+
use rustc_middle::ty::TyCtxt;
2523
use rustc_smir::rustc_internal;
24+
use stable_mir::ty::{RigidTy, TyKind};
25+
use stable_mir::*;
2626
use std::io::Write;
2727
use std::ops::ControlFlow;
2828

@@ -33,16 +33,16 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
3333
let items = stable_mir::all_local_items();
3434

3535
// Get all items and split generic vs monomorphic items.
36-
let (generic, mono) : (Vec<_>, Vec<_>) = items.into_iter().partition(|item| {
37-
item.requires_monomorphization()
38-
});
36+
let (generic, mono): (Vec<_>, Vec<_>) =
37+
items.into_iter().partition(|item| item.requires_monomorphization());
3938
assert_eq!(mono.len(), 3, "Expected 2 mono functions and one constant");
4039
assert_eq!(generic.len(), 2, "Expected 2 generic functions");
4140

4241
// For all monomorphic items, get the correspondent instances.
43-
let instances = mono.iter().filter_map(|item| {
44-
mir::mono::Instance::try_from(*item).ok()
45-
}).collect::<Vec<mir::mono::Instance>>();
42+
let instances = mono
43+
.iter()
44+
.filter_map(|item| mir::mono::Instance::try_from(*item).ok())
45+
.collect::<Vec<mir::mono::Instance>>();
4646
assert_eq!(instances.len(), mono.len());
4747

4848
// For all generic items, try_from should fail.
@@ -58,19 +58,22 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
5858
fn test_body(body: mir::Body) {
5959
for term in body.blocks.iter().map(|bb| &bb.terminator) {
6060
match &term.kind {
61-
Call{ func, .. } => {
61+
Call { func, .. } => {
6262
let TyKind::RigidTy(ty) = func.ty(&body.locals).kind() else { unreachable!() };
6363
let RigidTy::FnDef(def, args) = ty else { unreachable!() };
6464
let result = Instance::resolve(def, &args);
6565
assert!(result.is_ok());
6666
}
67-
Goto {..} | Assert{..} | SwitchInt{..} | Return | Drop {..} => { /* Do nothing */}
68-
_ => { unreachable!("Unexpected terminator {term:?}") }
67+
Goto { .. } | Assert { .. } | SwitchInt { .. } | Return | Drop { .. } => {
68+
/* Do nothing */
69+
}
70+
_ => {
71+
unreachable!("Unexpected terminator {term:?}")
72+
}
6973
}
7074
}
7175
}
7276

73-
7477
/// This test will generate and analyze a dummy crate using the stable mir.
7578
/// For that, it will first write the dummy crate into a file.
7679
/// Then it will create a `StableMir` using custom arguments and then
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// run-pass
2+
//! Test that users are able to use retrieve internal constructs from stable ones to help with
3+
//! the migration.
4+
5+
// ignore-stage1
6+
// ignore-cross-compile
7+
// ignore-remote
8+
// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
9+
// edition: 2021
10+
11+
#![feature(rustc_private)]
12+
#![feature(assert_matches)]
13+
#![feature(control_flow_enum)]
14+
15+
#[macro_use]
16+
extern crate rustc_smir;
17+
extern crate rustc_driver;
18+
extern crate rustc_interface;
19+
extern crate rustc_middle;
20+
extern crate stable_mir;
21+
22+
use rustc_middle::ty::TyCtxt;
23+
use rustc_smir::rustc_internal;
24+
use std::io::Write;
25+
use std::ops::ControlFlow;
26+
27+
const CRATE_NAME: &str = "input";
28+
29+
fn test_translation(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
30+
let main_fn = stable_mir::entry_fn().unwrap();
31+
let body = main_fn.body();
32+
let orig_ty = body.locals[0].ty;
33+
let rustc_ty = rustc_internal::internal(&orig_ty);
34+
assert!(rustc_ty.is_unit());
35+
ControlFlow::Continue(())
36+
}
37+
38+
/// This test will generate and analyze a dummy crate using the stable mir.
39+
/// For that, it will first write the dummy crate into a file.
40+
/// Then it will create a `StableMir` using custom arguments and then
41+
/// it will run the compiler.
42+
fn main() {
43+
let path = "internal_input.rs";
44+
generate_input(&path).unwrap();
45+
let args = vec![
46+
"rustc".to_string(),
47+
"--crate-name".to_string(),
48+
CRATE_NAME.to_string(),
49+
path.to_string(),
50+
];
51+
run!(args, tcx, test_translation(tcx)).unwrap();
52+
}
53+
54+
fn generate_input(path: &str) -> std::io::Result<()> {
55+
let mut file = std::fs::File::create(path)?;
56+
write!(
57+
file,
58+
r#"
59+
pub fn main() {{
60+
}}
61+
"#
62+
)?;
63+
Ok(())
64+
}

0 commit comments

Comments
 (0)
Please sign in to comment.