Skip to main content

hir_ty/next_solver/
ty.rs

1//! Things related to tys in the next-trait-solver.
2
3use std::ops::ControlFlow;
4
5use hir_def::{
6    AdtId, HasModule, TypeParamId,
7    hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance},
8};
9use hir_def::{TraitId, type_ref::Rawness};
10use intern::{Interned, InternedRef, impl_internable};
11use macros::GenericTypeVisitable;
12use rustc_abi::{ExternAbi, Float, Integer, Size};
13use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
14use rustc_type_ir::{
15    BoundVar, BoundVarIndexKind, ClosureKind, DebruijnIndex, FlagComputation, Flags, FloatTy,
16    FloatVid, GenericTypeVisitable, InferTy, IntTy, IntVid, Interner, TyVid, TypeFoldable,
17    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy,
18    Upcast, WithCachedTypeInfo,
19    inherent::{
20        AdtDef as _, BoundExistentialPredicates, GenericArgs as _, IntoKind, ParamLike,
21        Safety as _, SliceLike, Ty as _,
22    },
23    relate::Relate,
24    solve::SizedTraitKind,
25    walk::TypeWalker,
26};
27
28use crate::{
29    db::{HirDatabase, InternedOpaqueTyId},
30    lower::GenericPredicates,
31    next_solver::{
32        AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
33        CoroutineClosureIdWrapper, CoroutineIdWrapper, FnSig, GenericArgKind, PolyFnSig, Predicate,
34        Region, TraitRef, TypeAliasIdWrapper, Unnormalized,
35        abi::Safety,
36        impl_foldable_for_interned_slice, impl_foldable_for_stored_type, impl_stored_interned,
37        interned_slice,
38        util::{CoroutineArgsExt, IntegerTypeExt},
39    },
40};
41
42use super::{
43    DbInterner, GenericArgs, SolverDefId,
44    util::{FloatExt, IntegerExt},
45};
46
47pub type SimplifiedType<'db> = rustc_type_ir::fast_reject::SimplifiedType<SolverDefId<'db>>;
48pub type TyKind<'db> = rustc_type_ir::TyKind<DbInterner<'db>>;
49pub type FnHeader<'db> = rustc_type_ir::FnHeader<DbInterner<'db>>;
50pub type AliasTyKind<'db> = rustc_type_ir::AliasTyKind<DbInterner<'db>>;
51pub type AliasTermKind<'db> = rustc_type_ir::AliasTermKind<DbInterner<'db>>;
52pub type FnSigKind<'db> = rustc_type_ir::FnSigKind<DbInterner<'db>>;
53
54#[derive(Clone, Copy, PartialEq, Eq, Hash)]
55pub struct Ty<'db> {
56    pub(super) interned: InternedRef<'db, TyInterned>,
57}
58
59#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)]
60#[repr(align(4))] // Required for `GenericArg` bit-tagging.
61pub(super) struct TyInterned(WithCachedTypeInfo<TyKind<'static>>);
62
63impl_internable!(gc; TyInterned);
64impl_stored_interned!(TyInterned, Ty, StoredTy);
65impl_foldable_for_stored_type!(StoredTy);
66
67const _: () = {
68    const fn is_copy<T: Copy>() {}
69    is_copy::<Ty<'static>>();
70};
71
72impl<'db> Ty<'db> {
73    #[inline]
74    pub fn new(_interner: DbInterner<'db>, kind: TyKind<'db>) -> Self {
75        let kind = unsafe { std::mem::transmute::<TyKind<'db>, TyKind<'static>>(kind) };
76        let flags = FlagComputation::for_kind(&kind);
77        let cached = WithCachedTypeInfo {
78            internee: kind,
79            flags: flags.flags,
80            outer_exclusive_binder: flags.outer_exclusive_binder,
81        };
82        Self { interned: Interned::new_gc(TyInterned(cached)) }
83    }
84
85    #[inline]
86    pub fn inner(&self) -> &WithCachedTypeInfo<TyKind<'db>> {
87        let inner = &self.interned.0;
88        unsafe {
89            std::mem::transmute::<
90                &WithCachedTypeInfo<TyKind<'static>>,
91                &WithCachedTypeInfo<TyKind<'db>>,
92            >(inner)
93        }
94    }
95
96    pub fn new_adt(interner: DbInterner<'db>, adt_id: AdtId, args: GenericArgs<'db>) -> Self {
97        Ty::new(interner, TyKind::Adt(AdtDef::new(adt_id, interner), args))
98    }
99
100    pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32) -> Self {
101        Ty::new(interner, TyKind::Param(ParamTy { id, index }))
102    }
103
104    pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderType<'db>) -> Self {
105        Ty::new(interner, TyKind::Placeholder(placeholder))
106    }
107
108    pub fn new_infer(interner: DbInterner<'db>, infer: InferTy) -> Self {
109        Ty::new(interner, TyKind::Infer(infer))
110    }
111
112    pub fn new_int_var(interner: DbInterner<'db>, v: IntVid) -> Self {
113        Ty::new_infer(interner, InferTy::IntVar(v))
114    }
115
116    pub fn new_float_var(interner: DbInterner<'db>, v: FloatVid) -> Self {
117        Ty::new_infer(interner, InferTy::FloatVar(v))
118    }
119
120    #[inline]
121    pub fn new_int(interner: DbInterner<'db>, i: IntTy) -> Self {
122        let types = interner.default_types();
123        match i {
124            IntTy::Isize => types.types.isize,
125            IntTy::I8 => types.types.i8,
126            IntTy::I16 => types.types.i16,
127            IntTy::I32 => types.types.i32,
128            IntTy::I64 => types.types.i64,
129            IntTy::I128 => types.types.i128,
130        }
131    }
132
133    pub fn new_uint(interner: DbInterner<'db>, ui: UintTy) -> Self {
134        let types = interner.default_types();
135        match ui {
136            UintTy::Usize => types.types.usize,
137            UintTy::U8 => types.types.u8,
138            UintTy::U16 => types.types.u16,
139            UintTy::U32 => types.types.u32,
140            UintTy::U64 => types.types.u64,
141            UintTy::U128 => types.types.u128,
142        }
143    }
144
145    pub fn new_float(interner: DbInterner<'db>, f: FloatTy) -> Self {
146        let types = interner.default_types();
147        match f {
148            FloatTy::F16 => types.types.f16,
149            FloatTy::F32 => types.types.f32,
150            FloatTy::F64 => types.types.f64,
151            FloatTy::F128 => types.types.f128,
152        }
153    }
154
155    pub fn new_fresh(interner: DbInterner<'db>, n: u32) -> Self {
156        Ty::new_infer(interner, InferTy::FreshTy(n))
157    }
158
159    pub fn new_fresh_int(interner: DbInterner<'db>, n: u32) -> Self {
160        Ty::new_infer(interner, InferTy::FreshIntTy(n))
161    }
162
163    pub fn new_fresh_float(interner: DbInterner<'db>, n: u32) -> Self {
164        Ty::new_infer(interner, InferTy::FreshFloatTy(n))
165    }
166
167    pub fn new_empty_tuple(interner: DbInterner<'db>) -> Self {
168        interner.default_types().types.unit
169    }
170
171    pub fn new_imm_ptr(interner: DbInterner<'db>, ty: Ty<'db>) -> Self {
172        Ty::new_ptr(interner, ty, Mutability::Not)
173    }
174
175    pub fn new_imm_ref(interner: DbInterner<'db>, region: Region<'db>, ty: Ty<'db>) -> Self {
176        Ty::new_ref(interner, region, ty, Mutability::Not)
177    }
178
179    pub fn new_opaque(
180        interner: DbInterner<'db>,
181        def_id: InternedOpaqueTyId<'db>,
182        args: GenericArgs<'db>,
183    ) -> Self {
184        Ty::new_alias(
185            interner,
186            AliasTy::new_from_args(interner, AliasTyKind::Opaque { def_id: def_id.into() }, args),
187        )
188    }
189
190    /// Note: this needs an interner with crate.
191    pub fn new_array(interner: DbInterner<'db>, ty: Ty<'db>, n: u64) -> Ty<'db> {
192        Ty::new(interner, TyKind::Array(ty, Const::from_target_usize(interner, n)))
193    }
194
195    pub fn new_array_opt(interner: DbInterner<'db>, ty: Ty<'db>, n: Option<u128>) -> Ty<'db> {
196        Ty::new(
197            interner,
198            TyKind::Array(
199                ty,
200                crate::consteval::usize_const(interner.db, n, interner.expect_crate()),
201            ),
202        )
203    }
204
205    fn new_generic_adt(interner: DbInterner<'db>, adt_id: AdtId, ty_param: Ty<'db>) -> Ty<'db> {
206        let args = GenericArgs::fill_with_defaults(
207            interner,
208            adt_id.into(),
209            [ty_param.into()],
210            |_, _, _| panic!("all params except the first should have defaults"),
211        );
212        Ty::new_adt(interner, adt_id, args)
213    }
214
215    /// Note: Unlike most other constructors, this require the interner to have a crate, because this needs lang items.
216    pub fn new_box(interner: DbInterner<'db>, ty: Ty<'db>) -> Ty<'db> {
217        let Some(def_id) = interner.lang_items().OwnedBox else {
218            return Ty::new_error(interner, ErrorGuaranteed);
219        };
220        Ty::new_generic_adt(interner, def_id.into(), ty)
221    }
222
223    /// Returns the `Size` for primitive types (bool, uint, int, char, float).
224    pub fn primitive_size(self, interner: DbInterner<'db>) -> Size {
225        match self.kind() {
226            TyKind::Bool => Size::from_bytes(1),
227            TyKind::Char => Size::from_bytes(4),
228            TyKind::Int(ity) => Integer::from_int_ty(&interner, ity).size(),
229            TyKind::Uint(uty) => Integer::from_uint_ty(&interner, uty).size(),
230            TyKind::Float(fty) => Float::from_float_ty(fty).size(),
231            _ => panic!("non primitive type"),
232        }
233    }
234
235    pub fn int_size_and_signed(self, interner: DbInterner<'db>) -> (Size, bool) {
236        match self.kind() {
237            TyKind::Int(ity) => (Integer::from_int_ty(&interner, ity).size(), true),
238            TyKind::Uint(uty) => (Integer::from_uint_ty(&interner, uty).size(), false),
239            _ => panic!("non integer discriminant"),
240        }
241    }
242
243    pub fn walk(self) -> TypeWalker<DbInterner<'db>> {
244        TypeWalker::new(self.into())
245    }
246
247    /// Fast path helper for testing if a type is `Sized` or `MetaSized`.
248    ///
249    /// Returning true means the type is known to implement the sizedness trait. Returning `false`
250    /// means nothing -- could be sized, might not be.
251    ///
252    /// Note that we could never rely on the fact that a type such as `[_]` is trivially `!Sized`
253    /// because we could be in a type environment with a bound such as `[_]: Copy`. A function with
254    /// such a bound obviously never can be called, but that doesn't mean it shouldn't typecheck.
255    /// This is why this method doesn't return `Option<bool>`.
256    #[tracing::instrument(skip(tcx), level = "debug")]
257    pub fn has_trivial_sizedness(self, tcx: DbInterner<'db>, sizedness: SizedTraitKind) -> bool {
258        match self.kind() {
259            TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_))
260            | TyKind::Uint(_)
261            | TyKind::Int(_)
262            | TyKind::Bool
263            | TyKind::Float(_)
264            | TyKind::FnDef(..)
265            | TyKind::FnPtr(..)
266            | TyKind::UnsafeBinder(_)
267            | TyKind::RawPtr(..)
268            | TyKind::Char
269            | TyKind::Ref(..)
270            | TyKind::Coroutine(..)
271            | TyKind::CoroutineWitness(..)
272            | TyKind::Array(..)
273            | TyKind::Pat(..)
274            | TyKind::Closure(..)
275            | TyKind::CoroutineClosure(..)
276            | TyKind::Never
277            | TyKind::Error(_) => true,
278
279            TyKind::Str | TyKind::Slice(_) | TyKind::Dynamic(_, _) => match sizedness {
280                SizedTraitKind::Sized => false,
281                SizedTraitKind::MetaSized => true,
282            },
283
284            TyKind::Foreign(..) => match sizedness {
285                SizedTraitKind::Sized | SizedTraitKind::MetaSized => false,
286            },
287
288            TyKind::Tuple(tys) => {
289                tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness))
290            }
291
292            TyKind::Adt(def, args) => def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| {
293                ty.instantiate(tcx, args).skip_norm_wip().has_trivial_sizedness(tcx, sizedness)
294            }),
295
296            TyKind::Alias(..) | TyKind::Param(_) | TyKind::Placeholder(..) | TyKind::Bound(..) => {
297                false
298            }
299
300            TyKind::Infer(InferTy::TyVar(_)) => false,
301
302            TyKind::Infer(
303                InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_),
304            ) => {
305                panic!("`has_trivial_sizedness` applied to unexpected type: {self:?}")
306            }
307        }
308    }
309
310    /// Fast path helper for primitives which are always `Copy` and which
311    /// have a side-effect-free `Clone` impl.
312    ///
313    /// Returning true means the type is known to be pure and `Copy+Clone`.
314    /// Returning `false` means nothing -- could be `Copy`, might not be.
315    ///
316    /// This is mostly useful for optimizations, as these are the types
317    /// on which we can replace cloning with dereferencing.
318    pub fn is_trivially_pure_clone_copy(self) -> bool {
319        match self.kind() {
320            TyKind::Bool | TyKind::Char | TyKind::Never => true,
321
322            // These aren't even `Clone`
323            TyKind::Str | TyKind::Slice(..) | TyKind::Foreign(..) | TyKind::Dynamic(..) => false,
324
325            TyKind::Infer(InferTy::FloatVar(_) | InferTy::IntVar(_))
326            | TyKind::Int(..)
327            | TyKind::Uint(..)
328            | TyKind::Float(..) => true,
329
330            // ZST which can't be named are fine.
331            TyKind::FnDef(..) => true,
332
333            TyKind::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(),
334
335            // A 100-tuple isn't "trivial", so doing this only for reasonable sizes.
336            TyKind::Tuple(field_tys) => {
337                field_tys.len() <= 3 && field_tys.iter().all(Self::is_trivially_pure_clone_copy)
338            }
339
340            TyKind::Pat(ty, _) => ty.is_trivially_pure_clone_copy(),
341
342            // Sometimes traits aren't implemented for every ABI or arity,
343            // because we can't be generic over everything yet.
344            TyKind::FnPtr(..) => false,
345
346            // Definitely absolutely not copy.
347            TyKind::Ref(_, _, Mutability::Mut) => false,
348
349            // The standard library has a blanket Copy impl for shared references and raw pointers,
350            // for all unsized types.
351            TyKind::Ref(_, _, Mutability::Not) | TyKind::RawPtr(..) => true,
352
353            TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => false,
354
355            // Might be, but not "trivial" so just giving the safe answer.
356            TyKind::Adt(..) | TyKind::Closure(..) | TyKind::CoroutineClosure(..) => false,
357
358            TyKind::UnsafeBinder(_) => false,
359
360            // Needs normalization or revealing to determine, so no is the safe answer.
361            TyKind::Alias(..) => false,
362
363            TyKind::Param(..)
364            | TyKind::Placeholder(..)
365            | TyKind::Bound(..)
366            | TyKind::Infer(..)
367            | TyKind::Error(..) => false,
368        }
369    }
370
371    pub fn is_trivially_wf(self, tcx: DbInterner<'db>) -> bool {
372        match self.kind() {
373            TyKind::Bool
374            | TyKind::Char
375            | TyKind::Int(_)
376            | TyKind::Uint(_)
377            | TyKind::Float(_)
378            | TyKind::Str
379            | TyKind::Never
380            | TyKind::Param(_)
381            | TyKind::Placeholder(_)
382            | TyKind::Bound(..) => true,
383
384            TyKind::Slice(ty) => {
385                ty.is_trivially_wf(tcx) && ty.has_trivial_sizedness(tcx, SizedTraitKind::Sized)
386            }
387            TyKind::RawPtr(ty, _) => ty.is_trivially_wf(tcx),
388
389            TyKind::FnPtr(sig_tys, _) => {
390                sig_tys.skip_binder().inputs_and_output.iter().all(|ty| ty.is_trivially_wf(tcx))
391            }
392            TyKind::Ref(_, ty, _) => ty.is_global() && ty.is_trivially_wf(tcx),
393
394            TyKind::Infer(infer) => match infer {
395                InferTy::TyVar(_) => false,
396                InferTy::IntVar(_) | InferTy::FloatVar(_) => true,
397                InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_) => true,
398            },
399
400            TyKind::Adt(_, _)
401            | TyKind::Tuple(_)
402            | TyKind::Array(..)
403            | TyKind::Foreign(_)
404            | TyKind::Pat(_, _)
405            | TyKind::FnDef(..)
406            | TyKind::UnsafeBinder(..)
407            | TyKind::Dynamic(..)
408            | TyKind::Closure(..)
409            | TyKind::CoroutineClosure(..)
410            | TyKind::Coroutine(..)
411            | TyKind::CoroutineWitness(..)
412            | TyKind::Alias(..)
413            | TyKind::Error(_) => false,
414        }
415    }
416
417    #[inline]
418    pub fn is_never(self) -> bool {
419        matches!(self.kind(), TyKind::Never)
420    }
421
422    #[inline]
423    pub fn is_bool(self) -> bool {
424        matches!(self.kind(), TyKind::Bool)
425    }
426
427    /// Check if type is an `usize`.
428    #[inline]
429    pub fn is_usize(self) -> bool {
430        matches!(self.kind(), TyKind::Uint(UintTy::Usize))
431    }
432
433    #[inline]
434    pub fn is_char(self) -> bool {
435        matches!(self.kind(), TyKind::Char)
436    }
437
438    #[inline]
439    pub fn is_coroutine_closure(self) -> bool {
440        matches!(self.kind(), TyKind::CoroutineClosure(..))
441    }
442
443    /// A scalar type is one that denotes an atomic datum, with no sub-components.
444    /// (A RawPtr is scalar because it represents a non-managed pointer, so its
445    /// contents are abstract to rustc.)
446    #[inline]
447    pub fn is_scalar(self) -> bool {
448        matches!(
449            self.kind(),
450            TyKind::Bool
451                | TyKind::Char
452                | TyKind::Int(_)
453                | TyKind::Float(_)
454                | TyKind::Uint(_)
455                | TyKind::FnDef(..)
456                | TyKind::FnPtr(..)
457                | TyKind::RawPtr(_, _)
458                | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_))
459        )
460    }
461
462    #[inline]
463    pub fn is_infer(self) -> bool {
464        matches!(self.kind(), TyKind::Infer(..))
465    }
466
467    #[inline]
468    pub fn is_numeric(self) -> bool {
469        self.is_integral() || self.is_floating_point()
470    }
471
472    #[inline]
473    pub fn is_str(self) -> bool {
474        matches!(self.kind(), TyKind::Str)
475    }
476
477    #[inline]
478    pub fn is_unit(self) -> bool {
479        matches!(self.kind(), TyKind::Tuple(tys) if tys.is_empty())
480    }
481
482    #[inline]
483    pub fn is_u8(self) -> bool {
484        matches!(self.kind(), TyKind::Uint(UintTy::U8))
485    }
486
487    #[inline]
488    pub fn is_raw_ptr(self) -> bool {
489        matches!(self.kind(), TyKind::RawPtr(..))
490    }
491
492    #[inline]
493    pub fn is_ref(self) -> bool {
494        matches!(self.kind(), TyKind::Ref(..))
495    }
496
497    #[inline]
498    pub fn is_array(self) -> bool {
499        matches!(self.kind(), TyKind::Array(..))
500    }
501
502    #[inline]
503    pub fn is_slice(self) -> bool {
504        matches!(self.kind(), TyKind::Slice(..))
505    }
506
507    pub fn is_union(self) -> bool {
508        self.as_adt().is_some_and(|(adt, _)| matches!(adt, AdtId::UnionId(_)))
509    }
510
511    pub fn boxed_ty(self) -> Option<Ty<'db>> {
512        match self.kind() {
513            TyKind::Adt(adt_def, args) if adt_def.is_box() => Some(args.type_at(0)),
514            _ => None,
515        }
516    }
517
518    pub fn is_box(self) -> bool {
519        matches!(self.kind(), TyKind::Adt(adt_def, _) if adt_def.is_box())
520    }
521
522    #[inline]
523    pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> {
524        match self.kind() {
525            TyKind::Adt(adt_def, args) => Some((adt_def.def_id(), args)),
526            _ => None,
527        }
528    }
529
530    #[inline]
531    pub fn as_slice(self) -> Option<Ty<'db>> {
532        match self.kind() {
533            TyKind::Slice(ty) => Some(ty),
534            _ => None,
535        }
536    }
537
538    #[inline]
539    pub fn ty_vid(self) -> Option<TyVid> {
540        match self.kind() {
541            TyKind::Infer(rustc_type_ir::TyVar(vid)) => Some(vid),
542            _ => None,
543        }
544    }
545
546    /// Given a `fn` type, returns an equivalent `unsafe fn` type;
547    /// that is, a `fn` type that is equivalent in every way for being
548    /// unsafe.
549    pub fn safe_to_unsafe_fn_ty(interner: DbInterner<'db>, sig: PolyFnSig<'db>) -> Ty<'db> {
550        assert!(sig.safety().is_safe());
551        Ty::new_fn_ptr(interner, sig.map_bound(|sig| sig.set_safety(Safety::Unsafe)))
552    }
553
554    /// Returns the type of `*ty`.
555    ///
556    /// The parameter `explicit` indicates if this is an *explicit* dereference.
557    /// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
558    pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'db>> {
559        match self.kind() {
560            TyKind::Adt(adt, substs) if adt.is_box() => Some(substs.as_slice()[0].expect_ty()),
561            TyKind::Ref(_, ty, _) => Some(ty),
562            TyKind::RawPtr(ty, _) if explicit => Some(ty),
563            _ => None,
564        }
565    }
566
567    /// Returns the type of `ty[i]`.
568    pub fn builtin_index(self) -> Option<Ty<'db>> {
569        match self.kind() {
570            TyKind::Array(ty, _) | TyKind::Slice(ty) => Some(ty),
571            _ => None,
572        }
573    }
574
575    /// Whether the type contains some non-lifetime, aka. type or const, error type.
576    pub fn references_non_lt_error(self) -> bool {
577        references_non_lt_error(&self)
578    }
579
580    /// Whether the type contains a type error (ignoring const and lifetime errors).
581    pub fn references_only_ty_error(self) -> bool {
582        references_only_ty_error(&self)
583    }
584
585    pub fn callable_sig(self, interner: DbInterner<'db>) -> Option<Binder<'db, FnSig<'db>>> {
586        match self.kind() {
587            TyKind::FnDef(callable, args) => {
588                Some(interner.fn_sig(callable).instantiate(interner, args).skip_norm_wip())
589            }
590            TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
591            TyKind::Closure(_, closure_args) => {
592                Some(interner.signature_unclosure(closure_args.as_closure().sig(), Safety::Safe))
593            }
594            TyKind::CoroutineClosure(coroutine_id, args) => {
595                Some(args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
596                    let closure_args = args.as_coroutine_closure();
597                    let return_ty = sig.to_coroutine(
598                        interner,
599                        closure_args.parent_args(),
600                        closure_args.kind_ty(),
601                        interner.coroutine_for_closure(coroutine_id),
602                        closure_args.tupled_upvars_ty(),
603                    );
604                    FnSig {
605                        inputs_and_output: Tys::new_from_iter(
606                            interner,
607                            sig.tupled_inputs_ty
608                                .tuple_fields()
609                                .iter()
610                                .chain(std::iter::once(return_ty)),
611                        ),
612                        fn_sig_kind: sig.fn_sig_kind,
613                    }
614                }))
615            }
616            _ => None,
617        }
618    }
619
620    pub fn as_reference(self) -> Option<(Ty<'db>, Region<'db>, Mutability)> {
621        match self.kind() {
622            TyKind::Ref(region, ty, mutability) => Some((ty, region, mutability)),
623            _ => None,
624        }
625    }
626
627    pub fn as_reference_or_ptr(self) -> Option<(Ty<'db>, Rawness, Mutability)> {
628        match self.kind() {
629            TyKind::Ref(_, ty, mutability) => Some((ty, Rawness::Ref, mutability)),
630            TyKind::RawPtr(ty, mutability) => Some((ty, Rawness::RawPtr, mutability)),
631            _ => None,
632        }
633    }
634
635    pub fn is_tuple(self) -> bool {
636        matches!(self.kind(), TyKind::Tuple(_))
637    }
638
639    pub fn as_tuple(self) -> Option<Tys<'db>> {
640        match self.kind() {
641            TyKind::Tuple(tys) => Some(tys),
642            _ => None,
643        }
644    }
645
646    pub fn dyn_trait(self) -> Option<TraitId> {
647        let TyKind::Dynamic(bounds, _) = self.kind() else { return None };
648        Some(bounds.principal_def_id()?.0)
649    }
650
651    pub fn strip_references(self) -> Ty<'db> {
652        let mut t = self;
653        while let TyKind::Ref(_lifetime, ty, _mutability) = t.kind() {
654            t = ty;
655        }
656        t
657    }
658
659    pub fn strip_reference(self) -> Ty<'db> {
660        self.as_reference().map_or(self, |(ty, _, _)| ty)
661    }
662
663    /// Replace infer vars with errors.
664    ///
665    /// This needs to be called for every type that may contain infer vars and is yielded to outside inference,
666    /// as things other than inference do not expect to see infer vars.
667    pub fn replace_infer_with_error(self, interner: DbInterner<'db>) -> Ty<'db> {
668        self.fold_with(&mut crate::next_solver::infer::resolve::ReplaceInferWithError::new(
669            interner,
670        ))
671    }
672
673    pub fn from_builtin_type(
674        interner: DbInterner<'db>,
675        ty: hir_def::builtin_type::BuiltinType,
676    ) -> Ty<'db> {
677        let types = interner.default_types();
678        match ty {
679            hir_def::builtin_type::BuiltinType::Char => types.types.char,
680            hir_def::builtin_type::BuiltinType::Bool => types.types.bool,
681            hir_def::builtin_type::BuiltinType::Str => types.types.str,
682            hir_def::builtin_type::BuiltinType::Int(int) => match int {
683                hir_def::builtin_type::BuiltinInt::Isize => types.types.isize,
684                hir_def::builtin_type::BuiltinInt::I8 => types.types.i8,
685                hir_def::builtin_type::BuiltinInt::I16 => types.types.i16,
686                hir_def::builtin_type::BuiltinInt::I32 => types.types.i32,
687                hir_def::builtin_type::BuiltinInt::I64 => types.types.i64,
688                hir_def::builtin_type::BuiltinInt::I128 => types.types.i128,
689            },
690            hir_def::builtin_type::BuiltinType::Uint(uint) => match uint {
691                hir_def::builtin_type::BuiltinUint::Usize => types.types.usize,
692                hir_def::builtin_type::BuiltinUint::U8 => types.types.u8,
693                hir_def::builtin_type::BuiltinUint::U16 => types.types.u16,
694                hir_def::builtin_type::BuiltinUint::U32 => types.types.u32,
695                hir_def::builtin_type::BuiltinUint::U64 => types.types.u64,
696                hir_def::builtin_type::BuiltinUint::U128 => types.types.u128,
697            },
698            hir_def::builtin_type::BuiltinType::Float(float) => match float {
699                hir_def::builtin_type::BuiltinFloat::F16 => types.types.f16,
700                hir_def::builtin_type::BuiltinFloat::F32 => types.types.f32,
701                hir_def::builtin_type::BuiltinFloat::F64 => types.types.f64,
702                hir_def::builtin_type::BuiltinFloat::F128 => types.types.f128,
703            },
704        }
705    }
706
707    pub fn as_builtin(self) -> Option<hir_def::builtin_type::BuiltinType> {
708        let builtin = match self.kind() {
709            TyKind::Char => hir_def::builtin_type::BuiltinType::Char,
710            TyKind::Bool => hir_def::builtin_type::BuiltinType::Bool,
711            TyKind::Str => hir_def::builtin_type::BuiltinType::Str,
712            TyKind::Int(int) => hir_def::builtin_type::BuiltinType::Int(match int {
713                rustc_type_ir::IntTy::Isize => hir_def::builtin_type::BuiltinInt::Isize,
714                rustc_type_ir::IntTy::I8 => hir_def::builtin_type::BuiltinInt::I8,
715                rustc_type_ir::IntTy::I16 => hir_def::builtin_type::BuiltinInt::I16,
716                rustc_type_ir::IntTy::I32 => hir_def::builtin_type::BuiltinInt::I32,
717                rustc_type_ir::IntTy::I64 => hir_def::builtin_type::BuiltinInt::I64,
718                rustc_type_ir::IntTy::I128 => hir_def::builtin_type::BuiltinInt::I128,
719            }),
720            TyKind::Uint(uint) => hir_def::builtin_type::BuiltinType::Uint(match uint {
721                rustc_type_ir::UintTy::Usize => hir_def::builtin_type::BuiltinUint::Usize,
722                rustc_type_ir::UintTy::U8 => hir_def::builtin_type::BuiltinUint::U8,
723                rustc_type_ir::UintTy::U16 => hir_def::builtin_type::BuiltinUint::U16,
724                rustc_type_ir::UintTy::U32 => hir_def::builtin_type::BuiltinUint::U32,
725                rustc_type_ir::UintTy::U64 => hir_def::builtin_type::BuiltinUint::U64,
726                rustc_type_ir::UintTy::U128 => hir_def::builtin_type::BuiltinUint::U128,
727            }),
728            TyKind::Float(float) => hir_def::builtin_type::BuiltinType::Float(match float {
729                rustc_type_ir::FloatTy::F16 => hir_def::builtin_type::BuiltinFloat::F16,
730                rustc_type_ir::FloatTy::F32 => hir_def::builtin_type::BuiltinFloat::F32,
731                rustc_type_ir::FloatTy::F64 => hir_def::builtin_type::BuiltinFloat::F64,
732                rustc_type_ir::FloatTy::F128 => hir_def::builtin_type::BuiltinFloat::F128,
733            }),
734            _ => return None,
735        };
736        Some(builtin)
737    }
738
739    // FIXME: Should this be here?
740    pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'db>>> {
741        let interner = DbInterner::new_no_crate(db);
742
743        match self.kind() {
744            TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => Some(
745                def_id
746                    .0
747                    .predicates(db)
748                    .iter_instantiated_copied(interner, args.as_slice())
749                    .map(Unnormalized::skip_norm_wip)
750                    .collect(),
751            ),
752            TyKind::Param(param) => {
753                // FIXME: We shouldn't use `param.id` here.
754                let generic_params = GenericParams::of(db, param.id.parent());
755                let param_data = &generic_params[param.id.local_id()];
756                match param_data {
757                    TypeOrConstParamData::TypeParamData(p) => match p.provenance {
758                        TypeParamProvenance::ArgumentImplTrait => {
759                            let predicates = GenericPredicates::query_all(db, param.id.parent())
760                                .iter_identity()
761                                .map(Unnormalized::skip_norm_wip)
762                                .filter(|wc| match wc.kind().skip_binder() {
763                                    ClauseKind::Trait(tr) => tr.self_ty() == self,
764                                    ClauseKind::Projection(pred) => pred.self_ty() == self,
765                                    ClauseKind::TypeOutlives(pred) => pred.0 == self,
766                                    _ => false,
767                                })
768                                .collect::<Vec<_>>();
769
770                            Some(predicates)
771                        }
772                        _ => None,
773                    },
774                    _ => None,
775                }
776            }
777            TyKind::Coroutine(coroutine_id, _args) => {
778                let owner = coroutine_id.0.loc(db).owner;
779                let krate = owner.krate(db);
780                if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
781                    // This is only used by type walking.
782                    // Parameters will be walked outside, and projection predicate is not used.
783                    // So just provide the Future trait.
784                    let impl_bound = TraitRef::new_from_args(
785                        interner,
786                        future_trait.into(),
787                        GenericArgs::empty(interner),
788                    )
789                    .upcast(interner);
790                    Some(vec![impl_bound])
791                } else {
792                    None
793                }
794            }
795            _ => None,
796        }
797    }
798
799    /// FIXME: Get rid of this, it's not a good abstraction
800    pub fn equals_ctor(self, other: Ty<'db>) -> bool {
801        match (self.kind(), other.kind()) {
802            (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt.def_id() == adt2.def_id(),
803            (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
804                true
805            }
806            (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
807            (TyKind::Alias(alias), TyKind::Alias(alias2)) => alias.kind == alias2.kind,
808            (TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
809            (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
810            (TyKind::Ref(.., mutability), TyKind::Ref(.., mutability2))
811            | (TyKind::RawPtr(.., mutability), TyKind::RawPtr(.., mutability2)) => {
812                mutability == mutability2
813            }
814            (TyKind::FnPtr(sig, hdr), TyKind::FnPtr(sig2, hdr2)) => sig == sig2 && hdr == hdr2,
815            (TyKind::Tuple(tys), TyKind::Tuple(tys2)) => tys.len() == tys2.len(),
816            (TyKind::Str, TyKind::Str)
817            | (TyKind::Never, TyKind::Never)
818            | (TyKind::Char, TyKind::Char)
819            | (TyKind::Bool, TyKind::Bool) => true,
820            (TyKind::Int(int), TyKind::Int(int2)) => int == int2,
821            (TyKind::Float(float), TyKind::Float(float2)) => float == float2,
822            _ => false,
823        }
824    }
825}
826
827pub fn references_non_lt_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
828    t.has_non_region_error()
829}
830
831pub fn references_only_ty_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
832    references_non_lt_error(t) && t.visit_with(&mut ReferencesOnlyTyError).is_break()
833}
834
835struct ReferencesOnlyTyError;
836
837impl<'db> TypeVisitor<DbInterner<'db>> for ReferencesOnlyTyError {
838    type Result = ControlFlow<()>;
839
840    fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
841        if !ty.references_non_lt_error() {
842            ControlFlow::Continue(())
843        } else if ty.is_ty_error() {
844            ControlFlow::Break(())
845        } else {
846            ty.super_visit_with(self)
847        }
848    }
849
850    fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
851        if !references_non_lt_error(&c) {
852            ControlFlow::Continue(())
853        } else {
854            c.super_visit_with(self)
855        }
856    }
857
858    fn visit_predicate(&mut self, p: Predicate<'db>) -> Self::Result {
859        if !references_non_lt_error(&p) {
860            ControlFlow::Continue(())
861        } else {
862            p.super_visit_with(self)
863        }
864    }
865}
866
867impl<'db> std::fmt::Debug for Ty<'db> {
868    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
869        self.inner().internee.fmt(f)
870    }
871}
872
873impl<'db> IntoKind for Ty<'db> {
874    type Kind = TyKind<'db>;
875
876    #[inline]
877    fn kind(self) -> Self::Kind {
878        self.inner().internee
879    }
880}
881
882impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Ty<'db> {
883    fn generic_visit_with(&self, visitor: &mut V) {
884        if visitor.on_interned(self.interned).is_continue() {
885            self.kind().generic_visit_with(visitor);
886        }
887    }
888}
889
890impl<'db> TypeVisitable<DbInterner<'db>> for Ty<'db> {
891    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
892        &self,
893        visitor: &mut V,
894    ) -> V::Result {
895        visitor.visit_ty(*self)
896    }
897}
898
899impl<'db> TypeSuperVisitable<DbInterner<'db>> for Ty<'db> {
900    fn super_visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
901        &self,
902        visitor: &mut V,
903    ) -> V::Result {
904        match (*self).kind() {
905            TyKind::RawPtr(ty, _mutbl) => ty.visit_with(visitor),
906            TyKind::Array(typ, sz) => {
907                try_visit!(typ.visit_with(visitor));
908                sz.visit_with(visitor)
909            }
910            TyKind::Slice(typ) => typ.visit_with(visitor),
911            TyKind::Adt(_, args) => args.visit_with(visitor),
912            TyKind::Dynamic(ref trait_ty, ref reg) => {
913                try_visit!(trait_ty.visit_with(visitor));
914                reg.visit_with(visitor)
915            }
916            TyKind::Tuple(ts) => ts.visit_with(visitor),
917            TyKind::FnDef(_, args) => args.visit_with(visitor),
918            TyKind::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
919            TyKind::UnsafeBinder(f) => f.visit_with(visitor),
920            TyKind::Ref(r, ty, _) => {
921                try_visit!(r.visit_with(visitor));
922                ty.visit_with(visitor)
923            }
924            TyKind::Coroutine(_did, ref args) => args.visit_with(visitor),
925            TyKind::CoroutineWitness(_did, ref args) => args.visit_with(visitor),
926            TyKind::Closure(_did, ref args) => args.visit_with(visitor),
927            TyKind::CoroutineClosure(_did, ref args) => args.visit_with(visitor),
928            TyKind::Alias(ref data) => data.visit_with(visitor),
929
930            TyKind::Pat(ty, pat) => {
931                try_visit!(ty.visit_with(visitor));
932                pat.visit_with(visitor)
933            }
934
935            TyKind::Error(guar) => guar.visit_with(visitor),
936
937            TyKind::Bool
938            | TyKind::Char
939            | TyKind::Str
940            | TyKind::Int(_)
941            | TyKind::Uint(_)
942            | TyKind::Float(_)
943            | TyKind::Infer(_)
944            | TyKind::Bound(..)
945            | TyKind::Placeholder(..)
946            | TyKind::Param(..)
947            | TyKind::Never
948            | TyKind::Foreign(..) => V::Result::output(),
949        }
950    }
951}
952
953impl<'db> TypeFoldable<DbInterner<'db>> for Ty<'db> {
954    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
955        self,
956        folder: &mut F,
957    ) -> Result<Self, F::Error> {
958        folder.try_fold_ty(self)
959    }
960    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
961        folder.fold_ty(self)
962    }
963}
964
965impl<'db> TypeSuperFoldable<DbInterner<'db>> for Ty<'db> {
966    fn try_super_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
967        self,
968        folder: &mut F,
969    ) -> Result<Self, F::Error> {
970        let kind = match self.kind() {
971            TyKind::RawPtr(ty, mutbl) => TyKind::RawPtr(ty.try_fold_with(folder)?, mutbl),
972            TyKind::Array(typ, sz) => {
973                TyKind::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?)
974            }
975            TyKind::Slice(typ) => TyKind::Slice(typ.try_fold_with(folder)?),
976            TyKind::Adt(tid, args) => TyKind::Adt(tid, args.try_fold_with(folder)?),
977            TyKind::Dynamic(trait_ty, region) => {
978                TyKind::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
979            }
980            TyKind::Tuple(ts) => TyKind::Tuple(ts.try_fold_with(folder)?),
981            TyKind::FnDef(def_id, args) => TyKind::FnDef(def_id, args.try_fold_with(folder)?),
982            TyKind::FnPtr(sig_tys, hdr) => TyKind::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
983            TyKind::UnsafeBinder(f) => TyKind::UnsafeBinder(f.try_fold_with(folder)?),
984            TyKind::Ref(r, ty, mutbl) => {
985                TyKind::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
986            }
987            TyKind::Coroutine(did, args) => TyKind::Coroutine(did, args.try_fold_with(folder)?),
988            TyKind::CoroutineWitness(did, args) => {
989                TyKind::CoroutineWitness(did, args.try_fold_with(folder)?)
990            }
991            TyKind::Closure(did, args) => TyKind::Closure(did, args.try_fold_with(folder)?),
992            TyKind::CoroutineClosure(did, args) => {
993                TyKind::CoroutineClosure(did, args.try_fold_with(folder)?)
994            }
995            TyKind::Alias(data) => TyKind::Alias(data.try_fold_with(folder)?),
996            TyKind::Pat(ty, pat) => {
997                TyKind::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?)
998            }
999
1000            TyKind::Bool
1001            | TyKind::Char
1002            | TyKind::Str
1003            | TyKind::Int(_)
1004            | TyKind::Uint(_)
1005            | TyKind::Float(_)
1006            | TyKind::Error(_)
1007            | TyKind::Infer(_)
1008            | TyKind::Param(..)
1009            | TyKind::Bound(..)
1010            | TyKind::Placeholder(..)
1011            | TyKind::Never
1012            | TyKind::Foreign(..) => return Ok(self),
1013        };
1014
1015        Ok(if self.kind() == kind { self } else { Ty::new(folder.cx(), kind) })
1016    }
1017    fn super_fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
1018        self,
1019        folder: &mut F,
1020    ) -> Self {
1021        let kind = match self.kind() {
1022            TyKind::RawPtr(ty, mutbl) => TyKind::RawPtr(ty.fold_with(folder), mutbl),
1023            TyKind::Array(typ, sz) => TyKind::Array(typ.fold_with(folder), sz.fold_with(folder)),
1024            TyKind::Slice(typ) => TyKind::Slice(typ.fold_with(folder)),
1025            TyKind::Adt(tid, args) => TyKind::Adt(tid, args.fold_with(folder)),
1026            TyKind::Dynamic(trait_ty, region) => {
1027                TyKind::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
1028            }
1029            TyKind::Tuple(ts) => TyKind::Tuple(ts.fold_with(folder)),
1030            TyKind::FnDef(def_id, args) => TyKind::FnDef(def_id, args.fold_with(folder)),
1031            TyKind::FnPtr(sig_tys, hdr) => TyKind::FnPtr(sig_tys.fold_with(folder), hdr),
1032            TyKind::UnsafeBinder(f) => TyKind::UnsafeBinder(f.fold_with(folder)),
1033            TyKind::Ref(r, ty, mutbl) => {
1034                TyKind::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl)
1035            }
1036            TyKind::Coroutine(did, args) => TyKind::Coroutine(did, args.fold_with(folder)),
1037            TyKind::CoroutineWitness(did, args) => {
1038                TyKind::CoroutineWitness(did, args.fold_with(folder))
1039            }
1040            TyKind::Closure(did, args) => TyKind::Closure(did, args.fold_with(folder)),
1041            TyKind::CoroutineClosure(did, args) => {
1042                TyKind::CoroutineClosure(did, args.fold_with(folder))
1043            }
1044            TyKind::Alias(data) => TyKind::Alias(data.fold_with(folder)),
1045            TyKind::Pat(ty, pat) => TyKind::Pat(ty.fold_with(folder), pat.fold_with(folder)),
1046
1047            TyKind::Bool
1048            | TyKind::Char
1049            | TyKind::Str
1050            | TyKind::Int(_)
1051            | TyKind::Uint(_)
1052            | TyKind::Float(_)
1053            | TyKind::Error(_)
1054            | TyKind::Infer(_)
1055            | TyKind::Param(..)
1056            | TyKind::Bound(..)
1057            | TyKind::Placeholder(..)
1058            | TyKind::Never
1059            | TyKind::Foreign(..) => return self,
1060        };
1061
1062        if self.kind() == kind { self } else { Ty::new(folder.cx(), kind) }
1063    }
1064}
1065
1066impl<'db> Relate<DbInterner<'db>> for Ty<'db> {
1067    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
1068        relation: &mut R,
1069        a: Self,
1070        b: Self,
1071    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
1072        relation.tys(a, b)
1073    }
1074}
1075
1076impl<'db> Flags for Ty<'db> {
1077    fn flags(&self) -> rustc_type_ir::TypeFlags {
1078        self.inner().flags
1079    }
1080
1081    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
1082        self.inner().outer_exclusive_binder
1083    }
1084}
1085
1086impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
1087    fn new_unit(interner: DbInterner<'db>) -> Self {
1088        interner.default_types().types.unit
1089    }
1090
1091    fn new_bool(interner: DbInterner<'db>) -> Self {
1092        interner.default_types().types.bool
1093    }
1094
1095    fn new_u8(interner: DbInterner<'db>) -> Self {
1096        interner.default_types().types.u8
1097    }
1098
1099    fn new_usize(interner: DbInterner<'db>) -> Self {
1100        interner.default_types().types.usize
1101    }
1102
1103    fn new_infer(interner: DbInterner<'db>, var: rustc_type_ir::InferTy) -> Self {
1104        Ty::new(interner, TyKind::Infer(var))
1105    }
1106
1107    fn new_var(interner: DbInterner<'db>, var: rustc_type_ir::TyVid) -> Self {
1108        Ty::new(interner, TyKind::Infer(rustc_type_ir::InferTy::TyVar(var)))
1109    }
1110
1111    fn new_param(interner: DbInterner<'db>, param: ParamTy) -> Self {
1112        Ty::new(interner, TyKind::Param(param))
1113    }
1114
1115    fn new_placeholder(interner: DbInterner<'db>, param: PlaceholderType<'db>) -> Self {
1116        Ty::new(interner, TyKind::Placeholder(param))
1117    }
1118
1119    fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundTy<'db>) -> Self {
1120        Ty::new(interner, TyKind::Bound(BoundVarIndexKind::Bound(debruijn), var))
1121    }
1122
1123    fn new_anon_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundVar) -> Self {
1124        Ty::new(
1125            interner,
1126            TyKind::Bound(
1127                BoundVarIndexKind::Bound(debruijn),
1128                BoundTy { var, kind: BoundTyKind::Anon },
1129            ),
1130        )
1131    }
1132
1133    fn new_canonical_bound(interner: DbInterner<'db>, var: BoundVar) -> Self {
1134        Ty::new(
1135            interner,
1136            TyKind::Bound(BoundVarIndexKind::Canonical, BoundTy { var, kind: BoundTyKind::Anon }),
1137        )
1138    }
1139
1140    fn new_alias(interner: DbInterner<'db>, alias_ty: AliasTy<'db>) -> Self {
1141        Ty::new(interner, TyKind::Alias(alias_ty))
1142    }
1143
1144    fn new_error(interner: DbInterner<'db>, guar: ErrorGuaranteed) -> Self {
1145        Ty::new(interner, TyKind::Error(guar))
1146    }
1147
1148    fn new_adt(
1149        interner: DbInterner<'db>,
1150        adt_def: <DbInterner<'db> as Interner>::AdtDef,
1151        args: GenericArgs<'db>,
1152    ) -> Self {
1153        Ty::new(interner, TyKind::Adt(adt_def, args))
1154    }
1155
1156    fn new_foreign(interner: DbInterner<'db>, def_id: TypeAliasIdWrapper) -> Self {
1157        Ty::new(interner, TyKind::Foreign(def_id))
1158    }
1159
1160    fn new_dynamic(
1161        interner: DbInterner<'db>,
1162        preds: <DbInterner<'db> as Interner>::BoundExistentialPredicates,
1163        region: <DbInterner<'db> as Interner>::Region,
1164    ) -> Self {
1165        Ty::new(interner, TyKind::Dynamic(preds, region))
1166    }
1167
1168    fn new_coroutine(
1169        interner: DbInterner<'db>,
1170        def_id: CoroutineIdWrapper<'db>,
1171        args: <DbInterner<'db> as Interner>::GenericArgs,
1172    ) -> Self {
1173        Ty::new(interner, TyKind::Coroutine(def_id, args))
1174    }
1175
1176    fn new_coroutine_closure(
1177        interner: DbInterner<'db>,
1178        def_id: CoroutineClosureIdWrapper<'db>,
1179        args: <DbInterner<'db> as Interner>::GenericArgs,
1180    ) -> Self {
1181        Ty::new(interner, TyKind::CoroutineClosure(def_id, args))
1182    }
1183
1184    fn new_closure(
1185        interner: DbInterner<'db>,
1186        def_id: ClosureIdWrapper<'db>,
1187        args: <DbInterner<'db> as Interner>::GenericArgs,
1188    ) -> Self {
1189        Ty::new(interner, TyKind::Closure(def_id, args))
1190    }
1191
1192    fn new_coroutine_witness(
1193        interner: DbInterner<'db>,
1194        def_id: CoroutineIdWrapper<'db>,
1195        args: <DbInterner<'db> as Interner>::GenericArgs,
1196    ) -> Self {
1197        Ty::new(interner, TyKind::CoroutineWitness(def_id, args))
1198    }
1199
1200    fn new_coroutine_witness_for_coroutine(
1201        interner: DbInterner<'db>,
1202        def_id: CoroutineIdWrapper<'db>,
1203        coroutine_args: <DbInterner<'db> as Interner>::GenericArgs,
1204    ) -> Self {
1205        // HACK: Coroutine witness types are lifetime erased, so they
1206        // never reference any lifetime args from the coroutine. We erase
1207        // the regions here since we may get into situations where a
1208        // coroutine is recursively contained within itself, leading to
1209        // witness types that differ by region args. This means that
1210        // cycle detection in fulfillment will not kick in, which leads
1211        // to unnecessary overflows in async code. See the issue:
1212        // <https://github.com/rust-lang/rust/issues/145151>.
1213        let coroutine_args = interner.mk_args_from_iter(coroutine_args.iter().map(|arg| {
1214            match arg.kind() {
1215                GenericArgKind::Type(_) | GenericArgKind::Const(_) => arg,
1216                GenericArgKind::Lifetime(_) => {
1217                    crate::next_solver::Region::new(interner, rustc_type_ir::RegionKind::ReErased)
1218                        .into()
1219                }
1220            }
1221        }));
1222        Ty::new_coroutine_witness(interner, def_id, coroutine_args)
1223    }
1224
1225    fn new_ptr(interner: DbInterner<'db>, ty: Self, mutbl: rustc_ast_ir::Mutability) -> Self {
1226        Ty::new(interner, TyKind::RawPtr(ty, mutbl))
1227    }
1228
1229    fn new_ref(
1230        interner: DbInterner<'db>,
1231        region: <DbInterner<'db> as Interner>::Region,
1232        ty: Self,
1233        mutbl: rustc_ast_ir::Mutability,
1234    ) -> Self {
1235        Ty::new(interner, TyKind::Ref(region, ty, mutbl))
1236    }
1237
1238    fn new_array_with_const_len(
1239        interner: DbInterner<'db>,
1240        ty: Self,
1241        len: <DbInterner<'db> as Interner>::Const,
1242    ) -> Self {
1243        Ty::new(interner, TyKind::Array(ty, len))
1244    }
1245
1246    fn new_slice(interner: DbInterner<'db>, ty: Self) -> Self {
1247        Ty::new(interner, TyKind::Slice(ty))
1248    }
1249
1250    fn new_tup(interner: DbInterner<'db>, tys: &[<DbInterner<'db> as Interner>::Ty]) -> Self {
1251        Ty::new(interner, TyKind::Tuple(Tys::new_from_slice(tys)))
1252    }
1253
1254    fn new_tup_from_iter<It, T>(interner: DbInterner<'db>, iter: It) -> T::Output
1255    where
1256        It: Iterator<Item = T>,
1257        T: rustc_type_ir::CollectAndApply<Self, Self>,
1258    {
1259        T::collect_and_apply(iter, |ts| Ty::new_tup(interner, ts))
1260    }
1261
1262    fn new_fn_def(
1263        interner: DbInterner<'db>,
1264        def_id: CallableIdWrapper,
1265        args: <DbInterner<'db> as Interner>::GenericArgs,
1266    ) -> Self {
1267        Ty::new(interner, TyKind::FnDef(def_id, args))
1268    }
1269
1270    fn new_fn_ptr(
1271        interner: DbInterner<'db>,
1272        sig: rustc_type_ir::Binder<DbInterner<'db>, rustc_type_ir::FnSig<DbInterner<'db>>>,
1273    ) -> Self {
1274        let (sig_tys, header) = sig.split();
1275        Ty::new(interner, TyKind::FnPtr(sig_tys, header))
1276    }
1277
1278    fn new_pat(
1279        interner: DbInterner<'db>,
1280        ty: Self,
1281        pat: <DbInterner<'db> as Interner>::Pat,
1282    ) -> Self {
1283        Ty::new(interner, TyKind::Pat(ty, pat))
1284    }
1285
1286    fn new_unsafe_binder(
1287        interner: DbInterner<'db>,
1288        ty: rustc_type_ir::Binder<DbInterner<'db>, <DbInterner<'db> as Interner>::Ty>,
1289    ) -> Self {
1290        Ty::new(interner, TyKind::UnsafeBinder(ty.into()))
1291    }
1292
1293    fn tuple_fields(self) -> <DbInterner<'db> as Interner>::Tys {
1294        match self.kind() {
1295            TyKind::Tuple(args) => args,
1296            _ => panic!("tuple_fields called on non-tuple: {self:?}"),
1297        }
1298    }
1299
1300    fn to_opt_closure_kind(self) -> Option<rustc_type_ir::ClosureKind> {
1301        match self.kind() {
1302            TyKind::Int(int_ty) => match int_ty {
1303                IntTy::I8 => Some(ClosureKind::Fn),
1304                IntTy::I16 => Some(ClosureKind::FnMut),
1305                IntTy::I32 => Some(ClosureKind::FnOnce),
1306                _ => unreachable!("cannot convert type `{:?}` to a closure kind", self),
1307            },
1308
1309            // "Bound" types appear in canonical queries when the
1310            // closure type is not yet known, and `Placeholder` and `Param`
1311            // may be encountered in generic `AsyncFnKindHelper` goals.
1312            TyKind::Bound(..) | TyKind::Placeholder(_) | TyKind::Param(_) | TyKind::Infer(_) => {
1313                None
1314            }
1315
1316            TyKind::Error(_) => Some(ClosureKind::Fn),
1317
1318            _ => unreachable!("cannot convert type `{:?}` to a closure kind", self),
1319        }
1320    }
1321
1322    fn from_closure_kind(interner: DbInterner<'db>, kind: rustc_type_ir::ClosureKind) -> Self {
1323        let types = interner.default_types();
1324        match kind {
1325            ClosureKind::Fn => types.types.i8,
1326            ClosureKind::FnMut => types.types.i16,
1327            ClosureKind::FnOnce => types.types.i32,
1328        }
1329    }
1330
1331    fn from_coroutine_closure_kind(
1332        interner: DbInterner<'db>,
1333        kind: rustc_type_ir::ClosureKind,
1334    ) -> Self {
1335        let types = interner.default_types();
1336        match kind {
1337            ClosureKind::Fn | ClosureKind::FnMut => types.types.i16,
1338            ClosureKind::FnOnce => types.types.i32,
1339        }
1340    }
1341
1342    fn has_unsafe_fields(self) -> bool {
1343        false
1344    }
1345
1346    fn discriminant_ty(self, interner: DbInterner<'db>) -> Ty<'db> {
1347        match self.kind() {
1348            TyKind::Adt(adt, _) if adt.is_enum() => {
1349                adt.repr(interner.db).discr_type().to_ty(interner)
1350            }
1351            TyKind::Coroutine(_, args) => args.as_coroutine().discr_ty(interner),
1352
1353            TyKind::Param(_) | TyKind::Alias(..) | TyKind::Infer(InferTy::TyVar(_)) => {
1354                /*
1355                let assoc_items = tcx.associated_item_def_ids(
1356                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
1357                );
1358                TyKind::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
1359                */
1360                unimplemented!()
1361            }
1362
1363            TyKind::Pat(ty, _) => ty.discriminant_ty(interner),
1364
1365            TyKind::Bool
1366            | TyKind::Char
1367            | TyKind::Int(_)
1368            | TyKind::Uint(_)
1369            | TyKind::Float(_)
1370            | TyKind::Adt(..)
1371            | TyKind::Foreign(_)
1372            | TyKind::Str
1373            | TyKind::Array(..)
1374            | TyKind::Slice(_)
1375            | TyKind::RawPtr(_, _)
1376            | TyKind::Ref(..)
1377            | TyKind::FnDef(..)
1378            | TyKind::FnPtr(..)
1379            | TyKind::Dynamic(..)
1380            | TyKind::Closure(..)
1381            | TyKind::CoroutineClosure(..)
1382            | TyKind::CoroutineWitness(..)
1383            | TyKind::Never
1384            | TyKind::Tuple(_)
1385            | TyKind::Error(_)
1386            | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => {
1387                interner.default_types().types.u8
1388            }
1389
1390            TyKind::Bound(..)
1391            | TyKind::Placeholder(_)
1392            | TyKind::Infer(
1393                InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_),
1394            ) => {
1395                panic!(
1396                    "`dself.iter().map(|v| v.try_fold_with(folder)).collect::<Result<_, _>>()?iscriminant_ty` applied to unexpected type: {self:?}"
1397                )
1398            }
1399            TyKind::UnsafeBinder(..) => unimplemented!(),
1400        }
1401    }
1402}
1403
1404interned_slice!(TysStorage, Tys, StoredTys, tys, Ty<'db>, Ty<'static>);
1405impl_foldable_for_interned_slice!(Tys);
1406impl_foldable_for_stored_type!(StoredTys);
1407
1408impl<'db> Tys<'db> {
1409    #[inline]
1410    pub fn inputs(self) -> &'db [Ty<'db>] {
1411        self.as_slice().split_last().unwrap().1
1412    }
1413}
1414
1415impl<'db> rustc_type_ir::inherent::Tys<DbInterner<'db>> for Tys<'db> {
1416    fn inputs(self) -> <DbInterner<'db> as Interner>::FnInputTys {
1417        self.as_slice().split_last().unwrap().1
1418    }
1419
1420    fn output(self) -> <DbInterner<'db> as Interner>::Ty {
1421        *self.as_slice().split_last().unwrap().0
1422    }
1423}
1424
1425pub type PlaceholderType<'db> = rustc_type_ir::PlaceholderType<DbInterner<'db>>;
1426
1427#[derive(Copy, Clone, PartialEq, Eq, Hash)]
1428pub struct ParamTy {
1429    // FIXME: I'm not pleased with this. Ideally a `Param` should only know its index - the defining item
1430    // is known from the `EarlyBinder`. This should also be beneficial for memory usage. But code currently
1431    // assumes it can get the definition from `Param` alone - so that's what we got.
1432    pub id: TypeParamId,
1433    pub index: u32,
1434}
1435
1436impl ParamTy {
1437    pub fn to_ty<'db>(self, interner: DbInterner<'db>) -> Ty<'db> {
1438        Ty::new_param(interner, self.id, self.index)
1439    }
1440}
1441
1442impl std::fmt::Debug for ParamTy {
1443    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1444        write!(f, "#{}", self.index)
1445    }
1446}
1447
1448pub type BoundTy<'db> = rustc_type_ir::BoundTy<DbInterner<'db>>;
1449pub type BoundTyKind<'db> = rustc_type_ir::BoundTyKind<DbInterner<'db>>;
1450
1451#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
1452pub struct ErrorGuaranteed;
1453
1454impl<V> GenericTypeVisitable<V> for ErrorGuaranteed {
1455    fn generic_visit_with(&self, _visitor: &mut V) {}
1456}
1457
1458impl<'db> TypeVisitable<DbInterner<'db>> for ErrorGuaranteed {
1459    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
1460        &self,
1461        visitor: &mut V,
1462    ) -> V::Result {
1463        visitor.visit_error(*self)
1464    }
1465}
1466
1467impl<'db> TypeFoldable<DbInterner<'db>> for ErrorGuaranteed {
1468    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
1469        self,
1470        _folder: &mut F,
1471    ) -> Result<Self, F::Error> {
1472        Ok(self)
1473    }
1474    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, _folder: &mut F) -> Self {
1475        self
1476    }
1477}
1478
1479impl ParamLike for ParamTy {
1480    fn index(self) -> u32 {
1481        self.index
1482    }
1483}
1484
1485impl<'db> DbInterner<'db> {
1486    /// Given a closure signature, returns an equivalent fn signature. Detuples
1487    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
1488    /// you would get a `fn(u32, i32)`.
1489    /// `unsafety` determines the unsafety of the fn signature. If you pass
1490    /// `Safety::Unsafe` in the previous example, then you would get
1491    /// an `unsafe fn (u32, i32)`.
1492    /// It cannot convert a closure that requires unsafe.
1493    pub fn signature_unclosure(self, sig: PolyFnSig<'db>, safety: Safety) -> PolyFnSig<'db> {
1494        sig.map_bound(|s| {
1495            let params = match s.inputs()[0].kind() {
1496                TyKind::Tuple(params) => params,
1497                _ => panic!(),
1498            };
1499            // Ignore splatting, it is unsupported on closures.
1500            self.mk_fn_sig(params, s.output(), s.c_variadic(), safety, ExternAbi::Rust)
1501        })
1502    }
1503}