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