1#![allow(rustc::usage_of_qualified_ty)]
7
8use std::cell::RefCell;
9use std::iter;
10
11use rustc_abi::HasDataLayout;
12use rustc_hir::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 get_attrs_by_path(
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 .map(|attribute| {
257 let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
258 let span = attribute.span;
259 stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
260 })
261 .collect()
262 }
263
264 fn get_all_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def::Attribute> {
265 let mut tables = self.0.borrow_mut();
266 let tcx = tables.tcx;
267 let did = tables[def_id];
268 let filter_fn =
269 move |a: &&rustc_hir::Attribute| matches!(a.kind, rustc_hir::AttrKind::Normal(_));
270 let attrs_iter = if let Some(did) = did.as_local() {
271 tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
272 } else {
273 tcx.attrs_for_def(did).iter().filter(filter_fn)
274 };
275 attrs_iter
276 .map(|attribute| {
277 let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
278 let span = attribute.span;
279 stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
280 })
281 .collect()
282 }
283
284 fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
285 let tables = self.0.borrow();
286 tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
287 }
288
289 fn get_filename(&self, span: &Span) -> Filename {
290 let tables = self.0.borrow();
291 tables
292 .tcx
293 .sess
294 .source_map()
295 .span_to_filename(tables[*span])
296 .display(rustc_span::FileNameDisplayPreference::Local)
297 .to_string()
298 }
299
300 fn get_lines(&self, span: &Span) -> LineInfo {
301 let tables = self.0.borrow();
302 let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
303 LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
304 }
305
306 fn item_kind(&self, item: CrateItem) -> ItemKind {
307 let tables = self.0.borrow();
308 new_item_kind(tables.tcx.def_kind(tables[item.0]))
309 }
310
311 fn is_foreign_item(&self, item: DefId) -> bool {
312 let tables = self.0.borrow();
313 tables.tcx.is_foreign_item(tables[item])
314 }
315
316 fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind {
317 let mut tables = self.0.borrow_mut();
318 let def_id = tables[def.def_id()];
319 let tcx = tables.tcx;
320 use rustc_hir::def::DefKind;
321 match tcx.def_kind(def_id) {
322 DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
323 DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)),
324 DefKind::ForeignTy => ForeignItemKind::Type(
325 tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)),
326 ),
327 def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
328 }
329 }
330
331 fn adt_kind(&self, def: AdtDef) -> AdtKind {
332 let mut tables = self.0.borrow_mut();
333 let tcx = tables.tcx;
334 def.internal(&mut *tables, tcx).adt_kind().stable(&mut *tables)
335 }
336
337 fn adt_is_box(&self, def: AdtDef) -> bool {
338 let mut tables = self.0.borrow_mut();
339 let tcx = tables.tcx;
340 def.internal(&mut *tables, tcx).is_box()
341 }
342
343 fn adt_is_simd(&self, def: AdtDef) -> bool {
344 let mut tables = self.0.borrow_mut();
345 let tcx = tables.tcx;
346 def.internal(&mut *tables, tcx).repr().simd()
347 }
348
349 fn adt_is_cstr(&self, def: AdtDef) -> bool {
350 let mut tables = self.0.borrow_mut();
351 let tcx = tables.tcx;
352 let def_id = def.0.internal(&mut *tables, tcx);
353 tables.tcx.is_lang_item(def_id, LangItem::CStr)
354 }
355
356 fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
357 let mut tables = self.0.borrow_mut();
358 let tcx = tables.tcx;
359 let def_id = def.0.internal(&mut *tables, tcx);
360 let sig =
361 tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables, tcx));
362 sig.stable(&mut *tables)
363 }
364
365 fn intrinsic(&self, def: DefId) -> Option<IntrinsicDef> {
366 let mut tables = self.0.borrow_mut();
367 let tcx = tables.tcx;
368 let def_id = def.internal(&mut *tables, tcx);
369 let intrinsic = tcx.intrinsic_raw(def_id);
370 intrinsic.map(|_| IntrinsicDef(def))
371 }
372
373 fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol {
374 let mut tables = self.0.borrow_mut();
375 let tcx = tables.tcx;
376 let def_id = def.0.internal(&mut *tables, tcx);
377 tcx.intrinsic(def_id).unwrap().name.to_string()
378 }
379
380 fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig {
381 let mut tables = self.0.borrow_mut();
382 let tcx = tables.tcx;
383 let args_ref = args.internal(&mut *tables, tcx);
384 let sig = args_ref.as_closure().sig();
385 sig.stable(&mut *tables)
386 }
387
388 fn adt_variants_len(&self, def: AdtDef) -> usize {
389 let mut tables = self.0.borrow_mut();
390 let tcx = tables.tcx;
391 def.internal(&mut *tables, tcx).variants().len()
392 }
393
394 fn variant_name(&self, def: VariantDef) -> Symbol {
395 let mut tables = self.0.borrow_mut();
396 let tcx = tables.tcx;
397 def.internal(&mut *tables, tcx).name.to_string()
398 }
399
400 fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef> {
401 let mut tables = self.0.borrow_mut();
402 let tcx = tables.tcx;
403 def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect()
404 }
405
406 fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error> {
407 let mut tables = self.0.borrow_mut();
408 let tcx = tables.tcx;
409 let mir_const = cnst.internal(&mut *tables, tcx);
410 mir_const
411 .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized())
412 .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
413 }
414 fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error> {
415 let mut tables = self.0.borrow_mut();
416 let tcx = tables.tcx;
417 let mir_const = cnst.internal(&mut *tables, tcx);
418 mir_const
419 .try_to_target_usize(tables.tcx)
420 .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
421 }
422
423 fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error> {
424 let mut tables = self.0.borrow_mut();
425 let tcx = tables.tcx;
426 let ty_internal = ty.internal(&mut *tables, tcx);
427 let size = tables
428 .tcx
429 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty_internal))
430 .map_err(|err| {
431 Error::new(format!(
432 "Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
433 ))
434 })?
435 .size;
436 if size.bytes() != 0 {
437 return Err(Error::new(format!(
438 "Cannot create a zero-sized constant for type `{ty_internal}`: \
439 Type `{ty_internal}` has {} bytes",
440 size.bytes()
441 )));
442 }
443
444 Ok(mir::Const::Ty(ty_internal, ty::Const::zero_sized(tables.tcx, ty_internal))
445 .stable(&mut *tables))
446 }
447
448 fn new_const_str(&self, value: &str) -> MirConst {
449 let mut tables = self.0.borrow_mut();
450 let tcx = tables.tcx;
451 let ty = ty::Ty::new_static_str(tcx);
452 let bytes = value.as_bytes();
453 let valtree = ty::ValTree::from_raw_bytes(tcx, bytes);
454 let cv = ty::Value { ty, valtree };
455 let val = tcx.valtree_to_const_val(cv);
456 mir::Const::from_value(val, ty).stable(&mut tables)
457 }
458
459 fn new_const_bool(&self, value: bool) -> MirConst {
460 let mut tables = self.0.borrow_mut();
461 mir::Const::from_bool(tables.tcx, value).stable(&mut tables)
462 }
463
464 fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
465 let mut tables = self.0.borrow_mut();
466 let tcx = tables.tcx;
467 let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
468 let size = tables
469 .tcx
470 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
471 .unwrap()
472 .size;
473 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
474 Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
475 })?;
476 Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty)
477 .stable(&mut tables))
478 }
479 fn try_new_ty_const_uint(
480 &self,
481 value: u128,
482 uint_ty: UintTy,
483 ) -> Result<stable_mir::ty::TyConst, Error> {
484 let mut tables = self.0.borrow_mut();
485 let tcx = tables.tcx;
486 let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx));
487 let size = tables
488 .tcx
489 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
490 .unwrap()
491 .size;
492
493 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
495 Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
496 })?;
497 Ok(ty::Const::new_value(tcx, ValTree::from_scalar_int(tcx, scalar), ty)
498 .stable(&mut *tables))
499 }
500
501 fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty {
502 let mut tables = self.0.borrow_mut();
503 let tcx = tables.tcx;
504 let internal_kind = kind.internal(&mut *tables, tcx);
505 tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables)
506 }
507
508 fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty {
509 let mut tables = self.0.borrow_mut();
510 let tcx = tables.tcx;
511 let inner = ty.internal(&mut *tables, tcx);
512 ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables)
513 }
514
515 fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
516 let mut tables = self.0.borrow_mut();
517 let tcx = tables.tcx;
518 tcx.type_of(item.internal(&mut *tables, tcx)).instantiate_identity().stable(&mut *tables)
519 }
520
521 fn def_ty_with_args(&self, item: stable_mir::DefId, args: &GenericArgs) -> stable_mir::ty::Ty {
522 let mut tables = self.0.borrow_mut();
523 let tcx = tables.tcx;
524 let args = args.internal(&mut *tables, tcx);
525 let def_ty = tables.tcx.type_of(item.internal(&mut *tables, tcx));
526 tables
527 .tcx
528 .instantiate_and_normalize_erasing_regions(
529 args,
530 ty::TypingEnv::fully_monomorphized(),
531 def_ty,
532 )
533 .stable(&mut *tables)
534 }
535
536 fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String {
537 let mut tables = self.0.borrow_mut();
538 let tcx = tables.tcx;
539 cnst.internal(&mut *tables, tcx).to_string()
540 }
541
542 fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
543 let mut tables = self.0.borrow_mut();
544 tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
545 }
546
547 fn ty_pretty(&self, ty: stable_mir::ty::Ty) -> String {
548 let tables = self.0.borrow_mut();
549 tables.types[ty].to_string()
550 }
551
552 fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
553 let mut tables = self.0.borrow_mut();
554 tables.types[ty].kind().stable(&mut *tables)
555 }
556
557 fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String {
558 let tables = self.0.borrow_mut();
559 tables.ty_consts[ct].to_string()
560 }
561
562 fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty {
563 let mut tables = self.0.borrow_mut();
564 let tcx = tables.tcx;
565 let internal_kind = ty.internal(&mut *tables, tcx);
566 let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind);
567 internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables)
568 }
569
570 fn instance_body(&self, def: InstanceDef) -> Option<Body> {
571 let mut tables = self.0.borrow_mut();
572 let instance = tables.instances[def];
573 tables
574 .instance_has_body(instance)
575 .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
576 }
577
578 fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
579 let mut tables = self.0.borrow_mut();
580 let instance = tables.instances[def];
581 assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
582 instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables)
583 }
584
585 fn instance_args(&self, def: InstanceDef) -> GenericArgs {
586 let mut tables = self.0.borrow_mut();
587 let instance = tables.instances[def];
588 instance.args.stable(&mut *tables)
589 }
590
591 fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error> {
592 let mut tables = self.0.borrow_mut();
593 let instance = tables.instances[def];
594 Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
595 }
596
597 fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
598 let mut tables = self.0.borrow_mut();
599 let tcx = tables.tcx;
600 let sig = fn_ptr.internal(&mut *tables, tcx);
601 Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables))
602 }
603
604 fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
605 let mut tables = self.0.borrow_mut();
606 let def_id = tables.instances[def].def_id();
607 tables.create_def_id(def_id)
608 }
609
610 fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
611 let tables = self.0.borrow_mut();
612 let instance = tables.instances[instance];
613 tables.tcx.symbol_name(instance).name.to_string()
614 }
615
616 fn is_empty_drop_shim(&self, def: InstanceDef) -> bool {
617 let tables = self.0.borrow_mut();
618 let instance = tables.instances[def];
619 matches!(instance.def, ty::InstanceKind::DropGlue(_, None))
620 }
621
622 fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool {
623 let tables = self.0.borrow_mut();
624 let instance = tables.instances[def];
625 matches!(instance.def, ty::InstanceKind::AsyncDropGlueCtorShim(_, None))
626 }
627
628 fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
629 let mut tables = self.0.borrow_mut();
630 let def_id = tables[def_id];
631 Instance::mono(tables.tcx, def_id).stable(&mut *tables)
632 }
633
634 fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
635 let tables = self.0.borrow();
636 let def_id = tables[def_id];
637 let generics = tables.tcx.generics_of(def_id);
638 let result = generics.requires_monomorphization(tables.tcx);
639 result
640 }
641
642 fn resolve_instance(
643 &self,
644 def: stable_mir::ty::FnDef,
645 args: &stable_mir::ty::GenericArgs,
646 ) -> Option<stable_mir::mir::mono::Instance> {
647 let mut tables = self.0.borrow_mut();
648 let tcx = tables.tcx;
649 let def_id = def.0.internal(&mut *tables, tcx);
650 let args_ref = args.internal(&mut *tables, tcx);
651 match Instance::try_resolve(
652 tables.tcx,
653 ty::TypingEnv::fully_monomorphized(),
654 def_id,
655 args_ref,
656 ) {
657 Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
658 Ok(None) | Err(_) => None,
659 }
660 }
661
662 fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance {
663 let mut tables = self.0.borrow_mut();
664 let tcx = tables.tcx;
665 let internal_ty = ty.internal(&mut *tables, tcx);
666 let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty);
667 instance.stable(&mut *tables)
668 }
669
670 fn resolve_for_fn_ptr(
671 &self,
672 def: FnDef,
673 args: &GenericArgs,
674 ) -> Option<stable_mir::mir::mono::Instance> {
675 let mut tables = self.0.borrow_mut();
676 let tcx = tables.tcx;
677 let def_id = def.0.internal(&mut *tables, tcx);
678 let args_ref = args.internal(&mut *tables, tcx);
679 Instance::resolve_for_fn_ptr(
680 tables.tcx,
681 ty::TypingEnv::fully_monomorphized(),
682 def_id,
683 args_ref,
684 )
685 .stable(&mut *tables)
686 }
687
688 fn resolve_closure(
689 &self,
690 def: ClosureDef,
691 args: &GenericArgs,
692 kind: ClosureKind,
693 ) -> Option<stable_mir::mir::mono::Instance> {
694 let mut tables = self.0.borrow_mut();
695 let tcx = tables.tcx;
696 let def_id = def.0.internal(&mut *tables, tcx);
697 let args_ref = args.internal(&mut *tables, tcx);
698 let closure_kind = kind.internal(&mut *tables, tcx);
699 Some(
700 Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind)
701 .stable(&mut *tables),
702 )
703 }
704
705 fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result<Allocation, Error> {
706 let mut tables = self.0.borrow_mut();
707 let instance = tables.instances[def];
708 let tcx = tables.tcx;
709 let result = tcx.const_eval_instance(
710 ty::TypingEnv::fully_monomorphized(),
711 instance,
712 tcx.def_span(instance.def_id()),
713 );
714 result
715 .map(|const_val| {
716 alloc::try_new_allocation(
717 const_ty.internal(&mut *tables, tcx),
718 const_val,
719 &mut *tables,
720 )
721 })
722 .map_err(|e| e.stable(&mut *tables))?
723 }
724
725 fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
726 let mut tables = self.0.borrow_mut();
727 let tcx = tables.tcx;
728 let def_id = def.0.internal(&mut *tables, tcx);
729 tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
730 }
731
732 fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
733 let mut tables = self.0.borrow_mut();
734 let tcx = tables.tcx;
735 let alloc_id = alloc.internal(&mut *tables, tcx);
736 tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
737 }
738
739 fn vtable_allocation(
740 &self,
741 global_alloc: &GlobalAlloc,
742 ) -> Option<stable_mir::mir::alloc::AllocId> {
743 let mut tables = self.0.borrow_mut();
744 let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else {
745 return None;
746 };
747 let tcx = tables.tcx;
748 let alloc_id = tables.tcx.vtable_allocation((
749 ty.internal(&mut *tables, tcx),
750 trait_ref
751 .internal(&mut *tables, tcx)
752 .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
753 ));
754 Some(alloc_id.stable(&mut *tables))
755 }
756
757 fn krate(&self, def_id: stable_mir::DefId) -> Crate {
758 let tables = self.0.borrow();
759 smir_crate(tables.tcx, tables[def_id].krate)
760 }
761
762 fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
766 let tables = self.0.borrow_mut();
767 let instance = tables.instances[def];
768 if trimmed {
769 with_forced_trimmed_paths!(
770 tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
771 )
772 } else {
773 with_no_trimmed_paths!(
774 tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
775 )
776 }
777 }
778
779 fn ty_layout(&self, ty: Ty) -> Result<Layout, Error> {
780 let mut tables = self.0.borrow_mut();
781 let tcx = tables.tcx;
782 let ty = ty.internal(&mut *tables, tcx);
783 let layout = tables.layout_of(ty)?.layout;
784 Ok(layout.stable(&mut *tables))
785 }
786
787 fn layout_shape(&self, id: Layout) -> LayoutShape {
788 let mut tables = self.0.borrow_mut();
789 let tcx = tables.tcx;
790 id.internal(&mut *tables, tcx).0.stable(&mut *tables)
791 }
792
793 fn place_pretty(&self, place: &Place) -> String {
794 let mut tables = self.0.borrow_mut();
795 let tcx = tables.tcx;
796 format!("{:?}", place.internal(&mut *tables, tcx))
797 }
798
799 fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty {
800 let mut tables = self.0.borrow_mut();
801 let tcx = tables.tcx;
802 let rhs_internal = rhs.internal(&mut *tables, tcx);
803 let lhs_internal = lhs.internal(&mut *tables, tcx);
804 let ty = bin_op.internal(&mut *tables, tcx).ty(tcx, rhs_internal, lhs_internal);
805 ty.stable(&mut *tables)
806 }
807
808 fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty {
809 let mut tables = self.0.borrow_mut();
810 let tcx = tables.tcx;
811 let arg_internal = arg.internal(&mut *tables, tcx);
812 let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal);
813 ty.stable(&mut *tables)
814 }
815}
816
817pub(crate) struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
818
819impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> {
821 type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, ty::Ty<'tcx>>, Error>;
822
823 #[inline]
824 fn handle_fn_abi_err(
825 &self,
826 err: ty::layout::FnAbiError<'tcx>,
827 _span: rustc_span::Span,
828 fn_abi_request: ty::layout::FnAbiRequest<'tcx>,
829 ) -> Error {
830 Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}"))
831 }
832}
833
834impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> {
835 type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, Error>;
836
837 #[inline]
838 fn handle_layout_err(
839 &self,
840 err: ty::layout::LayoutError<'tcx>,
841 _span: rustc_span::Span,
842 ty: ty::Ty<'tcx>,
843 ) -> Error {
844 Error::new(format!("Failed to get layout for `{ty}`: {err}"))
845 }
846}
847
848impl<'tcx> HasTypingEnv<'tcx> for Tables<'tcx> {
849 fn typing_env(&self) -> ty::TypingEnv<'tcx> {
850 ty::TypingEnv::fully_monomorphized()
851 }
852}
853
854impl<'tcx> HasTyCtxt<'tcx> for Tables<'tcx> {
855 fn tcx(&self) -> TyCtxt<'tcx> {
856 self.tcx
857 }
858}
859
860impl<'tcx> HasDataLayout for Tables<'tcx> {
861 fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
862 self.tcx.data_layout()
863 }
864}