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