Skip to content

Commit a19d727

Browse files
committed
Add more SMIR internal impl and callback return value
In cases like Kani, we will invoke the rustc_internal run command directly for now. It would be handly to be able to have a callback that can return a value. We also need extra methods to convert stable constructs into internal ones, so we can break down the transition into finer grain commits.
1 parent 189d6c7 commit a19d727

File tree

3 files changed

+159
-21
lines changed

3 files changed

+159
-21
lines changed

compiler/rustc_smir/src/rustc_internal/internal.rs

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@
66
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
77
use crate::rustc_smir::Tables;
88
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
9-
use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
10-
use stable_mir::DefId;
9+
use rustc_span::Symbol;
10+
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
11+
use stable_mir::ty::{
12+
Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, GenericArgKind,
13+
GenericArgs, Region, TraitRef, Ty,
14+
};
15+
use stable_mir::{AllocId, CrateItem, DefId};
1116

1217
use super::RustcInternal;
1318

19+
impl<'tcx> RustcInternal<'tcx> for CrateItem {
20+
type T = rustc_span::def_id::DefId;
21+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
22+
self.0.internal(tables)
23+
}
24+
}
25+
1426
impl<'tcx> RustcInternal<'tcx> for DefId {
1527
type T = rustc_span::def_id::DefId;
1628
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
@@ -38,8 +50,9 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
3850

3951
impl<'tcx> RustcInternal<'tcx> for Region {
4052
type T = rustc_ty::Region<'tcx>;
41-
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
42-
todo!()
53+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
54+
// Cannot recover region. Use erased instead.
55+
tables.tcx.lifetimes.re_erased
4356
}
4457
}
4558

@@ -65,3 +78,118 @@ impl<'tcx> RustcInternal<'tcx> for Const {
6578
tables.constants[self.id]
6679
}
6780
}
81+
82+
impl<'tcx> RustcInternal<'tcx> for MonoItem {
83+
type T = rustc_middle::mir::mono::MonoItem<'tcx>;
84+
85+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
86+
use rustc_middle::mir::mono as rustc_mono;
87+
match self {
88+
MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables)),
89+
MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables)),
90+
MonoItem::GlobalAsm(_) => {
91+
unimplemented!()
92+
}
93+
}
94+
}
95+
}
96+
97+
impl<'tcx> RustcInternal<'tcx> for Instance {
98+
type T = rustc_ty::Instance<'tcx>;
99+
100+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
101+
tables.instances[self.def]
102+
}
103+
}
104+
105+
impl<'tcx> RustcInternal<'tcx> for StaticDef {
106+
type T = rustc_span::def_id::DefId;
107+
108+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
109+
self.0.internal(tables)
110+
}
111+
}
112+
113+
#[allow(rustc::usage_of_qualified_ty)]
114+
impl<'tcx, T> RustcInternal<'tcx> for Binder<T>
115+
where
116+
T: RustcInternal<'tcx>,
117+
T::T: rustc_ty::TypeVisitable<rustc_ty::TyCtxt<'tcx>>,
118+
{
119+
type T = rustc_ty::Binder<'tcx, T::T>;
120+
121+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
122+
rustc_ty::Binder::bind_with_vars(
123+
self.value.internal(tables),
124+
tables.tcx.mk_bound_variable_kinds_from_iter(
125+
self.bound_vars.iter().map(|bound| bound.internal(tables)),
126+
),
127+
)
128+
}
129+
}
130+
131+
impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
132+
type T = rustc_ty::BoundVariableKind;
133+
134+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
135+
match self {
136+
BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
137+
BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
138+
BoundTyKind::Param(def, symbol) => {
139+
rustc_ty::BoundTyKind::Param(def.0.internal(tables), Symbol::intern(&symbol))
140+
}
141+
}),
142+
BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind {
143+
BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::BrAnon,
144+
BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed(
145+
def.0.internal(tables),
146+
Symbol::intern(&symbol),
147+
),
148+
BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv,
149+
}),
150+
BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const,
151+
}
152+
}
153+
}
154+
155+
impl<'tcx> RustcInternal<'tcx> for TraitRef {
156+
type T = rustc_ty::TraitRef<'tcx>;
157+
158+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
159+
rustc_ty::TraitRef::new(
160+
tables.tcx,
161+
self.def_id.0.internal(tables),
162+
self.args().internal(tables),
163+
)
164+
}
165+
}
166+
167+
impl<'tcx> RustcInternal<'tcx> for AllocId {
168+
type T = rustc_middle::mir::interpret::AllocId;
169+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
170+
tables.alloc_ids[*self]
171+
}
172+
}
173+
174+
impl<'tcx> RustcInternal<'tcx> for ClosureKind {
175+
type T = rustc_ty::ClosureKind;
176+
177+
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
178+
match self {
179+
ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
180+
ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
181+
ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce,
182+
}
183+
}
184+
}
185+
186+
impl<'tcx, T> RustcInternal<'tcx> for &T
187+
where
188+
T: RustcInternal<'tcx>,
189+
{
190+
type T = T::T;
191+
192+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
193+
(*self).internal(tables)
194+
}
195+
}

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_span::def_id::{CrateNum, DefId};
1313
use rustc_span::Span;
1414
use scoped_tls::scoped_thread_local;
1515
use stable_mir::ty::IndexedVal;
16+
use stable_mir::Error;
1617
use std::cell::Cell;
1718
use std::cell::RefCell;
1819
use std::fmt::Debug;
@@ -21,11 +22,11 @@ use std::ops::Index;
2122

