1#![allow(rustc::usage_of_qualified_ty)]
4
5use std::iter;
6
7use rustc_abi::{Endian, Layout, ReprOptions};
8use rustc_hir::def::DefKind;
9use rustc_hir::{Attribute, LangItem};
10use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar};
11use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp};
12use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
13use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
14use rustc_middle::ty::util::Discr;
15use rustc_middle::ty::{
16 AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder,
17 ExistentialTraitRef, FnSig, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, List,
18 PolyFnSig, ScalarInt, TraitDef, TraitRef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy,
19 ValTree, VariantDef,
20};
21use rustc_middle::{mir, ty};
22use rustc_session::cstore::ForeignModule;
23use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
24use rustc_span::{FileNameDisplayPreference, Span, Symbol};
25use rustc_target::callconv::FnAbi;
26
27use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv};
28use crate::builder::BodyBuilder;
29use crate::{Bridge, SmirError, Tables, filter_def_ids};
30
31impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> {
32 fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
33 ty::Ty::new_foreign(self.tcx, def_id)
34 }
35}
36
37impl<'tcx, B: Bridge> SmirTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
38 fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx> {
39 ty::TypingEnv::fully_monomorphized()
40 }
41}
42
43impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
44 fn alloc_range(
45 &self,
46 offset: rustc_abi::Size,
47 size: rustc_abi::Size,
48 ) -> mir::interpret::AllocRange {
49 rustc_middle::mir::interpret::alloc_range(offset, size)
50 }
51}
52
53impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
54 pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
55 self.tcx.lift(value)
56 }
57
58 pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> {
59 self.tcx.adt_def(def_id)
60 }
61
62 pub fn coroutine_movability(&self, def_id: DefId) -> ty::Movability {
63 self.tcx.coroutine_movability(def_id)
64 }
65
66 pub fn valtree_to_const_val(&self, key: ty::Value<'tcx>) -> ConstValue<'tcx> {
67 self.tcx.valtree_to_const_val(key)
68 }
69
70 pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool {
75 let def_id = instance.def_id();
76 self.item_has_body(def_id)
77 || !matches!(
78 instance.def,
79 ty::InstanceKind::Virtual(..)
80 | ty::InstanceKind::Intrinsic(..)
81 | ty::InstanceKind::Item(..)
82 )
83 }
84
85 pub(crate) fn item_has_body(&self, def_id: DefId) -> bool {
90 let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) {
91 intrinsic.must_be_overridden
92 } else {
93 false
94 };
95 !must_override && self.tcx.is_mir_available(def_id)
96 }
97
98 fn filter_fn_def(&self, def_id: DefId) -> Option<DefId> {
99 if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
100 Some(def_id)
101 } else {
102 None
103 }
104 }
105
106 fn filter_static_def(&self, def_id: DefId) -> Option<DefId> {
107 matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id)
108 }
109
110 pub fn target_endian(&self) -> Endian {
111 self.tcx.data_layout.endian
112 }
113
114 pub fn target_pointer_size(&self) -> usize {
115 self.tcx.data_layout.pointer_size().bits().try_into().unwrap()
116 }
117
118 pub fn entry_fn(&self) -> Option<DefId> {
119 Some(self.tcx.entry_fn(())?.0)
120 }
121
122 pub fn all_local_items(&self) -> Vec<DefId> {
124 self.tcx.mir_keys(()).iter().map(|item| item.to_def_id()).collect()
125 }
126
127 pub fn mir_body(&self, item: DefId) -> &'tcx Body<'tcx> {
130 self.tcx.instance_mir(InstanceKind::Item(item))
131 }
132
133 pub fn has_body(&self, def: DefId) -> bool {
135 self.item_has_body(def)
136 }
137
138 pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec<DefId> {
139 self.tcx.foreign_modules(crate_num).keys().map(|mod_def_id| *mod_def_id).collect()
140 }
141
142 pub fn crate_functions(&self, crate_num: CrateNum) -> Vec<DefId> {
144 filter_def_ids(self.tcx, crate_num, |def_id| self.filter_fn_def(def_id))
145 }
146
147 pub fn crate_statics(&self, crate_num: CrateNum) -> Vec<DefId> {
149 filter_def_ids(self.tcx, crate_num, |def_id| self.filter_static_def(def_id))
150 }
151
152 pub fn foreign_module(&self, mod_def: DefId) -> &ForeignModule {
153 self.tcx.foreign_modules(mod_def.krate).get(&mod_def).unwrap()
154 }
155
156 pub fn foreign_items(&self, mod_def: DefId) -> Vec<DefId> {
157 self.tcx
158 .foreign_modules(mod_def.krate)
159 .get(&mod_def)
160 .unwrap()
161 .foreign_items
162 .iter()
163 .map(|item_def| *item_def)
164 .collect()
165 }
166
167 pub fn all_trait_decls(&self) -> impl Iterator<Item = DefId> {
168 self.tcx.all_traits_including_private()
169 }
170
171 pub fn trait_decls(&self, crate_num: CrateNum) -> Vec<DefId> {
172 self.tcx.traits(crate_num).iter().map(|trait_def_id| *trait_def_id).collect()
173 }
174
175 pub fn trait_decl(&self, trait_def: DefId) -> &'tcx TraitDef {
176 self.tcx.trait_def(trait_def)
177 }
178
179 pub fn all_trait_impls(&self) -> Vec<DefId> {
180 iter::once(LOCAL_CRATE)
181 .chain(self.tcx.crates(()).iter().copied())
182 .flat_map(|cnum| self.tcx.trait_impls_in_crate(cnum).iter())
183 .map(|impl_def_id| *impl_def_id)
184 .collect()
185 }
186
187 pub fn trait_impls(&self, crate_num: CrateNum) -> Vec<DefId> {
188 self.tcx.trait_impls_in_crate(crate_num).iter().map(|impl_def_id| *impl_def_id).collect()
189 }
190
191 pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder<'tcx, TraitRef<'tcx>> {
192 self.tcx.impl_trait_ref(impl_def).unwrap()
193 }
194
195 pub fn generics_of(&self, def_id: DefId) -> &'tcx ty::Generics {
196 self.tcx.generics_of(def_id)
197 }
198
199 pub fn predicates_of(
200 &self,
201 def_id: DefId,
202 ) -> (Option<DefId>, Vec<(ty::PredicateKind<'tcx>, Span)>) {
203 let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
204 (
205 parent,
206 predicates
207 .iter()
208 .map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span))
209 .collect(),
210 )
211 }
212
213 pub fn explicit_predicates_of(
214 &self,
215 def_id: DefId,
216 ) -> (Option<DefId>, Vec<(ty::PredicateKind<'tcx>, Span)>) {
217 let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
218 (
219 parent,
220 predicates
221 .iter()
222 .map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span))
223 .collect(),
224 )
225 }
226
227 pub fn crate_name(&self, crate_num: CrateNum) -> String {
228 self.tcx.crate_name(crate_num).to_string()
229 }
230
231 pub fn crate_is_local(&self, crate_num: CrateNum) -> bool {
232 crate_num == LOCAL_CRATE
233 }
234
235 pub fn crate_num_id(&self, crate_num: CrateNum) -> usize {
236 crate_num.into()
237 }
238
239 pub fn local_crate_num(&self) -> CrateNum {
240 LOCAL_CRATE
241 }
242
243 pub fn external_crates(&self) -> Vec<CrateNum> {
245 self.tcx.crates(()).iter().map(|crate_num| *crate_num).collect()
246 }
247
248 pub fn find_crates(&self, name: &str) -> Vec<CrateNum> {
250 let crates: Vec<CrateNum> = [LOCAL_CRATE]
251 .iter()
252 .chain(self.tcx.crates(()).iter())
253 .filter_map(|crate_num| {
254 let crate_name = self.tcx.crate_name(*crate_num).to_string();
255 (name == crate_name).then(|| *crate_num)
256 })
257 .collect();
258 crates
259 }
260
261 pub fn def_name(&self, def_id: DefId, trimmed: bool) -> String {
263 if trimmed {
264 with_forced_trimmed_paths!(self.tcx.def_path_str(def_id))
265 } else {
266 with_no_trimmed_paths!(self.tcx.def_path_str(def_id))
267 }
268 }
269
270 pub fn tool_attrs(&self, def_id: DefId, attr: &[String]) -> Vec<(String, Span)> {
278 let attr_name: Vec<_> = attr.iter().map(|seg| Symbol::intern(&seg)).collect();
279 self.tcx
280 .get_attrs_by_path(def_id, &attr_name)
281 .filter_map(|attribute| {
282 if let Attribute::Unparsed(u) = attribute {
283 let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute);
284 Some((attr_str, u.span))
285 } else {
286 None
287 }
288 })
289 .collect()
290 }
291
292 pub fn all_tool_attrs(&self, did: DefId) -> Vec<(String, Span)> {
294 let attrs_iter = if let Some(did) = did.as_local() {
295 self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(did)).iter()
296 } else {
297 self.tcx.attrs_for_def(did).iter()
298 };
299 attrs_iter
300 .filter_map(|attribute| {
301 if let Attribute::Unparsed(u) = attribute {
302 let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute);
303 Some((attr_str, u.span))
304 } else {
305 None
306 }
307 })
308 .collect()
309 }
310
311 pub fn span_to_string(&self, span: Span) -> String {
313 self.tcx.sess.source_map().span_to_diagnostic_string(span)
314 }
315
316 pub fn get_filename(&self, span: Span) -> String {
318 self.tcx
319 .sess
320 .source_map()
321 .span_to_filename(span)
322 .display(FileNameDisplayPreference::Local)
323 .to_string()
324 }
325
326 pub fn get_lines(&self, span: Span) -> (usize, usize, usize, usize) {
328 let lines = &self.tcx.sess.source_map().span_to_location_info(span);
329 (lines.1, lines.2, lines.3, lines.4)
330 }
331
332 pub fn def_kind(&self, item: DefId) -> DefKind {
334 self.tcx.def_kind(item)
335 }
336
337 pub fn is_foreign_item(&self, item: DefId) -> bool {
339 self.tcx.is_foreign_item(item)
340 }
341
342 pub fn foreign_item_kind(&self, def_id: DefId) -> DefKind {
344 self.tcx.def_kind(def_id)
345 }
346
347 pub fn adt_kind(&self, def: AdtDef<'tcx>) -> AdtKind {
349 def.adt_kind()
350 }
351
352 pub fn adt_is_box(&self, def: AdtDef<'tcx>) -> bool {
354 def.is_box()
355 }
356
357 pub fn adt_is_simd(&self, def: AdtDef<'tcx>) -> bool {
359 def.repr().simd()
360 }
361
362 pub fn adt_is_cstr(&self, def_id: DefId) -> bool {
364 self.tcx.is_lang_item(def_id, LangItem::CStr)
365 }
366
367 pub fn adt_repr(&self, def: AdtDef<'tcx>) -> ReprOptions {
369 def.repr()
370 }
371
372 pub fn fn_sig(
374 &self,
375 def_id: DefId,
376 args_ref: GenericArgsRef<'tcx>,
377 ) -> Binder<'tcx, FnSig<'tcx>> {
378 let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref);
379 sig
380 }
381
382 pub fn intrinsic(&self, def_id: DefId) -> Option<IntrinsicDef> {
384 let intrinsic = self.tcx.intrinsic_raw(def_id);
385 intrinsic
386 }
387
388 pub fn intrinsic_name(&self, def_id: DefId) -> String {
390 self.tcx.intrinsic(def_id).unwrap().name.to_string()
391 }
392
393 pub fn closure_sig(&self, args_ref: GenericArgsRef<'tcx>) -> Binder<'tcx, FnSig<'tcx>> {
395 args_ref.as_closure().sig()
396 }
397
398 pub fn adt_variants_len(&self, def: AdtDef<'tcx>) -> usize {
400 def.variants().len()
401 }
402
403 pub fn adt_discr_for_variant(
405 &self,
406 adt: AdtDef<'tcx>,
407 variant: rustc_abi::VariantIdx,
408 ) -> Discr<'tcx> {
409 adt.discriminant_for_variant(self.tcx, variant)
410 }
411
412 pub fn coroutine_discr_for_variant(
414 &self,
415 coroutine: DefId,
416 args: GenericArgsRef<'tcx>,
417 variant: rustc_abi::VariantIdx,
418 ) -> Discr<'tcx> {
419 args.as_coroutine().discriminant_for_variant(coroutine, self.tcx, variant)
420 }
421
422 pub fn variant_name(&self, def: &'tcx VariantDef) -> String {
424 def.name.to_string()
425 }
426
427 pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
429 use crate::context::SmirTypingEnv;
430 cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())
431 .ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
432 }
433
434 pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result<u64, B::Error> {
435 cnst.try_to_target_usize(self.tcx)
436 .ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
437 }
438
439 pub fn try_new_const_zst(&self, ty_internal: Ty<'tcx>) -> Result<MirConst<'tcx>, B::Error> {
440 let size = self
441 .tcx
442 .layout_of(self.fully_monomorphized().as_query_input(ty_internal))
443 .map_err(|err| {
444 B::Error::new(format!(
445 "Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
446 ))
447 })?
448 .size;
449 if size.bytes() != 0 {
450 return Err(B::Error::new(format!(
451 "Cannot create a zero-sized constant for type `{ty_internal}`: \
452 Type `{ty_internal}` has {} bytes",
453 size.bytes()
454 )));
455 }
456
457 Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal)))
458 }
459
460 pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> {
461 ty::Const::zero_sized(self.tcx, ty_internal)
462 }
463
464 pub fn new_const_str(&self, value: &str) -> MirConst<'tcx> {
466 let ty = Ty::new_static_str(self.tcx);
467 let bytes = value.as_bytes();
468 let valtree = ValTree::from_raw_bytes(self.tcx, bytes);
469 let cv = ty::Value { ty, valtree };
470 let val = self.tcx.valtree_to_const_val(cv);
471 MirConst::from_value(val, ty)
472 }
473
474 pub fn new_const_bool(&self, value: bool) -> MirConst<'tcx> {
476 MirConst::from_bool(self.tcx, value)
477 }
478
479 pub fn try_new_const_uint(
480 &self,
481 value: u128,
482 ty_internal: Ty<'tcx>,
483 ) -> Result<MirConst<'tcx>, B::Error> {
484 let size = self
485 .tcx
486 .layout_of(self.fully_monomorphized().as_query_input(ty_internal))
487 .unwrap()
488 .size;
489 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
490 B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
491 })?;
492 Ok(self.mir_const_from_scalar(Scalar::Int(scalar), ty_internal))
493 }
494
495 pub fn try_new_ty_const_uint(
496 &self,
497 value: u128,
498 ty_internal: Ty<'tcx>,
499 ) -> Result<ty::Const<'tcx>, B::Error> {
500 let size = self
501 .tcx
502 .layout_of(self.fully_monomorphized().as_query_input(ty_internal))
503 .unwrap()
504 .size;
505 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
506 B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
507 })?;
508
509 Ok(self.ty_const_new_value(ValTree::from_scalar_int(self.tcx, scalar), ty_internal))
510 }
511
512 pub fn ty_new_uint(&self, ty: UintTy) -> Ty<'tcx> {
513 Ty::new_uint(self.tcx, ty)
514 }
515
516 pub fn mir_const_from_scalar(&self, s: Scalar, ty: Ty<'tcx>) -> MirConst<'tcx> {
517 MirConst::from_scalar(self.tcx, s, ty)
518 }
519
520 pub fn ty_const_new_value(&self, valtree: ValTree<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
521 ty::Const::new_value(self.tcx, valtree, ty)
522 }
523
524 pub fn ty_valtree_from_scalar_int(&self, i: ScalarInt) -> ValTree<'tcx> {
525 ValTree::from_scalar_int(self.tcx, i)
526 }
527
528 pub fn new_rigid_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
530 self.tcx.mk_ty_from_kind(internal_kind)
531 }
532
533 pub fn new_box_ty(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
535 ty::Ty::new_box(self.tcx, ty)
536 }
537
538 pub fn def_ty(&self, item: DefId) -> Ty<'tcx> {
540 self.tcx.type_of(item).instantiate_identity()
541 }
542
543 pub fn def_ty_with_args(&self, item: DefId, args_ref: GenericArgsRef<'tcx>) -> Ty<'tcx> {
545 let def_ty = self.tcx.type_of(item);
546 self.tcx.instantiate_and_normalize_erasing_regions(
547 args_ref,
548 self.fully_monomorphized(),
549 def_ty,
550 )
551 }
552
553 pub fn span_of_an_item(&self, def_id: DefId) -> Span {
555 self.tcx.def_span(def_id)
556 }
557
558 pub fn ty_const_pretty(&self, ct: ty::Const<'tcx>) -> String {
559 ct.to_string()
560 }
561
562 pub fn ty_pretty(&self, ty: Ty<'tcx>) -> String {
564 ty.to_string()
565 }
566
567 pub fn ty_kind(&self, ty: Ty<'tcx>) -> &'tcx TyKind<'tcx> {
569 ty.kind()
570 }
571
572 pub fn rigid_ty_discriminant_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
574 let internal_ty = self.tcx.mk_ty_from_kind(internal_kind);
575 internal_ty.discriminant_ty(self.tcx)
576 }
577
578 pub fn instance_body(&self, instance: ty::Instance<'tcx>) -> Option<Body<'tcx>> {
580 self.instance_has_body(instance).then(|| BodyBuilder::new(self.tcx, instance).build())
581 }
582
583 pub fn instance_ty(&self, instance: ty::Instance<'tcx>) -> Ty<'tcx> {
585 assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
586 instance.ty(self.tcx, self.fully_monomorphized())
587 }
588
589 pub fn instance_args(&self, instance: ty::Instance<'tcx>) -> GenericArgsRef<'tcx> {
591 instance.args
592 }
593
594 pub fn instance_abi(
596 &self,
597 instance: ty::Instance<'tcx>,
598 ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
599 Ok(self.fn_abi_of_instance(instance, List::empty())?)
600 }
601
602 pub fn fn_ptr_abi(&self, sig: PolyFnSig<'tcx>) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
604 Ok(self.fn_abi_of_fn_ptr(sig, List::empty())?)
605 }
606
607 pub fn instance_def_id(
609 &self,
610 instances: ty::Instance<'tcx>,
611 tables: &mut Tables<'_, B>,
612 ) -> B::DefId {
613 let def_id = instances.def_id();
614 tables.create_def_id(def_id)
615 }
616
617 pub fn instance_mangled_name(&self, instance: ty::Instance<'tcx>) -> String {
619 self.tcx.symbol_name(instance).name.to_string()
620 }
621
622 pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool {
624 matches!(instance.def, ty::InstanceKind::DropGlue(_, None))
625 }
626
627 pub fn mono_instance(&self, def_id: DefId) -> Instance<'tcx> {
630 Instance::mono(self.tcx, def_id)
631 }
632
633 pub fn requires_monomorphization(&self, def_id: DefId) -> bool {
635 let generics = self.tcx.generics_of(def_id);
636 let result = generics.requires_monomorphization(self.tcx);
637 result
638 }
639
640 pub fn resolve_instance(
642 &self,
643 def_id: DefId,
644 args_ref: GenericArgsRef<'tcx>,
645 ) -> Option<Instance<'tcx>> {
646 match Instance::try_resolve(self.tcx, self.fully_monomorphized(), def_id, args_ref) {
647 Ok(Some(instance)) => Some(instance),
648 Ok(None) | Err(_) => None,
649 }
650 }
651
652 pub fn resolve_drop_in_place(&self, internal_ty: Ty<'tcx>) -> Instance<'tcx> {
654 let instance = Instance::resolve_drop_in_place(self.tcx, internal_ty);
655 instance
656 }
657
658 pub fn resolve_for_fn_ptr(
660 &self,
661 def_id: DefId,
662 args_ref: GenericArgsRef<'tcx>,
663 ) -> Option<Instance<'tcx>> {
664 Instance::resolve_for_fn_ptr(self.tcx, self.fully_monomorphized(), def_id, args_ref)
665 }
666
667 pub fn resolve_closure(
669 &self,
670 def_id: DefId,
671 args_ref: GenericArgsRef<'tcx>,
672 closure_kind: ClosureKind,
673 ) -> Option<Instance<'tcx>> {
674 Some(Instance::resolve_closure(self.tcx, def_id, args_ref, closure_kind))
675 }
676
677 pub fn eval_instance(
679 &self,
680 instance: ty::Instance<'tcx>,
681 ) -> Result<ConstValue<'tcx>, ErrorHandled> {
682 self.tcx.const_eval_instance(
683 self.fully_monomorphized(),
684 instance,
685 self.tcx.def_span(instance.def_id()),
686 )
687 }
688
689 pub fn eval_static_initializer(
691 &self,
692 def_id: DefId,
693 ) -> Result<ConstAllocation<'tcx>, ErrorHandled> {
694 self.tcx.eval_static_initializer(def_id)
695 }
696
697 pub fn global_alloc(&self, alloc_id: AllocId) -> GlobalAlloc<'tcx> {
699 self.tcx.global_alloc(alloc_id)
700 }
701
702 pub fn vtable_allocation(
704 &self,
705 ty: Ty<'tcx>,
706 trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
707 ) -> AllocId {
708 let alloc_id = self.tcx.vtable_allocation((
709 ty,
710 trait_ref.map(|principal| self.tcx.instantiate_bound_regions_with_erased(principal)),
711 ));
712 alloc_id
713 }
714
715 pub fn instance_name(&self, instance: ty::Instance<'tcx>, trimmed: bool) -> String {
719 if trimmed {
720 with_forced_trimmed_paths!(
721 self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
722 )
723 } else {
724 with_no_trimmed_paths!(
725 self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
726 )
727 }
728 }
729
730 pub fn ty_layout(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, B::Error> {
732 let layout = self.layout_of(ty)?.layout;
733 Ok(layout)
734 }
735
736 pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty<'tcx>, lhs: Ty<'tcx>) -> Ty<'tcx> {
738 bin_op.ty(self.tcx, rhs, lhs)
739 }
740
741 pub fn unop_ty(&self, un_op: UnOp, arg: Ty<'tcx>) -> Ty<'tcx> {
743 un_op.ty(self.tcx, arg)
744 }
745
746 pub fn associated_items(&self, def_id: DefId) -> Vec<AssocItem> {
748 let assoc_items = if self.tcx.is_trait_alias(def_id) {
749 Vec::new()
750 } else {
751 self.tcx
752 .associated_item_def_ids(def_id)
753 .iter()
754 .map(|did| self.tcx.associated_item(*did))
755 .collect()
756 };
757 assoc_items
758 }
759}