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