Skip to main content

rustc_type_ir/
inherent.rs

1//! Set of traits which are used to emulate the inherent impls that are present in `rustc_middle`.
2//! It is customary to glob-import `rustc_type_ir::inherent::*` to bring all of these traits into
3//! scope when programming in interner-agnostic settings, and to avoid importing any of these
4//! directly elsewhere (i.e. specify the full path for an implementation downstream).
5
6use std::fmt::Debug;
7use std::hash::Hash;
8
9use rustc_ast_ir::Mutability;
10
11use crate::elaborate::Elaboratable;
12use crate::fold::{TypeFoldable, TypeSuperFoldable};
13use crate::relate::Relate;
14use crate::solve::{AdtDestructorKind, SizedTraitKind};
15use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
16use crate::{
17    self as ty, ClauseKind, CollectAndApply, FieldInfo, Interner, PredicateKind, UpcastFrom,
18};
19
20#[rust_analyzer::prefer_underscore_import]
21pub trait Ty<I: Interner<Ty = Self>>:
22    Copy
23    + Debug
24    + Hash
25    + Eq
26    + Into<I::GenericArg>
27    + Into<I::Term>
28    + IntoKind<Kind = ty::TyKind<I>>
29    + TypeSuperVisitable<I>
30    + TypeSuperFoldable<I>
31    + Relate<I>
32    + Flags
33{
34    fn new_unit(interner: I) -> Self;
35
36    fn new_bool(interner: I) -> Self;
37
38    fn new_u8(interner: I) -> Self;
39
40    fn new_usize(interner: I) -> Self;
41
42    fn new_infer(interner: I, var: ty::InferTy) -> Self;
43
44    fn new_var(interner: I, var: ty::TyVid) -> Self;
45
46    fn new_param(interner: I, param: I::ParamTy) -> Self;
47
48    fn new_placeholder(interner: I, param: ty::PlaceholderType<I>) -> Self;
49
50    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundTy<I>) -> Self;
51
52    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
53
54    fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
55
56    fn new_alias(interner: I, is_rigid: ty::IsRigid, alias_ty: ty::AliasTy<I>) -> Self;
57
58    fn new_projection_from_args(
59        interner: I,
60        is_rigid: ty::IsRigid,
61        def_id: I::TraitAssocTyId,
62        args: I::GenericArgs,
63    ) -> Self {
64        Self::new_alias(
65            interner,
66            is_rigid,
67            ty::AliasTy::new_from_args(interner, ty::AliasTyKind::Projection { def_id }, args),
68        )
69    }
70
71    fn new_projection(
72        interner: I,
73        is_rigid: ty::IsRigid,
74        def_id: I::TraitAssocTyId,
75        args: impl IntoIterator<Item: Into<I::GenericArg>>,
76    ) -> Self {
77        Self::new_alias(
78            interner,
79            is_rigid,
80            ty::AliasTy::new(interner, ty::AliasTyKind::Projection { def_id }, args),
81        )
82    }
83
84    fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self;
85
86    fn new_adt(interner: I, adt_def: I::AdtDef, args: I::GenericArgs) -> Self;
87
88    fn new_foreign(interner: I, def_id: I::ForeignId) -> Self;
89
90    fn new_dynamic(interner: I, preds: I::BoundExistentialPredicates, region: I::Region) -> Self;
91
92    fn new_coroutine(interner: I, def_id: I::CoroutineId, args: I::GenericArgs) -> Self;
93
94    fn new_coroutine_closure(
95        interner: I,
96        def_id: I::CoroutineClosureId,
97        args: I::GenericArgs,
98    ) -> Self;
99
100    fn new_closure(interner: I, def_id: I::ClosureId, args: I::GenericArgs) -> Self;
101
102    fn new_coroutine_witness(interner: I, def_id: I::CoroutineId, args: I::GenericArgs) -> Self;
103
104    fn new_coroutine_witness_for_coroutine(
105        interner: I,
106        def_id: I::CoroutineId,
107        coroutine_args: I::GenericArgs,
108    ) -> Self;
109
110    fn new_ptr(interner: I, ty: Self, mutbl: Mutability) -> Self;
111
112    fn new_ref(interner: I, region: I::Region, ty: Self, mutbl: Mutability) -> Self;
113
114    fn new_array_with_const_len(interner: I, ty: Self, len: I::Const) -> Self;
115
116    fn new_slice(interner: I, ty: Self) -> Self;
117
118    fn new_tup(interner: I, tys: &[I::Ty]) -> Self;
119
120    fn new_tup_from_iter<It, T>(interner: I, iter: It) -> T::Output
121    where
122        It: Iterator<Item = T>,
123        T: CollectAndApply<Self, Self>;
124
125    fn new_fn_def(interner: I, def_id: I::FunctionId, args: I::GenericArgs) -> Self;
126
127    fn new_fn_ptr(interner: I, sig: ty::Binder<I, ty::FnSig<I>>) -> Self;
128
129    fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self;
130
131    fn new_unsafe_binder(interner: I, ty: ty::Binder<I, I::Ty>) -> Self;
132
133    fn tuple_fields(self) -> I::Tys;
134
135    fn to_opt_closure_kind(self) -> Option<ty::ClosureKind>;
136
137    fn from_closure_kind(interner: I, kind: ty::ClosureKind) -> Self;
138
139    fn from_coroutine_closure_kind(interner: I, kind: ty::ClosureKind) -> Self;
140
141    fn is_ty_var(self) -> bool {
142        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Infer(ty::TyVar(_)) => true,
    _ => false,
}matches!(self.kind(), ty::Infer(ty::TyVar(_)))
143    }
144
145    fn is_ty_error(self) -> bool {
146        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Error(_) => true,
    _ => false,
}matches!(self.kind(), ty::Error(_))
147    }
148
149    fn is_floating_point(self) -> bool {
150        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Float(_) | ty::Infer(ty::FloatVar(_)) => true,
    _ => false,
}matches!(self.kind(), ty::Float(_) | ty::Infer(ty::FloatVar(_)))
151    }
152
153    fn is_integral(self) -> bool {
154        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Infer(ty::IntVar(_)) | ty::Int(_) | ty::Uint(_) => true,
    _ => false,
}matches!(self.kind(), ty::Infer(ty::IntVar(_)) | ty::Int(_) | ty::Uint(_))
155    }
156
157    fn is_fn_ptr(self) -> bool {
158        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::FnPtr(..) => true,
    _ => false,
}matches!(self.kind(), ty::FnPtr(..))
159    }
160
161    /// Checks whether this type is an ADT that has unsafe fields.
162    fn has_unsafe_fields(self) -> bool;
163
164    fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
165        self.kind().fn_sig(interner)
166    }
167
168    fn discriminant_ty(self, interner: I) -> I::Ty;
169
170    fn is_known_rigid(self) -> bool {
171        self.kind().is_known_rigid()
172    }
173
174    fn is_guaranteed_unsized_raw(self) -> bool {
175        match self.kind() {
176            ty::Dynamic(_, _) | ty::Slice(_) | ty::Str => true,
177            ty::Bool
178            | ty::Char
179            | ty::Int(_)
180            | ty::Uint(_)
181            | ty::Float(_)
182            | ty::Adt(_, _)
183            | ty::Foreign(_)
184            | ty::Array(_, _)
185            | ty::Pat(_, _)
186            | ty::RawPtr(_, _)
187            | ty::Ref(_, _, _)
188            | ty::FnDef(_, _)
189            | ty::FnPtr(_, _)
190            | ty::UnsafeBinder(_)
191            | ty::Closure(_, _)
192            | ty::CoroutineClosure(_, _)
193            | ty::Coroutine(_, _)
194            | ty::CoroutineWitness(_, _)
195            | ty::Never
196            | ty::Tuple(_)
197            | ty::Alias(_, _)
198            | ty::Param(_)
199            | ty::Bound(_, _)
200            | ty::Placeholder(_)
201            | ty::Infer(_)
202            | ty::Error(_) => false,
203        }
204    }
205}
206
207#[rust_analyzer::prefer_underscore_import]
208pub trait Tys<I: Interner<Tys = Self>>:
209    Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default
210{
211    fn inputs(self) -> I::FnInputTys;
212
213    fn output(self) -> I::Ty;
214}
215
216#[rust_analyzer::prefer_underscore_import]
217pub trait Safety<I: Interner<Safety = Self>>: Copy + Debug + Hash + Eq {
218    /// The `safe` safety mode.
219    fn safe() -> Self;
220
221    /// The `unsafe` safety mode.
222    fn unsafe_mode() -> Self;
223
224    /// Is the safety mode `Safe`?
225    fn is_safe(self) -> bool;
226
227    /// The string prefix for this safety mode.
228    fn prefix_str(self) -> &'static str;
229}
230
231#[rust_analyzer::prefer_underscore_import]
232pub trait Region<I: Interner<Region = Self>>:
233    Copy
234    + Debug
235    + Hash
236    + Eq
237    + Into<I::GenericArg>
238    + IntoKind<Kind = ty::RegionKind<I>>
239    + Flags
240    + Relate<I>
241{
242    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundRegion<I>) -> Self;
243
244    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
245
246    fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
247
248    fn new_static(interner: I) -> Self;
249
250    fn new_placeholder(interner: I, var: ty::PlaceholderRegion<I>) -> Self;
251
252    fn is_bound(self) -> bool {
253        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReBound(..) => true,
    _ => false,
}matches!(self.kind(), ty::ReBound(..))
254    }
255}
256
257#[rust_analyzer::prefer_underscore_import]
258pub trait Const<I: Interner<Const = Self>>:
259    Copy
260    + Debug
261    + Hash
262    + Eq
263    + Into<I::GenericArg>
264    + Into<I::Term>
265    + IntoKind<Kind = ty::ConstKind<I>>
266    + TypeSuperVisitable<I>
267    + TypeSuperFoldable<I>
268    + Relate<I>
269    + Flags
270{
271    fn new_infer(interner: I, var: ty::InferConst) -> Self;
272
273    fn new_var(interner: I, var: ty::ConstVid) -> Self;
274
275    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, bound_const: ty::BoundConst<I>) -> Self;
276
277    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
278
279    fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
280
281    fn new_placeholder(interner: I, param: ty::PlaceholderConst<I>) -> Self;
282
283    fn new_unevaluated(interner: I, is_rigid: ty::IsRigid, uv: ty::UnevaluatedConst<I>) -> Self;
284
285    fn new_expr(interner: I, expr: I::ExprConst) -> Self;
286
287    fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self;
288
289    fn new_error_with_message(interner: I, msg: impl ToString) -> Self {
290        Self::new_error(interner, interner.delay_bug(msg))
291    }
292
293    fn is_ct_var(self) -> bool {
294        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ConstKind::Infer(ty::InferConst::Var(_)) => true,
    _ => false,
}matches!(self.kind(), ty::ConstKind::Infer(ty::InferConst::Var(_)))
295    }
296
297    fn is_ct_error(self) -> bool {
298        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ConstKind::Error(_) => true,
    _ => false,
}matches!(self.kind(), ty::ConstKind::Error(_))
299    }
300}
301
302#[rust_analyzer::prefer_underscore_import]
303pub trait ValueConst<I: Interner<ValueConst = Self>>: Copy + Debug + Hash + Eq {
304    fn ty(self) -> I::Ty;
305    fn valtree(self) -> I::ValTree;
306}
307
308#[rust_analyzer::prefer_underscore_import]
309pub trait ExprConst<I: Interner<ExprConst = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
310    fn args(self) -> I::GenericArgs;
311}
312
313#[rust_analyzer::prefer_underscore_import]
314pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
315    fn count(&self) -> usize;
316}
317
318#[rust_analyzer::prefer_underscore_import]
319pub trait GenericArg<I: Interner<GenericArg = Self>>:
320    Copy
321    + Debug
322    + Hash
323    + Eq
324    + IntoKind<Kind = ty::GenericArgKind<I>>
325    + TypeVisitable<I>
326    + Relate<I>
327    + From<I::Ty>
328    + From<I::Region>
329    + From<I::Const>
330    + From<I::Term>
331{
332    fn as_term(&self) -> Option<I::Term> {
333        match self.kind() {
334            ty::GenericArgKind::Lifetime(_) => None,
335            ty::GenericArgKind::Type(ty) => Some(ty.into()),
336            ty::GenericArgKind::Const(ct) => Some(ct.into()),
337        }
338    }
339
340    fn as_type(&self) -> Option<I::Ty> {
341        if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None }
342    }
343
344    fn expect_ty(&self) -> I::Ty {
345        self.as_type().expect("expected a type")
346    }
347
348    fn as_const(&self) -> Option<I::Const> {
349        if let ty::GenericArgKind::Const(c) = self.kind() { Some(c) } else { None }
350    }
351
352    fn expect_const(&self) -> I::Const {
353        self.as_const().expect("expected a const")
354    }
355
356    fn as_region(&self) -> Option<I::Region> {
357        if let ty::GenericArgKind::Lifetime(c) = self.kind() { Some(c) } else { None }
358    }
359
360    fn expect_region(&self) -> I::Region {
361        self.as_region().expect("expected a const")
362    }
363
364    fn is_non_region_infer(self) -> bool {
365        match self.kind() {
366            ty::GenericArgKind::Lifetime(_) => false,
367            ty::GenericArgKind::Type(ty) => ty.is_ty_var(),
368            ty::GenericArgKind::Const(ct) => ct.is_ct_var(),
369        }
370    }
371}
372
373#[rust_analyzer::prefer_underscore_import]
374pub trait Term<I: Interner<Term = Self>>:
375    Copy + Debug + Hash + Eq + IntoKind<Kind = ty::TermKind<I>> + TypeFoldable<I> + Relate<I>
376{
377    fn as_type(&self) -> Option<I::Ty> {
378        if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None }
379    }
380
381    fn expect_ty(&self) -> I::Ty {
382        self.as_type().expect("expected a type, but found a const")
383    }
384
385    fn as_const(&self) -> Option<I::Const> {
386        if let ty::TermKind::Const(c) = self.kind() { Some(c) } else { None }
387    }
388
389    fn expect_const(&self) -> I::Const {
390        self.as_const().expect("expected a const, but found a type")
391    }
392
393    fn is_infer(self) -> bool {
394        match self.kind() {
395            ty::TermKind::Ty(ty) => ty.is_ty_var(),
396            ty::TermKind::Const(ct) => ct.is_ct_var(),
397        }
398    }
399
400    fn is_error(self) -> bool {
401        match self.kind() {
402            ty::TermKind::Ty(ty) => ty.is_ty_error(),
403            ty::TermKind::Const(ct) => ct.is_ct_error(),
404        }
405    }
406
407    fn to_alias_term(self) -> Option<ty::AliasTerm<I>> {
408        match self.kind() {
409            ty::TermKind::Ty(ty) => match ty.kind() {
410                ty::Alias(_, alias_ty) => Some(alias_ty.into()),
411                _ => None,
412            },
413            ty::TermKind::Const(ct) => match ct.kind() {
414                ty::ConstKind::Unevaluated(_, uv) => Some(uv.into()),
415                _ => None,
416            },
417        }
418    }
419
420    fn is_non_rigid_alias(self) -> bool {
421        match self.kind() {
422            ty::TermKind::Ty(ty) => match ty.kind() {
423                ty::Alias(is_rigid, _) => is_rigid == ty::IsRigid::No,
424                _ => false,
425            },
426            ty::TermKind::Const(ct) => match ct.kind() {
427                ty::ConstKind::Unevaluated(is_rigid, _) => is_rigid == ty::IsRigid::No,
428                _ => false,
429            },
430        }
431    }
432}
433
434#[rust_analyzer::prefer_underscore_import]
435pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
436    Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
437{
438    fn rebase_onto(
439        self,
440        interner: I,
441        source_def_id: I::DefId,
442        target: I::GenericArgs,
443    ) -> I::GenericArgs;
444
445    fn type_at(self, i: usize) -> I::Ty;
446
447    fn region_at(self, i: usize) -> I::Region;
448
449    fn const_at(self, i: usize) -> I::Const;
450
451    fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
452
453    fn extend_with_error(
454        interner: I,
455        def_id: I::DefId,
456        original_args: &[I::GenericArg],
457    ) -> I::GenericArgs;
458
459    fn split_closure_args(self) -> ty::ClosureArgsParts<I>;
460    fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<I>;
461    fn split_coroutine_args(self) -> ty::CoroutineArgsParts<I>;
462
463    fn as_closure(self) -> ty::ClosureArgs<I> {
464        ty::ClosureArgs { args: self }
465    }
466    fn as_coroutine_closure(self) -> ty::CoroutineClosureArgs<I> {
467        ty::CoroutineClosureArgs { args: self }
468    }
469    fn as_coroutine(self) -> ty::CoroutineArgs<I> {
470        ty::CoroutineArgs { args: self }
471    }
472}
473
474#[rust_analyzer::prefer_underscore_import]
475pub trait Predicate<I: Interner<Predicate = Self>>:
476    Copy
477    + Debug
478    + Hash
479    + Eq
480    + TypeSuperVisitable<I>
481    + TypeSuperFoldable<I>
482    + Flags
483    + UpcastFrom<I, ty::PredicateKind<I>>
484    + UpcastFrom<I, ty::Binder<I, ty::PredicateKind<I>>>
485    + UpcastFrom<I, ty::ClauseKind<I>>
486    + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
487    + UpcastFrom<I, I::Clause>
488    + UpcastFrom<I, ty::NormalizesTo<I>>
489    + UpcastFrom<I, ty::TraitRef<I>>
490    + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
491    + UpcastFrom<I, ty::TraitPredicate<I>>
492    + UpcastFrom<I, ty::ProjectionPredicate<I>>
493    + UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>>
494    + UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>>
495    + IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>>
496    + Elaboratable<I>
497{
498    fn as_clause(self) -> Option<I::Clause>;
499
500    fn allow_normalization(self) -> bool {
501        match self.kind().skip_binder() {
502            PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
503                false
504            }
505            PredicateKind::Clause(ClauseKind::Trait(_))
506            | PredicateKind::Clause(ClauseKind::HostEffect(..))
507            | PredicateKind::Clause(ClauseKind::RegionOutlives(_))
508            | PredicateKind::Clause(ClauseKind::TypeOutlives(_))
509            | PredicateKind::Clause(ClauseKind::Projection(_))
510            | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
511            | PredicateKind::Clause(ClauseKind::UnstableFeature(_))
512            | PredicateKind::DynCompatible(_)
513            | PredicateKind::Subtype(_)
514            | PredicateKind::Coerce(_)
515            | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
516            | PredicateKind::ConstEquate(_, _)
517            | PredicateKind::NormalizesTo(..)
518            | PredicateKind::Ambiguous => true,
519        }
520    }
521}
522
523#[rust_analyzer::prefer_underscore_import]
524pub trait Clause<I: Interner<Clause = Self>>:
525    Copy
526    + Debug
527    + Hash
528    + Eq
529    + TypeFoldable<I>
530    + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
531    + UpcastFrom<I, ty::TraitRef<I>>
532    + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
533    + UpcastFrom<I, ty::TraitPredicate<I>>
534    + UpcastFrom<I, ty::Binder<I, ty::TraitPredicate<I>>>
535    + UpcastFrom<I, ty::ProjectionPredicate<I>>
536    + UpcastFrom<I, ty::Binder<I, ty::ProjectionPredicate<I>>>
537    + IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
538    + Elaboratable<I>
539{
540    fn as_predicate(self) -> I::Predicate;
541
542    fn as_type_outlives_clause(self) -> Option<ty::Binder<I, ty::OutlivesPredicate<I, I::Ty>>> {
543        self.kind()
544            .map_bound(|clause| {
545                if let ty::ClauseKind::TypeOutlives(outlives) = clause {
546                    Some(outlives)
547                } else {
548                    None
549                }
550            })
551            .transpose()
552    }
553
554    fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
555        self.kind()
556            .map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
557            .transpose()
558    }
559
560    fn as_host_effect_clause(self) -> Option<ty::Binder<I, ty::HostEffectPredicate<I>>> {
561        self.kind()
562            .map_bound(
563                |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None },
564            )
565            .transpose()
566    }
567
568    fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
569        self.kind()
570            .map_bound(
571                |clause| {
572                    if let ty::ClauseKind::Projection(p) = clause { Some(p) } else { None }
573                },
574            )
575            .transpose()
576    }
577
578    /// Performs a instantiation suitable for going from a
579    /// poly-trait-ref to supertraits that must hold if that
580    /// poly-trait-ref holds. This is slightly different from a normal
581    /// instantiation in terms of what happens with bound regions.
582    fn instantiate_supertrait(self, cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self;
583}
584
585#[rust_analyzer::prefer_underscore_import]
586pub trait Clauses<I: Interner<Clauses = Self>>:
587    Copy
588    + Debug
589    + Hash
590    + Eq
591    + TypeSuperVisitable<I>
592    + TypeSuperFoldable<I>
593    + Flags
594    + SliceLike<Item = I::Clause>
595{
596}
597
598#[rust_analyzer::prefer_underscore_import]
599pub trait IntoKind {
600    type Kind;
601
602    fn kind(self) -> Self::Kind;
603}
604
605#[rust_analyzer::prefer_underscore_import]
606pub trait ParamLike: Copy + Debug + Hash + Eq {
607    fn index(self) -> u32;
608}
609
610#[rust_analyzer::prefer_underscore_import]
611pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
612    fn def_id(self) -> I::AdtId;
613
614    fn is_struct(self) -> bool;
615
616    fn is_packed(self) -> bool;
617
618    /// Returns the type of the struct tail.
619    ///
620    /// Expects the `AdtDef` to be a struct. If it is not, then this will panic.
621    fn struct_tail_ty(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>;
622
623    fn is_phantom_data(self) -> bool;
624
625    fn is_manually_drop(self) -> bool;
626
627    fn field_representing_type_info(
628        self,
629        interner: I,
630        args: I::GenericArgs,
631    ) -> Option<FieldInfo<I>>;
632
633    // FIXME: perhaps use `all_fields` and expose `FieldDef`.
634    fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>;
635
636    fn sizedness_constraint(
637        self,
638        interner: I,
639        sizedness: SizedTraitKind,
640    ) -> Option<ty::EarlyBinder<I, I::Ty>>;
641
642    fn is_fundamental(self) -> bool;
643
644    fn destructor(self, interner: I) -> Option<AdtDestructorKind>;
645}
646
647#[rust_analyzer::prefer_underscore_import]
648pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
649    fn caller_bounds(self) -> impl SliceLike<Item = I::Clause>;
650}
651
652#[rust_analyzer::prefer_underscore_import]
653pub trait Features<I: Interner>: Copy {
654    fn generic_const_exprs(self) -> bool;
655
656    fn generic_const_args(self) -> bool;
657
658    fn coroutine_clone(self) -> bool;
659
660    fn feature_bound_holds_in_crate(self, symbol: I::Symbol) -> bool;
661}
662
663#[rust_analyzer::prefer_underscore_import]
664pub trait DefId<I: Interner, Local = <I as Interner>::LocalDefId>:
665    Copy + Debug + Hash + Eq + TypeFoldable<I>
666{
667    fn is_local(self) -> bool;
668
669    fn as_local(self) -> Option<Local>;
670}
671
672pub trait SpecificDefId<I: Interner, Local = <I as Interner>::LocalDefId>:
673    DefId<I, Local> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>
674{
675}
676
677impl<
678    I: Interner,
679    T: DefId<I, Local> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>,
680    Local,
681> SpecificDefId<I, Local> for T
682{
683}
684
685#[rust_analyzer::prefer_underscore_import]
686pub trait BoundExistentialPredicates<I: Interner>:
687    Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
688{
689    fn principal_def_id(self) -> Option<I::TraitId>;
690
691    fn principal(self) -> Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>;
692
693    fn auto_traits(self) -> impl IntoIterator<Item = I::TraitId>;
694
695    fn projection_bounds(
696        self,
697    ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
698}
699
700#[rust_analyzer::prefer_underscore_import]
701pub trait Span<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
702    fn dummy() -> Self;
703}
704
705#[rust_analyzer::prefer_underscore_import]
706pub trait OpaqueTypeStorageEntries: Debug + Copy + Default {
707    /// Whether the number of opaques has changed in a way that necessitates
708    /// reevaluating a goal. For now, this is only when the number of non-duplicated
709    /// entries changed.
710    fn needs_reevaluation(self, canonicalized: usize) -> bool;
711}
712
713pub trait BoundVarKinds<I: Interner>:
714    Copy + Debug + Hash + Eq + SliceLike<Item = ty::BoundVariableKind<I>> + Default
715{
716    fn from_vars(cx: I, iter: impl IntoIterator<Item = ty::BoundVariableKind<I>>) -> Self;
717}
718
719pub trait SliceLike: Sized + Copy {
720    type Item: Copy;
721    type IntoIter: Iterator<Item = Self::Item> + DoubleEndedIterator;
722
723    fn iter(self) -> Self::IntoIter;
724
725    fn as_slice(&self) -> &[Self::Item];
726
727    fn get(self, idx: usize) -> Option<Self::Item> {
728        self.as_slice().get(idx).copied()
729    }
730
731    fn len(self) -> usize {
732        self.as_slice().len()
733    }
734
735    fn is_empty(self) -> bool {
736        self.len() == 0
737    }
738
739    fn contains(self, t: &Self::Item) -> bool
740    where
741        Self::Item: PartialEq,
742    {
743        self.as_slice().contains(t)
744    }
745
746    fn to_vec(self) -> Vec<Self::Item> {
747        self.as_slice().to_vec()
748    }
749
750    fn last(self) -> Option<Self::Item> {
751        self.as_slice().last().copied()
752    }
753
754    fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
755        self.as_slice().split_last()
756    }
757}
758
759impl<'a, T: Copy> SliceLike for &'a [T] {
760    type Item = T;
761    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
762
763    fn iter(self) -> Self::IntoIter {
764        self.iter().copied()
765    }
766
767    fn as_slice(&self) -> &[Self::Item] {
768        *self
769    }
770}
771
772impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
773    type Item = T;
774    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
775
776    fn iter(self) -> Self::IntoIter {
777        self.into_iter().copied()
778    }
779
780    fn as_slice(&self) -> &[Self::Item] {
781        *self
782    }
783}
784
785impl<'a, S: SliceLike> SliceLike for &'a S {
786    type Item = S::Item;
787    type IntoIter = S::IntoIter;
788
789    fn iter(self) -> Self::IntoIter {
790        (*self).iter()
791    }
792
793    fn as_slice(&self) -> &[Self::Item] {
794        (*self).as_slice()
795    }
796}
797
798#[rust_analyzer::prefer_underscore_import]
799pub trait Symbol<I>: Copy + Hash + PartialEq + Eq + Debug {
800    fn is_kw_underscore_lifetime(self) -> bool;
801}