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