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