rustc_middle/ty/
mod.rs

1//! Defines how the compiler represents types internally.
2//!
3//! Two important entities in this module are:
4//!
5//! - [`rustc_middle::ty::Ty`], used to represent the semantics of a type.
6//! - [`rustc_middle::ty::TyCtxt`], the central data structure in the compiler.
7//!
8//! For more information, see ["The `ty` module: representing types"] in the rustc-dev-guide.
9//!
10//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
11
12#![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::expand::StrippedCfgItem;
29use rustc_ast::node_id::NodeMap;
30pub use rustc_ast_ir::{Movability, Mutability, try_visit};
31use rustc_attr_data_structures::AttributeKind;
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;
37use rustc_errors::{Diag, ErrorGuaranteed};
38use rustc_hir::LangItem;
39use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
40use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
41use rustc_hir::definitions::DisambiguatorState;
42use rustc_index::IndexVec;
43use rustc_index::bit_set::BitMatrix;
44use rustc_macros::{
45    Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
46    extension,
47};
48use rustc_query_system::ich::StableHashingContext;
49use rustc_serialize::{Decodable, Encodable};
50use rustc_session::lint::LintBuffer;
51pub use rustc_session::lint::RegisteredTools;
52use rustc_span::hygiene::MacroKind;
53use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
54pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
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::*;
63#[allow(hidden_glob_reexports, unused_imports)]
64use rustc_type_ir::{InferCtxtLike, Interner};
65use tracing::{debug, instrument};
66pub use vtable::*;
67use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};
68
69pub use self::closure::{
70    BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,
71    MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarId,
72    UpvarPath, analyze_coroutine_closure_captures, is_ancestor_or_same_capture,
73    place_to_string_for_capture,
74};
75pub use self::consts::{
76    Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, ValTreeKind,
77    Value,
78};
79pub use self::context::{
80    CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
81    TyCtxtFeed, tls,
82};
83pub use self::fold::*;
84pub use self::instance::{Instance, InstanceKind, ReifyReason, ShortInstance, UnusedGenericParams};
85pub use self::list::{List, ListWithCachedTypeInfo};
86pub use self::opaque_types::OpaqueTypeKey;
87pub use self::parameterized::ParameterizedOverTcx;
88pub use self::pattern::{Pattern, PatternKind};
89pub use self::predicate::{
90    AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
91    ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
92    HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
93    PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
94    PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
95    PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
96    RegionOutlivesPredicate, SubtypePredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate,
97};
98pub use self::region::{
99    BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region,
100    RegionKind, RegionVid,
101};
102pub use self::rvalue_scopes::RvalueScopes;
103pub use self::sty::{
104    AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
105    CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst,
106    ParamTy, PolyFnSig, TyKind, TypeAndMut, TypingMode, UpvarArgs,
107};
108pub use self::trait_def::TraitDef;
109pub use self::typeck_results::{
110    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
111    Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
112};
113pub use self::visit::*;
114use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
115use crate::metadata::ModChild;
116use crate::middle::privacy::EffectiveVisibilities;
117use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo};
118use crate::query::{IntoQueryParam, Providers};
119use crate::ty;
120use crate::ty::codec::{TyDecoder, TyEncoder};
121pub use crate::ty::diagnostics::*;
122use crate::ty::fast_reject::SimplifiedType;
123use crate::ty::util::Discr;
124use crate::ty::walk::TypeWalker;
125
126pub mod abstract_const;
127pub mod adjustment;
128pub mod cast;
129pub mod codec;
130pub mod error;
131pub mod fast_reject;
132pub mod inhabitedness;
133pub mod layout;
134pub mod normalize_erasing_regions;
135pub mod pattern;
136pub mod print;
137pub mod relate;
138pub mod significant_drop_order;
139pub mod trait_def;
140pub mod util;
141pub mod vtable;
142
143mod adt;
144mod assoc;
145mod closure;
146mod consts;
147mod context;
148mod diagnostics;
149mod elaborate_impl;
150mod erase_regions;
151mod fold;
152mod generic_args;
153mod generics;
154mod impls_ty;
155mod instance;
156mod intrinsic;
157mod list;
158mod opaque_types;
159mod parameterized;
160mod predicate;
161mod region;
162mod rvalue_scopes;
163mod structural_impls;
164#[allow(hidden_glob_reexports)]
165mod sty;
166mod typeck_results;
167mod visit;
168
169// Data types
170
171pub struct ResolverOutputs {
172    pub global_ctxt: ResolverGlobalCtxt,
173    pub ast_lowering: ResolverAstLowering,
174}
175
176#[derive(Debug)]
177pub struct ResolverGlobalCtxt {
178    pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
179    /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
180    pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
181    pub effective_visibilities: EffectiveVisibilities,
182    pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
183    pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
184    pub module_children: LocalDefIdMap<Vec<ModChild>>,
185    pub glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
186    pub main_def: Option<MainDefinition>,
187    pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
188    /// A list of proc macro LocalDefIds, written out in the order in which
189    /// they are declared in the static array generated by proc_macro_harness.
190    pub proc_macros: Vec<LocalDefId>,
191    /// Mapping from ident span to path span for paths that don't exist as written, but that
192    /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
193    pub confused_type_with_std_module: FxIndexMap<Span, Span>,
194    pub doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
195    pub doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
196    pub all_macro_rules: FxHashSet<Symbol>,
197    pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
198}
199
200/// Resolutions that should only be used for lowering.
201/// This struct is meant to be consumed by lowering.
202#[derive(Debug)]
203pub struct ResolverAstLowering {
204    pub legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
205
206    /// Resolutions for nodes that have a single resolution.
207    pub partial_res_map: NodeMap<hir::def::PartialRes>,
208    /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
209    pub import_res_map: NodeMap<hir::def::PerNS<Option<Res<ast::NodeId>>>>,
210    /// Resolutions for labels (node IDs of their corresponding blocks or loops).
211    pub label_res_map: NodeMap<ast::NodeId>,
212    /// Resolutions for lifetimes.
213    pub lifetimes_res_map: NodeMap<LifetimeRes>,
214    /// Lifetime parameters that lowering will have to introduce.
215    pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
216
217    pub next_node_id: ast::NodeId,
218
219    pub node_id_to_def_id: NodeMap<LocalDefId>,
220
221    pub disambiguator: DisambiguatorState,
222
223    pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
224    /// List functions and methods for which lifetime elision was successful.
225    pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
226
227    /// Lints that were emitted by the resolver and early lints.
228    pub lint_buffer: Steal<LintBuffer>,
229
230    /// Information about functions signatures for delegation items expansion
231    pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
232}
233
234#[derive(Debug)]
235pub struct DelegationFnSig {
236    pub header: ast::FnHeader,
237    pub param_count: usize,
238    pub has_self: bool,
239    pub c_variadic: bool,
240    pub target_feature: bool,
241}
242
243#[derive(Clone, Copy, Debug)]
244pub struct MainDefinition {
245    pub res: Res<ast::NodeId>,
246    pub is_import: bool,
247    pub span: Span,
248}
249
250impl MainDefinition {
251    pub fn opt_fn_def_id(self) -> Option<DefId> {
252        if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None }
253    }
254}
255
256/// The "header" of an impl is everything outside the body: a Self type, a trait
257/// ref (in the case of a trait impl), and a set of predicates (from the
258/// bounds / where-clauses).
259#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
260pub struct ImplHeader<'tcx> {
261    pub impl_def_id: DefId,
262    pub impl_args: ty::GenericArgsRef<'tcx>,
263    pub self_ty: Ty<'tcx>,
264    pub trait_ref: Option<TraitRef<'tcx>>,
265    pub predicates: Vec<Predicate<'tcx>>,
266}
267
268#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
269pub struct ImplTraitHeader<'tcx> {
270    pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
271    pub polarity: ImplPolarity,
272    pub safety: hir::Safety,
273    pub constness: hir::Constness,
274}
275
276#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
277pub enum ImplSubject<'tcx> {
278    Trait(TraitRef<'tcx>),
279    Inherent(Ty<'tcx>),
280}
281
282#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
283#[derive(TypeFoldable, TypeVisitable)]
284pub enum Asyncness {
285    Yes,
286    No,
287}
288
289impl Asyncness {
290    pub fn is_async(self) -> bool {
291        matches!(self, Asyncness::Yes)
292    }
293}
294
295#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
296pub enum Visibility<Id = LocalDefId> {
297    /// Visible everywhere (including in other crates).
298    Public,
299    /// Visible only in the given crate-local module.
300    Restricted(Id),
301}
302
303impl Visibility {
304    pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
305        match self {
306            ty::Visibility::Restricted(restricted_id) => {
307                if restricted_id.is_top_level_module() {
308                    "pub(crate)".to_string()
309                } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
310                    "pub(self)".to_string()
311                } else {
312                    format!(
313                        "pub(in crate{})",
314                        tcx.def_path(restricted_id.to_def_id()).to_string_no_crate_verbose()
315                    )
316                }
317            }
318            ty::Visibility::Public => "pub".to_string(),
319        }
320    }
321}
322
323#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
324#[derive(TypeFoldable, TypeVisitable)]
325pub struct ClosureSizeProfileData<'tcx> {
326    /// Tuple containing the types of closure captures before the feature `capture_disjoint_fields`
327    pub before_feature_tys: Ty<'tcx>,
328    /// Tuple containing the types of closure captures after the feature `capture_disjoint_fields`
329    pub after_feature_tys: Ty<'tcx>,
330}
331
332impl TyCtxt<'_> {
333    #[inline]
334    pub fn opt_parent(self, id: DefId) -> Option<DefId> {
335        self.def_key(id).parent.map(|index| DefId { index, ..id })
336    }
337
338    #[inline]
339    #[track_caller]
340    pub fn parent(self, id: DefId) -> DefId {
341        match self.opt_parent(id) {
342            Some(id) => id,
343            // not `unwrap_or_else` to avoid breaking caller tracking
344            None => bug!("{id:?} doesn't have a parent"),
345        }
346    }
347
348    #[inline]
349    #[track_caller]
350    pub fn opt_local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
351        self.opt_parent(id.to_def_id()).map(DefId::expect_local)
352    }
353
354    #[inline]
355    #[track_caller]
356    pub fn local_parent(self, id: impl Into<LocalDefId>) -> LocalDefId {
357        self.parent(id.into().to_def_id()).expect_local()
358    }
359
360    pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
361        if descendant.krate != ancestor.krate {
362            return false;
363        }
364
365        while descendant != ancestor {
366            match self.opt_parent(descendant) {
367                Some(parent) => descendant = parent,
368                None => return false,
369            }
370        }
371        true
372    }
373}
374
375impl<Id> Visibility<Id> {
376    pub fn is_public(self) -> bool {
377        matches!(self, Visibility::Public)
378    }
379
380    pub fn map_id<OutId>(self, f: impl FnOnce(Id) -> OutId) -> Visibility<OutId> {
381        match self {
382            Visibility::Public => Visibility::Public,
383            Visibility::Restricted(id) => Visibility::Restricted(f(id)),
384        }
385    }
386}
387
388impl<Id: Into<DefId>> Visibility<Id> {
389    pub fn to_def_id(self) -> Visibility<DefId> {
390        self.map_id(Into::into)
391    }
392
393    /// Returns `true` if an item with this visibility is accessible from the given module.
394    pub fn is_accessible_from(self, module: impl Into<DefId>, tcx: TyCtxt<'_>) -> bool {
395        match self {
396            // Public items are visible everywhere.
397            Visibility::Public => true,
398            Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()),
399        }
400    }
401
402    /// Returns `true` if this visibility is at least as accessible as the given visibility
403    pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tcx: TyCtxt<'_>) -> bool {
404        match vis {
405            Visibility::Public => self.is_public(),
406            Visibility::Restricted(id) => self.is_accessible_from(id, tcx),
407        }
408    }
409}
410
411impl Visibility<DefId> {
412    pub fn expect_local(self) -> Visibility {
413        self.map_id(|id| id.expect_local())
414    }
415
416    /// Returns `true` if this item is visible anywhere in the local crate.
417    pub fn is_visible_locally(self) -> bool {
418        match self {
419            Visibility::Public => true,
420            Visibility::Restricted(def_id) => def_id.is_local(),
421        }
422    }
423}
424
425/// The crate variances map is computed during typeck and contains the
426/// variance of every item in the local crate. You should not use it
427/// directly, because to do so will make your pass dependent on the
428/// HIR of every item in the local crate. Instead, use
429/// `tcx.variances_of()` to get the variance for a *particular*
430/// item.
431#[derive(HashStable, Debug)]
432pub struct CrateVariancesMap<'tcx> {
433    /// For each item with generics, maps to a vector of the variance
434    /// of its generics. If an item has no generics, it will have no
435    /// entry.
436    pub variances: DefIdMap<&'tcx [ty::Variance]>,
437}
438
439// Contains information needed to resolve types and (in the future) look up
440// the types of AST nodes.
441#[derive(Copy, Clone, PartialEq, Eq, Hash)]
442pub struct CReaderCacheKey {
443    pub cnum: Option<CrateNum>,
444    pub pos: usize,
445}
446
447/// Use this rather than `TyKind`, whenever possible.
448#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
449#[rustc_diagnostic_item = "Ty"]
450#[rustc_pass_by_value]
451pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
452
453impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> {
454    type Kind = TyKind<'tcx>;
455
456    fn kind(self) -> TyKind<'tcx> {
457        *self.kind()
458    }
459}
460
461impl<'tcx> rustc_type_ir::Flags for Ty<'tcx> {
462    fn flags(&self) -> TypeFlags {
463        self.0.flags
464    }
465
466    fn outer_exclusive_binder(&self) -> DebruijnIndex {
467        self.0.outer_exclusive_binder
468    }
469}
470
471impl EarlyParamRegion {
472    /// Does this early bound region have a name? Early bound regions normally
473    /// always have names except when using anonymous lifetimes (`'_`).
474    pub fn has_name(&self) -> bool {
475        self.name != kw::UnderscoreLifetime
476    }
477}
478
479/// The crate outlives map is computed during typeck and contains the
480/// outlives of every item in the local crate. You should not use it
481/// directly, because to do so will make your pass dependent on the
482/// HIR of every item in the local crate. Instead, use
483/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
484/// item.
485#[derive(HashStable, Debug)]
486pub struct CratePredicatesMap<'tcx> {
487    /// For each struct with outlive bounds, maps to a vector of the
488    /// predicate of its outlive bounds. If an item has no outlives
489    /// bounds, it will have no entry.
490    pub predicates: DefIdMap<&'tcx [(Clause<'tcx>, Span)]>,
491}
492
493#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
494pub struct Term<'tcx> {
495    ptr: NonNull<()>,
496    marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
497}
498
499impl<'tcx> rustc_type_ir::inherent::Term<TyCtxt<'tcx>> for Term<'tcx> {}
500
501impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> {
502    type Kind = TermKind<'tcx>;
503
504    fn kind(self) -> Self::Kind {
505        self.unpack()
506    }
507}
508
509unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
510    &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
511{
512}
513unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
514    &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
515{
516}
517unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
518unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
519
520impl Debug for Term<'_> {
521    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522        match self.unpack() {
523            TermKind::Ty(ty) => write!(f, "Term::Ty({ty:?})"),
524            TermKind::Const(ct) => write!(f, "Term::Const({ct:?})"),
525        }
526    }
527}
528
529impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
530    fn from(ty: Ty<'tcx>) -> Self {
531        TermKind::Ty(ty).pack()
532    }
533}
534
535impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
536    fn from(c: Const<'tcx>) -> Self {
537        TermKind::Const(c).pack()
538    }
539}
540
541impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
542    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
543        self.unpack().hash_stable(hcx, hasher);
544    }
545}
546
547impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
548    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
549        self,
550        folder: &mut F,
551    ) -> Result<Self, F::Error> {
552        match self.unpack() {
553            ty::TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into),
554            ty::TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
555        }
556    }
557
558    fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
559        match self.unpack() {
560            ty::TermKind::Ty(ty) => ty.fold_with(folder).into(),
561            ty::TermKind::Const(ct) => ct.fold_with(folder).into(),
562        }
563    }
564}
565
566impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
567    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
568        match self.unpack() {
569            ty::TermKind::Ty(ty) => ty.visit_with(visitor),
570            ty::TermKind::Const(ct) => ct.visit_with(visitor),
571        }
572    }
573}
574
575impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Term<'tcx> {
576    fn encode(&self, e: &mut E) {
577        self.unpack().encode(e)
578    }
579}
580
581impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Term<'tcx> {
582    fn decode(d: &mut D) -> Self {
583        let res: TermKind<'tcx> = Decodable::decode(d);
584        res.pack()
585    }
586}
587
588impl<'tcx> Term<'tcx> {
589    #[inline]
590    pub fn unpack(self) -> TermKind<'tcx> {
591        let ptr =
592            unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) };
593        // SAFETY: use of `Interned::new_unchecked` here is ok because these
594        // pointers were originally created from `Interned` types in `pack()`,
595        // and this is just going in the other direction.
596        unsafe {
597            match self.ptr.addr().get() & TAG_MASK {
598                TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
599                    ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
600                ))),
601                CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
602                    ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
603                ))),
604                _ => core::intrinsics::unreachable(),
605            }
606        }
607    }
608
609    pub fn as_type(&self) -> Option<Ty<'tcx>> {
610        if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
611    }
612
613    pub fn expect_type(&self) -> Ty<'tcx> {
614        self.as_type().expect("expected a type, but found a const")
615    }
616
617    pub fn as_const(&self) -> Option<Const<'tcx>> {
618        if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
619    }
620
621    pub fn expect_const(&self) -> Const<'tcx> {
622        self.as_const().expect("expected a const, but found a type")
623    }
624
625    pub fn into_arg(self) -> GenericArg<'tcx> {
626        match self.unpack() {
627            TermKind::Ty(ty) => ty.into(),
628            TermKind::Const(c) => c.into(),
629        }
630    }
631
632    pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
633        match self.unpack() {
634            TermKind::Ty(ty) => match *ty.kind() {
635                ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
636                _ => None,
637            },
638            TermKind::Const(ct) => match ct.kind() {
639                ConstKind::Unevaluated(uv) => Some(uv.into()),
640                _ => None,
641            },
642        }
643    }
644
645    pub fn is_infer(&self) -> bool {
646        match self.unpack() {
647            TermKind::Ty(ty) => ty.is_ty_var(),
648            TermKind::Const(ct) => ct.is_ct_infer(),
649        }
650    }
651
652    /// Iterator that walks `self` and any types reachable from
653    /// `self`, in depth-first order. Note that just walks the types
654    /// that appear in `self`, it does not descend into the fields of
655    /// structs or variants. For example:
656    ///
657    /// ```text
658    /// isize => { isize }
659    /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
660    /// [isize] => { [isize], isize }
661    /// ```
662    pub fn walk(self) -> TypeWalker<TyCtxt<'tcx>> {
663        TypeWalker::new(self.into())
664    }
665}
666
667const TAG_MASK: usize = 0b11;
668const TYPE_TAG: usize = 0b00;
669const CONST_TAG: usize = 0b01;
670
671#[extension(pub trait TermKindPackExt<'tcx>)]
672impl<'tcx> TermKind<'tcx> {
673    #[inline]
674    fn pack(self) -> Term<'tcx> {
675        let (tag, ptr) = match self {
676            TermKind::Ty(ty) => {
677                // Ensure we can use the tag bits.
678                assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
679                (TYPE_TAG, NonNull::from(ty.0.0).cast())
680            }
681            TermKind::Const(ct) => {
682                // Ensure we can use the tag bits.
683                assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
684                (CONST_TAG, NonNull::from(ct.0.0).cast())
685            }
686        };
687
688        Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
689    }
690}
691
692#[derive(Copy, Clone, PartialEq, Eq, Debug)]
693pub enum ParamTerm {
694    Ty(ParamTy),
695    Const(ParamConst),
696}
697
698impl ParamTerm {
699    pub fn index(self) -> usize {
700        match self {
701            ParamTerm::Ty(ty) => ty.index as usize,
702            ParamTerm::Const(ct) => ct.index as usize,
703        }
704    }
705}
706
707#[derive(Copy, Clone, Eq, PartialEq, Debug)]
708pub enum TermVid {
709    Ty(ty::TyVid),
710    Const(ty::ConstVid),
711}
712
713impl From<ty::TyVid> for TermVid {
714    fn from(value: ty::TyVid) -> Self {
715        TermVid::Ty(value)
716    }
717}
718
719impl From<ty::ConstVid> for TermVid {
720    fn from(value: ty::ConstVid) -> Self {
721        TermVid::Const(value)
722    }
723}
724
725/// Represents the bounds declared on a particular set of type
726/// parameters. Should eventually be generalized into a flag list of
727/// where-clauses. You can obtain an `InstantiatedPredicates` list from a
728/// `GenericPredicates` by using the `instantiate` method. Note that this method
729/// reflects an important semantic invariant of `InstantiatedPredicates`: while
730/// the `GenericPredicates` are expressed in terms of the bound type
731/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
732/// represented a set of bounds for some particular instantiation,
733/// meaning that the generic parameters have been instantiated with
734/// their values.
735///
736/// Example:
737/// ```ignore (illustrative)
738/// struct Foo<T, U: Bar<T>> { ... }
739/// ```
740/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
741/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
742/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
743/// [usize:Bar<isize>]]`.
744#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
745pub struct InstantiatedPredicates<'tcx> {
746    pub predicates: Vec<Clause<'tcx>>,
747    pub spans: Vec<Span>,
748}
749
750impl<'tcx> InstantiatedPredicates<'tcx> {
751    pub fn empty() -> InstantiatedPredicates<'tcx> {
752        InstantiatedPredicates { predicates: vec![], spans: vec![] }
753    }
754
755    pub fn is_empty(&self) -> bool {
756        self.predicates.is_empty()
757    }
758
759    pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
760        self.into_iter()
761    }
762}
763
764impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
765    type Item = (Clause<'tcx>, Span);
766
767    type IntoIter = std::iter::Zip<std::vec::IntoIter<Clause<'tcx>>, std::vec::IntoIter<Span>>;
768
769    fn into_iter(self) -> Self::IntoIter {
770        debug_assert_eq!(self.predicates.len(), self.spans.len());
771        std::iter::zip(self.predicates, self.spans)
772    }
773}
774
775impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
776    type Item = (Clause<'tcx>, Span);
777
778    type IntoIter = std::iter::Zip<
779        std::iter::Copied<std::slice::Iter<'a, Clause<'tcx>>>,
780        std::iter::Copied<std::slice::Iter<'a, Span>>,
781    >;
782
783    fn into_iter(self) -> Self::IntoIter {
784        debug_assert_eq!(self.predicates.len(), self.spans.len());
785        std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
786    }
787}
788
789#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
790pub struct OpaqueHiddenType<'tcx> {
791    /// The span of this particular definition of the opaque type. So
792    /// for example:
793    ///
794    /// ```ignore (incomplete snippet)
795    /// type Foo = impl Baz;
796    /// fn bar() -> Foo {
797    /// //          ^^^ This is the span we are looking for!
798    /// }
799    /// ```
800    ///
801    /// In cases where the fn returns `(impl Trait, impl Trait)` or
802    /// other such combinations, the result is currently
803    /// over-approximated, but better than nothing.
804    pub span: Span,
805
806    /// The type variable that represents the value of the opaque type
807    /// that we require. In other words, after we compile this function,
808    /// we will be created a constraint like:
809    /// ```ignore (pseudo-rust)
810    /// Foo<'a, T> = ?C
811    /// ```
812    /// where `?C` is the value of this type variable. =) It may
813    /// naturally refer to the type and lifetime parameters in scope
814    /// in this function, though ultimately it should only reference
815    /// those that are arguments to `Foo` in the constraint above. (In
816    /// other words, `?C` should not include `'b`, even though it's a
817    /// lifetime parameter on `foo`.)
818    pub ty: Ty<'tcx>,
819}
820
821/// Whether we're currently in HIR typeck or MIR borrowck.
822#[derive(Debug, Clone, Copy)]
823pub enum DefiningScopeKind {
824    /// During writeback in typeck, we don't care about regions and simply
825    /// erase them. This means we also don't check whether regions are
826    /// universal in the opaque type key. This will only be checked in
827    /// MIR borrowck.
828    HirTypeck,
829    MirBorrowck,
830}
831
832impl<'tcx> OpaqueHiddenType<'tcx> {
833    pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> {
834        OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) }
835    }
836
837    pub fn build_mismatch_error(
838        &self,
839        other: &Self,
840        tcx: TyCtxt<'tcx>,
841    ) -> Result<Diag<'tcx>, ErrorGuaranteed> {
842        (self.ty, other.ty).error_reported()?;
843        // Found different concrete types for the opaque type.
844        let sub_diag = if self.span == other.span {
845            TypeMismatchReason::ConflictType { span: self.span }
846        } else {
847            TypeMismatchReason::PreviousUse { span: self.span }
848        };
849        Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
850            self_ty: self.ty,
851            other_ty: other.ty,
852            other_span: other.span,
853            sub: sub_diag,
854        }))
855    }
856
857    #[instrument(level = "debug", skip(tcx), ret)]
858    pub fn remap_generic_params_to_declaration_params(
859        self,
860        opaque_type_key: OpaqueTypeKey<'tcx>,
861        tcx: TyCtxt<'tcx>,
862        defining_scope_kind: DefiningScopeKind,
863    ) -> Self {
864        let OpaqueTypeKey { def_id, args } = opaque_type_key;
865
866        // Use args to build up a reverse map from regions to their
867        // identity mappings. This is necessary because of `impl
868        // Trait` lifetimes are computed by replacing existing
869        // lifetimes with 'static and remapping only those used in the
870        // `impl Trait` return type, resulting in the parameters
871        // shifting.
872        let id_args = GenericArgs::identity_for_item(tcx, def_id);
873        debug!(?id_args);
874
875        // This zip may have several times the same lifetime in `args` paired with a different
876        // lifetime from `id_args`. Simply `collect`ing the iterator is the correct behaviour:
877        // it will pick the last one, which is the one we introduced in the impl-trait desugaring.
878        let map = args.iter().zip(id_args).collect();
879        debug!("map = {:#?}", map);
880
881        // Convert the type from the function into a type valid outside by mapping generic
882        // parameters to into the context of the opaque.
883        //
884        // We erase regions when doing this during HIR typeck.
885        let this = match defining_scope_kind {
886            DefiningScopeKind::HirTypeck => tcx.erase_regions(self),
887            DefiningScopeKind::MirBorrowck => self,
888        };
889        let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span));
890        if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) {
891            assert_eq!(result.ty, tcx.erase_regions(result.ty));
892        }
893        result
894    }
895}
896
897/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
898/// identified by both a universe, as well as a name residing within that universe. Distinct bound
899/// regions/types/consts within the same universe simply have an unknown relationship to one
900/// another.
901#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
902#[derive(HashStable, TyEncodable, TyDecodable)]
903pub struct Placeholder<T> {
904    pub universe: UniverseIndex,
905    pub bound: T,
906}
907impl Placeholder<BoundVar> {
908    pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
909        let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
910            // `ConstArgHasType` are never desugared to be higher ranked.
911            match clause.kind().skip_binder() {
912                ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
913                    assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
914
915                    match placeholder_ct.kind() {
916                        ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
917                            Some(ty)
918                        }
919                        _ => None,
920                    }
921                }
922                _ => None,
923            }
924        });
925
926        let ty = candidates.next().unwrap();
927        assert!(candidates.next().is_none());
928        ty
929    }
930}
931
932pub type PlaceholderRegion = Placeholder<BoundRegion>;
933
934impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion {
935    fn universe(self) -> UniverseIndex {
936        self.universe
937    }
938
939    fn var(self) -> BoundVar {
940        self.bound.var
941    }
942
943    fn with_updated_universe(self, ui: UniverseIndex) -> Self {
944        Placeholder { universe: ui, ..self }
945    }
946
947    fn new(ui: UniverseIndex, var: BoundVar) -> Self {
948        Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::Anon } }
949    }
950}
951
952pub type PlaceholderType = Placeholder<BoundTy>;
953
954impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderType {
955    fn universe(self) -> UniverseIndex {
956        self.universe
957    }
958
959    fn var(self) -> BoundVar {
960        self.bound.var
961    }
962
963    fn with_updated_universe(self, ui: UniverseIndex) -> Self {
964        Placeholder { universe: ui, ..self }
965    }
966
967    fn new(ui: UniverseIndex, var: BoundVar) -> Self {
968        Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
969    }
970}
971
972#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
973#[derive(TyEncodable, TyDecodable)]
974pub struct BoundConst<'tcx> {
975    pub var: BoundVar,
976    pub ty: Ty<'tcx>,
977}
978
979pub type PlaceholderConst = Placeholder<BoundVar>;
980
981impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst {
982    fn universe(self) -> UniverseIndex {
983        self.universe
984    }
985
986    fn var(self) -> BoundVar {
987        self.bound
988    }
989
990    fn with_updated_universe(self, ui: UniverseIndex) -> Self {
991        Placeholder { universe: ui, ..self }
992    }
993
994    fn new(ui: UniverseIndex, var: BoundVar) -> Self {
995        Placeholder { universe: ui, bound: var }
996    }
997}
998
999pub type Clauses<'tcx> = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
1000
1001impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> {
1002    fn flags(&self) -> TypeFlags {
1003        (**self).flags()
1004    }
1005
1006    fn outer_exclusive_binder(&self) -> DebruijnIndex {
1007        (**self).outer_exclusive_binder()
1008    }
1009}
1010
1011/// When interacting with the type system we must provide information about the
1012/// environment. `ParamEnv` is the type that represents this information. See the
1013/// [dev guide chapter][param_env_guide] for more information.
1014///
1015/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
1016#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1017#[derive(HashStable, TypeVisitable, TypeFoldable)]
1018pub struct ParamEnv<'tcx> {
1019    /// Caller bounds are `Obligation`s that the caller must satisfy. This is
1020    /// basically the set of bounds on the in-scope type parameters, translated
1021    /// into `Obligation`s, and elaborated and normalized.
1022    ///
1023    /// Use the `caller_bounds()` method to access.
1024    caller_bounds: Clauses<'tcx>,
1025}
1026
1027impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
1028    fn caller_bounds(self) -> impl inherent::SliceLike<Item = ty::Clause<'tcx>> {
1029        self.caller_bounds()
1030    }
1031}
1032
1033impl<'tcx> ParamEnv<'tcx> {
1034    /// Construct a trait environment suitable for contexts where there are
1035    /// no where-clauses in scope. In the majority of cases it is incorrect
1036    /// to use an empty environment. See the [dev guide section][param_env_guide]
1037    /// for information on what a `ParamEnv` is and how to acquire one.
1038    ///
1039    /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
1040    #[inline]
1041    pub fn empty() -> Self {
1042        Self::new(ListWithCachedTypeInfo::empty())
1043    }
1044
1045    #[inline]
1046    pub fn caller_bounds(self) -> Clauses<'tcx> {
1047        self.caller_bounds
1048    }
1049
1050    /// Construct a trait environment with the given set of predicates.
1051    #[inline]
1052    pub fn new(caller_bounds: Clauses<'tcx>) -> Self {
1053        ParamEnv { caller_bounds }
1054    }
1055
1056    /// Creates a pair of param-env and value for use in queries.
1057    pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
1058        ParamEnvAnd { param_env: self, value }
1059    }
1060}
1061
1062#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
1063#[derive(HashStable)]
1064pub struct ParamEnvAnd<'tcx, T> {
1065    pub param_env: ParamEnv<'tcx>,
1066    pub value: T,
1067}
1068
1069impl<'tcx, T> ParamEnvAnd<'tcx, T> {
1070    pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
1071        (self.param_env, self.value)
1072    }
1073}
1074
1075/// The environment in which to do trait solving.
1076///
1077/// Most of the time you only need to care about the `ParamEnv`
1078/// as the `TypingMode` is simply stored in the `InferCtxt`.
1079///
1080/// However, there are some places which rely on trait solving
1081/// without using an `InferCtxt` themselves. For these to be
1082/// able to use the trait system they have to be able to initialize
1083/// such an `InferCtxt` with the right `typing_mode`, so they need
1084/// to track both.
1085#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
1086#[derive(TypeVisitable, TypeFoldable)]
1087pub struct TypingEnv<'tcx> {
1088    pub typing_mode: TypingMode<'tcx>,
1089    pub param_env: ParamEnv<'tcx>,
1090}
1091
1092impl<'tcx> TypingEnv<'tcx> {
1093    /// Create a typing environment with no where-clauses in scope
1094    /// where all opaque types and default associated items are revealed.
1095    ///
1096    /// This is only suitable for monomorphized, post-typeck environments.
1097    /// Do not use this for MIR optimizations, as even though they also
1098    /// use `TypingMode::PostAnalysis`, they may still have where-clauses
1099    /// in scope.
1100    pub fn fully_monomorphized() -> TypingEnv<'tcx> {
1101        TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() }
1102    }
1103
1104    /// Create a typing environment for use during analysis outside of a body.
1105    ///
1106    /// Using a typing environment inside of bodies is not supported as the body
1107    /// may define opaque types. In this case the used functions have to be
1108    /// converted to use proper canonical inputs instead.
1109    pub fn non_body_analysis(
1110        tcx: TyCtxt<'tcx>,
1111        def_id: impl IntoQueryParam<DefId>,
1112    ) -> TypingEnv<'tcx> {
1113        TypingEnv { typing_mode: TypingMode::non_body_analysis(), param_env: tcx.param_env(def_id) }
1114    }
1115
1116    pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1117        TypingEnv {
1118            typing_mode: TypingMode::PostAnalysis,
1119            param_env: tcx.param_env_normalized_for_post_analysis(def_id),
1120        }
1121    }
1122
1123    /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all
1124    /// opaque types in the `param_env`.
1125    pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
1126        let TypingEnv { typing_mode, param_env } = self;
1127        if let TypingMode::PostAnalysis = typing_mode {
1128            return self;
1129        }
1130
1131        // No need to reveal opaques with the new solver enabled,
1132        // since we have lazy norm.
1133        let param_env = if tcx.next_trait_solver_globally() {
1134            ParamEnv::new(param_env.caller_bounds())
1135        } else {
1136            ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
1137        };
1138        TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
1139    }
1140
1141    /// Combine this typing environment with the given `value` to be used by
1142    /// not (yet) canonicalized queries. This only works if the value does not
1143    /// contain anything local to some `InferCtxt`, i.e. inference variables or
1144    /// placeholders.
1145    pub fn as_query_input<T>(self, value: T) -> PseudoCanonicalInput<'tcx, T>
1146    where
1147        T: TypeVisitable<TyCtxt<'tcx>>,
1148    {
1149        // FIXME(#132279): We should assert that the value does not contain any placeholders
1150        // as these placeholders are also local to the current inference context. However, we
1151        // currently use pseudo-canonical queries in the trait solver which replaces params with
1152        // placeholders. We should also simply not use pseudo-canonical queries in the trait
1153        // solver, at which point we can readd this assert. As of writing this comment, this is
1154        // only used by `fn layout_is_pointer_like` when calling `layout_of`.
1155        //
1156        // debug_assert!(!value.has_placeholders());
1157        PseudoCanonicalInput { typing_env: self, value }
1158    }
1159}
1160
1161/// Similar to `CanonicalInput`, this carries the `typing_mode` and the environment
1162/// necessary to do any kind of trait solving inside of nested queries.
1163///
1164/// Unlike proper canonicalization, this requires the `param_env` and the `value` to not
1165/// contain anything local to the `infcx` of the caller, so we don't actually canonicalize
1166/// anything.
1167///
1168/// This should be created by using `infcx.pseudo_canonicalize_query(param_env, value)`
1169/// or by using `typing_env.as_query_input(value)`.
1170#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1171#[derive(HashStable, TypeVisitable, TypeFoldable)]
1172pub struct PseudoCanonicalInput<'tcx, T> {
1173    pub typing_env: TypingEnv<'tcx>,
1174    pub value: T,
1175}
1176
1177#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
1178pub struct Destructor {
1179    /// The `DefId` of the destructor method
1180    pub did: DefId,
1181}
1182
1183// FIXME: consider combining this definition with regular `Destructor`
1184#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
1185pub struct AsyncDestructor {
1186    /// The `DefId` of the `impl AsyncDrop`
1187    pub impl_did: LocalDefId,
1188}
1189
1190#[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
1191pub struct VariantFlags(u8);
1192bitflags::bitflags! {
1193    impl VariantFlags: u8 {
1194        const NO_VARIANT_FLAGS        = 0;
1195        /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
1196        const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
1197    }
1198}
1199rustc_data_structures::external_bitflags_debug! { VariantFlags }
1200
1201/// Definition of a variant -- a struct's fields or an enum variant.
1202#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
1203pub struct VariantDef {
1204    /// `DefId` that identifies the variant itself.
1205    /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
1206    pub def_id: DefId,
1207    /// `DefId` that identifies the variant's constructor.
1208    /// If this variant is a struct variant, then this is `None`.
1209    pub ctor: Option<(CtorKind, DefId)>,
1210    /// Variant or struct name.
1211    pub name: Symbol,
1212    /// Discriminant of this variant.
1213    pub discr: VariantDiscr,
1214    /// Fields of this variant.
1215    pub fields: IndexVec<FieldIdx, FieldDef>,
1216    /// The error guarantees from parser, if any.
1217    tainted: Option<ErrorGuaranteed>,
1218    /// Flags of the variant (e.g. is field list non-exhaustive)?
1219    flags: VariantFlags,
1220}
1221
1222impl VariantDef {
1223    /// Creates a new `VariantDef`.
1224    ///
1225    /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
1226    /// represents an enum variant).
1227    ///
1228    /// `ctor_did` is the `DefId` that identifies the constructor of unit or
1229    /// tuple-variants/structs. If this is a `struct`-variant then this should be `None`.
1230    ///
1231    /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that
1232    /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having
1233    /// to go through the redirect of checking the ctor's attributes - but compiling a small crate
1234    /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any
1235    /// built-in trait), and we do not want to load attributes twice.
1236    ///
1237    /// If someone speeds up attribute loading to not be a performance concern, they can
1238    /// remove this hack and use the constructor `DefId` everywhere.
1239    #[instrument(level = "debug")]
1240    pub fn new(
1241        name: Symbol,
1242        variant_did: Option<DefId>,
1243        ctor: Option<(CtorKind, DefId)>,
1244        discr: VariantDiscr,
1245        fields: IndexVec<FieldIdx, FieldDef>,
1246        parent_did: DefId,
1247        recover_tainted: Option<ErrorGuaranteed>,
1248        is_field_list_non_exhaustive: bool,
1249    ) -> Self {
1250        let mut flags = VariantFlags::NO_VARIANT_FLAGS;
1251        if is_field_list_non_exhaustive {
1252            flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
1253        }
1254
1255        VariantDef {
1256            def_id: variant_did.unwrap_or(parent_did),
1257            ctor,
1258            name,
1259            discr,
1260            fields,
1261            flags,
1262            tainted: recover_tainted,
1263        }
1264    }
1265
1266    /// Returns `true` if the field list of this variant is `#[non_exhaustive]`.
1267    ///
1268    /// Note that this function will return `true` even if the type has been
1269    /// defined in the crate currently being compiled. If that's not what you
1270    /// want, see [`Self::field_list_has_applicable_non_exhaustive`].
1271    #[inline]
1272    pub fn is_field_list_non_exhaustive(&self) -> bool {
1273        self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
1274    }
1275
1276    /// Returns `true` if the field list of this variant is `#[non_exhaustive]`
1277    /// and the type has been defined in another crate.
1278    #[inline]
1279    pub fn field_list_has_applicable_non_exhaustive(&self) -> bool {
1280        self.is_field_list_non_exhaustive() && !self.def_id.is_local()
1281    }
1282
1283    /// Computes the `Ident` of this variant by looking up the `Span`
1284    pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
1285        Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
1286    }
1287
1288    /// Was this variant obtained as part of recovering from a syntactic error?
1289    #[inline]
1290    pub fn has_errors(&self) -> Result<(), ErrorGuaranteed> {
1291        self.tainted.map_or(Ok(()), Err)
1292    }
1293
1294    #[inline]
1295    pub fn ctor_kind(&self) -> Option<CtorKind> {
1296        self.ctor.map(|(kind, _)| kind)
1297    }
1298
1299    #[inline]
1300    pub fn ctor_def_id(&self) -> Option<DefId> {
1301        self.ctor.map(|(_, def_id)| def_id)
1302    }
1303
1304    /// Returns the one field in this variant.
1305    ///
1306    /// `panic!`s if there are no fields or multiple fields.
1307    #[inline]
1308    pub fn single_field(&self) -> &FieldDef {
1309        assert!(self.fields.len() == 1);
1310
1311        &self.fields[FieldIdx::ZERO]
1312    }
1313
1314    /// Returns the last field in this variant, if present.
1315    #[inline]
1316    pub fn tail_opt(&self) -> Option<&FieldDef> {
1317        self.fields.raw.last()
1318    }
1319
1320    /// Returns the last field in this variant.
1321    ///
1322    /// # Panics
1323    ///
1324    /// Panics, if the variant has no fields.
1325    #[inline]
1326    pub fn tail(&self) -> &FieldDef {
1327        self.tail_opt().expect("expected unsized ADT to have a tail field")
1328    }
1329
1330    /// Returns whether this variant has unsafe fields.
1331    pub fn has_unsafe_fields(&self) -> bool {
1332        self.fields.iter().any(|x| x.safety.is_unsafe())
1333    }
1334}
1335
1336impl PartialEq for VariantDef {
1337    #[inline]
1338    fn eq(&self, other: &Self) -> bool {
1339        // There should be only one `VariantDef` for each `def_id`, therefore
1340        // it is fine to implement `PartialEq` only based on `def_id`.
1341        //
1342        // Below, we exhaustively destructure `self` and `other` so that if the
1343        // definition of `VariantDef` changes, a compile-error will be produced,
1344        // reminding us to revisit this assumption.
1345
1346        let Self {
1347            def_id: lhs_def_id,
1348            ctor: _,
1349            name: _,
1350            discr: _,
1351            fields: _,
1352            flags: _,
1353            tainted: _,
1354        } = &self;
1355        let Self {
1356            def_id: rhs_def_id,
1357            ctor: _,
1358            name: _,
1359            discr: _,
1360            fields: _,
1361            flags: _,
1362            tainted: _,
1363        } = other;
1364
1365        let res = lhs_def_id == rhs_def_id;
1366
1367        // Double check that implicit assumption detailed above.
1368        if cfg!(debug_assertions) && res {
1369            let deep = self.ctor == other.ctor
1370                && self.name == other.name
1371                && self.discr == other.discr
1372                && self.fields == other.fields
1373                && self.flags == other.flags;
1374            assert!(deep, "VariantDef for the same def-id has differing data");
1375        }
1376
1377        res
1378    }
1379}
1380
1381impl Eq for VariantDef {}
1382
1383impl Hash for VariantDef {
1384    #[inline]
1385    fn hash<H: Hasher>(&self, s: &mut H) {
1386        // There should be only one `VariantDef` for each `def_id`, therefore
1387        // it is fine to implement `Hash` only based on `def_id`.
1388        //
1389        // Below, we exhaustively destructure `self` so that if the definition
1390        // of `VariantDef` changes, a compile-error will be produced, reminding
1391        // us to revisit this assumption.
1392
1393        let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _, tainted: _ } = &self;
1394        def_id.hash(s)
1395    }
1396}
1397
1398#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
1399pub enum VariantDiscr {
1400    /// Explicit value for this variant, i.e., `X = 123`.
1401    /// The `DefId` corresponds to the embedded constant.
1402    Explicit(DefId),
1403
1404    /// The previous variant's discriminant plus one.
1405    /// For efficiency reasons, the distance from the
1406    /// last `Explicit` discriminant is being stored,
1407    /// or `0` for the first variant, if it has none.
1408    Relative(u32),
1409}
1410
1411#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
1412pub struct FieldDef {
1413    pub did: DefId,
1414    pub name: Symbol,
1415    pub vis: Visibility<DefId>,
1416    pub safety: hir::Safety,
1417    pub value: Option<DefId>,
1418}
1419
1420impl PartialEq for FieldDef {
1421    #[inline]
1422    fn eq(&self, other: &Self) -> bool {
1423        // There should be only one `FieldDef` for each `did`, therefore it is
1424        // fine to implement `PartialEq` only based on `did`.
1425        //
1426        // Below, we exhaustively destructure `self` so that if the definition
1427        // of `FieldDef` changes, a compile-error will be produced, reminding
1428        // us to revisit this assumption.
1429
1430        let Self { did: lhs_did, name: _, vis: _, safety: _, value: _ } = &self;
1431
1432        let Self { did: rhs_did, name: _, vis: _, safety: _, value: _ } = other;
1433
1434        let res = lhs_did == rhs_did;
1435
1436        // Double check that implicit assumption detailed above.
1437        if cfg!(debug_assertions) && res {
1438            let deep =
1439                self.name == other.name && self.vis == other.vis && self.safety == other.safety;
1440            assert!(deep, "FieldDef for the same def-id has differing data");
1441        }
1442
1443        res
1444    }
1445}
1446
1447impl Eq for FieldDef {}
1448
1449impl Hash for FieldDef {
1450    #[inline]
1451    fn hash<H: Hasher>(&self, s: &mut H) {
1452        // There should be only one `FieldDef` for each `did`, therefore it is
1453        // fine to implement `Hash` only based on `did`.
1454        //
1455        // Below, we exhaustively destructure `self` so that if the definition
1456        // of `FieldDef` changes, a compile-error will be produced, reminding
1457        // us to revisit this assumption.
1458
1459        let Self { did, name: _, vis: _, safety: _, value: _ } = &self;
1460
1461        did.hash(s)
1462    }
1463}
1464
1465impl<'tcx> FieldDef {
1466    /// Returns the type of this field. The resulting type is not normalized. The `arg` is
1467    /// typically obtained via the second field of [`TyKind::Adt`].
1468    pub fn ty(&self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
1469        tcx.type_of(self.did).instantiate(tcx, args)
1470    }
1471
1472    /// Computes the `Ident` of this variant by looking up the `Span`
1473    pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
1474        Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
1475    }
1476}
1477
1478#[derive(Debug, PartialEq, Eq)]
1479pub enum ImplOverlapKind {
1480    /// These impls are always allowed to overlap.
1481    Permitted {
1482        /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
1483        marker: bool,
1484    },
1485}
1486
1487/// Useful source information about where a desugared associated type for an
1488/// RPITIT originated from.
1489#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
1490pub enum ImplTraitInTraitData {
1491    Trait { fn_def_id: DefId, opaque_def_id: DefId },
1492    Impl { fn_def_id: DefId },
1493}
1494
1495impl<'tcx> TyCtxt<'tcx> {
1496    pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> {
1497        self.typeck(self.hir_body_owner_def_id(body))
1498    }
1499
1500    pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
1501        self.associated_items(id)
1502            .in_definition_order()
1503            .filter(move |item| item.is_fn() && item.defaultness(self).has_value())
1504    }
1505
1506    pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions {
1507        let mut flags = ReprFlags::empty();
1508        let mut size = None;
1509        let mut max_align: Option<Align> = None;
1510        let mut min_pack: Option<Align> = None;
1511
1512        // Generate a deterministically-derived seed from the item's path hash
1513        // to allow for cross-crate compilation to actually work
1514        let mut field_shuffle_seed = self.def_path_hash(did.to_def_id()).0.to_smaller_hash();
1515
1516        // If the user defined a custom seed for layout randomization, xor the item's
1517        // path hash with the user defined seed, this will allowing determinism while
1518        // still allowing users to further randomize layout generation for e.g. fuzzing
1519        if let Some(user_seed) = self.sess.opts.unstable_opts.layout_seed {
1520            field_shuffle_seed ^= user_seed;
1521        }
1522
1523        if let Some(reprs) = attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr(r) => r)
1524        {
1525            for (r, _) in reprs {
1526                flags.insert(match *r {
1527                    attr::ReprRust => ReprFlags::empty(),
1528                    attr::ReprC => ReprFlags::IS_C,
1529                    attr::ReprPacked(pack) => {
1530                        min_pack = Some(if let Some(min_pack) = min_pack {
1531                            min_pack.min(pack)
1532                        } else {
1533                            pack
1534                        });
1535                        ReprFlags::empty()
1536                    }
1537                    attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
1538                    attr::ReprSimd => ReprFlags::IS_SIMD,
1539                    attr::ReprInt(i) => {
1540                        size = Some(match i {
1541                            attr::IntType::SignedInt(x) => match x {
1542                                ast::IntTy::Isize => IntegerType::Pointer(true),
1543                                ast::IntTy::I8 => IntegerType::Fixed(Integer::I8, true),
1544                                ast::IntTy::I16 => IntegerType::Fixed(Integer::I16, true),
1545                                ast::IntTy::I32 => IntegerType::Fixed(Integer::I32, true),
1546                                ast::IntTy::I64 => IntegerType::Fixed(Integer::I64, true),
1547                                ast::IntTy::I128 => IntegerType::Fixed(Integer::I128, true),
1548                            },
1549                            attr::IntType::UnsignedInt(x) => match x {
1550                                ast::UintTy::Usize => IntegerType::Pointer(false),
1551                                ast::UintTy::U8 => IntegerType::Fixed(Integer::I8, false),
1552                                ast::UintTy::U16 => IntegerType::Fixed(Integer::I16, false),
1553                                ast::UintTy::U32 => IntegerType::Fixed(Integer::I32, false),
1554                                ast::UintTy::U64 => IntegerType::Fixed(Integer::I64, false),
1555                                ast::UintTy::U128 => IntegerType::Fixed(Integer::I128, false),
1556                            },
1557                        });
1558                        ReprFlags::empty()
1559                    }
1560                    attr::ReprAlign(align) => {
1561                        max_align = max_align.max(Some(align));
1562                        ReprFlags::empty()
1563                    }
1564                    attr::ReprEmpty => {
1565                        /* skip these, they're just for diagnostics */
1566                        ReprFlags::empty()
1567                    }
1568                });
1569            }
1570        }
1571
1572        // If `-Z randomize-layout` was enabled for the type definition then we can
1573        // consider performing layout randomization
1574        if self.sess.opts.unstable_opts.randomize_layout {
1575            flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
1576        }
1577
1578        // box is special, on the one hand the compiler assumes an ordered layout, with the pointer
1579        // always at offset zero. On the other hand we want scalar abi optimizations.
1580        let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
1581
1582        // This is here instead of layout because the choice must make it into metadata.
1583        if is_box {
1584            flags.insert(ReprFlags::IS_LINEAR);
1585        }
1586
1587        ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed }
1588    }
1589
1590    /// Look up the name of a definition across crates. This does not look at HIR.
1591    pub fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
1592        if let Some(cnum) = def_id.as_crate_root() {
1593            Some(self.crate_name(cnum))
1594        } else {
1595            let def_key = self.def_key(def_id);
1596            match def_key.disambiguated_data.data {
1597                // The name of a constructor is that of its parent.
1598                rustc_hir::definitions::DefPathData::Ctor => self
1599                    .opt_item_name(DefId { krate: def_id.krate, index: def_key.parent.unwrap() }),
1600                _ => def_key.get_opt_name(),
1601            }
1602        }
1603    }
1604
1605    /// Look up the name of a definition across crates. This does not look at HIR.
1606    ///
1607    /// This method will ICE if the corresponding item does not have a name. In these cases, use
1608    /// [`opt_item_name`] instead.
1609    ///
1610    /// [`opt_item_name`]: Self::opt_item_name
1611    pub fn item_name(self, id: DefId) -> Symbol {
1612        self.opt_item_name(id).unwrap_or_else(|| {
1613            bug!("item_name: no name for {:?}", self.def_path(id));
1614        })
1615    }
1616
1617    /// Look up the name and span of a definition.
1618    ///
1619    /// See [`item_name`][Self::item_name] for more information.
1620    pub fn opt_item_ident(self, def_id: DefId) -> Option<Ident> {
1621        let def = self.opt_item_name(def_id)?;
1622        let span = self
1623            .def_ident_span(def_id)
1624            .unwrap_or_else(|| bug!("missing ident span for {def_id:?}"));
1625        Some(Ident::new(def, span))
1626    }
1627
1628    /// Look up the name and span of a definition.
1629    ///
1630    /// See [`item_name`][Self::item_name] for more information.
1631    pub fn item_ident(self, def_id: DefId) -> Ident {
1632        self.opt_item_ident(def_id).unwrap_or_else(|| {
1633            bug!("item_ident: no name for {:?}", self.def_path(def_id));
1634        })
1635    }
1636
1637    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
1638        if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
1639            Some(self.associated_item(def_id))
1640        } else {
1641            None
1642        }
1643    }
1644
1645    /// If the `def_id` is an associated type that was desugared from a
1646    /// return-position `impl Trait` from a trait, then provide the source info
1647    /// about where that RPITIT came from.
1648    pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
1649        if let DefKind::AssocTy = self.def_kind(def_id)
1650            && let AssocKind::Type { data: AssocTypeData::Rpitit(rpitit_info) } =
1651                self.associated_item(def_id).kind
1652        {
1653            Some(rpitit_info)
1654        } else {
1655            None
1656        }
1657    }
1658
1659    pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
1660        variant.fields.iter_enumerated().find_map(|(i, field)| {
1661            self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
1662        })
1663    }
1664
1665    /// Returns `Some` if the impls are the same polarity and the trait either
1666    /// has no items or is annotated `#[marker]` and prevents item overrides.
1667    #[instrument(level = "debug", skip(self), ret)]
1668    pub fn impls_are_allowed_to_overlap(
1669        self,
1670        def_id1: DefId,
1671        def_id2: DefId,
1672    ) -> Option<ImplOverlapKind> {
1673        let impl1 = self.impl_trait_header(def_id1).unwrap();
1674        let impl2 = self.impl_trait_header(def_id2).unwrap();
1675
1676        let trait_ref1 = impl1.trait_ref.skip_binder();
1677        let trait_ref2 = impl2.trait_ref.skip_binder();
1678
1679        // If either trait impl references an error, they're allowed to overlap,
1680        // as one of them essentially doesn't exist.
1681        if trait_ref1.references_error() || trait_ref2.references_error() {
1682            return Some(ImplOverlapKind::Permitted { marker: false });
1683        }
1684
1685        match (impl1.polarity, impl2.polarity) {
1686            (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
1687                // `#[rustc_reservation_impl]` impls don't overlap with anything
1688                return Some(ImplOverlapKind::Permitted { marker: false });
1689            }
1690            (ImplPolarity::Positive, ImplPolarity::Negative)
1691            | (ImplPolarity::Negative, ImplPolarity::Positive) => {
1692                // `impl AutoTrait for Type` + `impl !AutoTrait for Type`
1693                return None;
1694            }
1695            (ImplPolarity::Positive, ImplPolarity::Positive)
1696            | (ImplPolarity::Negative, ImplPolarity::Negative) => {}
1697        };
1698
1699        let is_marker_impl = |trait_ref: TraitRef<'_>| self.trait_def(trait_ref.def_id).is_marker;
1700        let is_marker_overlap = is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2);
1701
1702        if is_marker_overlap {
1703            return Some(ImplOverlapKind::Permitted { marker: true });
1704        }
1705
1706        None
1707    }
1708
1709    /// Returns `ty::VariantDef` if `res` refers to a struct,
1710    /// or variant or their constructors, panics otherwise.
1711    pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
1712        match res {
1713            Res::Def(DefKind::Variant, did) => {
1714                let enum_did = self.parent(did);
1715                self.adt_def(enum_did).variant_with_id(did)
1716            }
1717            Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(),
1718            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
1719                let variant_did = self.parent(variant_ctor_did);
1720                let enum_did = self.parent(variant_did);
1721                self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
1722            }
1723            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
1724                let struct_did = self.parent(ctor_did);
1725                self.adt_def(struct_did).non_enum_variant()
1726            }
1727            _ => bug!("expect_variant_res used with unexpected res {:?}", res),
1728        }
1729    }
1730
1731    /// Returns the possibly-auto-generated MIR of a [`ty::InstanceKind`].
1732    #[instrument(skip(self), level = "debug")]
1733    pub fn instance_mir(self, instance: ty::InstanceKind<'tcx>) -> &'tcx Body<'tcx> {
1734        match instance {
1735            ty::InstanceKind::Item(def) => {
1736                debug!("calling def_kind on def: {:?}", def);
1737                let def_kind = self.def_kind(def);
1738                debug!("returned from def_kind: {:?}", def_kind);
1739                match def_kind {
1740                    DefKind::Const
1741                    | DefKind::Static { .. }
1742                    | DefKind::AssocConst
1743                    | DefKind::Ctor(..)
1744                    | DefKind::AnonConst
1745                    | DefKind::InlineConst => self.mir_for_ctfe(def),
1746                    // If the caller wants `mir_for_ctfe` of a function they should not be using
1747                    // `instance_mir`, so we'll assume const fn also wants the optimized version.
1748                    _ => self.optimized_mir(def),
1749                }
1750            }
1751            ty::InstanceKind::VTableShim(..)
1752            | ty::InstanceKind::ReifyShim(..)
1753            | ty::InstanceKind::Intrinsic(..)
1754            | ty::InstanceKind::FnPtrShim(..)
1755            | ty::InstanceKind::Virtual(..)
1756            | ty::InstanceKind::ClosureOnceShim { .. }
1757            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
1758            | ty::InstanceKind::FutureDropPollShim(..)
1759            | ty::InstanceKind::DropGlue(..)
1760            | ty::InstanceKind::CloneShim(..)
1761            | ty::InstanceKind::ThreadLocalShim(..)
1762            | ty::InstanceKind::FnPtrAddrShim(..)
1763            | ty::InstanceKind::AsyncDropGlueCtorShim(..)
1764            | ty::InstanceKind::AsyncDropGlue(..) => self.mir_shims(instance),
1765        }
1766    }
1767
1768    // FIXME(@lcnr): Remove this function.
1769    pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] {
1770        if let Some(did) = did.as_local() {
1771            self.hir_attrs(self.local_def_id_to_hir_id(did))
1772        } else {
1773            self.attrs_for_def(did)
1774        }
1775    }
1776
1777    /// Gets all attributes with the given name.
1778    pub fn get_attrs(
1779        self,
1780        did: impl Into<DefId>,
1781        attr: Symbol,
1782    ) -> impl Iterator<Item = &'tcx hir::Attribute> {
1783        self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr))
1784    }
1785
1786    /// Gets all attributes.
1787    ///
1788    /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching.
1789    pub fn get_all_attrs(
1790        self,
1791        did: impl Into<DefId>,
1792    ) -> impl Iterator<Item = &'tcx hir::Attribute> {
1793        let did: DefId = did.into();
1794        if let Some(did) = did.as_local() {
1795            self.hir_attrs(self.local_def_id_to_hir_id(did)).iter()
1796        } else {
1797            self.attrs_for_def(did).iter()
1798        }
1799    }
1800
1801    /// Get an attribute from the diagnostic attribute namespace
1802    ///
1803    /// This function requests an attribute with the following structure:
1804    ///
1805    /// `#[diagnostic::$attr]`
1806    ///
1807    /// This function performs feature checking, so if an attribute is returned
1808    /// it can be used by the consumer
1809    pub fn get_diagnostic_attr(
1810        self,
1811        did: impl Into<DefId>,
1812        attr: Symbol,
1813    ) -> Option<&'tcx hir::Attribute> {
1814        let did: DefId = did.into();
1815        if did.as_local().is_some() {
1816            // it's a crate local item, we need to check feature flags
1817            if rustc_feature::is_stable_diagnostic_attribute(attr, self.features()) {
1818                self.get_attrs_by_path(did, &[sym::diagnostic, sym::do_not_recommend]).next()
1819            } else {
1820                None
1821            }
1822        } else {
1823            // we filter out unstable diagnostic attributes before
1824            // encoding attributes
1825            debug_assert!(rustc_feature::encode_cross_crate(attr));
1826            self.attrs_for_def(did)
1827                .iter()
1828                .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr))
1829        }
1830    }
1831
1832    pub fn get_attrs_by_path(
1833        self,
1834        did: DefId,
1835        attr: &[Symbol],
1836    ) -> impl Iterator<Item = &'tcx hir::Attribute> {
1837        let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr);
1838        if let Some(did) = did.as_local() {
1839            self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
1840        } else {
1841            self.attrs_for_def(did).iter().filter(filter_fn)
1842        }
1843    }
1844
1845    pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx hir::Attribute> {
1846        if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
1847            let did: DefId = did.into();
1848            bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
1849        } else {
1850            self.get_attrs(did, attr).next()
1851        }
1852    }
1853
1854    /// Determines whether an item is annotated with an attribute.
1855    pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
1856        self.get_attrs(did, attr).next().is_some()
1857    }
1858
1859    /// Determines whether an item is annotated with a multi-segment attribute
1860    pub fn has_attrs_with_path(self, did: impl Into<DefId>, attrs: &[Symbol]) -> bool {
1861        self.get_attrs_by_path(did.into(), attrs).next().is_some()
1862    }
1863
1864    /// Returns `true` if this is an `auto trait`.
1865    pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
1866        self.trait_def(trait_def_id).has_auto_impl
1867    }
1868
1869    /// Returns `true` if this is coinductive, either because it is
1870    /// an auto trait or because it has the `#[rustc_coinductive]` attribute.
1871    pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
1872        self.trait_def(trait_def_id).is_coinductive
1873    }
1874
1875    /// Returns `true` if this is a trait alias.
1876    pub fn trait_is_alias(self, trait_def_id: DefId) -> bool {
1877        self.def_kind(trait_def_id) == DefKind::TraitAlias
1878    }
1879
1880    /// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the
1881    /// coroutine is tainted by errors.
1882    ///
1883    /// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`,
1884    /// e.g. `args.as_coroutine().kind_ty()`.
1885    fn ordinary_coroutine_layout(
1886        self,
1887        def_id: DefId,
1888        coroutine_kind_ty: Ty<'tcx>,
1889    ) -> Option<&'tcx CoroutineLayout<'tcx>> {
1890        let mir = self.optimized_mir(def_id);
1891        // Regular coroutine
1892        if coroutine_kind_ty.is_unit() {
1893            mir.coroutine_layout_raw()
1894        } else {
1895            // If we have a `Coroutine` that comes from an coroutine-closure,
1896            // then it may be a by-move or by-ref body.
1897            let ty::Coroutine(_, identity_args) =
1898                *self.type_of(def_id).instantiate_identity().kind()
1899            else {
1900                unreachable!();
1901            };
1902            let identity_kind_ty = identity_args.as_coroutine().kind_ty();
1903            // If the types differ, then we must be getting the by-move body of
1904            // a by-ref coroutine.
1905            if identity_kind_ty == coroutine_kind_ty {
1906                mir.coroutine_layout_raw()
1907            } else {
1908                assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
1909                assert_matches!(
1910                    identity_kind_ty.to_opt_closure_kind(),
1911                    Some(ClosureKind::Fn | ClosureKind::FnMut)
1912                );
1913                self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
1914                    .coroutine_layout_raw()
1915            }
1916        }
1917    }
1918
1919    /// Returns layout of a `async_drop_in_place::{closure}` coroutine
1920    ///   (returned from `async fn async_drop_in_place<T>(..)`).
1921    /// Layout might be unavailable if the coroutine is tainted by errors.
1922    fn async_drop_coroutine_layout(
1923        self,
1924        def_id: DefId,
1925        args: GenericArgsRef<'tcx>,
1926    ) -> Option<&'tcx CoroutineLayout<'tcx>> {
1927        let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
1928        self.mir_shims(instance).coroutine_layout_raw()
1929    }
1930
1931    /// Returns layout of a coroutine. Layout might be unavailable if the
1932    /// coroutine is tainted by errors.
1933    pub fn coroutine_layout(
1934        self,
1935        def_id: DefId,
1936        args: GenericArgsRef<'tcx>,
1937    ) -> Option<&'tcx CoroutineLayout<'tcx>> {
1938        if self.is_async_drop_in_place_coroutine(def_id) {
1939            // layout of `async_drop_in_place<T>::{closure}` in case,
1940            // when T is a coroutine, contains this internal coroutine's ptr in upvars
1941            // and doesn't require any locals. Here is an `empty coroutine's layout`
1942            let arg_cor_ty = args.first().unwrap().expect_ty();
1943            if arg_cor_ty.is_coroutine() {
1944                let span = self.def_span(def_id);
1945                let source_info = SourceInfo::outermost(span);
1946                // Even minimal, empty coroutine has 3 states (RESERVED_VARIANTS),
1947                // so variant_fields and variant_source_info should have 3 elements.
1948                let variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
1949                    iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
1950                let variant_source_info: IndexVec<VariantIdx, SourceInfo> =
1951                    iter::repeat(source_info).take(CoroutineArgs::RESERVED_VARIANTS).collect();
1952                let proxy_layout = CoroutineLayout {
1953                    field_tys: [].into(),
1954                    field_names: [].into(),
1955                    variant_fields,
1956                    variant_source_info,
1957                    storage_conflicts: BitMatrix::new(0, 0),
1958                };
1959                return Some(self.arena.alloc(proxy_layout));
1960            } else {
1961                self.async_drop_coroutine_layout(def_id, args)
1962            }
1963        } else {
1964            self.ordinary_coroutine_layout(def_id, args.as_coroutine().kind_ty())
1965        }
1966    }
1967
1968    /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
1969    /// If it implements no trait, returns `None`.
1970    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
1971        self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id)
1972    }
1973
1974    /// If the given `DefId` describes an item belonging to a trait,
1975    /// returns the `DefId` of the trait that the trait item belongs to;
1976    /// otherwise, returns `None`.
1977    pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
1978        if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
1979            let parent = self.parent(def_id);
1980            if let DefKind::Trait | DefKind::TraitAlias = self.def_kind(parent) {
1981                return Some(parent);
1982            }
1983        }
1984        None
1985    }
1986
1987    /// If the given `DefId` describes a method belonging to an impl, returns the
1988    /// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
1989    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
1990        if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
1991            let parent = self.parent(def_id);
1992            if let DefKind::Impl { .. } = self.def_kind(parent) {
1993                return Some(parent);
1994            }
1995        }
1996        None
1997    }
1998
1999    pub fn is_exportable(self, def_id: DefId) -> bool {
2000        self.exportable_items(def_id.krate).contains(&def_id)
2001    }
2002
2003    /// Check if the given `DefId` is `#\[automatically_derived\]`, *and*
2004    /// whether it was produced by expanding a builtin derive macro.
2005    pub fn is_builtin_derived(self, def_id: DefId) -> bool {
2006        if self.is_automatically_derived(def_id)
2007            && let Some(def_id) = def_id.as_local()
2008            && let outer = self.def_span(def_id).ctxt().outer_expn_data()
2009            && matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _))
2010            && self.has_attr(outer.macro_def_id.unwrap(), sym::rustc_builtin_macro)
2011        {
2012            true
2013        } else {
2014            false
2015        }
2016    }
2017
2018    /// Check if the given `DefId` is `#\[automatically_derived\]`.
2019    pub fn is_automatically_derived(self, def_id: DefId) -> bool {
2020        self.has_attr(def_id, sym::automatically_derived)
2021    }
2022
2023    /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2024    /// with the name of the crate containing the impl.
2025    pub fn span_of_impl(self, impl_def_id: DefId) -> Result<Span, Symbol> {
2026        if let Some(impl_def_id) = impl_def_id.as_local() {
2027            Ok(self.def_span(impl_def_id))
2028        } else {
2029            Err(self.crate_name(impl_def_id.krate))
2030        }
2031    }
2032
2033    /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
2034    /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
2035    /// definition's parent/scope to perform comparison.
2036    pub fn hygienic_eq(self, use_ident: Ident, def_ident: Ident, def_parent_def_id: DefId) -> bool {
2037        // We could use `Ident::eq` here, but we deliberately don't. The identifier
2038        // comparison fails frequently, and we want to avoid the expensive
2039        // `normalize_to_macros_2_0()` calls required for the span comparison whenever possible.
2040        use_ident.name == def_ident.name
2041            && use_ident
2042                .span
2043                .ctxt()
2044                .hygienic_eq(def_ident.span.ctxt(), self.expn_that_defined(def_parent_def_id))
2045    }
2046
2047    pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
2048        ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope));
2049        ident
2050    }
2051
2052    // FIXME(vincenzopalazzo): move the HirId to a LocalDefId
2053    pub fn adjust_ident_and_get_scope(
2054        self,
2055        mut ident: Ident,
2056        scope: DefId,
2057        block: hir::HirId,
2058    ) -> (Ident, DefId) {
2059        let scope = ident
2060            .span
2061            .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
2062            .and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
2063            .unwrap_or_else(|| self.parent_module(block).to_def_id());
2064        (ident, scope)
2065    }
2066
2067    /// Checks whether this is a `const fn`. Returns `false` for non-functions.
2068    ///
2069    /// Even if this returns `true`, constness may still be unstable!
2070    #[inline]
2071    pub fn is_const_fn(self, def_id: DefId) -> bool {
2072        matches!(
2073            self.def_kind(def_id),
2074            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure
2075        ) && self.constness(def_id) == hir::Constness::Const
2076    }
2077
2078    /// Whether this item is conditionally constant for the purposes of the
2079    /// effects implementation.
2080    ///
2081    /// This roughly corresponds to all const functions and other callable
2082    /// items, along with const impls and traits, and associated types within
2083    /// those impls and traits.
2084    pub fn is_conditionally_const(self, def_id: impl Into<DefId>) -> bool {
2085        let def_id: DefId = def_id.into();
2086        match self.def_kind(def_id) {
2087            DefKind::Impl { of_trait: true } => {
2088                let header = self.impl_trait_header(def_id).unwrap();
2089                header.constness == hir::Constness::Const
2090                    && self.is_const_trait(header.trait_ref.skip_binder().def_id)
2091            }
2092            DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
2093                self.constness(def_id) == hir::Constness::Const
2094            }
2095            DefKind::Trait => self.is_const_trait(def_id),
2096            DefKind::AssocTy => {
2097                let parent_def_id = self.parent(def_id);
2098                match self.def_kind(parent_def_id) {
2099                    DefKind::Impl { of_trait: false } => false,
2100                    DefKind::Impl { of_trait: true } | DefKind::Trait => {
2101                        self.is_conditionally_const(parent_def_id)
2102                    }
2103                    _ => bug!("unexpected parent item of associated type: {parent_def_id:?}"),
2104                }
2105            }
2106            DefKind::AssocFn => {
2107                let parent_def_id = self.parent(def_id);
2108                match self.def_kind(parent_def_id) {
2109                    DefKind::Impl { of_trait: false } => {
2110                        self.constness(def_id) == hir::Constness::Const
2111                    }
2112                    DefKind::Impl { of_trait: true } | DefKind::Trait => {
2113                        self.is_conditionally_const(parent_def_id)
2114                    }
2115                    _ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
2116                }
2117            }
2118            DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
2119                hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
2120                hir::OpaqueTyOrigin::AsyncFn { .. } => false,
2121                // FIXME(const_trait_impl): ATPITs could be conditionally const?
2122                hir::OpaqueTyOrigin::TyAlias { .. } => false,
2123            },
2124            DefKind::Closure => {
2125                // Closures and RPITs will eventually have const conditions
2126                // for `~const` bounds.
2127                false
2128            }
2129            DefKind::Ctor(_, CtorKind::Const)
2130            | DefKind::Impl { of_trait: false }
2131            | DefKind::Mod
2132            | DefKind::Struct
2133            | DefKind::Union
2134            | DefKind::Enum
2135            | DefKind::Variant
2136            | DefKind::TyAlias
2137            | DefKind::ForeignTy
2138            | DefKind::TraitAlias
2139            | DefKind::TyParam
2140            | DefKind::Const
2141            | DefKind::ConstParam
2142            | DefKind::Static { .. }
2143            | DefKind::AssocConst
2144            | DefKind::Macro(_)
2145            | DefKind::ExternCrate
2146            | DefKind::Use
2147            | DefKind::ForeignMod
2148            | DefKind::AnonConst
2149            | DefKind::InlineConst
2150            | DefKind::Field
2151            | DefKind::LifetimeParam
2152            | DefKind::GlobalAsm
2153            | DefKind::SyntheticCoroutineBody => false,
2154        }
2155    }
2156
2157    #[inline]
2158    pub fn is_const_trait(self, def_id: DefId) -> bool {
2159        self.trait_def(def_id).constness == hir::Constness::Const
2160    }
2161
2162    #[inline]
2163    pub fn is_const_default_method(self, def_id: DefId) -> bool {
2164        matches!(self.trait_of_item(def_id), Some(trait_id) if self.is_const_trait(trait_id))
2165    }
2166
2167    pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
2168        if self.def_kind(def_id) != DefKind::AssocFn {
2169            return false;
2170        }
2171
2172        let Some(item) = self.opt_associated_item(def_id) else {
2173            return false;
2174        };
2175        if item.container != ty::AssocItemContainer::Impl {
2176            return false;
2177        }
2178
2179        let Some(trait_item_def_id) = item.trait_item_def_id else {
2180            return false;
2181        };
2182
2183        return !self
2184            .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
2185            .is_empty();
2186    }
2187}
2188
2189pub fn int_ty(ity: ast::IntTy) -> IntTy {
2190    match ity {
2191        ast::IntTy::Isize => IntTy::Isize,
2192        ast::IntTy::I8 => IntTy::I8,
2193        ast::IntTy::I16 => IntTy::I16,
2194        ast::IntTy::I32 => IntTy::I32,
2195        ast::IntTy::I64 => IntTy::I64,
2196        ast::IntTy::I128 => IntTy::I128,
2197    }
2198}
2199
2200pub fn uint_ty(uty: ast::UintTy) -> UintTy {
2201    match uty {
2202        ast::UintTy::Usize => UintTy::Usize,
2203        ast::UintTy::U8 => UintTy::U8,
2204        ast::UintTy::U16 => UintTy::U16,
2205        ast::UintTy::U32 => UintTy::U32,
2206        ast::UintTy::U64 => UintTy::U64,
2207        ast::UintTy::U128 => UintTy::U128,
2208    }
2209}
2210
2211pub fn float_ty(fty: ast::FloatTy) -> FloatTy {
2212    match fty {
2213        ast::FloatTy::F16 => FloatTy::F16,
2214        ast::FloatTy::F32 => FloatTy::F32,
2215        ast::FloatTy::F64 => FloatTy::F64,
2216        ast::FloatTy::F128 => FloatTy::F128,
2217    }
2218}
2219
2220pub fn ast_int_ty(ity: IntTy) -> ast::IntTy {
2221    match ity {
2222        IntTy::Isize => ast::IntTy::Isize,
2223        IntTy::I8 => ast::IntTy::I8,
2224        IntTy::I16 => ast::IntTy::I16,
2225        IntTy::I32 => ast::IntTy::I32,
2226        IntTy::I64 => ast::IntTy::I64,
2227        IntTy::I128 => ast::IntTy::I128,
2228    }
2229}
2230
2231pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy {
2232    match uty {
2233        UintTy::Usize => ast::UintTy::Usize,
2234        UintTy::U8 => ast::UintTy::U8,
2235        UintTy::U16 => ast::UintTy::U16,
2236        UintTy::U32 => ast::UintTy::U32,
2237        UintTy::U64 => ast::UintTy::U64,
2238        UintTy::U128 => ast::UintTy::U128,
2239    }
2240}
2241
2242pub fn provide(providers: &mut Providers) {
2243    closure::provide(providers);
2244    context::provide(providers);
2245    erase_regions::provide(providers);
2246    inhabitedness::provide(providers);
2247    util::provide(providers);
2248    print::provide(providers);
2249    super::util::bug::provide(providers);
2250    *providers = Providers {
2251        trait_impls_of: trait_def::trait_impls_of_provider,
2252        incoherent_impls: trait_def::incoherent_impls_provider,
2253        trait_impls_in_crate: trait_def::trait_impls_in_crate_provider,
2254        traits: trait_def::traits_provider,
2255        vtable_allocation: vtable::vtable_allocation_provider,
2256        ..*providers
2257    };
2258}
2259
2260/// A map for the local crate mapping each type to a vector of its
2261/// inherent impls. This is not meant to be used outside of coherence;
2262/// rather, you should request the vector for a specific type via
2263/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
2264/// (constructing this map requires touching the entire crate).
2265#[derive(Clone, Debug, Default, HashStable)]
2266pub struct CrateInherentImpls {
2267    pub inherent_impls: FxIndexMap<LocalDefId, Vec<DefId>>,
2268    pub incoherent_impls: FxIndexMap<SimplifiedType, Vec<LocalDefId>>,
2269}
2270
2271#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
2272pub struct SymbolName<'tcx> {
2273    /// `&str` gives a consistent ordering, which ensures reproducible builds.
2274    pub name: &'tcx str,
2275}
2276
2277impl<'tcx> SymbolName<'tcx> {
2278    pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> {
2279        SymbolName { name: tcx.arena.alloc_str(name) }
2280    }
2281}
2282
2283impl<'tcx> fmt::Display for SymbolName<'tcx> {
2284    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2285        fmt::Display::fmt(&self.name, fmt)
2286    }
2287}
2288
2289impl<'tcx> fmt::Debug for SymbolName<'tcx> {
2290    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2291        fmt::Display::fmt(&self.name, fmt)
2292    }
2293}
2294
2295#[derive(Debug, Default, Copy, Clone)]
2296pub struct InferVarInfo {
2297    /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
2298    /// obligation, where:
2299    ///
2300    ///  * `Foo` is not `Sized`
2301    ///  * `(): Foo` may be satisfied
2302    pub self_in_trait: bool,
2303    /// This is true if we identified that this Ty (`?T`) is found in a `<_ as
2304    /// _>::AssocType = ?T`
2305    pub output: bool,
2306}
2307
2308/// The constituent parts of a type level constant of kind ADT or array.
2309#[derive(Copy, Clone, Debug, HashStable)]
2310pub struct DestructuredConst<'tcx> {
2311    pub variant: Option<VariantIdx>,
2312    pub fields: &'tcx [ty::Const<'tcx>],
2313}
2314
2315// Some types are used a lot. Make sure they don't unintentionally get bigger.
2316#[cfg(target_pointer_width = "64")]
2317mod size_asserts {
2318    use rustc_data_structures::static_assert_size;
2319
2320    use super::*;
2321    // tidy-alphabetical-start
2322    static_assert_size!(PredicateKind<'_>, 32);
2323    static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
2324    // tidy-alphabetical-end
2325}
OSZAR »