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