1use 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 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 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 ValTree<I: Interner<ValTree = Self>>: Copy + Debug + Hash + Eq {
297 fn kind(&self) -> &ty::ValTreeKind<I>;
299}
300
301pub trait ExprConst<I: Interner<ExprConst = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
302 fn args(self) -> I::GenericArgs;
303}
304
305pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
306 fn count(&self) -> usize;
307}
308
309pub trait GenericArg<I: Interner<GenericArg = Self>>:
310 Copy
311 + Debug
312 + Hash
313 + Eq
314 + IntoKind<Kind = ty::GenericArgKind<I>>
315 + TypeVisitable<I>
316 + Relate<I>
317 + From<I::Ty>
318 + From<I::Region>
319 + From<I::Const>
320 + From<I::Term>
321{
322 fn as_term(&self) -> Option<I::Term> {
323 match self.kind() {
324 ty::GenericArgKind::Lifetime(_) => None,
325 ty::GenericArgKind::Type(ty) => Some(ty.into()),
326 ty::GenericArgKind::Const(ct) => Some(ct.into()),
327 }
328 }
329
330 fn as_type(&self) -> Option<I::Ty> {
331 if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None }
332 }
333
334 fn expect_ty(&self) -> I::Ty {
335 self.as_type().expect("expected a type")
336 }
337
338 fn as_const(&self) -> Option<I::Const> {
339 if let ty::GenericArgKind::Const(c) = self.kind() { Some(c) } else { None }
340 }
341
342 fn expect_const(&self) -> I::Const {
343 self.as_const().expect("expected a const")
344 }
345
346 fn as_region(&self) -> Option<I::Region> {
347 if let ty::GenericArgKind::Lifetime(c) = self.kind() { Some(c) } else { None }
348 }
349
350 fn expect_region(&self) -> I::Region {
351 self.as_region().expect("expected a const")
352 }
353
354 fn is_non_region_infer(self) -> bool {
355 match self.kind() {
356 ty::GenericArgKind::Lifetime(_) => false,
357 ty::GenericArgKind::Type(ty) => ty.is_ty_var(),
358 ty::GenericArgKind::Const(ct) => ct.is_ct_var(),
359 }
360 }
361}
362
363pub trait Term<I: Interner<Term = Self>>:
364 Copy + Debug + Hash + Eq + IntoKind<Kind = ty::TermKind<I>> + TypeFoldable<I> + Relate<I>
365{
366 fn as_type(&self) -> Option<I::Ty> {
367 if let ty::TermKind::Ty(ty) = self.kind() { Some(ty) } else { None }
368 }
369
370 fn expect_ty(&self) -> I::Ty {
371 self.as_type().expect("expected a type, but found a const")
372 }
373
374 fn as_const(&self) -> Option<I::Const> {
375 if let ty::TermKind::Const(c) = self.kind() { Some(c) } else { None }
376 }
377
378 fn expect_const(&self) -> I::Const {
379 self.as_const().expect("expected a const, but found a type")
380 }
381
382 fn is_infer(self) -> bool {
383 match self.kind() {
384 ty::TermKind::Ty(ty) => ty.is_ty_var(),
385 ty::TermKind::Const(ct) => ct.is_ct_var(),
386 }
387 }
388
389 fn is_error(self) -> bool {
390 match self.kind() {
391 ty::TermKind::Ty(ty) => ty.is_ty_error(),
392 ty::TermKind::Const(ct) => ct.is_ct_error(),
393 }
394 }
395
396 fn to_alias_term(self) -> Option<ty::AliasTerm<I>> {
397 match self.kind() {
398 ty::TermKind::Ty(ty) => match ty.kind() {
399 ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
400 _ => None,
401 },
402 ty::TermKind::Const(ct) => match ct.kind() {
403 ty::ConstKind::Unevaluated(uv) => Some(uv.into()),
404 _ => None,
405 },
406 }
407 }
408}
409
410pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
411 Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
412{
413 fn rebase_onto(
414 self,
415 interner: I,
416 source_def_id: I::DefId,
417 target: I::GenericArgs,
418 ) -> I::GenericArgs;
419
420 fn type_at(self, i: usize) -> I::Ty;
421
422 fn region_at(self, i: usize) -> I::Region;
423
424 fn const_at(self, i: usize) -> I::Const;
425
426 fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
427
428 fn extend_with_error(
429 interner: I,
430 def_id: I::DefId,
431 original_args: &[I::GenericArg],
432 ) -> I::GenericArgs;
433
434 fn split_closure_args(self) -> ty::ClosureArgsParts<I>;
435 fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<I>;
436 fn split_coroutine_args(self) -> ty::CoroutineArgsParts<I>;
437
438 fn as_closure(self) -> ty::ClosureArgs<I> {
439 ty::ClosureArgs { args: self }
440 }
441 fn as_coroutine_closure(self) -> ty::CoroutineClosureArgs<I> {
442 ty::CoroutineClosureArgs { args: self }
443 }
444 fn as_coroutine(self) -> ty::CoroutineArgs<I> {
445 ty::CoroutineArgs { args: self }
446 }
447}
448
449pub trait Predicate<I: Interner<Predicate = Self>>:
450 Copy
451 + Debug
452 + Hash
453 + Eq
454 + TypeSuperVisitable<I>
455 + TypeSuperFoldable<I>
456 + Flags
457 + UpcastFrom<I, ty::PredicateKind<I>>
458 + UpcastFrom<I, ty::Binder<I, ty::PredicateKind<I>>>
459 + UpcastFrom<I, ty::ClauseKind<I>>
460 + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
461 + UpcastFrom<I, I::Clause>
462 + UpcastFrom<I, ty::NormalizesTo<I>>
463 + UpcastFrom<I, ty::TraitRef<I>>
464 + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
465 + UpcastFrom<I, ty::TraitPredicate<I>>
466 + UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>>
467 + UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>>
468 + IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>>
469 + Elaboratable<I>
470{
471 fn as_clause(self) -> Option<I::Clause>;
472
473 fn as_normalizes_to(self) -> Option<ty::Binder<I, ty::NormalizesTo<I>>> {
474 let kind = self.kind();
475 match kind.skip_binder() {
476 ty::PredicateKind::NormalizesTo(pred) => Some(kind.rebind(pred)),
477 _ => None,
478 }
479 }
480
481 fn allow_normalization(self) -> bool;
483}
484
485pub trait Clause<I: Interner<Clause = Self>>:
486 Copy
487 + Debug
488 + Hash
489 + Eq
490 + TypeFoldable<I>
491 + UpcastFrom<I, ty::Binder<I, ty::ClauseKind<I>>>
492 + UpcastFrom<I, ty::TraitRef<I>>
493 + UpcastFrom<I, ty::Binder<I, ty::TraitRef<I>>>
494 + UpcastFrom<I, ty::TraitPredicate<I>>
495 + UpcastFrom<I, ty::Binder<I, ty::TraitPredicate<I>>>
496 + UpcastFrom<I, ty::ProjectionPredicate<I>>
497 + UpcastFrom<I, ty::Binder<I, ty::ProjectionPredicate<I>>>
498 + IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
499 + Elaboratable<I>
500{
501 fn as_predicate(self) -> I::Predicate;
502
503 fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
504 self.kind()
505 .map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
506 .transpose()
507 }
508
509 fn as_host_effect_clause(self) -> Option<ty::Binder<I, ty::HostEffectPredicate<I>>> {
510 self.kind()
511 .map_bound(
512 |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None },
513 )
514 .transpose()
515 }
516
517 fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
518 self.kind()
519 .map_bound(
520 |clause| {
521 if let ty::ClauseKind::Projection(p) = clause { Some(p) } else { None }
522 },
523 )
524 .transpose()
525 }
526
527 fn instantiate_supertrait(self, cx: I, trait_ref: ty::Binder<I, ty::TraitRef<I>>) -> Self;
532}
533
534pub trait Clauses<I: Interner<Clauses = Self>>:
535 Copy
536 + Debug
537 + Hash
538 + Eq
539 + TypeSuperVisitable<I>
540 + TypeSuperFoldable<I>
541 + Flags
542 + SliceLike<Item = I::Clause>
543{
544}
545
546pub trait PlaceholderLike<I: Interner>: Copy + Debug + Hash + Eq {
548 fn universe(self) -> ty::UniverseIndex;
549 fn var(self) -> ty::BoundVar;
550
551 type Bound: BoundVarLike<I>;
552 fn new(ui: ty::UniverseIndex, bound: Self::Bound) -> Self;
553 fn new_anon(ui: ty::UniverseIndex, var: ty::BoundVar) -> Self;
554 fn with_updated_universe(self, ui: ty::UniverseIndex) -> Self;
555}
556
557pub trait PlaceholderConst<I: Interner>: PlaceholderLike<I, Bound = I::BoundConst> {
558 fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty;
559}
560impl<I: Interner> PlaceholderConst<I> for I::PlaceholderConst {
561 fn find_const_ty_from_env(self, env: I::ParamEnv) -> I::Ty {
562 let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
563 match clause.kind().skip_binder() {
565 ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
566 assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
567
568 match placeholder_ct.kind() {
569 ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
570 Some(ty)
571 }
572 _ => None,
573 }
574 }
575 _ => None,
576 }
577 });
578
579 let ty = candidates.next().unwrap_or_else(|| {
586 panic!("cannot find `{self:?}` in param-env: {env:#?}");
587 });
588 assert!(
589 candidates.next().is_none(),
590 "did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}"
591 );
592 ty
593 }
594}
595
596pub trait IntoKind {
597 type Kind;
598
599 fn kind(self) -> Self::Kind;
600}
601
602pub trait BoundVarLike<I: Interner>: Copy + Debug + Hash + Eq {
603 fn var(self) -> ty::BoundVar;
604
605 fn assert_eq(self, var: I::BoundVarKind);
606}
607
608pub trait ParamLike: Copy + Debug + Hash + Eq {
609 fn index(self) -> u32;
610}
611
612pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
613 fn def_id(self) -> I::AdtId;
614
615 fn is_struct(self) -> bool;
616
617 fn struct_tail_ty(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>;
621
622 fn is_phantom_data(self) -> bool;
623
624 fn is_manually_drop(self) -> bool;
625
626 fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>;
628
629 fn sizedness_constraint(
630 self,
631 interner: I,
632 sizedness: SizedTraitKind,
633 ) -> Option<ty::EarlyBinder<I, I::Ty>>;
634
635 fn is_fundamental(self) -> bool;
636
637 fn destructor(self, interner: I) -> Option<AdtDestructorKind>;
638}
639
640pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
641 fn caller_bounds(self) -> impl SliceLike<Item = I::Clause>;
642}
643
644pub trait Features<I: Interner>: Copy {
645 fn generic_const_exprs(self) -> bool;
646
647 fn coroutine_clone(self) -> bool;
648
649 fn associated_const_equality(self) -> bool;
650
651 fn feature_bound_holds_in_crate(self, symbol: I::Symbol) -> bool;
652}
653
654pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
655 fn is_local(self) -> bool;
656
657 fn as_local(self) -> Option<I::LocalDefId>;
658}
659
660pub trait SpecificDefId<I: Interner>:
661 DefId<I> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>
662{
663}
664
665impl<I: Interner, T: DefId<I> + Into<I::DefId> + TryFrom<I::DefId, Error: std::fmt::Debug>>
666 SpecificDefId<I> for T
667{
668}
669
670pub trait BoundExistentialPredicates<I: Interner>:
671 Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
672{
673 fn principal_def_id(self) -> Option<I::TraitId>;
674
675 fn principal(self) -> Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>;
676
677 fn auto_traits(self) -> impl IntoIterator<Item = I::TraitId>;
678
679 fn projection_bounds(
680 self,
681 ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
682}
683
684pub trait Span<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
685 fn dummy() -> Self;
686}
687
688pub trait OpaqueTypeStorageEntries: Debug + Copy + Default {
689 fn needs_reevaluation(self, canonicalized: usize) -> bool;
693}
694
695pub trait SliceLike: Sized + Copy {
696 type Item: Copy;
697 type IntoIter: Iterator<Item = Self::Item> + DoubleEndedIterator;
698
699 fn iter(self) -> Self::IntoIter;
700
701 fn as_slice(&self) -> &[Self::Item];
702
703 fn get(self, idx: usize) -> Option<Self::Item> {
704 self.as_slice().get(idx).copied()
705 }
706
707 fn len(self) -> usize {
708 self.as_slice().len()
709 }
710
711 fn is_empty(self) -> bool {
712 self.len() == 0
713 }
714
715 fn contains(self, t: &Self::Item) -> bool
716 where
717 Self::Item: PartialEq,
718 {
719 self.as_slice().contains(t)
720 }
721
722 fn to_vec(self) -> Vec<Self::Item> {
723 self.as_slice().to_vec()
724 }
725
726 fn last(self) -> Option<Self::Item> {
727 self.as_slice().last().copied()
728 }
729
730 fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
731 self.as_slice().split_last()
732 }
733}
734
735impl<'a, T: Copy> SliceLike for &'a [T] {
736 type Item = T;
737 type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
738
739 fn iter(self) -> Self::IntoIter {
740 self.iter().copied()
741 }
742
743 fn as_slice(&self) -> &[Self::Item] {
744 *self
745 }
746}
747
748impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
749 type Item = T;
750 type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
751
752 fn iter(self) -> Self::IntoIter {
753 self.into_iter().copied()
754 }
755
756 fn as_slice(&self) -> &[Self::Item] {
757 *self
758 }
759}
760
761impl<'a, S: SliceLike> SliceLike for &'a S {
762 type Item = S::Item;
763 type IntoIter = S::IntoIter;
764
765 fn iter(self) -> Self::IntoIter {
766 (*self).iter()
767 }
768
769 fn as_slice(&self) -> &[Self::Item] {
770 (*self).as_slice()
771 }
772}