1#![allow(rustc::usage_of_ty_tykind)]
13
14use std::assert_matches::assert_matches;
15use std::fmt::Debug;
16use std::hash::{Hash, Hasher};
17use std::marker::PhantomData;
18use std::num::NonZero;
19use std::ptr::NonNull;
20use std::{fmt, iter, str};
21
22pub use adt::*;
23pub use assoc::*;
24pub use generic_args::{GenericArgKind, TermKind, *};
25pub use generics::*;
26pub use intrinsic::IntrinsicDef;
27use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
28use rustc_ast::AttrVec;
29use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree};
30use rustc_ast::node_id::NodeMap;
31pub use rustc_ast_ir::{Movability, Mutability, try_visit};
32use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
33use rustc_data_structures::intern::Interned;
34use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
35use rustc_data_structures::steal::Steal;
36use rustc_data_structures::unord::{UnordMap, UnordSet};
37use rustc_errors::{Diag, ErrorGuaranteed, LintBuffer};
38use rustc_hir::attrs::{AttributeKind, StrippedCfgItem};
39use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
40use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
41use rustc_hir::{LangItem, attrs as attr, find_attr};
42use rustc_index::IndexVec;
43use rustc_index::bit_set::BitMatrix;
44use rustc_macros::{
45 BlobDecodable, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
46 TypeVisitable, extension,
47};
48use rustc_query_system::ich::StableHashingContext;
49use rustc_serialize::{Decodable, Encodable};
50pub use rustc_session::lint::RegisteredTools;
51use rustc_span::hygiene::MacroKind;
52use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, sym};
53pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
54pub use rustc_type_ir::fast_reject::DeepRejectCtxt;
55#[allow(
56 hidden_glob_reexports,
57 rustc::usage_of_type_ir_inherent,
58 rustc::non_glob_import_of_type_ir_inherent
59)]
60use rustc_type_ir::inherent;
61pub use rustc_type_ir::relate::VarianceDiagInfo;
62pub use rustc_type_ir::solve::{CandidatePreferenceMode, SizedTraitKind};
63pub use rustc_type_ir::*;
64#[allow(hidden_glob_reexports, unused_imports)]
65use rustc_type_ir::{InferCtxtLike, Interner};
66use tracing::{debug, instrument, trace};
67pub use vtable::*;
68use {rustc_ast as ast, rustc_hir as hir};
69
70pub use self::closure::{
71 BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,
72 MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarId,
73 UpvarPath, analyze_coroutine_closure_captures, is_ancestor_or_same_capture,
74 place_to_string_for_capture,
75};
76pub use self::consts::{
77 AnonConstKind, AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr,
78 ExprKind, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKind, Value,
79};
80pub use self::context::{
81 CtxtInterners, CurrentGcx, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls,
82};
83pub use self::fold::*;
84pub use self::instance::{Instance, InstanceKind, ReifyReason, UnusedGenericParams};
85pub use self::list::{List, ListWithCachedTypeInfo};
86pub use self::opaque_types::OpaqueTypeKey;
87pub use self::pattern::{Pattern, PatternKind};
88pub use self::predicate::{
89 AliasTerm, ArgOutlivesPredicate, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
90 ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
91 HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
92 PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
93 PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
94 PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
95 RegionOutlivesPredicate, SubtypePredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate,
96};
97pub use self::region::{
98 BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region,
99 RegionKind, RegionVid,
100};
101pub use self::sty::{
102 AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
103 CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst,
104 ParamTy, PolyFnSig, TyKind, TypeAndMut, TypingMode, UpvarArgs,
105};
106pub use self::trait_def::TraitDef;
107pub use self::typeck_results::{
108 CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
109 Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
110};
111use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
112use crate::metadata::{AmbigModChild, ModChild};
113use crate::middle::privacy::EffectiveVisibilities;
114use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo};
115use crate::query::{IntoQueryParam, Providers};
116use crate::ty;
117use crate::ty::codec::{TyDecoder, TyEncoder};
118pub use crate::ty::diagnostics::*;
119use crate::ty::fast_reject::SimplifiedType;
120use crate::ty::layout::LayoutError;
121use crate::ty::util::Discr;
122use crate::ty::walk::TypeWalker;
123
124pub mod abstract_const;
125pub mod adjustment;
126pub mod cast;
127pub mod codec;
128pub mod error;
129pub mod fast_reject;
130pub mod inhabitedness;
131pub mod layout;
132pub mod normalize_erasing_regions;
133pub mod offload_meta;
134pub mod pattern;
135pub mod print;
136pub mod relate;
137pub mod significant_drop_order;
138pub mod trait_def;
139pub mod util;
140pub mod vtable;
141
142mod adt;
143mod assoc;
144mod closure;
145mod consts;
146mod context;
147mod diagnostics;
148mod elaborate_impl;
149mod erase_regions;
150mod fold;
151mod generic_args;
152mod generics;
153mod impls_ty;
154mod instance;
155mod intrinsic;
156mod list;
157mod opaque_types;
158mod predicate;
159mod region;
160mod structural_impls;
161#[allow(hidden_glob_reexports)]
162mod sty;
163mod typeck_results;
164mod visit;
165
166#[derive(Debug, HashStable)]
169pub struct ResolverGlobalCtxt {
170 pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
171 pub expn_that_defined: UnordMap<LocalDefId, ExpnId>,
173 pub effective_visibilities: EffectiveVisibilities,
174 pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
175 pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
176 pub module_children: LocalDefIdMap<Vec<ModChild>>,
177 pub ambig_module_children: LocalDefIdMap<Vec<AmbigModChild>>,
178 pub glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
179 pub main_def: Option<MainDefinition>,
180 pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
181 pub proc_macros: Vec<LocalDefId>,
184 pub confused_type_with_std_module: FxIndexMap<Span, Span>,
187 pub doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
188 pub doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
189 pub all_macro_rules: UnordSet<Symbol>,
190 pub stripped_cfg_items: Vec<StrippedCfgItem>,
191}
192
193#[derive(Debug)]
196pub struct ResolverAstLowering {
197 pub legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
198
199 pub partial_res_map: NodeMap<hir::def::PartialRes>,
201 pub import_res_map: NodeMap<hir::def::PerNS<Option<Res<ast::NodeId>>>>,
203 pub label_res_map: NodeMap<ast::NodeId>,
205 pub lifetimes_res_map: NodeMap<LifetimeRes>,
207 pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
209
210 pub next_node_id: ast::NodeId,
211
212 pub node_id_to_def_id: NodeMap<LocalDefId>,
213
214 pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
215 pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
217
218 pub lint_buffer: Steal<LintBuffer>,
220
221 pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
223}
224
225bitflags::bitflags! {
226 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
227 pub struct DelegationFnSigAttrs: u8 {
228 const TARGET_FEATURE = 1 << 0;
229 const MUST_USE = 1 << 1;
230 }
231}
232
233pub const DELEGATION_INHERIT_ATTRS_START: DelegationFnSigAttrs = DelegationFnSigAttrs::MUST_USE;
234
235#[derive(Debug)]
236pub struct DelegationFnSig {
237 pub header: ast::FnHeader,
238 pub param_count: usize,
239 pub has_self: bool,
240 pub c_variadic: bool,
241 pub attrs_flags: DelegationFnSigAttrs,
242 pub to_inherit_attrs: AttrVec,
243}
244
245#[derive(Clone, Copy, Debug, HashStable)]
246pub struct MainDefinition {
247 pub res: Res<ast::NodeId>,
248 pub is_import: bool,
249 pub span: Span,
250}
251
252impl MainDefinition {
253 pub fn opt_fn_def_id(self) -> Option<DefId> {
254 if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None }
255 }
256}
257
258#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
259pub struct ImplTraitHeader<'tcx> {
260 pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
261 pub polarity: ImplPolarity,
262 pub safety: hir::Safety,
263 pub constness: hir::Constness,
264}
265
266#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
267#[derive(TypeFoldable, TypeVisitable, Default)]
268pub enum Asyncness {
269 Yes,
270 #[default]
271 No,
272}
273
274impl Asyncness {
275 pub fn is_async(self) -> bool {
276 matches!(self, Asyncness::Yes)
277 }
278}
279
280#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, BlobDecodable, HashStable)]
281pub enum Visibility<Id = LocalDefId> {
282 Public,
284 Restricted(Id),
286}
287
288impl Visibility {
289 pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
290 match self {
291 ty::Visibility::Restricted(restricted_id) => {
292 if restricted_id.is_top_level_module() {
293 "pub(crate)".to_string()
294 } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
295 "pub(self)".to_string()
296 } else {
297 format!(
298 "pub(in crate{})",
299 tcx.def_path(restricted_id.to_def_id()).to_string_no_crate_verbose()
300 )
301 }
302 }
303 ty::Visibility::Public => "pub".to_string(),
304 }
305 }
306}
307
308#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
309#[derive(TypeFoldable, TypeVisitable)]
310pub struct ClosureSizeProfileData<'tcx> {
311 pub before_feature_tys: Ty<'tcx>,
313 pub after_feature_tys: Ty<'tcx>,
315}
316
317impl TyCtxt<'_> {
318 #[inline]
319 pub fn opt_parent(self, id: DefId) -> Option<DefId> {
320 self.def_key(id).parent.map(|index| DefId { index, ..id })
321 }
322
323 #[inline]
324 #[track_caller]
325 pub fn parent(self, id: DefId) -> DefId {
326 match self.opt_parent(id) {
327 Some(id) => id,
328 None => bug!("{id:?} doesn't have a parent"),
330 }
331 }
332
333 #[inline]
334 #[track_caller]
335 pub fn opt_local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
336 self.opt_parent(id.to_def_id()).map(DefId::expect_local)
337 }
338
339 #[inline]
340 #[track_caller]
341 pub fn local_parent(self, id: impl Into<LocalDefId>) -> LocalDefId {
342 self.parent(id.into().to_def_id()).expect_local()
343 }
344
345 pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
346 if descendant.krate != ancestor.krate {
347 return false;
348 }
349
350 while descendant != ancestor {
351 match self.opt_parent(descendant) {
352 Some(parent) => descendant = parent,
353 None => return false,
354 }
355 }
356 true
357 }
358}
359
360impl<Id> Visibility<Id> {
361 pub fn is_public(self) -> bool {
362 matches!(self, Visibility::Public)
363 }
364
365 pub fn map_id<OutId>(self, f: impl FnOnce(Id) -> OutId) -> Visibility<OutId> {
366 match self {
367 Visibility::Public => Visibility::Public,
368 Visibility::Restricted(id) => Visibility::Restricted(f(id)),
369 }
370 }
371}
372
373impl<Id: Into<DefId>> Visibility<Id> {
374 pub fn to_def_id(self) -> Visibility<DefId> {
375 self.map_id(Into::into)
376 }
377
378 pub fn is_accessible_from(self, module: impl Into<DefId>, tcx: TyCtxt<'_>) -> bool {
380 match self {
381 Visibility::Public => true,
383 Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()),
384 }
385 }
386
387 pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tcx: TyCtxt<'_>) -> bool {
389 match vis {
390 Visibility::Public => self.is_public(),
391 Visibility::Restricted(id) => self.is_accessible_from(id, tcx),
392 }
393 }
394}
395
396impl Visibility<DefId> {
397 pub fn expect_local(self) -> Visibility {
398 self.map_id(|id| id.expect_local())
399 }
400
401 pub fn is_visible_locally(self) -> bool {
403 match self {
404 Visibility::Public => true,
405 Visibility::Restricted(def_id) => def_id.is_local(),
406 }
407 }
408}
409
410#[derive(HashStable, Debug)]
417pub struct CrateVariancesMap<'tcx> {
418 pub variances: DefIdMap<&'tcx [ty::Variance]>,
422}
423
424#[derive(Copy, Clone, PartialEq, Eq, Hash)]
427pub struct CReaderCacheKey {
428 pub cnum: Option<CrateNum>,
429 pub pos: usize,
430}
431
432#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
434#[rustc_diagnostic_item = "Ty"]
435#[rustc_pass_by_value]
436pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
437
438impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> {
439 type Kind = TyKind<'tcx>;
440
441 fn kind(self) -> TyKind<'tcx> {
442 *self.kind()
443 }
444}
445
446impl<'tcx> rustc_type_ir::Flags for Ty<'tcx> {
447 fn flags(&self) -> TypeFlags {
448 self.0.flags
449 }
450
451 fn outer_exclusive_binder(&self) -> DebruijnIndex {
452 self.0.outer_exclusive_binder
453 }
454}
455
456#[derive(HashStable, Debug)]
463pub struct CratePredicatesMap<'tcx> {
464 pub predicates: DefIdMap<&'tcx [(Clause<'tcx>, Span)]>,
468}
469
470#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
471pub struct Term<'tcx> {
472 ptr: NonNull<()>,
473 marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
474}
475
476impl<'tcx> rustc_type_ir::inherent::Term<TyCtxt<'tcx>> for Term<'tcx> {}
477
478impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> {
479 type Kind = TermKind<'tcx>;
480
481 fn kind(self) -> Self::Kind {
482 self.kind()
483 }
484}
485
486unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
487 &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
488{
489}
490unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
491 &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
492{
493}
494unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
495unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
496
497impl Debug for Term<'_> {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 match self.kind() {
500 TermKind::Ty(ty) => write!(f, "Term::Ty({ty:?})"),
501 TermKind::Const(ct) => write!(f, "Term::Const({ct:?})"),
502 }
503 }
504}
505
506impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
507 fn from(ty: Ty<'tcx>) -> Self {
508 TermKind::Ty(ty).pack()
509 }
510}
511
512impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
513 fn from(c: Const<'tcx>) -> Self {
514 TermKind::Const(c).pack()
515 }
516}
517
518impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
519 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
520 self.kind().hash_stable(hcx, hasher);
521 }
522}
523
524impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
525 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
526 self,
527 folder: &mut F,
528 ) -> Result<Self, F::Error> {
529 match self.kind() {
530 ty::TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into),
531 ty::TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
532 }
533 }
534
535 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
536 match self.kind() {
537 ty::TermKind::Ty(ty) => ty.fold_with(folder).into(),
538 ty::TermKind::Const(ct) => ct.fold_with(folder).into(),
539 }
540 }
541}
542
543impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
544 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
545 match self.kind() {
546 ty::TermKind::Ty(ty) => ty.visit_with(visitor),
547 ty::TermKind::Const(ct) => ct.visit_with(visitor),
548 }
549 }
550}
551
552impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Term<'tcx> {
553 fn encode(&self, e: &mut E) {
554 self.kind().encode(e)
555 }
556}
557
558impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Term<'tcx> {
559 fn decode(d: &mut D) -> Self {
560 let res: TermKind<'tcx> = Decodable::decode(d);
561 res.pack()
562 }
563}
564
565impl<'tcx> Term<'tcx> {
566 #[inline]
567 pub fn kind(self) -> TermKind<'tcx> {
568 let ptr =
569 unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) };
570 unsafe {
574 match self.ptr.addr().get() & TAG_MASK {
575 TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
576 ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
577 ))),
578 CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
579 ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
580 ))),
581 _ => core::intrinsics::unreachable(),
582 }
583 }
584 }
585
586 pub fn as_type(&self) -> Option<Ty<'tcx>> {
587 if let TermKind::Ty(ty) = self.kind() { Some(ty) } else { None }
588 }
589
590 pub fn expect_type(&self) -> Ty<'tcx> {
591 self.as_type().expect("expected a type, but found a const")
592 }
593
594 pub fn as_const(&self) -> Option<Const<'tcx>> {
595 if let TermKind::Const(c) = self.kind() { Some(c) } else { None }
596 }
597
598 pub fn expect_const(&self) -> Const<'tcx> {
599 self.as_const().expect("expected a const, but found a type")
600 }
601
602 pub fn into_arg(self) -> GenericArg<'tcx> {
603 match self.kind() {
604 TermKind::Ty(ty) => ty.into(),
605 TermKind::Const(c) => c.into(),
606 }
607 }
608
609 pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
610 match self.kind() {
611 TermKind::Ty(ty) => match *ty.kind() {
612 ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
613 _ => None,
614 },
615 TermKind::Const(ct) => match ct.kind() {
616 ConstKind::Unevaluated(uv) => Some(uv.into()),
617 _ => None,
618 },
619 }
620 }
621
622 pub fn is_infer(&self) -> bool {
623 match self.kind() {
624 TermKind::Ty(ty) => ty.is_ty_var(),
625 TermKind::Const(ct) => ct.is_ct_infer(),
626 }
627 }
628
629 pub fn is_trivially_wf(&self, tcx: TyCtxt<'tcx>) -> bool {
630 match self.kind() {
631 TermKind::Ty(ty) => ty.is_trivially_wf(tcx),
632 TermKind::Const(ct) => ct.is_trivially_wf(),
633 }
634 }
635
636 pub fn walk(self) -> TypeWalker<TyCtxt<'tcx>> {
647 TypeWalker::new(self.into())
648 }
649}
650
651const TAG_MASK: usize = 0b11;
652const TYPE_TAG: usize = 0b00;
653const CONST_TAG: usize = 0b01;
654
655#[extension(pub trait TermKindPackExt<'tcx>)]
656impl<'tcx> TermKind<'tcx> {
657 #[inline]
658 fn pack(self) -> Term<'tcx> {
659 let (tag, ptr) = match self {
660 TermKind::Ty(ty) => {
661 assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
663 (TYPE_TAG, NonNull::from(ty.0.0).cast())
664 }
665 TermKind::Const(ct) => {
666 assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
668 (CONST_TAG, NonNull::from(ct.0.0).cast())
669 }
670 };
671
672 Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
673 }
674}
675
676#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
696pub struct InstantiatedPredicates<'tcx> {
697 pub predicates: Vec<Clause<'tcx>>,
698 pub spans: Vec<Span>,
699}
700
701impl<'tcx> InstantiatedPredicates<'tcx> {
702 pub fn empty() -> InstantiatedPredicates<'tcx> {
703 InstantiatedPredicates { predicates: vec![], spans: vec![] }
704 }
705
706 pub fn is_empty(&self) -> bool {
707 self.predicates.is_empty()
708 }
709
710 pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
711 self.into_iter()
712 }
713}
714
715impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
716 type Item = (Clause<'tcx>, Span);
717
718 type IntoIter = std::iter::Zip<std::vec::IntoIter<Clause<'tcx>>, std::vec::IntoIter<Span>>;
719
720 fn into_iter(self) -> Self::IntoIter {
721 debug_assert_eq!(self.predicates.len(), self.spans.len());
722 std::iter::zip(self.predicates, self.spans)
723 }
724}
725
726impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
727 type Item = (Clause<'tcx>, Span);
728
729 type IntoIter = std::iter::Zip<
730 std::iter::Copied<std::slice::Iter<'a, Clause<'tcx>>>,
731 std::iter::Copied<std::slice::Iter<'a, Span>>,
732 >;
733
734 fn into_iter(self) -> Self::IntoIter {
735 debug_assert_eq!(self.predicates.len(), self.spans.len());
736 std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
737 }
738}
739
740#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
741pub struct ProvisionalHiddenType<'tcx> {
742 pub span: Span,
756
757 pub ty: Ty<'tcx>,
770}
771
772#[derive(Debug, Clone, Copy)]
774pub enum DefiningScopeKind {
775 HirTypeck,
780 MirBorrowck,
781}
782
783impl<'tcx> ProvisionalHiddenType<'tcx> {
784 pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> ProvisionalHiddenType<'tcx> {
785 ProvisionalHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) }
786 }
787
788 pub fn build_mismatch_error(
789 &self,
790 other: &Self,
791 tcx: TyCtxt<'tcx>,
792 ) -> Result<Diag<'tcx>, ErrorGuaranteed> {
793 (self.ty, other.ty).error_reported()?;
794 let sub_diag = if self.span == other.span {
796 TypeMismatchReason::ConflictType { span: self.span }
797 } else {
798 TypeMismatchReason::PreviousUse { span: self.span }
799 };
800 Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
801 self_ty: self.ty,
802 other_ty: other.ty,
803 other_span: other.span,
804 sub: sub_diag,
805 }))
806 }
807
808 #[instrument(level = "debug", skip(tcx), ret)]
809 pub fn remap_generic_params_to_declaration_params(
810 self,
811 opaque_type_key: OpaqueTypeKey<'tcx>,
812 tcx: TyCtxt<'tcx>,
813 defining_scope_kind: DefiningScopeKind,
814 ) -> DefinitionSiteHiddenType<'tcx> {
815 let OpaqueTypeKey { def_id, args } = opaque_type_key;
816
817 let id_args = GenericArgs::identity_for_item(tcx, def_id);
824 debug!(?id_args);
825
826 let map = args.iter().zip(id_args).collect();
830 debug!("map = {:#?}", map);
831
832 let ty = match defining_scope_kind {
838 DefiningScopeKind::HirTypeck => {
839 fold_regions(tcx, self.ty, |_, _| tcx.lifetimes.re_erased)
840 }
841 DefiningScopeKind::MirBorrowck => self.ty,
842 };
843 let result_ty = ty.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span));
844 if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) {
845 assert_eq!(result_ty, fold_regions(tcx, result_ty, |_, _| tcx.lifetimes.re_erased));
846 }
847 DefinitionSiteHiddenType { span: self.span, ty: ty::EarlyBinder::bind(result_ty) }
848 }
849}
850
851#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
852pub struct DefinitionSiteHiddenType<'tcx> {
853 pub span: Span,
866
867 pub ty: ty::EarlyBinder<'tcx, Ty<'tcx>>,
869}
870
871impl<'tcx> DefinitionSiteHiddenType<'tcx> {
872 pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> DefinitionSiteHiddenType<'tcx> {
873 DefinitionSiteHiddenType {
874 span: DUMMY_SP,
875 ty: ty::EarlyBinder::bind(Ty::new_error(tcx, guar)),
876 }
877 }
878
879 pub fn build_mismatch_error(
880 &self,
881 other: &Self,
882 tcx: TyCtxt<'tcx>,
883 ) -> Result<Diag<'tcx>, ErrorGuaranteed> {
884 let self_ty = self.ty.instantiate_identity();
885 let other_ty = other.ty.instantiate_identity();
886 (self_ty, other_ty).error_reported()?;
887 let sub_diag = if self.span == other.span {
889 TypeMismatchReason::ConflictType { span: self.span }
890 } else {
891 TypeMismatchReason::PreviousUse { span: self.span }
892 };
893 Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
894 self_ty,
895 other_ty,
896 other_span: other.span,
897 sub: sub_diag,
898 }))
899 }
900}
901
902pub type PlaceholderRegion<'tcx> = ty::Placeholder<TyCtxt<'tcx>, BoundRegion>;
903
904impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for PlaceholderRegion<'tcx> {
905 type Bound = BoundRegion;
906
907 fn universe(self) -> UniverseIndex {
908 self.universe
909 }
910
911 fn var(self) -> BoundVar {
912 self.bound.var
913 }
914
915 fn with_updated_universe(self, ui: UniverseIndex) -> Self {
916 ty::Placeholder::new(ui, self.bound)
917 }
918
919 fn new(ui: UniverseIndex, bound: BoundRegion) -> Self {
920 ty::Placeholder::new(ui, bound)
921 }
922
923 fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self {
924 ty::Placeholder::new(ui, BoundRegion { var, kind: BoundRegionKind::Anon })
925 }
926}
927
928pub type PlaceholderType<'tcx> = ty::Placeholder<TyCtxt<'tcx>, BoundTy>;
929
930impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for PlaceholderType<'tcx> {
931 type Bound = BoundTy;
932
933 fn universe(self) -> UniverseIndex {
934 self.universe
935 }
936
937 fn var(self) -> BoundVar {
938 self.bound.var
939 }
940
941 fn with_updated_universe(self, ui: UniverseIndex) -> Self {
942 ty::Placeholder::new(ui, self.bound)
943 }
944
945 fn new(ui: UniverseIndex, bound: BoundTy) -> Self {
946 ty::Placeholder::new(ui, bound)
947 }
948
949 fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self {
950 ty::Placeholder::new(ui, BoundTy { var, kind: BoundTyKind::Anon })
951 }
952}
953
954#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
955#[derive(TyEncodable, TyDecodable)]
956pub struct BoundConst {
957 pub var: BoundVar,
958}
959
960impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundConst {
961 fn var(self) -> BoundVar {
962 self.var
963 }
964
965 fn assert_eq(self, var: ty::BoundVariableKind) {
966 var.expect_const()
967 }
968}
969
970pub type PlaceholderConst<'tcx> = ty::Placeholder<TyCtxt<'tcx>, BoundConst>;
971
972impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for PlaceholderConst<'tcx> {
973 type Bound = BoundConst;
974
975 fn universe(self) -> UniverseIndex {
976 self.universe
977 }
978
979 fn var(self) -> BoundVar {
980 self.bound.var
981 }
982
983 fn with_updated_universe(self, ui: UniverseIndex) -> Self {
984 ty::Placeholder::new(ui, self.bound)
985 }
986
987 fn new(ui: UniverseIndex, bound: BoundConst) -> Self {
988 ty::Placeholder::new(ui, bound)
989 }
990
991 fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self {
992 ty::Placeholder::new(ui, BoundConst { var })
993 }
994}
995
996pub type Clauses<'tcx> = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
997
998impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> {
999 fn flags(&self) -> TypeFlags {
1000 (**self).flags()
1001 }
1002
1003 fn outer_exclusive_binder(&self) -> DebruijnIndex {
1004 (**self).outer_exclusive_binder()
1005 }
1006}
1007
1008#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1014#[derive(HashStable, TypeVisitable, TypeFoldable)]
1015pub struct ParamEnv<'tcx> {
1016 caller_bounds: Clauses<'tcx>,
1022}
1023
1024impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
1025 fn caller_bounds(self) -> impl inherent::SliceLike<Item = ty::Clause<'tcx>> {
1026 self.caller_bounds()
1027 }
1028}
1029
1030impl<'tcx> ParamEnv<'tcx> {
1031 #[inline]
1038 pub fn empty() -> Self {
1039 Self::new(ListWithCachedTypeInfo::empty())
1040 }
1041
1042 #[inline]
1043 pub fn caller_bounds(self) -> Clauses<'tcx> {
1044 self.caller_bounds
1045 }
1046
1047 #[inline]
1049 pub fn new(caller_bounds: Clauses<'tcx>) -> Self {
1050 ParamEnv { caller_bounds }
1051 }
1052
1053 pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
1055 ParamEnvAnd { param_env: self, value }
1056 }
1057}
1058
1059#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
1060#[derive(HashStable)]
1061pub struct ParamEnvAnd<'tcx, T> {
1062 pub param_env: ParamEnv<'tcx>,
1063 pub value: T,
1064}
1065
1066#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
1077#[derive(TypeVisitable, TypeFoldable)]
1078pub struct TypingEnv<'tcx> {
1079 #[type_foldable(identity)]
1080 #[type_visitable(ignore)]
1081 pub typing_mode: TypingMode<'tcx>,
1082 pub param_env: ParamEnv<'tcx>,
1083}
1084
1085impl<'tcx> TypingEnv<'tcx> {
1086 pub fn fully_monomorphized() -> TypingEnv<'tcx> {
1094 TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() }
1095 }
1096
1097 pub fn non_body_analysis(
1103 tcx: TyCtxt<'tcx>,
1104 def_id: impl IntoQueryParam<DefId>,
1105 ) -> TypingEnv<'tcx> {
1106 TypingEnv { typing_mode: TypingMode::non_body_analysis(), param_env: tcx.param_env(def_id) }
1107 }
1108
1109 pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1110 tcx.typing_env_normalized_for_post_analysis(def_id)
1111 }
1112
1113 pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
1116 let TypingEnv { typing_mode, param_env } = self;
1117 if let TypingMode::PostAnalysis = typing_mode {
1118 return self;
1119 }
1120
1121 let param_env = if tcx.next_trait_solver_globally() {
1124 param_env
1125 } else {
1126 ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
1127 };
1128 TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
1129 }
1130
1131 pub fn as_query_input<T>(self, value: T) -> PseudoCanonicalInput<'tcx, T>
1136 where
1137 T: TypeVisitable<TyCtxt<'tcx>>,
1138 {
1139 PseudoCanonicalInput { typing_env: self, value }
1152 }
1153}
1154
1155#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1165#[derive(HashStable, TypeVisitable, TypeFoldable)]
1166pub struct PseudoCanonicalInput<'tcx, T> {
1167 pub typing_env: TypingEnv<'tcx>,
1168 pub value: T,
1169}
1170
1171#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
1172pub struct Destructor {
1173 pub did: DefId,
1175}
1176
1177#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
1179pub struct AsyncDestructor {
1180 pub impl_did: DefId,
1182}
1183
1184#[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
1185pub struct VariantFlags(u8);
1186bitflags::bitflags! {
1187 impl VariantFlags: u8 {
1188 const NO_VARIANT_FLAGS = 0;
1189 const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
1191 }
1192}
1193rustc_data_structures::external_bitflags_debug! { VariantFlags }
1194
1195#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
1197pub struct VariantDef {
1198 pub def_id: DefId,
1201 pub ctor: Option<(CtorKind, DefId)>,
1204 pub name: Symbol,
1206 pub discr: VariantDiscr,
1208 pub fields: IndexVec<FieldIdx, FieldDef>,
1210 tainted: Option<ErrorGuaranteed>,
1212 flags: VariantFlags,
1214}
1215
1216impl VariantDef {
1217 #[instrument(level = "debug")]
1234 pub fn new(
1235 name: Symbol,
1236 variant_did: Option<DefId>,
1237 ctor: Option<(CtorKind, DefId)>,
1238 discr: VariantDiscr,
1239 fields: IndexVec<FieldIdx, FieldDef>,
1240 parent_did: DefId,
1241 recover_tainted: Option<ErrorGuaranteed>,
1242 is_field_list_non_exhaustive: bool,
1243 ) -> Self {
1244 let mut flags = VariantFlags::NO_VARIANT_FLAGS;
1245 if is_field_list_non_exhaustive {
1246 flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
1247 }
1248
1249 VariantDef {
1250 def_id: variant_did.unwrap_or(parent_did),
1251 ctor,
1252 name,
1253 discr,
1254 fields,
1255 flags,
1256 tainted: recover_tainted,
1257 }
1258 }
1259
1260 #[inline]
1266 pub fn is_field_list_non_exhaustive(&self) -> bool {
1267 self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
1268 }
1269
1270 #[inline]
1273 pub fn field_list_has_applicable_non_exhaustive(&self) -> bool {
1274 self.is_field_list_non_exhaustive() && !self.def_id.is_local()
1275 }
1276
1277 pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
1279 Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
1280 }
1281
1282 #[inline]
1284 pub fn has_errors(&self) -> Result<(), ErrorGuaranteed> {
1285 self.tainted.map_or(Ok(()), Err)
1286 }
1287
1288 #[inline]
1289 pub fn ctor_kind(&self) -> Option<CtorKind> {
1290 self.ctor.map(|(kind, _)| kind)
1291 }
1292
1293 #[inline]
1294 pub fn ctor_def_id(&self) -> Option<DefId> {
1295 self.ctor.map(|(_, def_id)| def_id)
1296 }
1297
1298 #[inline]
1302 pub fn single_field(&self) -> &FieldDef {
1303 assert!(self.fields.len() == 1);
1304
1305 &self.fields[FieldIdx::ZERO]
1306 }
1307
1308 #[inline]
1310 pub fn tail_opt(&self) -> Option<&FieldDef> {
1311 self.fields.raw.last()
1312 }
1313
1314 #[inline]
1320 pub fn tail(&self) -> &FieldDef {
1321 self.tail_opt().expect("expected unsized ADT to have a tail field")
1322 }
1323
1324 pub fn has_unsafe_fields(&self) -> bool {
1326 self.fields.iter().any(|x| x.safety.is_unsafe())
1327 }
1328}
1329
1330impl PartialEq for VariantDef {
1331 #[inline]
1332 fn eq(&self, other: &Self) -> bool {
1333 let Self {
1341 def_id: lhs_def_id,
1342 ctor: _,
1343 name: _,
1344 discr: _,
1345 fields: _,
1346 flags: _,
1347 tainted: _,
1348 } = &self;
1349 let Self {
1350 def_id: rhs_def_id,
1351 ctor: _,
1352 name: _,
1353 discr: _,
1354 fields: _,
1355 flags: _,
1356 tainted: _,
1357 } = other;
1358
1359 let res = lhs_def_id == rhs_def_id;
1360
1361 if cfg!(debug_assertions) && res {
1363 let deep = self.ctor == other.ctor
1364 && self.name == other.name
1365 && self.discr == other.discr
1366 && self.fields == other.fields
1367 && self.flags == other.flags;
1368 assert!(deep, "VariantDef for the same def-id has differing data");
1369 }
1370
1371 res
1372 }
1373}
1374
1375impl Eq for VariantDef {}
1376
1377impl Hash for VariantDef {
1378 #[inline]
1379 fn hash<H: Hasher>(&self, s: &mut H) {
1380 let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _, tainted: _ } = &self;
1388 def_id.hash(s)
1389 }
1390}
1391
1392#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
1393pub enum VariantDiscr {
1394 Explicit(DefId),
1397
1398 Relative(u32),
1403}
1404
1405#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
1406pub struct FieldDef {
1407 pub did: DefId,
1408 pub name: Symbol,
1409 pub vis: Visibility<DefId>,
1410 pub safety: hir::Safety,
1411 pub value: Option<DefId>,
1412}
1413
1414impl PartialEq for FieldDef {
1415 #[inline]
1416 fn eq(&self, other: &Self) -> bool {
1417 let Self { did: lhs_did, name: _, vis: _, safety: _, value: _ } = &self;
1425
1426 let Self { did: rhs_did, name: _, vis: _, safety: _, value: _ } = other;
1427
1428 let res = lhs_did == rhs_did;
1429
1430 if cfg!(debug_assertions) && res {
1432 let deep =
1433 self.name == other.name && self.vis == other.vis && self.safety == other.safety;
1434 assert!(deep, "FieldDef for the same def-id has differing data");
1435 }
1436
1437 res
1438 }
1439}
1440
1441impl Eq for FieldDef {}
1442
1443impl Hash for FieldDef {
1444 #[inline]
1445 fn hash<H: Hasher>(&self, s: &mut H) {
1446 let Self { did, name: _, vis: _, safety: _, value: _ } = &self;
1454
1455 did.hash(s)
1456 }
1457}
1458
1459impl<'tcx> FieldDef {
1460 pub fn ty(&self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
1463 tcx.type_of(self.did).instantiate(tcx, args)
1464 }
1465
1466 pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
1468 Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
1469 }
1470}
1471
1472#[derive(Debug, PartialEq, Eq)]
1473pub enum ImplOverlapKind {
1474 Permitted {
1476 marker: bool,
1478 },
1479}
1480
1481#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
1484pub enum ImplTraitInTraitData {
1485 Trait { fn_def_id: DefId, opaque_def_id: DefId },
1486 Impl { fn_def_id: DefId },
1487}
1488
1489impl<'tcx> TyCtxt<'tcx> {
1490 pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> {
1491 self.typeck(self.hir_body_owner_def_id(body))
1492 }
1493
1494 pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
1495 self.associated_items(id)
1496 .in_definition_order()
1497 .filter(move |item| item.is_fn() && item.defaultness(self).has_value())
1498 }
1499
1500 pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions {
1501 let mut flags = ReprFlags::empty();
1502 let mut size = None;
1503 let mut max_align: Option<Align> = None;
1504 let mut min_pack: Option<Align> = None;
1505
1506 let mut field_shuffle_seed = self.def_path_hash(did.to_def_id()).0.to_smaller_hash();
1509
1510 if let Some(user_seed) = self.sess.opts.unstable_opts.layout_seed {
1514 field_shuffle_seed ^= user_seed;
1515 }
1516
1517 let attributes = self.get_all_attrs(did);
1518 if let Some(reprs) = find_attr!(attributes, AttributeKind::Repr { reprs, .. } => reprs) {
1519 for (r, _) in reprs {
1520 flags.insert(match *r {
1521 attr::ReprRust => ReprFlags::empty(),
1522 attr::ReprC => ReprFlags::IS_C,
1523 attr::ReprPacked(pack) => {
1524 min_pack = Some(if let Some(min_pack) = min_pack {
1525 min_pack.min(pack)
1526 } else {
1527 pack
1528 });
1529 ReprFlags::empty()
1530 }
1531 attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
1532 attr::ReprSimd => ReprFlags::IS_SIMD,
1533 attr::ReprInt(i) => {
1534 size = Some(match i {
1535 attr::IntType::SignedInt(x) => match x {
1536 ast::IntTy::Isize => IntegerType::Pointer(true),
1537 ast::IntTy::I8 => IntegerType::Fixed(Integer::I8, true),
1538 ast::IntTy::I16 => IntegerType::Fixed(Integer::I16, true),
1539 ast::IntTy::I32 => IntegerType::Fixed(Integer::I32, true),
1540 ast::IntTy::I64 => IntegerType::Fixed(Integer::I64, true),
1541 ast::IntTy::I128 => IntegerType::Fixed(Integer::I128, true),
1542 },
1543 attr::IntType::UnsignedInt(x) => match x {
1544 ast::UintTy::Usize => IntegerType::Pointer(false),
1545 ast::UintTy::U8 => IntegerType::Fixed(Integer::I8, false),
1546 ast::UintTy::U16 => IntegerType::Fixed(Integer::I16, false),
1547 ast::UintTy::U32 => IntegerType::Fixed(Integer::I32, false),
1548 ast::UintTy::U64 => IntegerType::Fixed(Integer::I64, false),
1549 ast::UintTy::U128 => IntegerType::Fixed(Integer::I128, false),
1550 },
1551 });
1552 ReprFlags::empty()
1553 }
1554 attr::ReprAlign(align) => {
1555 max_align = max_align.max(Some(align));
1556 ReprFlags::empty()
1557 }
1558 });
1559 }
1560 }
1561
1562 if self.sess.opts.unstable_opts.randomize_layout {
1565 flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
1566 }
1567
1568 let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
1571
1572 if is_box {
1574 flags.insert(ReprFlags::IS_LINEAR);
1575 }
1576
1577 if find_attr!(attributes, AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)) {
1579 flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS);
1580 }
1581
1582 ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed }
1583 }
1584
1585 pub fn opt_item_name(self, def_id: impl IntoQueryParam<DefId>) -> Option<Symbol> {
1587 let def_id = def_id.into_query_param();
1588 if let Some(cnum) = def_id.as_crate_root() {
1589 Some(self.crate_name(cnum))
1590 } else {
1591 let def_key = self.def_key(def_id);
1592 match def_key.disambiguated_data.data {
1593 rustc_hir::definitions::DefPathData::Ctor => self
1595 .opt_item_name(DefId { krate: def_id.krate, index: def_key.parent.unwrap() }),
1596 _ => def_key.get_opt_name(),
1597 }
1598 }
1599 }
1600
1601 pub fn item_name(self, id: impl IntoQueryParam<DefId>) -> Symbol {
1608 let id = id.into_query_param();
1609 self.opt_item_name(id).unwrap_or_else(|| {
1610 bug!("item_name: no name for {:?}", self.def_path(id));
1611 })
1612 }
1613
1614 pub fn opt_item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Option<Ident> {
1618 let def_id = def_id.into_query_param();
1619 let def = self.opt_item_name(def_id)?;
1620 let span = self
1621 .def_ident_span(def_id)
1622 .unwrap_or_else(|| bug!("missing ident span for {def_id:?}"));
1623 Some(Ident::new(def, span))
1624 }
1625
1626 pub fn item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Ident {
1630 let def_id = def_id.into_query_param();
1631 self.opt_item_ident(def_id).unwrap_or_else(|| {
1632 bug!("item_ident: no name for {:?}", self.def_path(def_id));
1633 })
1634 }
1635
1636 pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
1637 if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
1638 Some(self.associated_item(def_id))
1639 } else {
1640 None
1641 }
1642 }
1643
1644 pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
1648 if let DefKind::AssocTy = self.def_kind(def_id)
1649 && let AssocKind::Type { data: AssocTypeData::Rpitit(rpitit_info) } =
1650 self.associated_item(def_id).kind
1651 {
1652 Some(rpitit_info)
1653 } else {
1654 None
1655 }
1656 }
1657
1658 pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
1659 variant.fields.iter_enumerated().find_map(|(i, field)| {
1660 self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
1661 })
1662 }
1663
1664 #[instrument(level = "debug", skip(self), ret)]
1667 pub fn impls_are_allowed_to_overlap(
1668 self,
1669 def_id1: DefId,
1670 def_id2: DefId,
1671 ) -> Option<ImplOverlapKind> {
1672 let impl1 = self.impl_trait_header(def_id1);
1673 let impl2 = self.impl_trait_header(def_id2);
1674
1675 let trait_ref1 = impl1.trait_ref.skip_binder();
1676 let trait_ref2 = impl2.trait_ref.skip_binder();
1677
1678 if trait_ref1.references_error() || trait_ref2.references_error() {
1681 return Some(ImplOverlapKind::Permitted { marker: false });
1682 }
1683
1684 match (impl1.polarity, impl2.polarity) {
1685 (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
1686 return Some(ImplOverlapKind::Permitted { marker: false });
1688 }
1689 (ImplPolarity::Positive, ImplPolarity::Negative)
1690 | (ImplPolarity::Negative, ImplPolarity::Positive) => {
1691 return None;
1693 }
1694 (ImplPolarity::Positive, ImplPolarity::Positive)
1695 | (ImplPolarity::Negative, ImplPolarity::Negative) => {}
1696 };
1697
1698 let is_marker_impl = |trait_ref: TraitRef<'_>| self.trait_def(trait_ref.def_id).is_marker;
1699 let is_marker_overlap = is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2);
1700
1701 if is_marker_overlap {
1702 return Some(ImplOverlapKind::Permitted { marker: true });
1703 }
1704
1705 None
1706 }
1707
1708 pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
1711 match res {
1712 Res::Def(DefKind::Variant, did) => {
1713 let enum_did = self.parent(did);
1714 self.adt_def(enum_did).variant_with_id(did)
1715 }
1716 Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(),
1717 Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
1718 let variant_did = self.parent(variant_ctor_did);
1719 let enum_did = self.parent(variant_did);
1720 self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
1721 }
1722 Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
1723 let struct_did = self.parent(ctor_did);
1724 self.adt_def(struct_did).non_enum_variant()
1725 }
1726 _ => bug!("expect_variant_res used with unexpected res {:?}", res),
1727 }
1728 }
1729
1730 #[instrument(skip(self), level = "debug")]
1732 pub fn instance_mir(self, instance: ty::InstanceKind<'tcx>) -> &'tcx Body<'tcx> {
1733 match instance {
1734 ty::InstanceKind::Item(def) => {
1735 debug!("calling def_kind on def: {:?}", def);
1736 let def_kind = self.def_kind(def);
1737 debug!("returned from def_kind: {:?}", def_kind);
1738 match def_kind {
1739 DefKind::Const
1740 | DefKind::Static { .. }
1741 | DefKind::AssocConst
1742 | DefKind::Ctor(..)
1743 | DefKind::AnonConst
1744 | DefKind::InlineConst => self.mir_for_ctfe(def),
1745 _ => self.optimized_mir(def),
1748 }
1749 }
1750 ty::InstanceKind::VTableShim(..)
1751 | ty::InstanceKind::ReifyShim(..)
1752 | ty::InstanceKind::Intrinsic(..)
1753 | ty::InstanceKind::FnPtrShim(..)
1754 | ty::InstanceKind::Virtual(..)
1755 | ty::InstanceKind::ClosureOnceShim { .. }
1756 | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
1757 | ty::InstanceKind::FutureDropPollShim(..)
1758 | ty::InstanceKind::DropGlue(..)
1759 | ty::InstanceKind::CloneShim(..)
1760 | ty::InstanceKind::ThreadLocalShim(..)
1761 | ty::InstanceKind::FnPtrAddrShim(..)
1762 | ty::InstanceKind::AsyncDropGlueCtorShim(..)
1763 | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance),
1764 }
1765 }
1766
1767 pub fn get_attrs(
1769 self,
1770 did: impl Into<DefId>,
1771 attr: Symbol,
1772 ) -> impl Iterator<Item = &'tcx hir::Attribute> {
1773 self.get_all_attrs(did).iter().filter(move |a: &&hir::Attribute| a.has_name(attr))
1774 }
1775
1776 pub fn get_all_attrs(self, did: impl Into<DefId>) -> &'tcx [hir::Attribute] {
1781 let did: DefId = did.into();
1782 if let Some(did) = did.as_local() {
1783 self.hir_attrs(self.local_def_id_to_hir_id(did))
1784 } else {
1785 self.attrs_for_def(did)
1786 }
1787 }
1788
1789 pub fn get_diagnostic_attr(
1798 self,
1799 did: impl Into<DefId>,
1800 attr: Symbol,
1801 ) -> Option<&'tcx hir::Attribute> {
1802 let did: DefId = did.into();
1803 if did.as_local().is_some() {
1804 if rustc_feature::is_stable_diagnostic_attribute(attr, self.features()) {
1806 self.get_attrs_by_path(did, &[sym::diagnostic, sym::do_not_recommend]).next()
1807 } else {
1808 None
1809 }
1810 } else {
1811 debug_assert!(rustc_feature::encode_cross_crate(attr));
1814 self.attrs_for_def(did)
1815 .iter()
1816 .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr))
1817 }
1818 }
1819
1820 pub fn get_attrs_by_path(
1821 self,
1822 did: DefId,
1823 attr: &[Symbol],
1824 ) -> impl Iterator<Item = &'tcx hir::Attribute> {
1825 let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr);
1826 if let Some(did) = did.as_local() {
1827 self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
1828 } else {
1829 self.attrs_for_def(did).iter().filter(filter_fn)
1830 }
1831 }
1832
1833 pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx hir::Attribute> {
1834 if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
1835 let did: DefId = did.into();
1836 bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
1837 } else {
1838 self.get_attrs(did, attr).next()
1839 }
1840 }
1841
1842 pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
1844 self.get_attrs(did, attr).next().is_some()
1845 }
1846
1847 pub fn has_attrs_with_path(self, did: impl Into<DefId>, attrs: &[Symbol]) -> bool {
1849 self.get_attrs_by_path(did.into(), attrs).next().is_some()
1850 }
1851
1852 pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
1854 self.trait_def(trait_def_id).has_auto_impl
1855 }
1856
1857 pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
1860 self.trait_def(trait_def_id).is_coinductive
1861 }
1862
1863 pub fn trait_is_alias(self, trait_def_id: DefId) -> bool {
1865 self.def_kind(trait_def_id) == DefKind::TraitAlias
1866 }
1867
1868 fn layout_error(self, err: LayoutError<'tcx>) -> &'tcx LayoutError<'tcx> {
1870 self.arena.alloc(err)
1871 }
1872
1873 fn ordinary_coroutine_layout(
1879 self,
1880 def_id: DefId,
1881 args: GenericArgsRef<'tcx>,
1882 ) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
1883 let coroutine_kind_ty = args.as_coroutine().kind_ty();
1884 let mir = self.optimized_mir(def_id);
1885 let ty = || Ty::new_coroutine(self, def_id, args);
1886 if coroutine_kind_ty.is_unit() {
1888 mir.coroutine_layout_raw().ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
1889 } else {
1890 let ty::Coroutine(_, identity_args) =
1893 *self.type_of(def_id).instantiate_identity().kind()
1894 else {
1895 unreachable!();
1896 };
1897 let identity_kind_ty = identity_args.as_coroutine().kind_ty();
1898 if identity_kind_ty == coroutine_kind_ty {
1901 mir.coroutine_layout_raw()
1902 .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
1903 } else {
1904 assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
1905 assert_matches!(
1906 identity_kind_ty.to_opt_closure_kind(),
1907 Some(ClosureKind::Fn | ClosureKind::FnMut)
1908 );
1909 self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
1910 .coroutine_layout_raw()
1911 .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
1912 }
1913 }
1914 }
1915
1916 fn async_drop_coroutine_layout(
1920 self,
1921 def_id: DefId,
1922 args: GenericArgsRef<'tcx>,
1923 ) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
1924 let ty = || Ty::new_coroutine(self, def_id, args);
1925 if args[0].has_placeholders() || args[0].has_non_region_param() {
1926 return Err(self.layout_error(LayoutError::TooGeneric(ty())));
1927 }
1928 let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
1929 self.mir_shims(instance)
1930 .coroutine_layout_raw()
1931 .ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
1932 }
1933
1934 pub fn coroutine_layout(
1937 self,
1938 def_id: DefId,
1939 args: GenericArgsRef<'tcx>,
1940 ) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
1941 if self.is_async_drop_in_place_coroutine(def_id) {
1942 let arg_cor_ty = args.first().unwrap().expect_ty();
1946 if arg_cor_ty.is_coroutine() {
1947 let span = self.def_span(def_id);
1948 let source_info = SourceInfo::outermost(span);
1949 let variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
1952 iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
1953 let variant_source_info: IndexVec<VariantIdx, SourceInfo> =
1954 iter::repeat(source_info).take(CoroutineArgs::RESERVED_VARIANTS).collect();
1955 let proxy_layout = CoroutineLayout {
1956 field_tys: [].into(),
1957 field_names: [].into(),
1958 variant_fields,
1959 variant_source_info,
1960 storage_conflicts: BitMatrix::new(0, 0),
1961 };
1962 return Ok(self.arena.alloc(proxy_layout));
1963 } else {
1964 self.async_drop_coroutine_layout(def_id, args)
1965 }
1966 } else {
1967 self.ordinary_coroutine_layout(def_id, args)
1968 }
1969 }
1970
1971 pub fn assoc_parent(self, def_id: DefId) -> Option<(DefId, DefKind)> {
1973 if !self.def_kind(def_id).is_assoc() {
1974 return None;
1975 }
1976 let parent = self.parent(def_id);
1977 let def_kind = self.def_kind(parent);
1978 Some((parent, def_kind))
1979 }
1980
1981 pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> {
1983 self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id()
1984 }
1985
1986 pub fn trait_of_assoc(self, def_id: DefId) -> Option<DefId> {
1989 match self.assoc_parent(def_id) {
1990 Some((id, DefKind::Trait)) => Some(id),
1991 _ => None,
1992 }
1993 }
1994
1995 pub fn impl_is_of_trait(self, def_id: impl IntoQueryParam<DefId>) -> bool {
1996 let def_id = def_id.into_query_param();
1997 let DefKind::Impl { of_trait } = self.def_kind(def_id) else {
1998 panic!("expected Impl for {def_id:?}");
1999 };
2000 of_trait
2001 }
2002
2003 pub fn impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
2006 match self.assoc_parent(def_id) {
2007 Some((id, DefKind::Impl { .. })) => Some(id),
2008 _ => None,
2009 }
2010 }
2011
2012 pub fn inherent_impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
2015 match self.assoc_parent(def_id) {
2016 Some((id, DefKind::Impl { of_trait: false })) => Some(id),
2017 _ => None,
2018 }
2019 }
2020
2021 pub fn trait_impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
2024 match self.assoc_parent(def_id) {
2025 Some((id, DefKind::Impl { of_trait: true })) => Some(id),
2026 _ => None,
2027 }
2028 }
2029
2030 pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
2031 self.impl_trait_header(def_id).polarity
2032 }
2033
2034 pub fn impl_trait_ref(
2036 self,
2037 def_id: impl IntoQueryParam<DefId>,
2038 ) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
2039 self.impl_trait_header(def_id).trait_ref
2040 }
2041
2042 pub fn impl_opt_trait_ref(
2045 self,
2046 def_id: impl IntoQueryParam<DefId>,
2047 ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> {
2048 let def_id = def_id.into_query_param();
2049 self.impl_is_of_trait(def_id).then(|| self.impl_trait_ref(def_id))
2050 }
2051
2052 pub fn impl_trait_id(self, def_id: impl IntoQueryParam<DefId>) -> DefId {
2054 self.impl_trait_ref(def_id).skip_binder().def_id
2055 }
2056
2057 pub fn impl_opt_trait_id(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> {
2060 let def_id = def_id.into_query_param();
2061 self.impl_is_of_trait(def_id).then(|| self.impl_trait_id(def_id))
2062 }
2063
2064 pub fn is_exportable(self, def_id: DefId) -> bool {
2065 self.exportable_items(def_id.krate).contains(&def_id)
2066 }
2067
2068 pub fn is_builtin_derived(self, def_id: DefId) -> bool {
2071 if self.is_automatically_derived(def_id)
2072 && let Some(def_id) = def_id.as_local()
2073 && let outer = self.def_span(def_id).ctxt().outer_expn_data()
2074 && matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _))
2075 && find_attr!(
2076 self.get_all_attrs(outer.macro_def_id.unwrap()),
2077 AttributeKind::RustcBuiltinMacro { .. }
2078 )
2079 {
2080 true
2081 } else {
2082 false
2083 }
2084 }
2085
2086 pub fn is_automatically_derived(self, def_id: DefId) -> bool {
2088 find_attr!(self.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..))
2089 }
2090
2091 pub fn span_of_impl(self, impl_def_id: DefId) -> Result<Span, Symbol> {
2094 if let Some(impl_def_id) = impl_def_id.as_local() {
2095 Ok(self.def_span(impl_def_id))
2096 } else {
2097 Err(self.crate_name(impl_def_id.krate))
2098 }
2099 }
2100
2101 pub fn hygienic_eq(self, use_ident: Ident, def_ident: Ident, def_parent_def_id: DefId) -> bool {
2105 use_ident.name == def_ident.name
2109 && use_ident
2110 .span
2111 .ctxt()
2112 .hygienic_eq(def_ident.span.ctxt(), self.expn_that_defined(def_parent_def_id))
2113 }
2114
2115 pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
2116 ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope));
2117 ident
2118 }
2119
2120 pub fn adjust_ident_and_get_scope(
2122 self,
2123 mut ident: Ident,
2124 scope: DefId,
2125 block: hir::HirId,
2126 ) -> (Ident, DefId) {
2127 let scope = ident
2128 .span
2129 .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
2130 .and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
2131 .unwrap_or_else(|| self.parent_module(block).to_def_id());
2132 (ident, scope)
2133 }
2134
2135 #[inline]
2139 pub fn is_const_fn(self, def_id: DefId) -> bool {
2140 matches!(
2141 self.def_kind(def_id),
2142 DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure
2143 ) && self.constness(def_id) == hir::Constness::Const
2144 }
2145
2146 pub fn is_conditionally_const(self, def_id: impl Into<DefId>) -> bool {
2153 let def_id: DefId = def_id.into();
2154 match self.def_kind(def_id) {
2155 DefKind::Impl { of_trait: true } => {
2156 let header = self.impl_trait_header(def_id);
2157 header.constness == hir::Constness::Const
2158 && self.is_const_trait(header.trait_ref.skip_binder().def_id)
2159 }
2160 DefKind::Impl { of_trait: false } => self.constness(def_id) == hir::Constness::Const,
2161 DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
2162 self.constness(def_id) == hir::Constness::Const
2163 }
2164 DefKind::TraitAlias | DefKind::Trait => self.is_const_trait(def_id),
2165 DefKind::AssocTy => {
2166 let parent_def_id = self.parent(def_id);
2167 match self.def_kind(parent_def_id) {
2168 DefKind::Impl { of_trait: false } => false,
2169 DefKind::Impl { of_trait: true } | DefKind::Trait => {
2170 self.is_conditionally_const(parent_def_id)
2171 }
2172 _ => bug!("unexpected parent item of associated type: {parent_def_id:?}"),
2173 }
2174 }
2175 DefKind::AssocFn => {
2176 let parent_def_id = self.parent(def_id);
2177 match self.def_kind(parent_def_id) {
2178 DefKind::Impl { of_trait: false } => {
2179 self.constness(def_id) == hir::Constness::Const
2180 }
2181 DefKind::Impl { of_trait: true } | DefKind::Trait => {
2182 self.is_conditionally_const(parent_def_id)
2183 }
2184 _ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
2185 }
2186 }
2187 DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
2188 hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
2189 hir::OpaqueTyOrigin::AsyncFn { .. } => false,
2190 hir::OpaqueTyOrigin::TyAlias { .. } => false,
2192 },
2193 DefKind::Closure => {
2194 false
2197 }
2198 DefKind::Ctor(_, CtorKind::Const)
2199 | DefKind::Mod
2200 | DefKind::Struct
2201 | DefKind::Union
2202 | DefKind::Enum
2203 | DefKind::Variant
2204 | DefKind::TyAlias
2205 | DefKind::ForeignTy
2206 | DefKind::TyParam
2207 | DefKind::Const
2208 | DefKind::ConstParam
2209 | DefKind::Static { .. }
2210 | DefKind::AssocConst
2211 | DefKind::Macro(_)
2212 | DefKind::ExternCrate
2213 | DefKind::Use
2214 | DefKind::ForeignMod
2215 | DefKind::AnonConst
2216 | DefKind::InlineConst
2217 | DefKind::Field
2218 | DefKind::LifetimeParam
2219 | DefKind::GlobalAsm
2220 | DefKind::SyntheticCoroutineBody => false,
2221 }
2222 }
2223
2224 #[inline]
2225 pub fn is_const_trait(self, def_id: DefId) -> bool {
2226 self.trait_def(def_id).constness == hir::Constness::Const
2227 }
2228
2229 pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
2230 if self.def_kind(def_id) != DefKind::AssocFn {
2231 return false;
2232 }
2233
2234 let Some(item) = self.opt_associated_item(def_id) else {
2235 return false;
2236 };
2237
2238 let AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container else {
2239 return false;
2240 };
2241
2242 !self.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id).is_empty()
2243 }
2244}
2245
2246pub fn provide(providers: &mut Providers) {
2247 closure::provide(providers);
2248 context::provide(providers);
2249 erase_regions::provide(providers);
2250 inhabitedness::provide(providers);
2251 util::provide(providers);
2252 print::provide(providers);
2253 super::util::bug::provide(providers);
2254 *providers = Providers {
2255 trait_impls_of: trait_def::trait_impls_of_provider,
2256 incoherent_impls: trait_def::incoherent_impls_provider,
2257 trait_impls_in_crate: trait_def::trait_impls_in_crate_provider,
2258 traits: trait_def::traits_provider,
2259 vtable_allocation: vtable::vtable_allocation_provider,
2260 ..*providers
2261 };
2262}
2263
2264#[derive(Clone, Debug, Default, HashStable)]
2270pub struct CrateInherentImpls {
2271 pub inherent_impls: FxIndexMap<LocalDefId, Vec<DefId>>,
2272 pub incoherent_impls: FxIndexMap<SimplifiedType, Vec<LocalDefId>>,
2273}
2274
2275#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
2276pub struct SymbolName<'tcx> {
2277 pub name: &'tcx str,
2279}
2280
2281impl<'tcx> SymbolName<'tcx> {
2282 pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> {
2283 SymbolName { name: tcx.arena.alloc_str(name) }
2284 }
2285}
2286
2287impl<'tcx> fmt::Display for SymbolName<'tcx> {
2288 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2289 fmt::Display::fmt(&self.name, fmt)
2290 }
2291}
2292
2293impl<'tcx> fmt::Debug for SymbolName<'tcx> {
2294 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2295 fmt::Display::fmt(&self.name, fmt)
2296 }
2297}
2298
2299#[derive(Copy, Clone, Debug, HashStable)]
2301pub struct DestructuredConst<'tcx> {
2302 pub variant: Option<VariantIdx>,
2303 pub fields: &'tcx [ty::Const<'tcx>],
2304}
2305
2306pub fn fnc_typetrees<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>) -> FncTree {
2310 if tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::NoTT) {
2312 return FncTree { args: vec![], ret: TypeTree::new() };
2313 }
2314
2315 if !fn_ty.is_fn() {
2317 return FncTree { args: vec![], ret: TypeTree::new() };
2318 }
2319
2320 let fn_sig = fn_ty.fn_sig(tcx);
2322 let sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
2323
2324 let mut args = vec![];
2326 for ty in sig.inputs().iter() {
2327 let type_tree = typetree_from_ty(tcx, *ty);
2328 args.push(type_tree);
2329 }
2330
2331 let ret = typetree_from_ty(tcx, sig.output());
2333
2334 FncTree { args, ret }
2335}
2336
2337pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
2340 let mut visited = Vec::new();
2341 typetree_from_ty_inner(tcx, ty, 0, &mut visited)
2342}
2343
2344const MAX_TYPETREE_DEPTH: usize = 6;
2347
2348fn typetree_from_ty_inner<'tcx>(
2350 tcx: TyCtxt<'tcx>,
2351 ty: Ty<'tcx>,
2352 depth: usize,
2353 visited: &mut Vec<Ty<'tcx>>,
2354) -> TypeTree {
2355 if depth >= MAX_TYPETREE_DEPTH {
2356 trace!("typetree depth limit {} reached for type: {}", MAX_TYPETREE_DEPTH, ty);
2357 return TypeTree::new();
2358 }
2359
2360 if visited.contains(&ty) {
2361 return TypeTree::new();
2362 }
2363
2364 visited.push(ty);
2365 let result = typetree_from_ty_impl(tcx, ty, depth, visited);
2366 visited.pop();
2367 result
2368}
2369
2370fn typetree_from_ty_impl<'tcx>(
2372 tcx: TyCtxt<'tcx>,
2373 ty: Ty<'tcx>,
2374 depth: usize,
2375 visited: &mut Vec<Ty<'tcx>>,
2376) -> TypeTree {
2377 typetree_from_ty_impl_inner(tcx, ty, depth, visited, false)
2378}
2379
2380fn typetree_from_ty_impl_inner<'tcx>(
2382 tcx: TyCtxt<'tcx>,
2383 ty: Ty<'tcx>,
2384 depth: usize,
2385 visited: &mut Vec<Ty<'tcx>>,
2386 is_reference_target: bool,
2387) -> TypeTree {
2388 if ty.is_scalar() {
2389 let (kind, size) = if ty.is_integral() || ty.is_char() || ty.is_bool() {
2390 (Kind::Integer, ty.primitive_size(tcx).bytes_usize())
2391 } else if ty.is_floating_point() {
2392 match ty {
2393 x if x == tcx.types.f16 => (Kind::Half, 2),
2394 x if x == tcx.types.f32 => (Kind::Float, 4),
2395 x if x == tcx.types.f64 => (Kind::Double, 8),
2396 x if x == tcx.types.f128 => (Kind::F128, 16),
2397 _ => (Kind::Integer, 0),
2398 }
2399 } else {
2400 (Kind::Integer, 0)
2401 };
2402
2403 let offset = if is_reference_target && !ty.is_array() { 0 } else { -1 };
2406 return TypeTree(vec![Type { offset, size, kind, child: TypeTree::new() }]);
2407 }
2408
2409 if ty.is_ref() || ty.is_raw_ptr() || ty.is_box() {
2410 let Some(inner_ty) = ty.builtin_deref(true) else {
2411 return TypeTree::new();
2412 };
2413
2414 let child = typetree_from_ty_impl_inner(tcx, inner_ty, depth + 1, visited, true);
2415 return TypeTree(vec![Type {
2416 offset: -1,
2417 size: tcx.data_layout.pointer_size().bytes_usize(),
2418 kind: Kind::Pointer,
2419 child,
2420 }]);
2421 }
2422
2423 if ty.is_array() {
2424 if let ty::Array(element_ty, len_const) = ty.kind() {
2425 let len = len_const.try_to_target_usize(tcx).unwrap_or(0);
2426 if len == 0 {
2427 return TypeTree::new();
2428 }
2429 let element_tree =
2430 typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false);
2431 let mut types = Vec::new();
2432 for elem_type in &element_tree.0 {
2433 types.push(Type {
2434 offset: -1,
2435 size: elem_type.size,
2436 kind: elem_type.kind,
2437 child: elem_type.child.clone(),
2438 });
2439 }
2440
2441 return TypeTree(types);
2442 }
2443 }
2444
2445 if ty.is_slice() {
2446 if let ty::Slice(element_ty) = ty.kind() {
2447 let element_tree =
2448 typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false);
2449 return element_tree;
2450 }
2451 }
2452
2453 if let ty::Tuple(tuple_types) = ty.kind() {
2454 if tuple_types.is_empty() {
2455 return TypeTree::new();
2456 }
2457
2458 let mut types = Vec::new();
2459 let mut current_offset = 0;
2460
2461 for tuple_ty in tuple_types.iter() {
2462 let element_tree =
2463 typetree_from_ty_impl_inner(tcx, tuple_ty, depth + 1, visited, false);
2464
2465 let element_layout = tcx
2466 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tuple_ty))
2467 .ok()
2468 .map(|layout| layout.size.bytes_usize())
2469 .unwrap_or(0);
2470
2471 for elem_type in &element_tree.0 {
2472 types.push(Type {
2473 offset: if elem_type.offset == -1 {
2474 current_offset as isize
2475 } else {
2476 current_offset as isize + elem_type.offset
2477 },
2478 size: elem_type.size,
2479 kind: elem_type.kind,
2480 child: elem_type.child.clone(),
2481 });
2482 }
2483
2484 current_offset += element_layout;
2485 }
2486
2487 return TypeTree(types);
2488 }
2489
2490 if let ty::Adt(adt_def, args) = ty.kind() {
2491 if adt_def.is_struct() {
2492 let struct_layout =
2493 tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty));
2494 if let Ok(layout) = struct_layout {
2495 let mut types = Vec::new();
2496
2497 for (field_idx, field_def) in adt_def.all_fields().enumerate() {
2498 let field_ty = field_def.ty(tcx, args);
2499 let field_tree =
2500 typetree_from_ty_impl_inner(tcx, field_ty, depth + 1, visited, false);
2501
2502 let field_offset = layout.fields.offset(field_idx).bytes_usize();
2503
2504 for elem_type in &field_tree.0 {
2505 types.push(Type {
2506 offset: if elem_type.offset == -1 {
2507 field_offset as isize
2508 } else {
2509 field_offset as isize + elem_type.offset
2510 },
2511 size: elem_type.size,
2512 kind: elem_type.kind,
2513 child: elem_type.child.clone(),
2514 });
2515 }
2516 }
2517
2518 return TypeTree(types);
2519 }
2520 }
2521 }
2522
2523 TypeTree::new()
2524}