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