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