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