1#![allow(rustc::usage_of_qualified_ty)]
4
5use std::iter;
6
7use rustc_abi::{Endian, Layout, ReprOptions};
8use rustc_attr_ir::Attribute;
9use rustc_attr_ir::lang_items::LangItem;
10use rustc_crate_store::ForeignModule;
11use rustc_hir::def::DefKind;
12use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar};
13use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp};
14use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
15use rustc_middle::ty::print::{
16 with_forced_trimmed_paths, with_no_trimmed_paths, with_resolve_crate_name,
17};
18use rustc_middle::ty::util::Discr;
19use rustc_middle::ty::{
20 AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder,
21 ExistentialTraitRef, FnSig, GenericArgs, Instance, InstanceKind, IntrinsicDef, List, PolyFnSig,
22 ScalarInt, TraitDef, TraitRef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy, ValTree,
23 VariantDef, VtblEntry,
24};
25use rustc_middle::{mir, ty};
26use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
27use rustc_span::{Span, Symbol};
28use rustc_target::callconv::FnAbi;
29
30use super::{AllocRangeHelpers, CompilerCtxt, TyHelpers};
31use crate::builder::BodyBuilder;
32use crate::{Bridge, Error, Tables, filter_def_ids};
33
34impl<'tcx, B: Bridge> TyHelpers<'tcx> for CompilerCtxt<'tcx, B> {
35 fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
36 ty::Ty::new_foreign(self.tcx, def_id)
37 }
38}
39
40impl<'tcx, B: Bridge> AllocRangeHelpers<'tcx> for CompilerCtxt<'tcx, B> {
41 fn alloc_range(
42 &self,
43 offset: rustc_abi::Size,
44 size: rustc_abi::Size,
45 ) -> mir::interpret::AllocRange {
46 rustc_middle::mir::interpret::alloc_range(offset, size)
47 }
48}
49
50impl<'tcx, B: Bridge> rustc_hir_pretty::PpAnn for CompilerCtxt<'tcx, B> {
51 fn nested(&self, state: &mut rustc_hir_pretty::State<'_>, nested: rustc_hir_pretty::Nested) {
52 rustc_hir_pretty::PpAnn::nested(
53 &(&self.tcx as &dyn rustc_hir::intravisit::HirTyCtxt<'_>),
54 state,
55 nested,
56 )
57 }
58}
59
60impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
61 pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> T::Lifted {
62 self.tcx.lift(value)
63 }
64
65 pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> {
66 self.tcx.adt_def(def_id)
67 }
68
69 pub fn coroutine_movability(&self, def_id: DefId) -> ty::Movability {
70 self.tcx.coroutine_movability(def_id)
71 }
72
73 pub fn valtree_to_const_val(&self, key: ty::Value<'tcx>) -> ConstValue {
74 self.tcx.valtree_to_const_val(key)
75 }
76
77 pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool {
82 let def_id = instance.def_id();
83 self.item_has_body(def_id)
84 || !#[allow(non_exhaustive_omitted_patterns)] match instance.def {
ty::InstanceKind::Virtual(..) | ty::InstanceKind::Intrinsic(..) |
ty::InstanceKind::Item(..) => true,
_ => false,
}matches!(
85 instance.def,
86 ty::InstanceKind::Virtual(..)
87 | ty::InstanceKind::Intrinsic(..)
88 | ty::InstanceKind::Item(..)
89 )
90 }
91
92 pub(crate) fn item_has_body(&self, def_id: DefId) -> bool {
97 let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) {
98 intrinsic.must_be_overridden
99 } else {
100 false
101 };
102 !must_override && self.tcx.is_mir_available(def_id) && !self.tcx.is_trivial_const(def_id)
104 }
105
106 fn filter_fn_def(&self, def_id: DefId) -> Option<DefId> {
107 if #[allow(non_exhaustive_omitted_patterns)] match self.tcx.def_kind(def_id) {
DefKind::Fn | DefKind::AssocFn => true,
_ => false,
}matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
108 Some(def_id)
109 } else {
110 None
111 }
112 }
113
114 fn filter_static_def(&self, def_id: DefId) -> Option<DefId> {
115 #[allow(non_exhaustive_omitted_patterns)] match self.tcx.def_kind(def_id) {
DefKind::Static { .. } => true,
_ => false,
}matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id)
116 }
117
118 fn filter_adt_def(&self, def_id: DefId) -> Option<DefId> {
119 #[allow(non_exhaustive_omitted_patterns)] match self.tcx.def_kind(def_id) {
DefKind::Struct | DefKind::Enum | DefKind::Union => true,
_ => false,
}matches!(self.tcx.def_kind(def_id), DefKind::Struct | DefKind::Enum | DefKind::Union)
120 .then(|| def_id)
121 }
122
123 pub fn target_endian(&self) -> Endian {
124 self.tcx.data_layout.endian
125 }
126
127 pub fn target_pointer_size(&self) -> usize {
128 self.tcx.data_layout.pointer_size().bits().try_into().unwrap()
129 }
130
131 pub fn entry_fn(&self) -> Option<DefId> {
132 Some(self.tcx.entry_fn(())?.0)
133 }
134
135 pub fn all_local_items(&self) -> Vec<DefId> {
137 self.tcx.mir_keys(()).iter().map(|item| item.to_def_id()).collect()
138 }
139
140 pub fn mir_body(&self, item: DefId) -> &'tcx Body<'tcx> {
143 self.tcx.instance_mir(InstanceKind::Item(item))
144 }
145
146 pub fn has_body(&self, def: DefId) -> bool {
148 self.item_has_body(def)
149 }
150
151 pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec<DefId> {
152 self.tcx.foreign_modules(crate_num).keys().map(|mod_def_id| *mod_def_id).collect()
153 }
154
155 pub fn crate_functions(&self, crate_num: CrateNum) -> Vec<DefId> {
157 filter_def_ids(self.tcx, crate_num, |def_id| self.filter_fn_def(def_id))
158 }
159
160 pub fn crate_statics(&self, crate_num: CrateNum) -> Vec<DefId> {
162 filter_def_ids(self.tcx, crate_num, |def_id| self.filter_static_def(def_id))
163 }
164
165 pub fn crate_adts(&self, crate_num: CrateNum) -> Vec<DefId> {
167 filter_def_ids(self.tcx, crate_num, |def_id| self.filter_adt_def(def_id))
168 }
169
170 pub fn foreign_module(&self, mod_def: DefId) -> &ForeignModule {
171 self.tcx.foreign_modules(mod_def.krate).get(&mod_def).unwrap()
172 }
173
174 pub fn foreign_items(&self, mod_def: DefId) -> Vec<DefId> {
175 self.tcx
176 .foreign_modules(mod_def.krate)
177 .get(&mod_def)
178 .unwrap()
179 .foreign_items
180 .iter()
181 .map(|item_def| *item_def)
182 .collect()
183 }
184
185 pub fn all_trait_decls(&self) -> impl Iterator<Item = DefId> {
186 self.tcx.all_traits_including_private()
187 }
188
189 pub fn trait_decls(&self, crate_num: CrateNum) -> Vec<DefId> {
190 self.tcx.traits(crate_num).iter().map(|trait_def_id| *trait_def_id).collect()
191 }
192
193 pub fn trait_decl(&self, trait_def: DefId) -> &'tcx TraitDef {
194 self.tcx.trait_def(trait_def)
195 }
196
197 pub fn all_trait_impls(&self) -> Vec<DefId> {
198 iter::once(LOCAL_CRATE)
199 .chain(self.tcx.crates(()).iter().copied())
200 .flat_map(|cnum| self.tcx.trait_impls_in_crate(cnum).iter())
201 .map(|impl_def_id| *impl_def_id)
202 .collect()
203 }
204
205 pub fn trait_impls(&self, crate_num: CrateNum) -> Vec<DefId> {
206 self.tcx.trait_impls_in_crate(crate_num).iter().map(|impl_def_id| *impl_def_id).collect()
207 }
208
209 pub fn inherent_impls(&self, def_id: DefId) -> Vec<DefId> {
211 self.tcx.inherent_impls(def_id).iter().copied().collect()
212 }
213
214 pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder<'tcx, TraitRef<'tcx>> {
215 self.tcx.impl_trait_ref(impl_def)
216 }
217
218 pub fn generics_of(&self, def_id: DefId) -> &'tcx ty::Generics {
219 self.tcx.generics_of(def_id)
220 }
221
222 pub fn clauses_of(&self, def_id: DefId) -> (Option<DefId>, Vec<(ty::ClauseKind<'tcx>, Span)>) {
223 let ty::GenericClauses { parent, clauses } = self.tcx.clauses_of(def_id);
224 (
225 parent,
226 clauses.iter().map(|(clause, span)| (clause.kind().skip_binder(), *span)).collect(),
227 )
228 }
229
230 pub fn explicit_clauses_of(
231 &self,
232 def_id: DefId,
233 ) -> (Option<DefId>, Vec<(ty::ClauseKind<'tcx>, Span)>) {
234 let ty::GenericClauses { parent, clauses } = self.tcx.explicit_clauses_of(def_id);
235 (
236 parent,
237 clauses.iter().map(|(clause, span)| (clause.kind().skip_binder(), *span)).collect(),
238 )
239 }
240
241 pub fn crate_name(&self, crate_num: CrateNum) -> String {
242 self.tcx.crate_name(crate_num).to_string()
243 }
244
245 pub fn crate_is_local(&self, crate_num: CrateNum) -> bool {
246 crate_num == LOCAL_CRATE
247 }
248
249 pub fn crate_num_id(&self, crate_num: CrateNum) -> usize {
250 crate_num.into()
251 }
252
253 pub fn local_crate_num(&self) -> CrateNum {
254 LOCAL_CRATE
255 }
256
257 pub fn external_crates(&self) -> Vec<CrateNum> {
259 self.tcx.crates(()).iter().map(|crate_num| *crate_num).collect()
260 }
261
262 pub fn find_crates(&self, name: &str) -> Vec<CrateNum> {
264 let crates: Vec<CrateNum> = [LOCAL_CRATE]
265 .iter()
266 .chain(self.tcx.crates(()).iter())
267 .filter_map(|crate_num| {
268 let crate_name = self.tcx.crate_name(*crate_num).to_string();
269 (name == crate_name).then(|| *crate_num)
270 })
271 .collect();
272 crates
273 }
274
275 pub fn def_name(&self, def_id: DefId, trimmed: bool) -> String {
277 if trimmed {
278 { let _guard = ForceTrimmedGuard::new(); self.tcx.def_path_str(def_id) }with_forced_trimmed_paths!(self.tcx.def_path_str(def_id))
279 } else {
280 {
let _guard = CrateNamePrefixGuard::new();
{ let _guard = NoTrimmedGuard::new(); self.tcx.def_path_str(def_id) }
}with_resolve_crate_name!(with_no_trimmed_paths!(self.tcx.def_path_str(def_id)))
282 }
283 }
284
285 pub fn def_parent(&self, def_id: DefId) -> Option<DefId> {
287 self.tcx.opt_parent(def_id)
288 }
289
290 pub fn tool_attrs(&self, def_id: DefId, attr: &[String]) -> Vec<(String, Span)> {
295 let attr_name: Vec<_> = attr.iter().map(|seg| Symbol::intern(&seg)).collect();
296 self.tcx
297 .tool_attrs(def_id, &attr_name)
298 .map(|attribute| {
299 (rustc_hir_pretty::attritem_to_string(self, attribute), attribute.span)
300 })
301 .collect()
302 }
303
304 pub fn all_tool_attrs(&self, did: DefId) -> Vec<(String, Span)> {
306 let attrs_iter = if let Some(did) = did.as_local() {
307 self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(did)).iter()
308 } else {
309 self.tcx.attrs_for_def(did).iter()
310 };
311 attrs_iter
312 .filter_map(|attribute| {
313 if let Attribute::Tool(u) = attribute {
314 let attr_str = rustc_hir_pretty::attribute_to_string(self, attribute);
315 Some((attr_str, u.span))
316 } else {
317 None
318 }
319 })
320 .collect()
321 }
322
323 pub fn span_to_string(&self, span: Span) -> String {
325 self.tcx.sess.source_map().span_to_diagnostic_string(span)
326 }
327
328 pub fn get_filename(&self, span: Span) -> String {
330 self.tcx.sess.source_map().span_to_filename(span).prefer_local_unconditionally().to_string()
331 }
332
333 pub fn get_lines(&self, span: Span) -> (usize, usize, usize, usize) {
335 let lines = &self.tcx.sess.source_map().span_to_location_info(span);
336 (lines.1, lines.2, lines.3, lines.4)
337 }
338
339 pub fn def_kind(&self, item: DefId) -> DefKind {
341 self.tcx.def_kind(item)
342 }
343
344 pub fn is_foreign_item(&self, item: DefId) -> bool {
346 self.tcx.is_foreign_item(item)
347 }
348
349 pub fn foreign_item_kind(&self, def_id: DefId) -> DefKind {
351 self.tcx.def_kind(def_id)
352 }
353
354 pub fn adt_kind(&self, def: AdtDef<'tcx>) -> AdtKind {
356 def.adt_kind()
357 }
358
359 pub fn adt_is_box(&self, def: AdtDef<'tcx>) -> bool {
361 def.is_box()
362 }
363
364 pub fn adt_is_simd(&self, def: AdtDef<'tcx>) -> bool {
366 def.repr().simd()
367 }
368
369 pub fn adt_is_cstr(&self, def_id: DefId) -> bool {
371 self.tcx.is_lang_item(def_id, LangItem::CStr)
372 }
373
374 pub fn adt_repr(&self, def: AdtDef<'tcx>) -> ReprOptions {
376 def.repr()
377 }
378
379 pub fn fn_sig(&self, def_id: DefId, args_ref: GenericArgs<'tcx>) -> Binder<'tcx, FnSig<'tcx>> {
381 let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref).skip_norm_wip();
382 sig
383 }
384
385 pub fn constness(&self, def_id: DefId) -> rustc_hir::Constness {
387 self.tcx.constness(def_id)
388 }
389
390 pub fn asyncness(&self, def_id: DefId) -> ty::Asyncness {
392 self.tcx.asyncness(def_id)
393 }
394
395 pub fn intrinsic(&self, def_id: DefId) -> Option<IntrinsicDef> {
397 let intrinsic = self.tcx.intrinsic_raw(def_id);
398 intrinsic
399 }
400
401 pub fn intrinsic_name(&self, def_id: DefId) -> String {
403 self.tcx.intrinsic(def_id).unwrap().name.to_string()
404 }
405
406 pub fn closure_sig(&self, args_ref: GenericArgs<'tcx>) -> Binder<'tcx, FnSig<'tcx>> {
408 args_ref.as_closure().sig()
409 }
410
411 pub fn adt_variants_len(&self, def: AdtDef<'tcx>) -> usize {
413 def.variants().len()
414 }
415
416 pub fn adt_discr_for_variant(
418 &self,
419 adt: AdtDef<'tcx>,
420 variant: rustc_abi::VariantIdx,
421 ) -> Discr<'tcx> {
422 adt.discriminant_for_variant(self.tcx, variant)
423 }
424
425 pub fn coroutine_discr_for_variant(
427 &self,
428 coroutine: DefId,
429 args: GenericArgs<'tcx>,
430 variant: rustc_abi::VariantIdx,
431 ) -> Discr<'tcx> {
432 args.as_coroutine().discriminant_for_variant(coroutine, self.tcx, variant)
433 }
434
435 pub fn variant_name(&self, def: &'tcx VariantDef) -> String {
437 def.name.to_string()
438 }
439
440 pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
442 cnst.try_eval_target_usize(self.tcx, self.typing_env())
443 .ok_or_else(|| B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Const `{0:?}` cannot be encoded as u64",
cnst))
})format!("Const `{cnst:?}` cannot be encoded as u64")))
444 }
445
446 pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result<u64, B::Error> {
447 cnst.try_to_target_usize(self.tcx)
448 .ok_or_else(|| B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Const `{0:?}` cannot be encoded as u64",
cnst))
})format!("Const `{cnst:?}` cannot be encoded as u64")))
449 }
450
451 pub fn try_new_const_zst(&self, ty_internal: Ty<'tcx>) -> Result<MirConst<'tcx>, B::Error> {
452 let size = self
453 .tcx
454 .layout_of(self.typing_env().as_query_input(ty_internal))
455 .map_err(|err| {
456 B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Cannot create a zero-sized constant for type `{0}`: {1}",
ty_internal, err))
})format!(
457 "Cannot create a zero-sized constant for type `{ty_internal}`: {err}"
458 ))
459 })?
460 .size;
461 if size.bytes() != 0 {
462 return Err(B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Cannot create a zero-sized constant for type `{1}`: Type `{1}` has {0} bytes",
size.bytes(), ty_internal))
})format!(
463 "Cannot create a zero-sized constant for type `{ty_internal}`: \
464 Type `{ty_internal}` has {} bytes",
465 size.bytes()
466 )));
467 }
468
469 Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal)))
470 }
471
472 pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> {
473 ty::Const::zero_sized(self.tcx, ty_internal)
474 }
475
476 pub fn span_as_caller_location(&self, span: Span) -> MirConst<'tcx> {
481 let val = self.tcx.span_as_caller_location(span);
482 let ty = self.tcx.caller_location_ty();
483 MirConst::from_value(val, ty)
484 }
485
486 pub fn new_const_str(&self, value: &str) -> MirConst<'tcx> {
488 let ty = Ty::new_static_str(self.tcx);
489 let bytes = value.as_bytes();
490 let valtree = ValTree::from_raw_bytes(self.tcx, bytes);
491 let cv = ty::Value { ty, valtree };
492 let val = self.tcx.valtree_to_const_val(cv);
493 MirConst::from_value(val, ty)
494 }
495
496 pub fn new_const_bool(&self, value: bool) -> MirConst<'tcx> {
498 MirConst::from_bool(self.tcx, value)
499 }
500
501 pub fn try_new_const_uint(
502 &self,
503 value: u128,
504 ty_internal: Ty<'tcx>,
505 ) -> Result<MirConst<'tcx>, B::Error> {
506 let size = self.tcx.layout_of(self.typing_env().as_query_input(ty_internal)).unwrap().size;
507 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
508 B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Value overflow: cannot convert `{0}` to `{1}`.",
value, ty_internal))
})format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
509 })?;
510 Ok(self.mir_const_from_scalar(Scalar::Int(scalar), ty_internal))
511 }
512
513 pub fn try_new_ty_const_uint(
514 &self,
515 value: u128,
516 ty_internal: Ty<'tcx>,
517 ) -> Result<ty::Const<'tcx>, B::Error> {
518 let size = self.tcx.layout_of(self.typing_env().as_query_input(ty_internal)).unwrap().size;
519 let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
520 B::Error::new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Value overflow: cannot convert `{0}` to `{1}`.",
value, ty_internal))
})format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
521 })?;
522
523 Ok(self.ty_const_new_value(ValTree::from_scalar_int(self.tcx, scalar), ty_internal))
524 }
525
526 pub fn ty_new_uint(&self, ty: UintTy) -> Ty<'tcx> {
527 Ty::new_uint(self.tcx, ty)
528 }
529
530 pub fn mir_const_from_scalar(&self, s: Scalar, ty: Ty<'tcx>) -> MirConst<'tcx> {
531 MirConst::from_scalar(self.tcx, s, ty)
532 }
533
534 pub fn ty_const_new_value(&self, valtree: ValTree<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
535 ty::Const::new_value(self.tcx, valtree, ty)
536 }
537
538 pub fn ty_valtree_from_scalar_int(&self, i: ScalarInt) -> ValTree<'tcx> {
539 ValTree::from_scalar_int(self.tcx, i)
540 }
541
542 pub fn new_rigid_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
544 self.tcx.mk_ty_from_kind(internal_kind)
545 }
546
547 pub fn new_box_ty(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
549 ty::Ty::new_box(self.tcx, ty)
550 }
551
552 pub fn def_ty(&self, item: DefId) -> Ty<'tcx> {
554 self.tcx.type_of(item).instantiate_identity().skip_norm_wip()
555 }
556
557 pub fn def_ty_with_args(&self, item: DefId, args_ref: GenericArgs<'tcx>) -> Ty<'tcx> {
559 let def_ty = self.tcx.type_of(item);
560 self.tcx.instantiate_and_normalize_erasing_regions(args_ref, self.typing_env(), def_ty)
561 }
562
563 pub fn span_of_a_def(&self, def_id: DefId) -> Span {
565 self.tcx.def_span(def_id)
566 }
567
568 pub fn ty_const_pretty(&self, ct: ty::Const<'tcx>) -> String {
569 ct.to_string()
570 }
571
572 pub fn ty_pretty(&self, ty: Ty<'tcx>) -> String {
574 ty.to_string()
575 }
576
577 pub fn ty_kind(&self, ty: Ty<'tcx>) -> &'tcx TyKind<'tcx> {
579 ty.kind()
580 }
581
582 pub fn rigid_ty_discriminant_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> {
584 let internal_ty = self.tcx.mk_ty_from_kind(internal_kind);
585 internal_ty.discriminant_ty(self.tcx)
586 }
587
588 pub fn instance_body(&self, instance: ty::Instance<'tcx>) -> Option<Body<'tcx>> {
590 self.instance_has_body(instance).then(|| BodyBuilder::new(self.tcx, instance).build())
591 }
592
593 pub fn instance_ty(&self, instance: ty::Instance<'tcx>) -> Ty<'tcx> {
595 if !!instance.has_non_region_param() {
{
::core::panicking::panic_fmt(format_args!("{0:?} needs further instantiation",
instance));
}
};assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
596 instance.ty(self.tcx, self.typing_env())
597 }
598
599 pub fn instance_args(&self, instance: ty::Instance<'tcx>) -> GenericArgs<'tcx> {
601 instance.args
602 }
603
604 pub fn instance_abi(
606 &self,
607 instance: ty::Instance<'tcx>,
608 ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
609 Ok(self.fn_abi_of_instance(instance, List::empty())?)
610 }
611
612 pub fn fn_ptr_abi(&self, sig: PolyFnSig<'tcx>) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> {
614 Ok(self.fn_abi_of_fn_ptr(sig, List::empty())?)
615 }
616
617 pub fn instance_def_id(
619 &self,
620 instances: ty::Instance<'tcx>,
621 tables: &mut Tables<'_, B>,
622 ) -> B::DefId {
623 let def_id = instances.def_id();
624 tables.create_def_id(def_id)
625 }
626
627 pub fn instance_mangled_name(&self, instance: ty::Instance<'tcx>) -> String {
629 self.tcx.symbol_name(instance).name.to_string()
630 }
631
632 pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool {
634 #[allow(non_exhaustive_omitted_patterns)] match instance.def {
ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)) => true,
_ => false,
}matches!(instance.def, ty::InstanceKind::Shim(ty::ShimKind::DropGlue(_, None)))
635 }
636
637 pub fn instance_requires_caller_location(&self, instance: ty::Instance<'tcx>) -> bool {
643 instance.def.requires_caller_location(self.tcx)
644 }
645
646 pub fn mono_instance(&self, def_id: DefId) -> Instance<'tcx> {
649 Instance::mono(self.tcx, def_id)
650 }
651
652 pub fn requires_monomorphization(&self, def_id: DefId) -> bool {
654 let generics = self.tcx.generics_of(def_id);
655 let result = generics.requires_monomorphization(self.tcx);
656 result
657 }
658
659 pub fn resolve_instance(
661 &self,
662 def_id: DefId,
663 args_ref: GenericArgs<'tcx>,
664 ) -> Option<Instance<'tcx>> {
665 match Instance::try_resolve(self.tcx, self.typing_env(), def_id, args_ref) {
666 Ok(Some(instance)) => Some(instance),
667 Ok(None) | Err(_) => None,
668 }
669 }
670
671 pub fn resolve_drop_in_place(&self, internal_ty: Ty<'tcx>) -> Instance<'tcx> {
673 let instance = Instance::resolve_drop_glue(self.tcx, internal_ty);
674 instance
675 }
676
677 pub fn resolve_for_fn_ptr(
679 &self,
680 def_id: DefId,
681 args_ref: GenericArgs<'tcx>,
682 ) -> Option<Instance<'tcx>> {
683 Instance::resolve_for_fn_ptr(self.tcx, self.typing_env(), def_id, args_ref)
684 }
685
686 pub fn resolve_closure(
688 &self,
689 def_id: DefId,
690 args_ref: GenericArgs<'tcx>,
691 closure_kind: ClosureKind,
692 ) -> Option<Instance<'tcx>> {
693 Some(Instance::resolve_closure(self.tcx, def_id, args_ref, closure_kind))
694 }
695
696 pub fn eval_instance(&self, instance: ty::Instance<'tcx>) -> Result<ConstValue, ErrorHandled> {
698 self.tcx.const_eval_instance(
699 self.typing_env(),
700 instance,
701 self.tcx.def_span(instance.def_id()),
702 )
703 }
704
705 pub fn eval_static_initializer(
707 &self,
708 def_id: DefId,
709 ) -> Result<ConstAllocation<'tcx>, ErrorHandled> {
710 self.tcx.eval_static_initializer(def_id)
711 }
712
713 pub fn global_alloc(&self, alloc_id: AllocId) -> GlobalAlloc<'tcx> {
715 self.tcx.global_alloc(alloc_id)
716 }
717
718 pub fn vtable_allocation(
720 &self,
721 ty: Ty<'tcx>,
722 trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
723 ) -> AllocId {
724 let alloc_id = self.tcx.vtable_allocation((
725 ty,
726 trait_ref.map(|principal| self.tcx.instantiate_bound_regions_with_erased(principal)),
727 ));
728 alloc_id
729 }
730
731 pub fn instance_name(&self, instance: ty::Instance<'tcx>, trimmed: bool) -> String {
735 if trimmed {
736 {
let _guard = ForceTrimmedGuard::new();
self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
}with_forced_trimmed_paths!(
737 self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
738 )
739 } else {
740 {
let _guard = CrateNamePrefixGuard::new();
{
let _guard = NoTrimmedGuard::new();
self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
}
}with_resolve_crate_name!(with_no_trimmed_paths!(
741 self.tcx.def_path_str_with_args(instance.def_id(), instance.args)
742 ))
743 }
744 }
745
746 pub fn ty_layout(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, B::Error> {
748 let layout = self.layout_of(ty)?.layout;
749 Ok(layout)
750 }
751
752 pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty<'tcx>, lhs: Ty<'tcx>) -> Ty<'tcx> {
754 bin_op.ty(self.tcx, rhs, lhs)
755 }
756
757 pub fn unop_ty(&self, un_op: UnOp, arg: Ty<'tcx>) -> Ty<'tcx> {
759 un_op.ty(self.tcx, arg)
760 }
761
762 pub fn associated_items(&self, def_id: DefId) -> Vec<AssocItem> {
764 let assoc_items = if self.tcx.is_trait_alias(def_id) {
765 Vec::new()
766 } else {
767 self.tcx
768 .associated_item_def_ids(def_id)
769 .iter()
770 .map(|did| self.tcx.associated_item(*did))
771 .collect()
772 };
773 assoc_items
774 }
775
776 pub fn associated_item(&self, def_id: DefId) -> Option<AssocItem> {
778 self.tcx.opt_associated_item(def_id)
779 }
780
781 pub fn vtable_entries(&self, trait_ref: TraitRef<'tcx>) -> Vec<VtblEntry<'tcx>> {
783 self.tcx.vtable_entries(trait_ref).to_vec()
784 }
785
786 pub fn vtable_entry(&self, trait_ref: TraitRef<'tcx>, idx: usize) -> Option<VtblEntry<'tcx>> {
790 self.vtable_entries(trait_ref).get(idx).copied()
791 }
792}