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