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