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