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