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