rustc_smir/rustc_smir/
mod.rs1use std::ops::RangeInclusive;
11
12use rustc_data_structures::PointeeSized;
13use rustc_hir::def::DefKind;
14use rustc_middle::mir;
15use rustc_middle::mir::interpret::AllocId;
16use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
17use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
18use stable_mir::abi::Layout;
19use stable_mir::mir::mono::{InstanceDef, StaticDef};
20use stable_mir::ty::{FnDef, MirConstId, Span, TyConstId};
21use stable_mir::{CtorKind, ItemKind};
22use tracing::debug;
23
24use crate::rustc_internal::IndexMap;
25use crate::stable_mir;
26
27mod alloc;
28mod builder;
29pub mod context;
30mod convert;
31
32pub struct Tables<'tcx> {
33 pub(crate) tcx: TyCtxt<'tcx>,
34 pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
35 pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
36 pub(crate) spans: IndexMap<rustc_span::Span, Span>,
37 pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
38 pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
39 pub(crate) ty_consts: IndexMap<ty::Const<'tcx>, TyConstId>,
40 pub(crate) mir_consts: IndexMap<mir::Const<'tcx>, MirConstId>,
41 pub(crate) layouts: IndexMap<rustc_abi::Layout<'tcx>, Layout>,
42}
43
44impl<'tcx> Tables<'tcx> {
45 pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
46 self.types.create_or_fetch(ty)
47 }
48
49 pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId {
50 self.ty_consts.create_or_fetch(ct)
51 }
52
53 pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId {
54 self.mir_consts.create_or_fetch(constant)
55 }
56
57 pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool {
62 let def_id = instance.def_id();
63 self.item_has_body(def_id)
64 || !matches!(
65 instance.def,
66 ty::InstanceKind::Virtual(..)
67 | ty::InstanceKind::Intrinsic(..)
68 | ty::InstanceKind::Item(..)
69 )
70 }
71
72 pub(crate) fn item_has_body(&self, def_id: DefId) -> bool {
77 let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) {
78 intrinsic.must_be_overridden
79 } else {
80 false
81 };
82 !must_override && self.tcx.is_mir_available(def_id)
83 }
84
85 fn to_fn_def(&mut self, def_id: DefId) -> Option<FnDef> {
86 if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
87 Some(self.fn_def(def_id))
88 } else {
89 None
90 }
91 }
92
93 fn to_static(&mut self, def_id: DefId) -> Option<StaticDef> {
94 matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| self.static_def(def_id))
95 }
96}
97
98pub(crate) fn filter_def_ids<F, T>(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec<T>
100where
101 F: FnMut(DefId) -> Option<T>,
102{
103 if krate == LOCAL_CRATE {
104 tcx.iter_local_def_id().filter_map(|did| func(did.to_def_id())).collect()
105 } else {
106 let num_definitions = tcx.num_extern_def_ids(krate);
107 (0..num_definitions)
108 .filter_map(move |i| {
109 let def_id = DefId { krate, index: rustc_span::def_id::DefIndex::from_usize(i) };
110 func(def_id)
111 })
112 .collect()
113 }
114}
115
116pub(crate) fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
118 let crate_name = tcx.crate_name(crate_num).to_string();
119 let is_local = crate_num == LOCAL_CRATE;
120 debug!(?crate_name, ?crate_num, "smir_crate");
121 stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
122}
123
124pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
125 match kind {
126 DefKind::Mod
127 | DefKind::Struct
128 | DefKind::Union
129 | DefKind::Enum
130 | DefKind::Variant
131 | DefKind::Trait
132 | DefKind::TyAlias
133 | DefKind::ForeignTy
134 | DefKind::TraitAlias
135 | DefKind::AssocTy
136 | DefKind::TyParam
137 | DefKind::ConstParam
138 | DefKind::Macro(_)
139 | DefKind::ExternCrate
140 | DefKind::Use
141 | DefKind::ForeignMod
142 | DefKind::OpaqueTy
143 | DefKind::Field
144 | DefKind::LifetimeParam
145 | DefKind::Impl { .. }
146 | DefKind::GlobalAsm => {
147 unreachable!("Not a valid item kind: {kind:?}");
148 }
149 DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
150 ItemKind::Fn
151 }
152 DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
153 ItemKind::Const
154 }
155 DefKind::Static { .. } => ItemKind::Static,
156 DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
157 DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
158 }
159}
160
161pub trait Stable<'cx>: PointeeSized {
163 type T;
165 fn stable(&self, tables: &mut Tables<'_>) -> Self::T;
167}
168
169impl<'tcx, T> Stable<'tcx> for &T
170where
171 T: Stable<'tcx>,
172{
173 type T = T::T;
174
175 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
176 (*self).stable(tables)
177 }
178}
179
180impl<'tcx, T> Stable<'tcx> for Option<T>
181where
182 T: Stable<'tcx>,
183{
184 type T = Option<T::T>;
185
186 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
187 self.as_ref().map(|value| value.stable(tables))
188 }
189}
190
191impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
192where
193 T: Stable<'tcx>,
194 E: Stable<'tcx>,
195{
196 type T = Result<T::T, E::T>;
197
198 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
199 match self {
200 Ok(val) => Ok(val.stable(tables)),
201 Err(error) => Err(error.stable(tables)),
202 }
203 }
204}
205
206impl<'tcx, T> Stable<'tcx> for &[T]
207where
208 T: Stable<'tcx>,
209{
210 type T = Vec<T::T>;
211 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
212 self.iter().map(|e| e.stable(tables)).collect()
213 }
214}
215
216impl<'tcx, T, U> Stable<'tcx> for (T, U)
217where
218 T: Stable<'tcx>,
219 U: Stable<'tcx>,
220{
221 type T = (T::T, U::T);
222 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
223 (self.0.stable(tables), self.1.stable(tables))
224 }
225}
226
227impl<'tcx, T> Stable<'tcx> for RangeInclusive<T>
228where
229 T: Stable<'tcx>,
230{
231 type T = RangeInclusive<T::T>;
232 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
233 RangeInclusive::new(self.start().stable(tables), self.end().stable(tables))
234 }
235}