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_param(self, index: u32) -> bool {
426        match self.kind() {
427            TyKind::Param(data) => data.index == index,
428            _ => false,
429        }
430    }
431
432    #[inline]
433    pub fn is_never(self) -> bool {
434        matches!(self.kind(), TyKind::Never)
435    }
436
437    #[inline]
438    pub fn is_bool(self) -> bool {
439        matches!(self.kind(), TyKind::Bool)
440    }
441
442    /// Check if type is an `usize`.
443    #[inline]
444    pub fn is_usize(self) -> bool {
445        matches!(self.kind(), TyKind::Uint(UintTy::Usize))
446    }
447
448    #[inline]
449    pub fn is_char(self) -> bool {
450        matches!(self.kind(), TyKind::Char)
451    }
452
453    #[inline]
454    pub fn is_coroutine_closure(self) -> bool {
455        matches!(self.kind(), TyKind::CoroutineClosure(..))
456    }
457
458    /// A scalar type is one that denotes an atomic datum, with no sub-components.
459    /// (A RawPtr is scalar because it represents a non-managed pointer, so its
460    /// contents are abstract to rustc.)
461    #[inline]
462    pub fn is_scalar(self) -> bool {
463        matches!(
464            self.kind(),
465            TyKind::Bool
466                | TyKind::Char
467                | TyKind::Int(_)
468                | TyKind::Float(_)
469                | TyKind::Uint(_)
470                | TyKind::FnDef(..)
471                | TyKind::FnPtr(..)
472                | TyKind::RawPtr(_, _)
473                | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_))
474        )
475    }
476
477    #[inline]
478    pub fn is_infer(self) -> bool {
479        matches!(self.kind(), TyKind::Infer(..))
480    }
481
482    #[inline]
483    pub fn is_numeric(self) -> bool {
484        self.is_integral() || self.is_floating_point()
485    }
486
487    #[inline]
488    pub fn is_str(self) -> bool {
489        matches!(self.kind(), TyKind::Str)
490    }
491
492    #[inline]
493    pub fn is_unit(self) -> bool {
494        matches!(self.kind(), TyKind::Tuple(tys) if tys.is_empty())
495    }
496
497    #[inline]
498    pub fn is_u8(self) -> bool {
499        matches!(self.kind(), TyKind::Uint(UintTy::U8))
500    }
501
502    #[inline]
503    pub fn is_raw_ptr(self) -> bool {
504        matches!(self.kind(), TyKind::RawPtr(..))
505    }
506
507    #[inline]
508    pub fn is_ref(self) -> bool {
509        matches!(self.kind(), TyKind::Ref(..))
510    }
511
512    #[inline]
513    pub fn is_array(self) -> bool {
514        matches!(self.kind(), TyKind::Array(..))
515    }
516
517    #[inline]
518    pub fn is_slice(self) -> bool {
519        matches!(self.kind(), TyKind::Slice(..))
520    }
521
522    pub fn is_union(self) -> bool {
523        self.as_adt().is_some_and(|(adt, _)| matches!(adt, AdtId::UnionId(_)))
524    }
525
526    pub fn boxed_ty(self) -> Option<Ty<'db>> {
527        match self.kind() {
528            TyKind::Adt(adt_def, args) if adt_def.is_box() => Some(args.type_at(0)),
529            _ => None,
530        }
531    }
532
533    pub fn is_box(self) -> bool {
534        matches!(self.kind(), TyKind::Adt(adt_def, _) if adt_def.is_box())
535    }
536
537    #[inline]
538    pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> {
539        match self.kind() {
540            TyKind::Adt(adt_def, args) => Some((adt_def.def_id(), args)),
541            _ => None,
542        }
543    }
544
545    #[inline]
546    pub fn as_slice(self) -> Option<Ty<'db>> {
547        match self.kind() {
548            TyKind::Slice(ty) => Some(ty),
549            _ => None,
550        }
551    }
552
553    #[inline]
554    pub fn ty_vid(self) -> Option<TyVid> {
555        match self.kind() {
556            TyKind::Infer(rustc_type_ir::TyVar(vid)) => Some(vid),
557            _ => None,
558        }
559    }
560
561    /// Given a `fn` type, returns an equivalent `unsafe fn` type;
562    /// that is, a `fn` type that is equivalent in every way for being
563    /// unsafe.
564    pub fn safe_to_unsafe_fn_ty(interner: DbInterner<'db>, sig: PolyFnSig<'db>) -> Ty<'db> {
565        assert!(sig.safety().is_safe());
566        Ty::new_fn_ptr(interner, sig.map_bound(|sig| sig.set_safety(Safety::Unsafe)))
567    }
568
569    /// Returns the type of `*ty`.
570    ///
571    /// The parameter `explicit` indicates if this is an *explicit* dereference.
572    /// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
573    pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'db>> {
574        match self.kind() {
575            TyKind::Adt(adt, substs) if adt.is_box() => Some(substs.as_slice()[0].expect_ty()),
576            TyKind::Ref(_, ty, _) => Some(ty),
577            TyKind::RawPtr(ty, _) if explicit => Some(ty),
578            _ => None,
579        }
580    }
581
582    /// Returns the type of `ty[i]`.
583    pub fn builtin_index(self) -> Option<Ty<'db>> {
584        match self.kind() {
585            TyKind::Array(ty, _) | TyKind::Slice(ty) => Some(ty),
586            _ => None,
587        }
588    }
589
590    /// Whether the type contains some non-lifetime, aka. type or const, error type.
591    pub fn references_non_lt_error(self) -> bool {
592        references_non_lt_error(&self)
593    }
594
595    /// Whether the type contains a type error (ignoring const and lifetime errors).
596    pub fn references_only_ty_error(self) -> bool {
597        references_only_ty_error(&self)
598    }
599
600    pub fn callable_sig(self, interner: DbInterner<'db>) -> Option<Binder<'db, FnSig<'db>>> {
601        match self.kind() {
602            TyKind::FnDef(callable, args) => {
603                Some(interner.fn_sig(callable).instantiate(interner, args).skip_norm_wip())
604            }
605            TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
606            TyKind::Closure(_, closure_args) => {
607                Some(interner.signature_unclosure(closure_args.as_closure().sig(), Safety::Safe))
608            }
609            TyKind::CoroutineClosure(coroutine_id, args) => {
610                Some(args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
611                    let closure_args = args.as_coroutine_closure();
612                    let return_ty = sig.to_coroutine(
613                        interner,
614                        closure_args.parent_args(),
615                        closure_args.kind_ty(),
616                        interner.coroutine_for_closure(coroutine_id),
617                        closure_args.tupled_upvars_ty(),
618                    );
619                    FnSig {
620                        inputs_and_output: Tys::new_from_iter(
621                            sig.tupled_inputs_ty
622                                .tuple_fields()
623                                .iter()
624                                .chain(std::iter::once(return_ty)),
625                        ),
626                        fn_sig_kind: sig.fn_sig_kind,
627                    }
628                }))
629            }
630            _ => None,
631        }
632    }
633
634    pub fn as_reference(self) -> Option<(Ty<'db>, Region<'db>, Mutability)> {
635        match self.kind() {
636            TyKind::Ref(region, ty, mutability) => Some((ty, region, mutability)),
637            _ => None,
638        }
639    }
640
641    pub fn as_reference_or_ptr(self) -> Option<(Ty<'db>, Rawness, Mutability)> {
642        match self.kind() {
643            TyKind::Ref(_, ty, mutability) => Some((ty, Rawness::Ref, mutability)),
644            TyKind::RawPtr(ty, mutability) => Some((ty, Rawness::RawPtr, mutability)),
645            _ => None,
646        }
647    }
648
649    pub fn is_tuple(self) -> bool {
650        matches!(self.kind(), TyKind::Tuple(_))
651    }
652
653    pub fn as_tuple(self) -> Option<Tys<'db>> {
654        match self.kind() {
655            TyKind::Tuple(tys) => Some(tys),
656            _ => None,
657        }
658    }
659
660    pub fn dyn_trait(self) -> Option<TraitId> {
661        let TyKind::Dynamic(bounds, _) = self.kind() else { return None };
662        Some(bounds.principal_def_id()?.0)
663    }
664
665    pub fn strip_references(self) -> Ty<'db> {
666        let mut t = self;
667        while let TyKind::Ref(_lifetime, ty, _mutability) = t.kind() {
668            t = ty;
669        }
670        t
671    }
672
673    pub fn strip_reference(self) -> Ty<'db> {
674        self.as_reference().map_or(self, |(ty, _, _)| ty)
675    }
676
677    /// Replace infer vars with errors.
678    ///
679    /// This needs to be called for every type that may contain infer vars and is yielded to outside inference,
680    /// as things other than inference do not expect to see infer vars.
681    pub fn replace_infer_with_error(self, interner: DbInterner<'db>) -> Ty<'db> {
682        self.fold_with(&mut crate::next_solver::infer::resolve::ReplaceInferWithError::new(
683            interner,
684        ))
685    }
686
687    pub fn from_builtin_type(
688        interner: DbInterner<'db>,
689        ty: hir_def::builtin_type::BuiltinType,
690    ) -> Ty<'db> {
691        let types = interner.default_types();
692        match ty {
693            hir_def::builtin_type::BuiltinType::Char => types.types.char,
694            hir_def::builtin_type::BuiltinType::Bool => types.types.bool,
695            hir_def::builtin_type::BuiltinType::Str => types.types.str,
696            hir_def::builtin_type::BuiltinType::Int(int) => match int {
697                hir_def::builtin_type::BuiltinInt::Isize => types.types.isize,
698                hir_def::builtin_type::BuiltinInt::I8 => types.types.i8,
699                hir_def::builtin_type::BuiltinInt::I16 => types.types.i16,
700                hir_def::builtin_type::BuiltinInt::I32 => types.types.i32,
701                hir_def::builtin_type::BuiltinInt::I64 => types.types.i64,
702                hir_def::builtin_type::BuiltinInt::I128 => types.types.i128,
703            },
704            hir_def::builtin_type::BuiltinType::Uint(uint) => match uint {
705                hir_def::builtin_type::BuiltinUint::Usize => types.types.usize,
706                hir_def::builtin_type::BuiltinUint::U8 => types.types.u8,
707                hir_def::builtin_type::BuiltinUint::U16 => types.types.u16,
708                hir_def::builtin_type::BuiltinUint::U32 => types.types.u32,
709                hir_def::builtin_type::BuiltinUint::U64 => types.types.u64,
710                hir_def::builtin_type::BuiltinUint::U128 => types.types.u128,
711            },
712            hir_def::builtin_type::BuiltinType::Float(float) => match float {
713                hir_def::builtin_type::BuiltinFloat::F16 => types.types.f16,
714                hir_def::builtin_type::BuiltinFloat::F32 => types.types.f32,
715                hir_def::builtin_type::BuiltinFloat::F64 => types.types.f64,
716                hir_def::builtin_type::BuiltinFloat::F128 => types.types.f128,
717            },
718        }
719    }
720
721    pub fn as_builtin(self) -> Option<hir_def::builtin_type::BuiltinType> {
722        let builtin = match self.kind() {
723            TyKind::Char => hir_def::builtin_type::BuiltinType::Char,
724            TyKind::Bool => hir_def::builtin_type::BuiltinType::Bool,
725            TyKind::Str => hir_def::builtin_type::BuiltinType::Str,
726            TyKind::Int(int) => hir_def::builtin_type::BuiltinType::Int(match int {
727                rustc_type_ir::IntTy::Isize => hir_def::builtin_type::BuiltinInt::Isize,
728                rustc_type_ir::IntTy::I8 => hir_def::builtin_type::BuiltinInt::I8,
729                rustc_type_ir::IntTy::I16 => hir_def::builtin_type::BuiltinInt::I16,
730                rustc_type_ir::IntTy::I32 => hir_def::builtin_type::BuiltinInt::I32,
731                rustc_type_ir::IntTy::I64 => hir_def::builtin_type::BuiltinInt::I64,
732                rustc_type_ir::IntTy::I128 => hir_def::builtin_type::BuiltinInt::I128,
733            }),
734            TyKind::Uint(uint) => hir_def::builtin_type::BuiltinType::Uint(match uint {
735                rustc_type_ir::UintTy::Usize => hir_def::builtin_type::BuiltinUint::Usize,
736                rustc_type_ir::UintTy::U8 => hir_def::builtin_type::BuiltinUint::U8,
737                rustc_type_ir::UintTy::U16 => hir_def::builtin_type::BuiltinUint::U16,
738                rustc_type_ir::UintTy::U32 => hir_def::builtin_type::BuiltinUint::U32,
739                rustc_type_ir::UintTy::U64 => hir_def::builtin_type::BuiltinUint::U64,
740                rustc_type_ir::UintTy::U128 => hir_def::builtin_type::BuiltinUint::U128,
741            }),
742            TyKind::Float(float) => hir_def::builtin_type::BuiltinType::Float(match float {
743                rustc_type_ir::FloatTy::F16 => hir_def::builtin_type::BuiltinFloat::F16,
744                rustc_type_ir::FloatTy::F32 => hir_def::builtin_type::BuiltinFloat::F32,
745                rustc_type_ir::FloatTy::F64 => hir_def::builtin_type::BuiltinFloat::F64,
746                rustc_type_ir::FloatTy::F128 => hir_def::builtin_type::BuiltinFloat::F128,
747            }),
748            _ => return None,
749        };
750        Some(builtin)
751    }
752
753    // FIXME: Should this be here?
754    pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'db>>> {
755        let interner = DbInterner::new_no_crate(db);
756
757        match self.kind() {
758            TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => Some(
759                def_id
760                    .0
761                    .predicates(db)
762                    .iter_instantiated_copied(interner, args.as_slice())
763                    .map(Unnormalized::skip_norm_wip)
764                    .collect(),
765            ),
766            TyKind::Param(param) => {
767                // FIXME: We shouldn't use `param.id` here.
768                let generic_params = GenericParams::of(db, param.id.parent());
769                let param_data = &generic_params[param.id.local_id()];
770                match param_data {
771                    TypeOrConstParamData::TypeParamData(p) => match p.provenance {
772                        TypeParamProvenance::ArgumentImplTrait => {
773                            let predicates = GenericPredicates::query_all(db, param.id.parent())
774                                .iter_identity()
775                                .map(Unnormalized::skip_norm_wip)
776                                .filter(|wc| match wc.kind().skip_binder() {
777                                    ClauseKind::Trait(tr) => tr.self_ty() == self,
778                                    ClauseKind::Projection(pred) => pred.self_ty() == self,
779                                    ClauseKind::TypeOutlives(pred) => pred.0 == self,
780                                    _ => false,
781                                })
782                                .collect::<Vec<_>>();
783
784                            Some(predicates)
785                        }
786                        _ => None,
787                    },
788                    _ => None,
789                }
790            }
791            TyKind::Coroutine(coroutine_id, _args) => {
792                let owner = coroutine_id.0.loc(db).owner;
793                let krate = owner.krate(db);
794                if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
795                    // This is only used by type walking.
796                    // Parameters will be walked outside, and projection predicate is not used.
797                    // So just provide the Future trait.
798                    let impl_bound = TraitRef::new_from_args(
799                        interner,
800                        future_trait.into(),
801                        GenericArgs::empty(),
802                    )
803                    .upcast(interner);
804                    Some(vec![impl_bound])
805                } else {
806                    None
807                }
808            }
809            _ => None,
810        }
811    }
812
813    /// FIXME: Get rid of this, it's not a good abstraction
814    pub fn equals_ctor(self, other: Ty<'db>) -> bool {
815        match (self.kind(), other.kind()) {
816            (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt.def_id() == adt2.def_id(),
817            (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
818                true
819            }
820            (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
821            (TyKind::Alias(alias), TyKind::Alias(alias2)) => alias.kind == alias2.kind,
822            (TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
823            (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
824            (TyKind::Ref(.., mutability), TyKind::Ref(.., mutability2))
825            | (TyKind::RawPtr(.., mutability), TyKind::RawPtr(.., mutability2)) => {
826                mutability == mutability2
827            }
828            (TyKind::FnPtr(sig, hdr), TyKind::FnPtr(sig2, hdr2)) => sig == sig2 && hdr == hdr2,
829            (TyKind::Tuple(tys), TyKind::Tuple(tys2)) => tys.len() == tys2.len(),
830            (TyKind::Str, TyKind::Str)
831            | (TyKind::Never, TyKind::Never)
832            | (TyKind::Char, TyKind::Char)
833            | (TyKind::Bool, TyKind::Bool) => true,
834            (TyKind::Int(int), TyKind::Int(int2)) => int == int2,
835            (TyKind::Float(float), TyKind::Float(float2)) => float == float2,
836            _ => false,
837        }
838    }
839}
840
841pub fn references_non_lt_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
842    t.has_non_region_error()
843}
844
845pub fn references_only_ty_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
846    references_non_lt_error(t) && t.visit_with(&mut ReferencesOnlyTyError).is_break()
847}
848
849struct ReferencesOnlyTyError;
850
851impl<'db> TypeVisitor<DbInterner<'db>> for ReferencesOnlyTyError {
852    type Result = ControlFlow<()>;
853
854    fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
855        if !ty.references_non_lt_error() {
856            ControlFlow::Continue(())
857        } else if ty.is_ty_error() {
858            ControlFlow::Break(())
859        } else {
860            ty.super_visit_with(self)
861        }
862    }
863
864    fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
865        if !references_non_lt_error(&c) {
866            ControlFlow::Continue(())
867        } else {
868            c.super_visit_with(self)
869        }
870    }
871
872    fn visit_predicate(&mut self, p: Predicate<'db>) -> Self::Result {
873        if !references_non_lt_error(&p) {
874            ControlFlow::Continue(())
875        } else {
876            p.super_visit_with(self)
877        }
878    }
879}
880
881impl<'db> std::fmt::Debug for Ty<'db> {
882    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
883        self.inner().internee.fmt(f)
884    }
885}
886
887impl<'db> IntoKind for Ty<'db> {
888    type Kind = TyKind<'db>;
889
890    #[inline]
891    fn kind(self) -> Self::Kind {
892        self.inner().internee
893    }
894}
895
896impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Ty<'db> {
897    fn generic_visit_with(&self, visitor: &mut V) {
898        if visitor.on_interned(self.interned).is_continue() {
899            self.kind().generic_visit_with(visitor);
900        }
901    }
902}
903
904impl<'db> TypeVisitable<DbInterner<'db>> for Ty<'db> {
905    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
906        &self,
907        visitor: &mut V,
908    ) -> V::Result {
909        visitor.visit_ty(*self)
910    }
911}
912
913impl<'db> TypeSuperVisitable<DbInterner<'db>> for Ty<'db> {
914    fn super_visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
915        &self,
916        visitor: &mut V,
917    ) -> V::Result {
918        match (*self).kind() {
919            TyKind::RawPtr(ty, _mutbl) => ty.visit_with(visitor),
920            TyKind::Array(typ, sz) => {
921                try_visit!(typ.visit_with(visitor));
922                sz.visit_with(visitor)
923            }
924            TyKind::Slice(typ) => typ.visit_with(visitor),
925            TyKind::Adt(_, args) => args.visit_with(visitor),
926            TyKind::Dynamic(ref trait_ty, ref reg) => {
927                try_visit!(trait_ty.visit_with(visitor));
928                reg.visit_with(visitor)
929            }
930            TyKind::Tuple(ts) => ts.visit_with(visitor),
931            TyKind::FnDef(_, args) => args.visit_with(visitor),
932            TyKind::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
933            TyKind::UnsafeBinder(f) => f.visit_with(visitor),
934            TyKind::Ref(r, ty, _) => {
935                try_visit!(r.visit_with(visitor));
936                ty.visit_with(visitor)
937            }
938            TyKind::Coroutine(_did, ref args) => args.visit_with(visitor),
939            TyKind::CoroutineWitness(_did, ref args) => args.visit_with(visitor),
940            TyKind::Closure(_did, ref args) => args.visit_with(visitor),
941            TyKind::CoroutineClosure(_did, ref args) => args.visit_with(visitor),
942            TyKind::Alias(ref data) => data.visit_with(visitor),
943
944            TyKind::Pat(ty, pat) => {
945                try_visit!(ty.visit_with(visitor));
946                pat.visit_with(visitor)
947            }
948
949            TyKind::Error(guar) => guar.visit_with(visitor),
950
951            TyKind::Bool
952            | TyKind::Char
953            | TyKind::Str
954            | TyKind::Int(_)
955            | TyKind::Uint(_)
956            | TyKind::Float(_)
957            | TyKind::Infer(_)
958            | TyKind::Bound(..)
959            | TyKind::Placeholder(..)
960            | TyKind::Param(..)
961            | TyKind::Never
962            | TyKind::Foreign(..) => V::Result::output(),
963        }
964    }
965}
966
967impl<'db> TypeFoldable<DbInterner<'db>> for Ty<'db> {
968    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
969        self,
970        folder: &mut F,
971    ) -> Result<Self, F::Error> {
972        folder.try_fold_ty(self)
973    }
974    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
975        folder.fold_ty(self)
976    }
977}
978
979impl<'db> TypeSuperFoldable<DbInterner<'db>> for Ty<'db> {
980    fn try_super_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
981        self,
982        folder: &mut F,
983    ) -> Result<Self, F::Error> {
984        let kind = match self.kind() {
985            TyKind::RawPtr(ty, mutbl) => TyKind::RawPtr(ty.try_fold_with(folder)?, mutbl),
986            TyKind::Array(typ, sz) => {
987                TyKind::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?)
988            }
989            TyKind::Slice(typ) => TyKind::Slice(typ.try_fold_with(folder)?),
990            TyKind::Adt(tid, args) => TyKind::Adt(tid, args.try_fold_with(folder)?),
991            TyKind::Dynamic(trait_ty, region) => {
992                TyKind::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
993            }
994            TyKind::Tuple(ts) => TyKind::Tuple(ts.try_fold_with(folder)?),
995            TyKind::FnDef(def_id, args) => TyKind::FnDef(def_id, args.try_fold_with(folder)?),
996            TyKind::FnPtr(sig_tys, hdr) => TyKind::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
997            TyKind::UnsafeBinder(f) => TyKind::UnsafeBinder(f.try_fold_with(folder)?),
998            TyKind::Ref(r, ty, mutbl) => {
999                TyKind::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
1000            }
1001            TyKind::Coroutine(did, args) => TyKind::Coroutine(did, args.try_fold_with(folder)?),
1002            TyKind::CoroutineWitness(did, args) => {
1003                TyKind::CoroutineWitness(did, args.try_fold_with(folder)?)
1004            }
1005            TyKind::Closure(did, args) => TyKind::Closure(did, args.try_fold_with(folder)?),
1006            TyKind::CoroutineClosure(did, args) => {
1007                TyKind::CoroutineClosure(did, args.try_fold_with(folder)?)
1008            }
1009            TyKind::Alias(data) => TyKind::Alias(data.try_fold_with(folder)?),
1010            TyKind::Pat(ty, pat) => {
1011                TyKind::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?)
1012            }
1013
1014            TyKind::Bool
1015            | TyKind::Char
1016            | TyKind::Str
1017            | TyKind::Int(_)
1018            | TyKind::Uint(_)
1019            | TyKind::Float(_)
1020            | TyKind::Error(_)
1021            | TyKind::Infer(_)
1022            | TyKind::Param(..)
1023            | TyKind::Bound(..)
1024            | TyKind::Placeholder(..)
1025            | TyKind::Never
1026            | TyKind::Foreign(..) => return Ok(self),
1027        };
1028
1029        Ok(if self.kind() == kind { self } else { Ty::new(folder.cx(), kind) })
1030    }
1031    fn super_fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
1032        self,
1033        folder: &mut F,
1034    ) -> Self {
1035        let kind = match self.kind() {
1036            TyKind::RawPtr(ty, mutbl) => TyKind::RawPtr(ty.fold_with(folder), mutbl),
1037            TyKind::Array(typ, sz) => TyKind::Array(typ.fold_with(folder), sz.fold_with(folder)),
1038            TyKind::Slice(typ) => TyKind::Slice(typ.fold_with(folder)),
1039            TyKind::Adt(tid, args) => TyKind::Adt(tid, args.fold_with(folder)),
1040            TyKind::Dynamic(trait_ty, region) => {
1041                TyKind::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
1042            }
1043            TyKind::Tuple(ts) => TyKind::Tuple(ts.fold_with(folder)),
1044            TyKind::FnDef(def_id, args) => TyKind::FnDef(def_id, args.fold_with(folder)),
1045            TyKind::FnPtr(sig_tys, hdr) => TyKind::FnPtr(sig_tys.fold_with(folder), hdr),
1046            TyKind::UnsafeBinder(f) => TyKind::UnsafeBinder(f.fold_with(folder)),
1047            TyKind::Ref(r, ty, mutbl) => {
1048                TyKind::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl)
1049            }
1050            TyKind::Coroutine(did, args) => TyKind::Coroutine(did, args.fold_with(folder)),
1051            TyKind::CoroutineWitness(did, args) => {
1052                TyKind::CoroutineWitness(did, args.fold_with(folder))
1053            }
1054            TyKind::Closure(did, args) => TyKind::Closure(did, args.fold_with(folder)),
1055            TyKind::CoroutineClosure(did, args) => {
1056                TyKind::CoroutineClosure(did, args.fold_with(folder))
1057            }
1058            TyKind::Alias(data) => TyKind::Alias(data.fold_with(folder)),
1059            TyKind::Pat(ty, pat) => TyKind::Pat(ty.fold_with(folder), pat.fold_with(folder)),
1060
1061            TyKind::Bool
1062            | TyKind::Char
1063            | TyKind::Str
1064            | TyKind::Int(_)
1065            | TyKind::Uint(_)
1066            | TyKind::Float(_)
1067            | TyKind::Error(_)
1068            | TyKind::Infer(_)
1069            | TyKind::Param(..)
1070            | TyKind::Bound(..)
1071            | TyKind::Placeholder(..)
1072            | TyKind::Never
1073            | TyKind::Foreign(..) => return self,
1074        };
1075
1076        if self.kind() == kind { self } else { Ty::new(folder.cx(), kind) }
1077    }
1078}
1079
1080impl<'db> Relate<DbInterner<'db>> for Ty<'db> {
1081    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
1082        relation: &mut R,
1083        a: Self,
1084        b: Self,
1085    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
1086        relation.tys(a, b)
1087    }
1088}
1089
1090impl<'db> Flags for Ty<'db> {
1091    fn flags(&self) -> rustc_type_ir::TypeFlags {
1092        self.inner().flags
1093    }
1094
1095    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
1096        self.inner().outer_exclusive_binder
1097    }
1098}
1099
1100impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
1101    fn new_unit(interner: DbInterner<'db>) -> Self {
1102        interner.default_types().types.unit
1103    }
1104
1105    fn new_bool(interner: DbInterner<'db>) -> Self {
1106        interner.default_types().types.bool
1107    }
1108
1109    fn new_u8(interner: DbInterner<'db>) -> Self {
1110        interner.default_types().types.u8
1111    }
1112
1113    fn new_usize(interner: DbInterner<'db>) -> Self {
1114        interner.default_types().types.usize
1115    }
1116
1117    fn new_infer(interner: DbInterner<'db>, var: rustc_type_ir::InferTy) -> Self {
1118        Ty::new(interner, TyKind::Infer(var))
1119    }
1120
1121    fn new_var(interner: DbInterner<'db>, var: rustc_type_ir::TyVid) -> Self {
1122        Ty::new(interner, TyKind::Infer(rustc_type_ir::InferTy::TyVar(var)))
1123    }
1124
1125    fn new_param(interner: DbInterner<'db>, param: ParamTy) -> Self {
1126        Ty::new(interner, TyKind::Param(param))
1127    }
1128
1129    fn new_placeholder(interner: DbInterner<'db>, param: PlaceholderType<'db>) -> Self {
1130        Ty::new(interner, TyKind::Placeholder(param))
1131    }
1132
1133    fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundTy<'db>) -> Self {
1134        Ty::new(interner, TyKind::Bound(BoundVarIndexKind::Bound(debruijn), var))
1135    }
1136
1137    fn new_anon_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundVar) -> Self {
1138        Ty::new(
1139            interner,
1140            TyKind::Bound(
1141                BoundVarIndexKind::Bound(debruijn),
1142                BoundTy { var, kind: BoundTyKind::Anon },
1143            ),
1144        )
1145    }
1146
1147    fn new_canonical_bound(interner: DbInterner<'db>, var: BoundVar) -> Self {
1148        Ty::new(
1149            interner,
1150            TyKind::Bound(BoundVarIndexKind::Canonical, BoundTy { var, kind: BoundTyKind::Anon }),
1151        )
1152    }
1153
1154    fn new_alias(interner: DbInterner<'db>, alias_ty: AliasTy<'db>) -> Self {
1155        Ty::new(interner, TyKind::Alias(alias_ty))
1156    }
1157
1158    fn new_error(interner: DbInterner<'db>, guar: ErrorGuaranteed) -> Self {
1159        Ty::new(interner, TyKind::Error(guar))
1160    }
1161
1162    fn new_adt(
1163        interner: DbInterner<'db>,
1164        adt_def: <DbInterner<'db> as Interner>::AdtDef,
1165        args: GenericArgs<'db>,
1166    ) -> Self {
1167        Ty::new(interner, TyKind::Adt(adt_def, args))
1168    }
1169
1170    fn new_foreign(interner: DbInterner<'db>, def_id: TypeAliasIdWrapper) -> Self {
1171        Ty::new(interner, TyKind::Foreign(def_id))
1172    }
1173
1174    fn new_dynamic(
1175        interner: DbInterner<'db>,
1176        preds: <DbInterner<'db> as Interner>::BoundExistentialPredicates,
1177        region: <DbInterner<'db> as Interner>::Region,
1178    ) -> Self {
1179        Ty::new(interner, TyKind::Dynamic(preds, region))
1180    }
1181
1182    fn new_coroutine(
1183        interner: DbInterner<'db>,
1184        def_id: CoroutineIdWrapper<'db>,
1185        args: <DbInterner<'db> as Interner>::GenericArgs,
1186    ) -> Self {
1187        Ty::new(interner, TyKind::Coroutine(def_id, args))
1188    }
1189
1190    fn new_coroutine_closure(
1191        interner: DbInterner<'db>,
1192        def_id: CoroutineClosureIdWrapper<'db>,
1193        args: <DbInterner<'db> as Interner>::GenericArgs,
1194    ) -> Self {
1195        Ty::new(interner, TyKind::CoroutineClosure(def_id, args))
1196    }
1197
1198    fn new_closure(
1199        interner: DbInterner<'db>,
1200        def_id: ClosureIdWrapper<'db>,
1201        args: <DbInterner<'db> as Interner>::GenericArgs,
1202    ) -> Self {
1203        Ty::new(interner, TyKind::Closure(def_id, args))
1204    }
1205
1206    fn new_coroutine_witness(
1207        interner: DbInterner<'db>,
1208        def_id: CoroutineIdWrapper<'db>,
1209        args: <DbInterner<'db> as Interner>::GenericArgs,
1210    ) -> Self {
1211        Ty::new(interner, TyKind::CoroutineWitness(def_id, args))
1212    }
1213
1214    fn new_coroutine_witness_for_coroutine(
1215        interner: DbInterner<'db>,
1216        def_id: CoroutineIdWrapper<'db>,
1217        coroutine_args: <DbInterner<'db> as Interner>::GenericArgs,
1218    ) -> Self {
1219        // HACK: Coroutine witness types are lifetime erased, so they
1220        // never reference any lifetime args from the coroutine. We erase
1221        // the regions here since we may get into situations where a
1222        // coroutine is recursively contained within itself, leading to
1223        // witness types that differ by region args. This means that
1224        // cycle detection in fulfillment will not kick in, which leads
1225        // to unnecessary overflows in async code. See the issue:
1226        // <https://github.com/rust-lang/rust/issues/145151>.
1227        let coroutine_args = interner.mk_args_from_iter(coroutine_args.iter().map(|arg| {
1228            match arg.kind() {
1229                GenericArgKind::Type(_) | GenericArgKind::Const(_) => arg,
1230                GenericArgKind::Lifetime(_) => {
1231                    crate::next_solver::Region::new(interner, rustc_type_ir::RegionKind::ReErased)
1232                        .into()
1233                }
1234            }
1235        }));
1236        Ty::new_coroutine_witness(interner, def_id, coroutine_args)
1237    }
1238
1239    fn new_ptr(interner: DbInterner<'db>, ty: Self, mutbl: rustc_ast_ir::Mutability) -> Self {
1240        Ty::new(interner, TyKind::RawPtr(ty, mutbl))
1241    }
1242
1243    fn new_ref(
1244        interner: DbInterner<'db>,
1245        region: <DbInterner<'db> as Interner>::Region,
1246        ty: Self,
1247        mutbl: rustc_ast_ir::Mutability,
1248    ) -> Self {
1249        Ty::new(interner, TyKind::Ref(region, ty, mutbl))
1250    }
1251
1252    fn new_array_with_const_len(
1253        interner: DbInterner<'db>,
1254        ty: Self,
1255        len: <DbInterner<'db> as Interner>::Const,
1256    ) -> Self {
1257        Ty::new(interner, TyKind::Array(ty, len))
1258    }
1259
1260    fn new_slice(interner: DbInterner<'db>, ty: Self) -> Self {
1261        Ty::new(interner, TyKind::Slice(ty))
1262    }
1263
1264    fn new_tup(interner: DbInterner<'db>, tys: &[<DbInterner<'db> as Interner>::Ty]) -> Self {
1265        Ty::new(interner, TyKind::Tuple(Tys::new_from_slice(tys)))
1266    }
1267
1268    fn new_tup_from_iter<It, T>(interner: DbInterner<'db>, iter: It) -> T::Output
1269    where
1270        It: Iterator<Item = T>,
1271        T: rustc_type_ir::CollectAndApply<Self, Self>,
1272    {
1273        T::collect_and_apply(iter, |ts| Ty::new_tup(interner, ts))
1274    }
1275
1276    fn new_fn_def(
1277        interner: DbInterner<'db>,
1278        def_id: CallableIdWrapper,
1279        args: <DbInterner<'db> as Interner>::GenericArgs,
1280    ) -> Self {
1281        Ty::new(interner, TyKind::FnDef(def_id, args))
1282    }
1283
1284    fn new_fn_ptr(
1285        interner: DbInterner<'db>,
1286        sig: rustc_type_ir::Binder<DbInterner<'db>, rustc_type_ir::FnSig<DbInterner<'db>>>,
1287    ) -> Self {
1288        let (sig_tys, header) = sig.split();
1289        Ty::new(interner, TyKind::FnPtr(sig_tys, header))
1290    }
1291
1292    fn new_pat(
1293        interner: DbInterner<'db>,
1294        ty: Self,
1295        pat: <DbInterner<'db> as Interner>::Pat,
1296    ) -> Self {
1297        Ty::new(interner, TyKind::Pat(ty, pat))
1298    }
1299
1300    fn new_unsafe_binder(
1301        interner: DbInterner<'db>,
1302        ty: rustc_type_ir::Binder<DbInterner<'db>, <DbInterner<'db> as Interner>::Ty>,
1303    ) -> Self {
1304        Ty::new(interner, TyKind::UnsafeBinder(ty.into()))
1305    }
1306
1307    fn tuple_fields(self) -> <DbInterner<'db> as Interner>::Tys {
1308        match self.kind() {
1309            TyKind::Tuple(args) => args,
1310            _ => panic!("tuple_fields called on non-tuple: {self:?}"),
1311        }
1312    }
1313
1314    fn to_opt_closure_kind(self) -> Option<rustc_type_ir::ClosureKind> {
1315        match self.kind() {
1316            TyKind::Int(int_ty) => match int_ty {
1317                IntTy::I8 => Some(ClosureKind::Fn),
1318                IntTy::I16 => Some(ClosureKind::FnMut),
1319                IntTy::I32 => Some(ClosureKind::FnOnce),
1320                _ => unreachable!("cannot convert type `{:?}` to a closure kind", self),
1321            },
1322
1323            // "Bound" types appear in canonical queries when the
1324            // closure type is not yet known, and `Placeholder` and `Param`
1325            // may be encountered in generic `AsyncFnKindHelper` goals.
1326            TyKind::Bound(..) | TyKind::Placeholder(_) | TyKind::Param(_) | TyKind::Infer(_) => {
1327                None
1328            }
1329
1330            TyKind::Error(_) => Some(ClosureKind::Fn),
1331
1332            _ => unreachable!("cannot convert type `{:?}` to a closure kind", self),
1333        }
1334    }
1335
1336    fn from_closure_kind(interner: DbInterner<'db>, kind: rustc_type_ir::ClosureKind) -> Self {
1337        let types = interner.default_types();
1338        match kind {
1339            ClosureKind::Fn => types.types.i8,
1340            ClosureKind::FnMut => types.types.i16,
1341            ClosureKind::FnOnce => types.types.i32,
1342        }
1343    }
1344
1345    fn from_coroutine_closure_kind(
1346        interner: DbInterner<'db>,
1347        kind: rustc_type_ir::ClosureKind,
1348    ) -> Self {
1349        let types = interner.default_types();
1350        match kind {
1351            ClosureKind::Fn | ClosureKind::FnMut => types.types.i16,
1352            ClosureKind::FnOnce => types.types.i32,
1353        }
1354    }
1355
1356    fn has_unsafe_fields(self) -> bool {
1357        false
1358    }
1359
1360    fn discriminant_ty(self, interner: DbInterner<'db>) -> Ty<'db> {
1361        match self.kind() {
1362            TyKind::Adt(adt, _) if adt.is_enum() => {
1363                adt.repr(interner.db).discr_type().to_ty(interner)
1364            }
1365            TyKind::Coroutine(_, args) => args.as_coroutine().discr_ty(interner),
1366
1367            TyKind::Param(_) | TyKind::Alias(..) | TyKind::Infer(InferTy::TyVar(_)) => {
1368                /*
1369                let assoc_items = tcx.associated_item_def_ids(
1370                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
1371                );
1372                TyKind::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
1373                */
1374                unimplemented!()
1375            }
1376
1377            TyKind::Pat(ty, _) => ty.discriminant_ty(interner),
1378
1379            TyKind::Bool
1380            | TyKind::Char
1381            | TyKind::Int(_)
1382            | TyKind::Uint(_)
1383            | TyKind::Float(_)
1384            | TyKind::Adt(..)
1385            | TyKind::Foreign(_)
1386            | TyKind::Str
1387            | TyKind::Array(..)
1388            | TyKind::Slice(_)
1389            | TyKind::RawPtr(_, _)
1390            | TyKind::Ref(..)
1391            | TyKind::FnDef(..)
1392            | TyKind::FnPtr(..)
1393            | TyKind::Dynamic(..)
1394            | TyKind::Closure(..)
1395            | TyKind::CoroutineClosure(..)
1396            | TyKind::CoroutineWitness(..)
1397            | TyKind::Never
1398            | TyKind::Tuple(_)
1399            | TyKind::Error(_)
1400            | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => {
1401                interner.default_types().types.u8
1402            }
1403
1404            TyKind::Bound(..)
1405            | TyKind::Placeholder(_)
1406            | TyKind::Infer(
1407                InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_),
1408            ) => {
1409                panic!(
1410                    "`dself.iter().map(|v| v.try_fold_with(folder)).collect::<Result<_, _>>()?iscriminant_ty` applied to unexpected type: {self:?}"
1411                )
1412            }
1413            TyKind::UnsafeBinder(..) => unimplemented!(),
1414        }
1415    }
1416}
1417
1418interned_slice!(TysStorage, Tys, StoredTys, tys, Ty<'db>, Ty<'static>);
1419impl_foldable_for_interned_slice!(Tys);
1420impl_foldable_for_stored_type!(StoredTys);
1421
1422impl<'db> Tys<'db> {
1423    #[inline]
1424    pub fn inputs(self) -> &'db [Ty<'db>] {
1425        self.as_slice().split_last().unwrap().1
1426    }
1427}
1428
1429impl<'db> rustc_type_ir::inherent::Tys<DbInterner<'db>> for Tys<'db> {
1430    fn inputs(self) -> <DbInterner<'db> as Interner>::FnInputTys {
1431        self.as_slice().split_last().unwrap().1
1432    }
1433
1434    fn output(self) -> <DbInterner<'db> as Interner>::Ty {
1435        *self.as_slice().split_last().unwrap().0
1436    }
1437}
1438
1439pub type PlaceholderType<'db> = rustc_type_ir::PlaceholderType<DbInterner<'db>>;
1440
1441#[derive(Copy, Clone, PartialEq, Eq, Hash)]
1442pub struct ParamTy {
1443    // FIXME: I'm not pleased with this. Ideally a `Param` should only know its index - the defining item
1444    // is known from the `EarlyBinder`. This should also be beneficial for memory usage. But code currently
1445    // assumes it can get the definition from `Param` alone - so that's what we got.
1446    pub id: TypeParamId,
1447    pub index: u32,
1448}
1449
1450impl ParamTy {
1451    pub fn to_ty<'db>(self, interner: DbInterner<'db>) -> Ty<'db> {
1452        Ty::new_param(interner, self.id, self.index)
1453    }
1454}
1455
1456impl std::fmt::Debug for ParamTy {
1457    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1458        write!(f, "#{}", self.index)
1459    }
1460}
1461
1462pub type BoundTy<'db> = rustc_type_ir::BoundTy<DbInterner<'db>>;
1463pub type BoundTyKind<'db> = rustc_type_ir::BoundTyKind<DbInterner<'db>>;
1464
1465#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
1466pub struct ErrorGuaranteed;
1467
1468impl<V> GenericTypeVisitable<V> for ErrorGuaranteed {
1469    fn generic_visit_with(&self, _visitor: &mut V) {}
1470}
1471
1472impl<'db> TypeVisitable<DbInterner<'db>> for ErrorGuaranteed {
1473    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
1474        &self,
1475        visitor: &mut V,
1476    ) -> V::Result {
1477        visitor.visit_error(*self)
1478    }
1479}
1480
1481impl<'db> TypeFoldable<DbInterner<'db>> for ErrorGuaranteed {
1482    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
1483        self,
1484        _folder: &mut F,
1485    ) -> Result<Self, F::Error> {
1486        Ok(self)
1487    }
1488    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, _folder: &mut F) -> Self {
1489        self
1490    }
1491}
1492
1493impl ParamLike for ParamTy {
1494    fn index(self) -> u32 {
1495        self.index
1496    }
1497}
1498
1499impl<'db> DbInterner<'db> {
1500    /// Given a closure signature, returns an equivalent fn signature. Detuples
1501    /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
1502    /// you would get a `fn(u32, i32)`.
1503    /// `unsafety` determines the unsafety of the fn signature. If you pass
1504    /// `Safety::Unsafe` in the previous example, then you would get
1505    /// an `unsafe fn (u32, i32)`.
1506    /// It cannot convert a closure that requires unsafe.
1507    pub fn signature_unclosure(self, sig: PolyFnSig<'db>, safety: Safety) -> PolyFnSig<'db> {
1508        sig.map_bound(|s| {
1509            let params = match s.inputs()[0].kind() {
1510                TyKind::Tuple(params) => params,
1511                _ => panic!(),
1512            };
1513            // Ignore splatting, it is unsupported on closures.
1514            self.mk_fn_sig(params, s.output(), s.c_variadic(), safety, ExternAbi::Rust)
1515        })
1516    }
1517}