1#![allow(rustc::usage_of_qualified_ty)]
4
5use std::cell::RefCell;
6use std::iter;
7
8use rustc_abi::HasDataLayout;
9use rustc_hir::{Attribute, LangItem};
10use rustc_middle::ty::layout::{
11 FnAbiOf, FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOf, LayoutOfHelpers,
12};
13use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
14use rustc_middle::ty::{
15 GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
16};
17use rustc_middle::{mir, ty};
18use rustc_span::def_id::LOCAL_CRATE;
19use stable_mir::abi::{FnAbi, Layout, LayoutShape};
20use stable_mir::mir::alloc::GlobalAlloc;
21use stable_mir::mir::mono::{InstanceDef, StaticDef};
22use stable_mir::mir::{BinOp, Body, Place, UnOp};
23use stable_mir::target::{MachineInfo, MachineSize};
24use stable_mir::ty::{
25 AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
26 ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty,
27 TyConst, TyKind, UintTy, VariantDef,
28};
29use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};
30
31use crate::rustc_internal::RustcInternal;
32use crate::rustc_smir::builder::BodyBuilder;
33use crate::rustc_smir::{Stable, Tables, alloc, filter_def_ids, new_item_kind, smir_crate};
34use crate::stable_mir;
35
36pub struct SmirCtxt<'tcx>(pub RefCell<Tables<'tcx>>);
41
42impl<'tcx> SmirCtxt<'tcx> {
43 pub fn target_info(&self) -> MachineInfo {
44 let mut tables = self.0.borrow_mut();
45 MachineInfo {
46 endian: tables.tcx.data_layout.endian.stable(&mut *tables),
47 pointer_width: MachineSize::from_bits(
48 tables.tcx.data_layout.pointer_size.bits().try_into().unwrap(),
49 ),
50 }
51 }
52
53 pub fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
54 let mut tables = self.0.borrow_mut();
55 let tcx = tables.tcx;
56 Some(tables.crate_item(tcx.entry_fn(())?.0))
57 }
58
59 pub fn all_local_items(&self) -> stable_mir::CrateItems {
61 let mut tables = self.0.borrow_mut();
62 tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
63 }
64
65 pub fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
68 let mut tables = self.0.borrow_mut();
69 let def_id = tables[item];
70 tables.tcx.instance_mir(rustc_middle::ty::InstanceKind::Item(def_id)).stable(&mut tables)
71 }
72
73 pub fn has_body(&self, def: DefId) -> bool {
75 let mut tables = self.0.borrow_mut();
76 let tcx = tables.tcx;
77 let def_id = def.internal(&mut *tables, tcx);
78 tables.item_has_body(def_id)
79 }
80
81 pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec<stable_mir::ty::ForeignModuleDef> {
82 let mut tables = self.0.borrow_mut();
83 let tcx = tables.tcx;
84 tcx.foreign_modules(crate_num.internal(&mut *tables, tcx))
85 .keys()
86 .map(|mod_def_id| tables.foreign_module_def(*mod_def_id))
87 .collect()
88 }
89
90 pub fn crate_functions(&self, crate_num: CrateNum) -> Vec<FnDef> {
92 let mut tables = self.0.borrow_mut();
93 let tcx = tables.tcx;
94 let krate = crate_num.internal(&mut *tables, tcx);
95 filter_def_ids(tcx, krate, |def_id| tables.to_fn_def(def_id))
96 }
97
98 pub fn crate_statics(&self, crate_num: CrateNum) -> Vec<StaticDef> {
100 let mut tables = self.0.borrow_mut();
101 let tcx = tables.tcx;
102 let krate = crate_num.internal(&mut *tables, tcx);
103 filter_def_ids(tcx, krate, |def_id| tables.to_static(def_id))
104 }
105
106 pub fn foreign_module(
107 &self,
108 mod_def: stable_mir::ty::ForeignModuleDef,
109 ) -> stable_mir::ty::ForeignModule {
110 let mut tables = self.0.borrow_mut();
111 let def_id = tables[mod_def.def_id()];
112 let mod_def = tables.tcx.foreign_modules(def_id.krate).get(&def_id).unwrap();
113 mod_def.stable(&mut *tables)
114 }
115
116 pub fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec<ForeignDef> {
117 let mut tables = self.0.borrow_mut();
118 let def_id = tables[mod_def.def_id()];
119 tables
120 .tcx
121 .foreign_modules(def_id.krate)
122 .get(&def_id)
123 .unwrap()
124 .foreign_items
125 .iter()
126 .map(|item_def| tables.foreign_def(*item_def))
127 .collect()
128 }
129
130 pub fn all_trait_decls(&self) -> stable_mir::TraitDecls {
131 let mut tables = self.0.borrow_mut();
132 tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect()
133 }
134
135 pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls {
136 let mut tables = self.0.borrow_mut();
137 let tcx = tables.tcx;
138 tcx.traits(crate_num.internal(&mut *tables, tcx))
139 .iter()
140 .map(|trait_def_id| tables.trait_def(*trait_def_id))
141 .collect()
142 }
143
144 pub fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
145 let mut tables = self.0.borrow_mut();
146 let def_id = tables[trait_def.0];
147 let trait_def = tables.tcx.trait_def(def_id);
148 trait_def.stable(&mut *tables)
149 }
150
151 pub fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
152 let mut tables = self.0.borrow_mut();
153 let tcx = tables.tcx;
154 iter::once(LOCAL_CRATE)
155 .chain(tables.tcx.crates(()).iter().copied())
156 .flat_map(|cnum| tcx.trait_impls_in_crate(cnum).iter())
157 .map(|impl_def_id| tables.impl_def(*impl_def_id))
158 .collect()
159 }
160
161 pub fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls {
162 let mut tables = self.0.borrow_mut();
163 let tcx = tables.tcx;
164 tcx.trait_impls_in_crate(crate_num.internal(&mut *tables, tcx))
165 .iter()
166 .map(|impl_def_id| tables.impl_def(*impl_def_id))
167 .collect()
168 }
169
170 pub fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
171 let mut tables = self.0.borrow_mut();
172 let def_id = tables[impl_def.0];
173 let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
174 impl_trait.stable(&mut *tables)
175 }
176
177 pub fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
178 let mut tables = self.0.borrow_mut();
179 let def_id = tables[def_id];
180 let generics = tables.tcx.generics_of(def_id);
181 generics.stable(&mut *tables)
182 }
183
184 pub fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
185 let mut tables = self.0.borrow_mut();
186 let def_id = tables[def_id];
187 let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
188 stable_mir::ty::GenericPredicates {
189 parent: parent.map(|did| tables.trait_def(did)),
190 predicates: predicates
191 .iter()
192 .map(|(clause, span)| {
193 (
194 clause.as_predicate().kind().skip_binder().stable(&mut *tables),
195 span.stable(&mut *tables),
196 )
197 })
198 .collect(),
199 }
200 }
201
202 pub fn explicit_predicates_of(
203 &self,
204 def_id: stable_mir::DefId,
205 ) -> stable_mir::ty::GenericPredicates {
206 let mut tables = self.0.borrow_mut();
207 let def_id = tables[def_id];
208 let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id);
209 stable_mir::ty::GenericPredicates {
210 parent: parent.map(|did| tables.trait_def(did)),
211 predicates: predicates
212 .iter()
213 .map(|(clause, span)| {
214 (
215 clause.as_predicate().kind().skip_binder().stable(&mut *tables),
216 span.stable(&mut *tables),
217 )
218 })
219 .collect(),
220 }
221 }
222
223 pub fn local_crate(&self) -> stable_mir::Crate {
225 let tables = self.0.borrow();
226 smir_crate(tables.tcx, LOCAL_CRATE)
227 }
228
229 pub fn external_crates(&self) -> Vec<stable_mir::Crate> {
231 let tables = self.0.borrow();
232 tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
233 }
234
235 pub fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
237 let tables = self.0.borrow();
238 let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
239 .iter()
240 .chain(tables.tcx.crates(()).iter())
241 .filter_map(|crate_num| {
242 let crate_name = tables.tcx.crate_name(*crate_num).to_string();
243 (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
244 })
245 .collect();
246 crates
247 }
248
249 pub fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
251 let tables = self.0.borrow();
252 if trimmed {
253 with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
254 } else {
255 with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
256 }
257 }
258
259 pub fn tool_attrs(
267 &self,
268 def_id: stable_mir::DefId,
269 attr: &[stable_mir::Symbol],
270 ) -> Vec<stable_mir::crate_def::Attribute> {
271 let mut tables = self.0.borrow_mut();
272 let tcx = tables.tcx;
273 let did = tables[def_id];
274 let attr_name: Vec<_> = attr.iter().map(|seg| rustc_span::Symbol::intern(&seg)).collect();
275 tcx.get_attrs_by_path(did, &attr_name)
276 .filter_map(|attribute| {
277 if let Attribute::Unparsed(u) = attribute {
278 let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
279 Some(stable_mir::crate_def::Attribute::new(
280 attr_str,
281 u.span.stable(&mut *tables),
282 ))
283 } else {
284 None
285 }
286 })
287 .collect()
288 }
289
290 pub fn all_tool_attrs(
292 &self,
293 def_id: stable_mir::DefId,
294 ) -> Vec<stable_mir::crate_def::Attribute> {
295 let mut tables = self.0.borrow_mut();
296 let tcx = tables.tcx;
297 let did = tables[def_id];
298 let attrs_iter = if let Some(did) = did.as_local() {
299 tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter()
300 } else {
301 tcx.attrs_for_def(did).iter()
302 };
303 attrs_iter
304 .filter_map(|attribute| {
305 if let Attribute::Unparsed(u) = attribute {
306 let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
307 Some(stable_mir::crate_def::Attribute::new(
308 attr_str,
309 u.span.stable(&mut *tables),
310 ))
311 } else {
312 None
313 }
314 })
315 .collect()
316 }
317
318 pub fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
320 let tables = self.0.borrow();
321 tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
322 }
323
324 pub fn get_filename(&self, span: &Span) -> Filename {
326 let tables = self.0.borrow();
327 tables
328 .tcx
329 .sess
330 .source_map()
331 .span_to_filename(tables[*span])
332 .display(rustc_span::FileNameDisplayPreference::Local)
333 .to_string()
334 }
335
336 pub fn get_lines(&self, span: &Span) -> LineInfo {
338 let tables = self.0.borrow();
339 let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
340 LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
341 }
342
343 pub fn item_kind(&self, item: CrateItem) -> ItemKind {
345 let tables = self.0.borrow();
346 new_item_kind(tables.tcx.def_kind(tables[item.0]))
347 }
348
349 pub fn is_foreign_item(&self, item: DefId) -> bool {
351 let tables = self.0.borrow();
352 tables.tcx.is_foreign_item(tables[item])
353 }
354
355 pub fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind {
357 let mut tables = self.0.borrow_mut();
358 let def_id = tables[def.def_id()];
359 let tcx = tables.tcx;
360 use rustc_hir::def::DefKind;
361 match tcx.def_kind(def_id) {
362 DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
363 DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)),
364 DefKind::ForeignTy => ForeignItemKind::Type(
365 tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)),
366 ),
367 def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
368 }
369 }
370
371 pub fn adt_kind(&self, def: AdtDef) -> AdtKind {
373 let mut tables = self.0.borrow_mut();
374 let tcx = tables.tcx;
375 def.internal(&mut *tables, tcx).adt_kind().stable(&mut *tables)
376 }
377
378 pub fn adt_is_box(&self, def: AdtDef) -> bool {
380 let mut tables = self.0.borrow_mut();
381 let tcx = tables.tcx;
382 def.internal(&mut *tables, tcx).is_box()
383 }
384
385 pub fn adt_is_simd(&self, def: AdtDef) -> bool {
387 let mut tables = self.0.borrow_mut();
388 let tcx = tables.tcx;
389 def.internal(&mut *tables, tcx).repr().simd()
390 }
391
392 pub fn adt_is_cstr(&self, def: AdtDef) -> bool {
394 let mut tables = self.0.borrow_mut();
395 let tcx = tables.tcx;
396 let def_id = def.0.internal(&mut *tables, tcx);
397 tables.tcx.is_lang_item(def_id, LangItem::CStr)
398 }
399
400 pub fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
402 let mut tables = self.0.borrow_mut();
403 let tcx = tables.tcx;
404 let def_id = def.0.internal(&mut *tables, tcx);
405 let sig =
406 tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables, tcx));
407 sig.stable(&mut *tables)
408 }
409
410 pub fn intrinsic(&self, def: DefId) -> Option<IntrinsicDef> {
412 let mut tables = self.0.borrow_mut();
413 let tcx = tables.tcx;
414 let def_id = def.internal(&mut *tables, tcx);
415 let intrinsic = tcx.intrinsic_raw(def_id);
416 intrinsic.map(|_| IntrinsicDef(def))
417 }
418
419 pub fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol {
421 let mut tables = self.0.borrow_mut();
422 let tcx = tables.tcx;
423 let def_id = def.0.internal(&mut *tables, tcx);
424 tcx.intrinsic(def_id).unwrap().name.to_string()
425 }
426
427 pub fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig {
429 let mut tables = self.0.borrow_mut();
430 let tcx = tables.tcx;
431 let args_ref = args.internal(&mut *tables, tcx);
432 let sig = args_ref.as_closure().sig();
433 sig.stable(&mut *tables)
434 }
435
436 pub fn adt_variants_len(&self, def: AdtDef) -> usize {
438 let mut tables = self.0.borrow_mut();
439 let tcx = tables.tcx;
440 def.internal(&mut *tables, tcx).variants().len()
441 }
442
443 pub fn variant_name(&self, def: VariantDef) -> Symbol {
445 let mut tables = self.0.borrow_mut();
446 let tcx = tables.tcx;
447 def.internal(&mut *tables, tcx).name.to_string()
448 }
449
450 pub fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef> {
451 let mut tables = self.0.borrow_mut();
452 let tcx = tables.tcx;
453 def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect()
454 }
455
456 pub fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error> {
458 let mut tables = self.0.borrow_mut();
459 let tcx = tables.tcx;
460 let mir_const = cnst.internal(&mut *tables, tcx);
461 mir_const
462 .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized())
463 .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
464 }
465 pub fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error> {
466 let mut tables = self.0.borrow_mut();
467 let tcx = tables.tcx;
468 let mir_const = cnst.internal(&mut *tables, tcx);
469 mir_const
470 .try_to_target_usize(tables.tcx)
471 .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
472 }
473
474 pub fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error> {
476 let mut tables = self.0.borrow_mut();
477 let tcx = tables.tcx;
478 let ty_internal = ty.internal(&mut *tables, tcx);
479 let size = tables
480 .tcx
481 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty_internal))
482 .map_err(|err| {
483 Error::new(format!(
484 "Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
485 ))
486 })?
487 .size;
488 if size.bytes() != 0 {
489 return Err(Error::new(format!(
490 "Cannot create a zero-sized constant for type `{ty_internal}`: \
491 Type `{ty_internal}` has {} bytes",
492 size.bytes()
493 )));
494 }
495
496 Ok(mir::Const::Ty(ty_internal, ty::Const::zero_sized(tables.tcx, ty_internal))
497 .stable(&mut *tables))
498 }
499
500 pub fn new_const_str(&self, value: &str) -> MirConst {
502 let mut tables = self.0.borrow_mut();
503 let tcx = tables.tcx;
504 let ty = ty::Ty::new_static_str(tcx);
505 let bytes = value.as_bytes();
506 let valtree = ty::ValTree::from_raw_bytes(tcx, bytes);
507 let cv = ty::Value { ty, valtree };
508 let val = tcx.valtree_to_const_val(cv);
509 mir::Const::from_value(val, ty).stable(&mut tables)
510 }
511
512 pub fn new_const_bool(&self, value: bool) -> MirConst {
514 let mut tables = self.0.borrow_mut();
515 mir::Const::from_bool(tables.tcx, value).stable(&mut tables)
516 }
517
518 pub fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
520 let mut tables = self.0.borrow_mut();
521 let tcx = tables.tcx;
522 let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
523 let size = tables
524 .tcx
525 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
526 .unwrap()
527 .size;
528 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
529 Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
530 })?;
531 Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty)
532 .stable(&mut tables))
533 }
534 pub fn try_new_ty_const_uint(
535 &self,
536 value: u128,
537 uint_ty: UintTy,
538 ) -> Result<stable_mir::ty::TyConst, Error> {
539 let mut tables = self.0.borrow_mut();
540 let tcx = tables.tcx;
541 let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
542 let size = tables
543 .tcx
544 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
545 .unwrap()
546 .size;
547
548 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
550 Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
551 })?;
552 Ok(ty::Const::new_value(tcx, ValTree::from_scalar_int(tcx, scalar), ty)
553 .stable(&mut *tables))
554 }
555
556 pub fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty {
558 let mut tables = self.0.borrow_mut();
559 let tcx = tables.tcx;
560 let internal_kind = kind.internal(&mut *tables, tcx);
561 tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables)
562 }
563
564 pub fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty {
566 let mut tables = self.0.borrow_mut();
567 let tcx = tables.tcx;
568 let inner = ty.internal(&mut *tables, tcx);
569 ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables)
570 }
571
572 pub fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
574 let mut tables = self.0.borrow_mut();
575 let tcx = tables.tcx;
576 tcx.type_of(item.internal(&mut *tables, tcx)).instantiate_identity().stable(&mut *tables)
577 }
578
579 pub fn def_ty_with_args(
581 &self,
582 item: stable_mir::DefId,
583 args: &GenericArgs,
584 ) -> stable_mir::ty::Ty {
585 let mut tables = self.0.borrow_mut();
586 let tcx = tables.tcx;
587 let args = args.internal(&mut *tables, tcx);
588 let def_ty = tables.tcx.type_of(item.internal(&mut *tables, tcx));
589 tables
590 .tcx
591 .instantiate_and_normalize_erasing_regions(
592 args,
593 ty::TypingEnv::fully_monomorphized(),
594 def_ty,
595 )
596 .stable(&mut *tables)
597 }
598
599 pub fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String {
601 let mut tables = self.0.borrow_mut();
602 let tcx = tables.tcx;
603 cnst.internal(&mut *tables, tcx).to_string()
604 }
605
606 pub fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
608 let mut tables = self.0.borrow_mut();
609 tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
610 }
611
612 pub fn ty_pretty(&self, ty: stable_mir::ty::Ty) -> String {
614 let tables = self.0.borrow_mut();
615 tables.types[ty].to_string()
616 }
617
618 pub fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
620 let mut tables = self.0.borrow_mut();
621 tables.types[ty].kind().stable(&mut *tables)
622 }
623
624 pub fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String {
625 let tables = self.0.borrow_mut();
626 tables.ty_consts[ct].to_string()
627 }
628
629 pub fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty {
631 let mut tables = self.0.borrow_mut();
632 let tcx = tables.tcx;
633 let internal_kind = ty.internal(&mut *tables, tcx);
634 let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind);
635 internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables)
636 }
637
638 pub fn instance_body(&self, def: InstanceDef) -> Option<Body> {
640 let mut tables = self.0.borrow_mut();
641 let instance = tables.instances[def];
642 tables
643 .instance_has_body(instance)
644 .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
645 }
646
647 pub fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
649 let mut tables = self.0.borrow_mut();
650 let instance = tables.instances[def];
651 assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
652 instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables)
653 }
654
655 pub fn instance_args(&self, def: InstanceDef) -> GenericArgs {
657 let mut tables = self.0.borrow_mut();
658 let instance = tables.instances[def];
659 instance.args.stable(&mut *tables)
660 }
661
662 pub fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error> {
664 let mut tables = self.0.borrow_mut();
665 let instance = tables.instances[def];
666 Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
667 }
668
669 pub fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
671 let mut tables = self.0.borrow_mut();
672 let tcx = tables.tcx;
673 let sig = fn_ptr.internal(&mut *tables, tcx);
674 Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables))
675 }
676
677 pub fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
679 let mut tables = self.0.borrow_mut();
680 let def_id = tables.instances[def].def_id();
681 tables.create_def_id(def_id)
682 }
683
684 pub fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
686 let tables = self.0.borrow_mut();
687 let instance = tables.instances[instance];
688 tables.tcx.symbol_name(instance).name.to_string()
689 }
690
691 pub fn is_empty_drop_shim(&self, def: InstanceDef) -> bool {
693 let tables = self.0.borrow_mut();
694 let instance = tables.instances[def];
695 matches!(instance.def, ty::InstanceKind::DropGlue(_, None))
696 }
697
698 pub fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
701 let mut tables = self.0.borrow_mut();
702 let def_id = tables[def_id];
703 Instance::mono(tables.tcx, def_id).stable(&mut *tables)
704 }
705
706 pub fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
708 let tables = self.0.borrow();
709 let def_id = tables[def_id];
710 let generics = tables.tcx.generics_of(def_id);
711 let result = generics.requires_monomorphization(tables.tcx);
712 result
713 }
714
715 pub fn resolve_instance(
717 &self,
718 def: stable_mir::ty::FnDef,
719 args: &stable_mir::ty::GenericArgs,
720 ) -> Option<stable_mir::mir::mono::Instance> {
721 let mut tables = self.0.borrow_mut();
722 let tcx = tables.tcx;
723 let def_id = def.0.internal(&mut *tables, tcx);
724 let args_ref = args.internal(&mut *tables, tcx);
725 match Instance::try_resolve(
726 tables.tcx,
727 ty::TypingEnv::fully_monomorphized(),
728 def_id,
729 args_ref,
730 ) {
731 Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
732 Ok(None) | Err(_) => None,
733 }
734 }
735
736 pub fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance {
738 let mut tables = self.0.borrow_mut();
739 let tcx = tables.tcx;
740 let internal_ty = ty.internal(&mut *tables, tcx);
741 let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty);
742 instance.stable(&mut *tables)
743 }
744
745 pub fn resolve_for_fn_ptr(
747 &self,
748 def: FnDef,
749 args: &GenericArgs,
750 ) -> Option<stable_mir::mir::mono::Instance> {
751 let mut tables = self.0.borrow_mut();
752 let tcx = tables.tcx;
753 let def_id = def.0.internal(&mut *tables, tcx);
754 let args_ref = args.internal(&mut *tables, tcx);
755 Instance::resolve_for_fn_ptr(
756 tables.tcx,
757 ty::TypingEnv::fully_monomorphized(),
758 def_id,
759 args_ref,
760 )
761 .stable(&mut *tables)
762 }
763
764 pub fn resolve_closure(
766 &self,
767 def: ClosureDef,
768 args: &GenericArgs,
769 kind: ClosureKind,
770 ) -> Option<stable_mir::mir::mono::Instance> {
771 let mut tables = self.0.borrow_mut();
772 let tcx = tables.tcx;
773 let def_id = def.0.internal(&mut *tables, tcx);
774 let args_ref = args.internal(&mut *tables, tcx);
775 let closure_kind = kind.internal(&mut *tables, tcx);
776 Some(
777 Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind)
778 .stable(&mut *tables),
779 )
780 }
781
782 pub fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result<Allocation, Error> {
784 let mut tables = self.0.borrow_mut();
785 let instance = tables.instances[def];
786 let tcx = tables.tcx;
787 let result = tcx.const_eval_instance(
788 ty::TypingEnv::fully_monomorphized(),
789 instance,
790 tcx.def_span(instance.def_id()),
791 );
792 result
793 .map(|const_val| {
794 alloc::try_new_allocation(
795 const_ty.internal(&mut *tables, tcx),
796 const_val,
797 &mut *tables,
798 )
799 })
800 .map_err(|e| e.stable(&mut *tables))?
801 }
802
803 pub fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
805 let mut tables = self.0.borrow_mut();
806 let tcx = tables.tcx;
807 let def_id = def.0.internal(&mut *tables, tcx);
808 tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
809 }
810
811 pub fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
813 let mut tables = self.0.borrow_mut();
814 let tcx = tables.tcx;
815 let alloc_id = alloc.internal(&mut *tables, tcx);
816 tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
817 }
818
819 pub fn vtable_allocation(
821 &self,
822 global_alloc: &GlobalAlloc,
823 ) -> Option<stable_mir::mir::alloc::AllocId> {
824 let mut tables = self.0.borrow_mut();
825 let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else {
826 return None;
827 };
828 let tcx = tables.tcx;
829 let alloc_id = tables.tcx.vtable_allocation((
830 ty.internal(&mut *tables, tcx),
831 trait_ref
832 .internal(&mut *tables, tcx)
833 .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
834 ));
835 Some(alloc_id.stable(&mut *tables))
836 }
837
838 pub fn krate(&self, def_id: stable_mir::DefId) -> Crate {
839 let tables = self.0.borrow();
840 smir_crate(tables.tcx, tables[def_id].krate)
841 }
842
843 pub fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
847 let tables = self.0.borrow_mut();
848 let instance = tables.instances[def];
849 if trimmed {
850 with_forced_trimmed_paths!(
851 tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
852 )
853 } else {
854 with_no_trimmed_paths!(
855 tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
856 )
857 }
858 }
859
860 pub fn ty_layout(&self, ty: Ty) -> Result<Layout, Error> {
862 let mut tables = self.0.borrow_mut();
863 let tcx = tables.tcx;
864 let ty = ty.internal(&mut *tables, tcx);
865 let layout = tables.layout_of(ty)?.layout;
866 Ok(layout.stable(&mut *tables))
867 }
868
869 pub fn layout_shape(&self, id: Layout) -> LayoutShape {
871 let mut tables = self.0.borrow_mut();
872 let tcx = tables.tcx;
873 id.internal(&mut *tables, tcx).0.stable(&mut *tables)
874 }
875
876 pub fn place_pretty(&self, place: &Place) -> String {
878 let mut tables = self.0.borrow_mut();
879 let tcx = tables.tcx;
880 format!("{:?}", place.internal(&mut *tables, tcx))
881 }
882
883 pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty {
885 let mut tables = self.0.borrow_mut();
886 let tcx = tables.tcx;
887 let rhs_internal = rhs.internal(&mut *tables, tcx);
888 let lhs_internal = lhs.internal(&mut *tables, tcx);
889 let ty = bin_op.internal(&mut *tables, tcx).ty(tcx, rhs_internal, lhs_internal);
890 ty.stable(&mut *tables)
891 }
892
893 pub fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty {
895 let mut tables = self.0.borrow_mut();
896 let tcx = tables.tcx;
897 let arg_internal = arg.internal(&mut *tables, tcx);
898 let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal);
899 ty.stable(&mut *tables)
900 }
901
902 pub fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems {
904 let mut tables = self.0.borrow_mut();
905 let tcx = tables.tcx;
906 let def_id = tables[def_id];
907 let assoc_items = if tcx.is_trait_alias(def_id) {
908 Vec::new()
909 } else {
910 tcx.associated_item_def_ids(def_id)
911 .iter()
912 .map(|did| tcx.associated_item(*did).stable(&mut *tables))
913 .collect()
914 };
915 assoc_items
916 }
917}
918
919impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> {
921 type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, ty::Ty<'tcx>>, Error>;
922
923 #[inline]
924 fn handle_fn_abi_err(
925 &self,
926 err: ty::layout::FnAbiError<'tcx>,
927 _span: rustc_span::Span,
928 fn_abi_request: ty::layout::FnAbiRequest<'tcx>,
929 ) -> Error {
930 Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}"))
931 }
932}
933
934impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> {
935 type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, Error>;
936
937 #[inline]
938 fn handle_layout_err(
939 &self,
940 err: ty::layout::LayoutError<'tcx>,
941 _span: rustc_span::Span,
942 ty: ty::Ty<'tcx>,
943 ) -> Error {
944 Error::new(format!("Failed to get layout for `{ty}`: {err}"))
945 }
946}
947
948impl<'tcx> HasTypingEnv<'tcx> for Tables<'tcx> {
949 fn typing_env(&self) -> ty::TypingEnv<'tcx> {
950 ty::TypingEnv::fully_monomorphized()
951 }
952}
953
954impl<'tcx> HasTyCtxt<'tcx> for Tables<'tcx> {
955 fn tcx(&self) -> TyCtxt<'tcx> {
956 self.tcx
957 }
958}
959
960impl<'tcx> HasDataLayout for Tables<'tcx> {
961 fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
962 self.tcx.data_layout()
963 }
964}