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