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