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