2223
mod internal;
2324

24-
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
25+
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
2526
with_tables(|tables| item.stable(tables))
2627
}
2728

28-
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
29+
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: S) -> S::T {
2930
with_tables(|tables| item.internal(tables))
3031
}
3132

@@ -140,12 +141,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
140141
// datastructures and stable MIR datastructures
141142
scoped_thread_local! (static TLV: Cell<*const ()>);
142143

143-
pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
144+
pub(crate) fn init<'tcx, F, T>(tables: &TablesWrapper<'tcx>, f: F) -> T
145+
where
146+
F: FnOnce() -> T,
147+
{
144148
assert!(!TLV.is_set());
145149
let ptr = tables as *const _ as *const ();
146-
TLV.set(&Cell::new(ptr), || {
147-
f();
148-
});
150+
TLV.set(&Cell::new(ptr), || f())
149151
}
150152

151153
/// Loads the current context and calls a function with it.
@@ -161,7 +163,10 @@ pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R
161163
})
162164
}
163165

164-
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
166+
pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
167+
where
168+
F: FnOnce() -> T,
169+
{
165170
let tables = TablesWrapper(RefCell::new(Tables {
166171
tcx,
167172
def_ids: IndexMap::default(),
@@ -171,7 +176,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
171176
instances: IndexMap::default(),
172177
constants: IndexMap::default(),
173178
}));
174-
stable_mir::run(&tables, || init(&tables, f));
179+
stable_mir::run(&tables, || init(&tables, f))
175180
}
176181

177182
#[macro_export]
@@ -237,7 +242,8 @@ macro_rules! run {
237242
queries.global_ctxt().unwrap().enter(|tcx| {
238243
rustc_internal::run(tcx, || {
239244
self.result = Some((self.callback)(tcx));
240-
});
245+
})
246+
.unwrap();
241247
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
242248
Compilation::Continue
243249
} else {

compiler/stable_mir/src/lib.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub type Symbol = String;
4747
pub type CrateNum = usize;
4848

4949
/// A unique identification number for each item accessible for the current compilation unit.
50-
#[derive(Clone, Copy, PartialEq, Eq)]
50+
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
5151
pub struct DefId(usize);
5252

5353
impl Debug for DefId {
@@ -240,12 +240,16 @@ pub trait Context {
240240
// datastructures and stable MIR datastructures
241241
scoped_thread_local! (static TLV: Cell<*const ()>);
242242

243-
pub fn run(context: &dyn Context, f: impl FnOnce()) {
244-
assert!(!TLV.is_set());
245-
let ptr: *const () = &context as *const &_ as _;
246-
TLV.set(&Cell::new(ptr), || {
247-
f();
248-
});
243+
pub fn run<F, T>(context: &dyn Context, f: F) -> Result<T, Error>
244+
where
245+
F: FnOnce() -> T,
246+
{
247+
if TLV.is_set() {
248+
Err(Error::from("StableMIR already running"))
249+
} else {
250+
let ptr: *const () = &context as *const &_ as _;
251+
TLV.set(&Cell::new(ptr), || Ok(f()))
252+
}
249253
}
250254

251255
/// Loads the current context and calls a function with it.
@@ -260,7 +264,7 @@ pub fn with<R>(f: impl FnOnce(&dyn Context) -> R) -> R {
260264
}
261265

262266
/// A type that provides internal information but that can still be used for debug purpose.
263-
#[derive(Clone, Eq, PartialEq)]
267+
#[derive(Clone, PartialEq, Eq, Hash)]
264268
pub struct Opaque(String);
265269

266270
impl std::fmt::Display for Opaque {

0 commit comments

Comments
 (0)