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