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