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, alias_ty: ty::AliasTy<I>) -> Self;
56
57    fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self {
58        Self::new_alias(
59            interner,
60            ty::AliasTy::new_from_args(interner, ty::AliasTyKind::Projection { def_id }, args),
61        )
62    }
63
64    fn new_projection(
65        interner: I,
66        def_id: I::DefId,
67        args: impl IntoIterator<Item: Into<I::GenericArg>>,
68    ) -> Self {
69        Self::new_alias(
70            interner,
71            ty::AliasTy::new(interner, ty::AliasTyKind::Projection { 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        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Infer(ty::TyVar(_)) => true,
    _ => false,
}matches!(self.kind(), ty::Infer(ty::TyVar(_)))
134    }
135
136    fn is_ty_error(self) -> bool {
137        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::Error(_) => true,
    _ => false,
}matches!(self.kind(), ty::Error(_))
138    }
139
140    fn is_floating_point(self) -> bool {
141        #[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(_)))
142    }
143
144    fn is_integral(self) -> bool {
145        #[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(_))
146    }
147
148    fn is_fn_ptr(self) -> bool {
149        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::FnPtr(..) => true,
    _ => false,
}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 FSigKind<I: Interner<FSigKind = Self>>: Copy + Debug + Hash + Eq {
207    /// The identity function.
208    fn fn_sig_kind(self) -> Self;
209
210    /// Create a new FnSigKind with the given ABI, safety, and C-style variadic flag.
211    fn new(abi: I::Abi, safety: I::Safety, c_variadic: bool) -> Self;
212
213    /// Returns the ABI.
214    fn abi(self) -> I::Abi;
215
216    /// Returns the safety mode.
217    fn safety(self) -> I::Safety;
218
219    /// Do the function arguments end with a C-style variadic argument?
220    fn c_variadic(self) -> bool;
221}
222
223pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq {
224    /// The identity function.
225    fn abi(self) -> Self;
226
227    /// The ABI `extern "Rust"`.
228    fn rust() -> I::Abi;
229
230    /// Whether this ABI is `extern "Rust"`.
231    fn is_rust(self) -> bool;
232
233    /// Pack the ABI into a small dense integer, so it can be stored as packed `FnSigKind` flags.
234    fn pack_abi(self) -> u8;
235
236    /// Unpack the ABI from packed `FnSigKind` flags.
237    fn unpack_abi(abi_index: u8) -> Self;
238}
239
240pub trait Safety<I: Interner<Safety = Self>>: Copy + Debug + Hash + Eq {
241    /// The `safe` safety mode.
242    fn safe() -> Self;
243
244    /// The `unsafe` safety mode.
245    fn unsafe_mode() -> Self;
246
247    /// Is the safety mode `Safe`?
248    fn is_safe(self) -> bool;
249
250    /// The string prefix for this safety mode.
251    fn prefix_str(self) -> &'static str;
252}
253
254pub trait Region<I: Interner<Region = Self>>:
255    Copy
256    + Debug
257    + Hash
258    + Eq
259    + Into<I::GenericArg>
260    + IntoKind<Kind = ty::RegionKind<I>>
261    + Flags
262    + Relate<I>
263{
264    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundRegion<I>) -> Self;
265
266    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
267
268    fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
269
270    fn new_static(interner: I) -> Self;
271
272    fn new_placeholder(interner: I, var: ty::PlaceholderRegion<I>) -> Self;
273
274    fn is_bound(self) -> bool {
275        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ReBound(..) => true,
    _ => false,
}matches!(self.kind(), ty::ReBound(..))
276    }
277}
278
279pub trait Const<I: Interner<Const = Self>>:
280    Copy
281    + Debug
282    + Hash
283    + Eq
284    + Into<I::GenericArg>
285    + Into<I::Term>
286    + IntoKind<Kind = ty::ConstKind<I>>
287    + TypeSuperVisitable<I>
288    + TypeSuperFoldable<I>
289    + Relate<I>
290    + Flags
291{
292    fn new_infer(interner: I, var: ty::InferConst) -> Self;
293
294    fn new_var(interner: I, var: ty::ConstVid) -> Self;
295
296    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, bound_const: ty::BoundConst<I>) -> Self;
297
298    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
299
300    fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
301
302    fn new_placeholder(interner: I, param: ty::PlaceholderConst<I>) -> Self;
303
304    fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>) -> Self;
305
306    fn new_expr(interner: I, expr: I::ExprConst) -> Self;
307
308    fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self;
309
310    fn new_error_with_message(interner: I, msg: impl ToString) -> Self {
311        Self::new_error(interner, interner.delay_bug(msg))
312    }
313
314    fn is_ct_var(self) -> bool {
315        #[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(_)))
316    }
317
318    fn is_ct_error(self) -> bool {
319        #[allow(non_exhaustive_omitted_patterns)] match self.kind() {
    ty::ConstKind::Error(_) => true,
    _ => false,
}matches!(self.kind(), ty::ConstKind::Error(_))
320    }
321}
322
323pub trait ValueConst<I: Interner<ValueConst = Self>>: Copy + Debug + Hash + Eq {
324    fn ty(self) -> I::Ty;
325    fn valtree(self) -> I::ValTree;
326}
327
328pub trait ExprConst<I: Interner<ExprConst = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
329    fn args(self) -> I::GenericArgs;
330}
331
332pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
333    fn count(&self) -> usize;
334}
335
336pub trait GenericArg<I: Interner<GenericArg = Self>>:
337    Copy
338    + Debug
339    + Hash
340    + Eq
341    + IntoKind<Kind = ty::GenericArgKind<I>>
342    + TypeVisitable<I>
343    + Relate<I>
344    + From<I::Ty>
345    + From<I::Region>
346    + From<I::Const>
347    + From<I::Term>
348{
349    fn as_term(&self) -> Option<I::Term> {
350        match self.kind() {
351            ty::GenericArgKind::Lifetime(_) => None,
352            ty::GenericArgKind::Type(ty) => Some(ty.into()),
353            ty::GenericArgKind::Const(ct) => Some(ct.into()),
354        }
355    }
356
357    fn as_type(&self) -> Option<I::Ty> {
358        if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None }
359    }
360
361    fn expect_ty(&self) -> I::Ty {
362        self.as_type().expect("expected a type")
363    }
364
365    fn as_const(&self) -> Option<I::Const> {
366        if let ty::GenericArgKind::Const(c) = self.kind() { Some(c) } else { None }
367    }
368
369    fn expect_const(&self) -> I::Const {
370        self.as_const().expect("expected a const")
371    }
372
373    fn as_region(&self) -> Option<I::Region> {
374        if let ty::GenericArgKind::Lifetime(c) = self.kind() { Some(c) } else { None }
375    }
376
377    fn expect_region(&self) -> I::Region {
378        self.as_region().expect("expected a const")
379    }
380
381    fn is_non_region_infer(self) -> bool {
382        match self.kind() {
383            ty::GenericArgKind::Lifetime(_) => false,
384            ty::GenericArgKind::Type(ty) => ty.is_ty_var(),
385            ty::GenericArgKind::Const(ct) => ct.is_ct_var(),
386        }
387    }
388}
389
390pub trait Term<I: Interner<Term = Self>>:
391    Copy + Debug + Hash + Eq + IntoKind<Kind = ty::TermKind<I>> + TypeFoldable<I> + Relate<I>
392{
393    fn as_type(&self) -> Option<I::Ty> {
394        if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None }
395    }
396
397    fn expect_ty(&self) -> I::Ty {
398        self.as_type().expect("expected a type, but found a const")
399    }
400
401    fn as_const(&self) -> Option<I::Const> {
402        if let ty::TermKind::Const(c) = self.kind() { Some(c) } else { None }
403    }
404
405    fn expect_const(&self) -> I::Const {
406        self.as_const().expect("expected a const, but found a type")
407    }
408
409    fn is_infer(self) -> bool {
410        match self.kind() {
411            ty::TermKind::Ty(ty) => ty.is_ty_var(),
412            ty::TermKind::Const(ct) => ct.is_ct_var(),
413        }
414    }
415
416    fn is_error(self) -> bool {
417        match self.kind() {
418            ty::TermKind::Ty(ty) => ty.is_ty_error(),
419            ty::TermKind::Const(ct) => ct.is_ct_error(),
420        }
421    }
422
423    fn to_alias_term(self) -> Option<ty::AliasTerm<I>> {
424        match self.kind() {
425            ty::TermKind::Ty(ty) => match ty.kind() {
426                ty::Alias(alias_ty) => Some(alias_ty.into()),
427                _ => None,
428            },
429            ty::TermKind::Const(ct) => match ct.kind() {
430                ty::ConstKind::Unevaluated(uv) => Some(uv.into()),
431                _ => None,
432            },
433        }
434    }
435}
436
437pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
438    Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
439{
440    fn rebase_onto(
441        self,
442        interner: I,
443        source_def_id: I::DefId,
444        target: I::GenericArgs,
445    ) -> I::GenericArgs;
446
447    fn type_at(self, i: usize) -> I::Ty;
448
449    fn region_at(self, i: usize) -> I::Region;
450
451    fn const_at(self, i: usize) -> I::Const;
452
453    fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
454
455    fn extend_with_error(
456        interner: I,
457        def_id: I::DefId,
458        original_args: &[I::GenericArg],
459    ) -> I::GenericArgs;
460
461    fn split_closure_args(self) -> ty::ClosureArgsParts<I>;
462    fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<I>;
463    fn split_coroutine_args(self) -> ty::CoroutineArgsParts<I>;
464
465    fn as_closure(self) -> ty::ClosureArgs<I> {
466        ty::ClosureArgs { args: self }
467    }
468    fn as_coroutine_closure(self) -> ty::CoroutineClosureArgs<I> {
469        ty::CoroutineClosureArgs { args: self }
470    }
471    fn as_coroutine(self) -> ty::CoroutineArgs<I> {
472        ty::CoroutineArgs { args: self }
473    }
474}
475
476pub trait Predicate<I: Interner<Predicate = Self>>:
477    Copy
478    + Debug
479    + Hash
480    + Eq
481    + TypeSuperVisitable<I>
482    + TypeSuperFoldable<I>
483    + Flags
484    + UpcastFrom<I, ty::PredicateKind<I>>
485    + UpcastFrom<I, ty::Binder<I, ty::PredicateKind<I>>>
486    + UpcastFrom<I, ty::ClauseKind<I>>
487    + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
488    + UpcastFrom<I, I::Clause>
489    + UpcastFrom<I, ty::NormalizesTo<I>>
490    + UpcastFrom<I, ty::TraitRef<I>>
491    + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
492    + UpcastFrom<I, ty::TraitPredicate<I>>
493    + UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>>
494    + UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>>
495    + IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>>
496    + Elaboratable<I>
497{
498    fn as_clause(self) -> Option<I::Clause>;
499
500    fn as_normalizes_to(self) -> Option<ty::Binder<I, ty::NormalizesTo<I>>> {
501        let kind = self.kind();
502        match kind.skip_binder() {
503            ty::PredicateKind::NormalizesTo(pred) => Some(kind.rebind(pred)),
504            _ => None,
505        }
506    }
507
508    fn allow_normalization(self) -> bool {
509        match self.kind().skip_binder() {
510            PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
511                false
512            }
513            PredicateKind::Clause(ClauseKind::Trait(_))
514            | PredicateKind::Clause(ClauseKind::HostEffect(..))
515            | PredicateKind::Clause(ClauseKind::RegionOutlives(_))
516            | PredicateKind::Clause(ClauseKind::TypeOutlives(_))
517            | PredicateKind::Clause(ClauseKind::Projection(_))
518            | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
519            | PredicateKind::Clause(ClauseKind::UnstableFeature(_))
520            | PredicateKind::DynCompatible(_)
521            | PredicateKind::Subtype(_)
522            | PredicateKind::Coerce(_)
523            | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
524            | PredicateKind::ConstEquate(_, _)
525            | PredicateKind::NormalizesTo(..)
526            | PredicateKind::Ambiguous => true,
527        }
528    }
529}
530
531pub trait Clause<I: Interner<Clause = Self>>:
532    Copy
533    + Debug
534    + Hash
535    + Eq
536    + TypeFoldable<I>
537    + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
538    + UpcastFrom<I, ty::TraitRef<I>>
539    + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
540    + UpcastFrom<I, ty::TraitPredicate<I>>
541    + UpcastFrom<I, ty::Binder<I, ty::TraitPredicate<I>>>
542    + UpcastFrom<I, ty::ProjectionPredicate<I>>
543    + UpcastFrom<I, ty::Binder<I, ty::ProjectionPredicate<I>>>
544    + IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
545    + Elaboratable<I>
546{
547    fn as_predicate(self) -> I::Predicate;
548
549    fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
550        self.kind()
551            .map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
552            .transpose()
553    }
554
555    fn as_host_effect_clause(self) -> Option<ty::Binder<I, ty::HostEffectPredicate<I>>> {
556        self.kind()
557            .map_bound(
558                |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None },
559            )
560            .transpose()
561    }
562
563    fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
564        self.kind()
565            .map_bound(
566                |clause| {
567                    if let ty::ClauseKind::Projection(p) = clause { Some(p) } else { None }
568                },
569            )
570            .transpose()
571    }
572
573    /// Performs a instantiation suitable for going from a
574    /// poly-trait-ref to supertraits that must hold if that
575    /// poly-trait-ref holds. This is slightly different from a normal
576    /// instantiation in terms of what happens with bound regions.
577    fn instantiate_supertrait(self, cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self;
578}
579
580pub trait Clauses<I: Interner<Clauses = Self>>:
581    Copy
582    + Debug
583    + Hash
584    + Eq
585    + TypeSuperVisitable<I>
586    + TypeSuperFoldable<I>
587    + Flags
588    + SliceLike<Item = I::Clause>
589{
590}
591
592pub trait IntoKind {
593    type Kind;
594
595    fn kind(self) -> Self::Kind;
596}
597
598pub trait ParamLike: Copy + Debug + Hash + Eq {
599    fn index(self) -> u32;
600}
601
602pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
603    fn def_id(self) -> I::AdtId;
604
605    fn is_struct(self) -> bool;
606
607    fn is_packed(self) -> bool;
608
609    /// Returns the type of the struct tail.
610    ///
611    /// Expects the `AdtDef` to be a struct. If it is not, then this will panic.
612    fn struct_tail_ty(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>;
613
614    fn is_phantom_data(self) -> bool;
615
616    fn is_manually_drop(self) -> bool;
617
618    fn field_representing_type_info(
619        self,
620        interner: I,
621        args: I::GenericArgs,
622    ) -> Option<FieldInfo<I>>;
623
624    // FIXME: perhaps use `all_fields` and expose `FieldDef`.
625    fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>;
626
627    fn sizedness_constraint(
628        self,
629        interner: I,
630        sizedness: SizedTraitKind,
631    ) -> Option<ty::EarlyBinder<I, I::Ty>>;
632
633    fn is_fundamental(self) -> bool;
634
635    fn destructor(self, interner: I) -> Option<AdtDestructorKind>;
636}
637
638pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
639    fn caller_bounds(self) -> impl SliceLike<Item = I::Clause>;
640}
641
642pub trait Features<I: Interner>: Copy {
643    fn generic_const_exprs(self) -> bool;
644
645    fn coroutine_clone(self) -> bool;
646
647    fn feature_bound_holds_in_crate(self, symbol: I::Symbol) -> bool;
648}
649
650pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
651    fn is_local(self) -> bool;
652
653    fn as_local(self) -> Option<I::LocalDefId>;
654}
655
656pub trait SpecificDefId<I: Interner>:
657    DefId<I> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>
658{
659}
660
661impl<I: Interner, T: DefId<I> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>>
662    SpecificDefId<I> for T
663{
664}
665
666pub trait BoundExistentialPredicates<I: Interner>:
667    Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
668{
669    fn principal_def_id(self) -> Option<I::TraitId>;
670
671    fn principal(self) -> Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>;
672
673    fn auto_traits(self) -> impl IntoIterator<Item = I::TraitId>;
674
675    fn projection_bounds(
676        self,
677    ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
678}
679
680pub trait Span<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
681    fn dummy() -> Self;
682}
683
684pub trait OpaqueTypeStorageEntries: Debug + Copy + Default {
685    /// Whether the number of opaques has changed in a way that necessitates
686    /// reevaluating a goal. For now, this is only when the number of non-duplicated
687    /// entries changed.
688    fn needs_reevaluation(self, canonicalized: usize) -> bool;
689}
690
691pub trait SliceLike: Sized + Copy {
692    type Item: Copy;
693    type IntoIter: Iterator<Item = Self::Item> + DoubleEndedIterator;
694
695    fn iter(self) -> Self::IntoIter;
696
697    fn as_slice(&self) -> &[Self::Item];
698
699    fn get(self, idx: usize) -> Option<Self::Item> {
700        self.as_slice().get(idx).copied()
701    }
702
703    fn len(self) -> usize {
704        self.as_slice().len()
705    }
706
707    fn is_empty(self) -> bool {
708        self.len() == 0
709    }
710
711    fn contains(self, t: &Self::Item) -> bool
712    where
713        Self::Item: PartialEq,
714    {
715        self.as_slice().contains(t)
716    }
717
718    fn to_vec(self) -> Vec<Self::Item> {
719        self.as_slice().to_vec()
720    }
721
722    fn last(self) -> Option<Self::Item> {
723        self.as_slice().last().copied()
724    }
725
726    fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
727        self.as_slice().split_last()
728    }
729}
730
731impl<'a, T: Copy> SliceLike for &'a [T] {
732    type Item = T;
733    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
734
735    fn iter(self) -> Self::IntoIter {
736        self.iter().copied()
737    }
738
739    fn as_slice(&self) -> &[Self::Item] {
740        *self
741    }
742}
743
744impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
745    type Item = T;
746    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
747
748    fn iter(self) -> Self::IntoIter {
749        self.into_iter().copied()
750    }
751
752    fn as_slice(&self) -> &[Self::Item] {
753        *self
754    }
755}
756
757impl<'a, S: SliceLike> SliceLike for &'a S {
758    type Item = S::Item;
759    type IntoIter = S::IntoIter;
760
761    fn iter(self) -> Self::IntoIter {
762        (*self).iter()
763    }
764
765    fn as_slice(&self) -> &[Self::Item] {
766        (*self).as_slice()
767    }
768}
769
770pub trait Symbol<I>: Copy + Hash + PartialEq + Eq + Debug {
771    fn is_kw_underscore_lifetime(self) -> bool;
772}