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