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