chalk_solve/rust_ir.rs
1//! Contains the definition for the "Rust IR" -- this is basically a "lowered"
2//! version of the AST, roughly corresponding to [the HIR] in the Rust
3//! compiler.
4
5use chalk_derive::{HasInterner, TypeFoldable, TypeVisitable};
6use chalk_ir::cast::Cast;
7use chalk_ir::fold::shift::Shift;
8use chalk_ir::interner::Interner;
9use chalk_ir::{
10 try_break, visit::TypeVisitable, AdtId, AliasEq, AliasTy, AssocTypeId, Binders, DebruijnIndex,
11 FnDefId, GenericArg, ImplId, OpaqueTyId, ProjectionTy, QuantifiedWhereClause, Substitution,
12 ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind,
13};
14use std::iter;
15use std::ops::ControlFlow;
16
17/// Identifier for an "associated type value" found in some impl.
18#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct AssociatedTyValueId<I: Interner>(pub I::DefId);
20
21chalk_ir::id_visit!(AssociatedTyValueId);
22chalk_ir::id_fold!(AssociatedTyValueId);
23
24#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)]
25pub struct ImplDatum<I: Interner> {
26 pub polarity: Polarity,
27 pub binders: Binders<ImplDatumBound<I>>,
28 pub impl_type: ImplType,
29 pub associated_ty_value_ids: Vec<AssociatedTyValueId<I>>,
30}
31
32impl<I: Interner> ImplDatum<I> {
33 pub fn is_positive(&self) -> bool {
34 self.polarity.is_positive()
35 }
36
37 pub fn trait_id(&self) -> TraitId<I> {
38 self.binders.skip_binders().trait_ref.trait_id
39 }
40
41 pub fn self_type_adt_id(&self, interner: I) -> Option<AdtId<I>> {
42 match self
43 .binders
44 .skip_binders()
45 .trait_ref
46 .self_type_parameter(interner)
47 .kind(interner)
48 {
49 TyKind::Adt(id, _) => Some(*id),
50 _ => None,
51 }
52 }
53}
54
55#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, TypeFoldable, TypeVisitable)]
56pub struct ImplDatumBound<I: Interner> {
57 pub trait_ref: TraitRef<I>,
58 pub where_clauses: Vec<QuantifiedWhereClause<I>>,
59}
60
61#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
62pub enum ImplType {
63 Local,
64 External,
65}
66
67chalk_ir::const_visit!(ImplType);
68
69#[derive(Clone, Debug, PartialEq, Eq, Hash)]
70pub struct DefaultImplDatum<I: Interner> {
71 pub binders: Binders<DefaultImplDatumBound<I>>,
72}
73
74#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner)]
75pub struct DefaultImplDatumBound<I: Interner> {
76 pub trait_ref: TraitRef<I>,
77 pub accessible_tys: Vec<Ty<I>>,
78}
79
80#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)]
81pub struct AdtDatum<I: Interner> {
82 pub binders: Binders<AdtDatumBound<I>>,
83 pub id: AdtId<I>,
84 pub flags: AdtFlags,
85 pub kind: AdtKind,
86}
87
88#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
89pub enum AdtKind {
90 Struct,
91 Enum,
92 Union,
93}
94
95chalk_ir::const_visit!(AdtKind);
96
97#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
98pub struct AdtDatumBound<I: Interner> {
99 pub variants: Vec<AdtVariantDatum<I>>,
100 pub where_clauses: Vec<QuantifiedWhereClause<I>>,
101}
102
103#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
104pub struct AdtVariantDatum<I: Interner> {
105 pub fields: Vec<Ty<I>>,
106}
107
108#[derive(Clone, Debug, PartialEq, Eq, Hash)]
109pub struct AdtFlags {
110 pub upstream: bool,
111 pub fundamental: bool,
112 pub phantom_data: bool,
113}
114
115chalk_ir::const_visit!(AdtFlags);
116
117#[derive(Clone, Debug, PartialEq, Eq, Hash)]
118pub struct AdtRepr<I: Interner> {
119 pub c: bool,
120 pub packed: bool,
121 pub int: Option<chalk_ir::Ty<I>>,
122}
123
124/// Information about the size and alignment of an ADT.
125#[derive(Clone, Debug, PartialEq, Eq, Hash)]
126pub struct AdtSizeAlign {
127 one_zst: bool,
128}
129
130impl AdtSizeAlign {
131 pub fn from_one_zst(one_zst: bool) -> AdtSizeAlign {
132 AdtSizeAlign { one_zst }
133 }
134
135 pub fn one_zst(&self) -> bool {
136 self.one_zst
137 }
138}
139
140#[derive(Clone, Debug, PartialEq, Eq, Hash)]
141/// A rust intermediate representation (rust_ir) of a function definition/declaration.
142/// For example, in the following rust code:
143///
144/// ```ignore
145/// fn foo<T>() -> i32 where T: Eq;
146/// ```
147///
148/// This would represent the declaration of `foo`.
149///
150/// Note this is distinct from a function pointer, which points to
151/// a function with a given type signature, whereas this represents
152/// a specific function definition.
153pub struct FnDefDatum<I: Interner> {
154 pub id: FnDefId<I>,
155 pub sig: chalk_ir::FnSig<I>,
156 pub binders: Binders<FnDefDatumBound<I>>,
157}
158
159/// Avoids visiting `I::FnAbi`
160impl<I: Interner> TypeVisitable<I> for FnDefDatum<I> {
161 fn visit_with<B>(
162 &self,
163 visitor: &mut dyn chalk_ir::visit::TypeVisitor<I, BreakTy = B>,
164 outer_binder: DebruijnIndex,
165 ) -> ControlFlow<B> {
166 try_break!(self.id.visit_with(visitor, outer_binder));
167 self.binders.visit_with(visitor, outer_binder)
168 }
169}
170
171/// Represents the inputs and outputs on a `FnDefDatum`. This is split
172/// from the where clauses, since these can contain bound lifetimes.
173#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
174pub struct FnDefInputsAndOutputDatum<I: Interner> {
175 /// Types of the function's arguments
176 /// ```ignore
177 /// fn foo<T>(bar: i32, baz: T);
178 /// ^^^ ^
179 /// ```
180 ///
181 pub argument_types: Vec<Ty<I>>,
182 /// Return type of the function
183 /// ```ignore
184 /// fn foo<T>() -> i32;
185 /// ^^^
186 /// ```
187 pub return_type: Ty<I>,
188}
189
190#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
191/// Represents the bounds on a `FnDefDatum`, including
192/// the function definition's type signature and where clauses.
193pub struct FnDefDatumBound<I: Interner> {
194 /// Inputs and outputs defined on a function
195 /// These are needed for late-bound regions in rustc. For example the
196 /// lifetime `'a` in
197 /// ```ignore
198 /// fn foo<'a, T>(&'a T);
199 /// ^^
200 /// ```
201 /// Rustc doesn't pass in late-bound the regions in substs, but the inputs
202 /// and outputs may use them. `where_clauses` don't need an extra set of
203 /// `Binders`, since any lifetimes found in where clauses are not late-bound.
204 ///
205 /// For more information, see [this rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/early-late-bound.html).
206 pub inputs_and_output: Binders<FnDefInputsAndOutputDatum<I>>,
207
208 /// Where clauses defined on the function
209 /// ```ignore
210 /// fn foo<T>() where T: Eq;
211 /// ^^^^^^^^^^^
212 /// ```
213 pub where_clauses: Vec<QuantifiedWhereClause<I>>,
214}
215
216#[derive(Clone, Debug, PartialEq, Eq, Hash)]
217/// A rust intermediate representation (rust_ir) of a Trait Definition. For
218/// example, given the following rust code:
219///
220/// ```
221/// use std::fmt::Debug;
222///
223/// trait Foo<T>
224/// where
225/// T: Debug,
226/// {
227/// type Bar<U>;
228/// }
229/// ```
230///
231/// This would represent the `trait Foo` declaration. Note that the details of
232/// the trait members (e.g., the associated type declaration (`type Bar<U>`) are
233/// not contained in this type, and are represented separately (e.g., in
234/// [`AssociatedTyDatum`]).
235///
236/// Not to be confused with the rust_ir for a Trait Implementation, which is
237/// represented by [`ImplDatum`]
238///
239/// [`ImplDatum`]: struct.ImplDatum.html
240/// [`AssociatedTyDatum`]: struct.AssociatedTyDatum.html
241#[derive(TypeVisitable)]
242pub struct TraitDatum<I: Interner> {
243 pub id: TraitId<I>,
244
245 pub binders: Binders<TraitDatumBound<I>>,
246
247 /// "Flags" indicate special kinds of traits, like auto traits.
248 /// In Rust syntax these are represented in different ways, but in
249 /// chalk we add annotations like `#[auto]`.
250 pub flags: TraitFlags,
251
252 pub associated_ty_ids: Vec<AssocTypeId<I>>,
253
254 /// If this is a well-known trait, which one? If `None`, this is a regular,
255 /// user-defined trait.
256 pub well_known: Option<WellKnownTrait>,
257}
258
259/// A list of the traits that are "well known" to chalk, which means that
260/// the chalk-solve crate has special, hard-coded impls for them.
261#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
262pub enum WellKnownTrait {
263 Sized,
264 Copy,
265 Clone,
266 Drop,
267 /// The trait `FnOnce<Args>` - the generic argument `Args` is always a tuple
268 /// corresponding to the arguments of a function implementing this trait.
269 /// E.g. `fn(u8, bool): FnOnce<(u8, bool)>`
270 FnOnce,
271 FnMut,
272 Fn,
273 AsyncFnOnce,
274 AsyncFnMut,
275 AsyncFn,
276 Unsize,
277 Unpin,
278 CoerceUnsized,
279 DiscriminantKind,
280 Coroutine,
281 DispatchFromDyn,
282 Tuple,
283 Pointee,
284 FnPtr,
285 Future,
286}
287
288chalk_ir::const_visit!(WellKnownTrait);
289
290/// A list of the associated types that are "well known" to chalk, which means that
291/// the chalk-solve crate has special, hard-coded impls for them.
292#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
293pub enum WellKnownAssocType {
294 AsyncFnOnceOutput,
295}
296
297chalk_ir::const_visit!(WellKnownAssocType);
298
299impl<I: Interner> TraitDatum<I> {
300 pub fn is_auto_trait(&self) -> bool {
301 self.flags.auto
302 }
303
304 pub fn is_non_enumerable_trait(&self) -> bool {
305 self.flags.non_enumerable
306 }
307
308 pub fn is_coinductive_trait(&self) -> bool {
309 self.flags.coinductive
310 }
311
312 /// Gives access to the where clauses of the trait, quantified over the type parameters of the trait:
313 ///
314 /// ```ignore
315 /// trait Foo<T> where T: Debug { }
316 /// ^^^^^^^^^^^^^^
317 /// ```
318 pub fn where_clauses(&self) -> Binders<&Vec<QuantifiedWhereClause<I>>> {
319 self.binders.as_ref().map(|td| &td.where_clauses)
320 }
321}
322
323#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, TypeVisitable)]
324pub struct TraitDatumBound<I: Interner> {
325 /// Where clauses defined on the trait:
326 ///
327 /// ```ignore
328 /// trait Foo<T> where T: Debug { }
329 /// ^^^^^^^^^^^^^^
330 /// ```
331 pub where_clauses: Vec<QuantifiedWhereClause<I>>,
332}
333
334#[derive(Clone, Debug, PartialEq, Eq, Hash)]
335pub struct TraitFlags {
336 /// An "auto trait" is one that is "automatically implemented" for every
337 /// struct, so long as no explicit impl is given.
338 ///
339 /// Examples are `Send` and `Sync`.
340 pub auto: bool,
341
342 pub marker: bool,
343
344 /// Indicate that a trait is defined upstream (in a dependency), used during
345 /// coherence checking.
346 pub upstream: bool,
347
348 /// A fundamental trait is a trait where adding an impl for an existing type
349 /// is considered a breaking change. Examples of fundamental traits are the
350 /// closure traits like `Fn` and `FnMut`.
351 ///
352 /// As of this writing (2020-03-27), fundamental traits are declared by the
353 /// unstable `#[fundamental]` attribute in rustc, and hence cannot appear
354 /// outside of the standard library.
355 pub fundamental: bool,
356
357 /// Indicates that chalk cannot list all of the implementations of the given
358 /// trait, likely because it is a publicly exported trait in a library.
359 ///
360 /// Currently (2020-03-27) rustc and rust-analyzer mark all traits as
361 /// non_enumerable, and in the future it may become the only option.
362 pub non_enumerable: bool,
363
364 pub coinductive: bool,
365}
366
367chalk_ir::const_visit!(TraitFlags);
368
369/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
370#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
371pub enum InlineBound<I: Interner> {
372 TraitBound(TraitBound<I>),
373 AliasEqBound(AliasEqBound<I>),
374}
375
376#[allow(type_alias_bounds)]
377pub type QuantifiedInlineBound<I: Interner> = Binders<InlineBound<I>>;
378
379pub trait IntoWhereClauses<I: Interner> {
380 type Output;
381
382 fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<Self::Output>;
383}
384
385impl<I: Interner> IntoWhereClauses<I> for InlineBound<I> {
386 type Output = WhereClause<I>;
387
388 /// Applies the `InlineBound` to `self_ty` and lowers to a
389 /// [`chalk_ir::DomainGoal`].
390 ///
391 /// Because an `InlineBound` does not know anything about what it's binding,
392 /// you must provide that type as `self_ty`.
393 fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
394 match self {
395 InlineBound::TraitBound(b) => b.into_where_clauses(interner, self_ty),
396 InlineBound::AliasEqBound(b) => b.into_where_clauses(interner, self_ty),
397 }
398 }
399}
400
401impl<I: Interner> IntoWhereClauses<I> for QuantifiedInlineBound<I> {
402 type Output = QuantifiedWhereClause<I>;
403
404 fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<QuantifiedWhereClause<I>> {
405 let self_ty = self_ty.shifted_in(interner);
406 self.map_ref(|b| b.into_where_clauses(interner, self_ty))
407 .into_iter()
408 .collect()
409 }
410}
411
412/// Represents a trait bound on e.g. a type or type parameter.
413/// Does not know anything about what it's binding.
414#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
415pub struct TraitBound<I: Interner> {
416 pub trait_id: TraitId<I>,
417 pub args_no_self: Vec<GenericArg<I>>,
418}
419
420impl<I: Interner> TraitBound<I> {
421 fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
422 let trait_ref = self.as_trait_ref(interner, self_ty);
423 vec![WhereClause::Implemented(trait_ref)]
424 }
425
426 pub fn as_trait_ref(&self, interner: I, self_ty: Ty<I>) -> TraitRef<I> {
427 TraitRef {
428 trait_id: self.trait_id,
429 substitution: Substitution::from_iter(
430 interner,
431 iter::once(self_ty.cast(interner)).chain(self.args_no_self.iter().cloned()),
432 ),
433 }
434 }
435}
436
437/// Represents an alias equality bound on e.g. a type or type parameter.
438/// Does not know anything about what it's binding.
439#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
440pub struct AliasEqBound<I: Interner> {
441 pub trait_bound: TraitBound<I>,
442 pub associated_ty_id: AssocTypeId<I>,
443 /// Does not include trait parameters.
444 pub parameters: Vec<GenericArg<I>>,
445 pub value: Ty<I>,
446}
447
448impl<I: Interner> AliasEqBound<I> {
449 fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
450 let trait_ref = self.trait_bound.as_trait_ref(interner, self_ty);
451
452 let substitution = Substitution::from_iter(
453 interner,
454 trait_ref
455 .substitution
456 .iter(interner)
457 .cloned()
458 .chain(self.parameters.iter().cloned()),
459 );
460
461 vec![
462 WhereClause::Implemented(trait_ref),
463 WhereClause::AliasEq(AliasEq {
464 alias: AliasTy::Projection(ProjectionTy {
465 associated_ty_id: self.associated_ty_id,
466 substitution,
467 }),
468 ty: self.value.clone(),
469 }),
470 ]
471 }
472}
473
474pub trait Anonymize<I: Interner> {
475 /// Utility function that converts from a list of generic arguments
476 /// which *have* associated data (`WithKind<I, T>`) to a list of
477 /// "anonymous" generic parameters that just preserves their
478 /// kinds (`VariableKind<I>`). Often convenient in lowering.
479 fn anonymize(&self) -> Vec<VariableKind<I>>;
480}
481
482impl<I: Interner, T> Anonymize<I> for [WithKind<I, T>] {
483 fn anonymize(&self) -> Vec<VariableKind<I>> {
484 self.iter().map(|pk| pk.kind.clone()).collect()
485 }
486}
487
488/// Represents an associated type declaration found inside of a trait:
489///
490/// ```notrust
491/// trait Foo<P1..Pn> { // P0 is Self
492/// type Bar<Pn..Pm>: [bounds]
493/// where
494/// [where_clauses];
495/// }
496/// ```
497///
498/// The meaning of each of these parts:
499///
500/// * The *parameters* `P0...Pm` are all in scope for this associated type.
501/// * The *bounds* `bounds` are things that the impl must prove to be true.
502/// * The *where clauses* `where_clauses` are things that the impl can *assume* to be true
503/// (but which projectors must prove).
504#[derive(Clone, Debug, PartialEq, Eq, Hash)]
505pub struct AssociatedTyDatum<I: Interner> {
506 /// The trait this associated type is defined in.
507 pub trait_id: TraitId<I>,
508
509 /// The ID of this associated type
510 pub id: AssocTypeId<I>,
511
512 /// Name of this associated type.
513 pub name: I::Identifier,
514
515 /// These binders represent the `P0...Pm` variables. The binders
516 /// are in the order `[Pn..Pm; P0..Pn]`. That is, the variables
517 /// from `Bar` come first (corresponding to the de bruijn concept
518 /// that "inner" binders are lower indices, although within a
519 /// given binder we do not have an ordering).
520 pub binders: Binders<AssociatedTyDatumBound<I>>,
521}
522
523// Manual implementation to avoid I::Identifier type.
524impl<I: Interner> TypeVisitable<I> for AssociatedTyDatum<I> {
525 fn visit_with<B>(
526 &self,
527 visitor: &mut dyn chalk_ir::visit::TypeVisitor<I, BreakTy = B>,
528 outer_binder: DebruijnIndex,
529 ) -> ControlFlow<B> {
530 try_break!(self.trait_id.visit_with(visitor, outer_binder));
531 try_break!(self.id.visit_with(visitor, outer_binder));
532 self.binders.visit_with(visitor, outer_binder)
533 }
534}
535
536/// Encodes the parts of `AssociatedTyDatum` where the parameters
537/// `P0..Pm` are in scope (`bounds` and `where_clauses`).
538#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
539pub struct AssociatedTyDatumBound<I: Interner> {
540 /// Bounds on the associated type itself.
541 ///
542 /// These must be proven by the implementer, for all possible parameters that
543 /// would result in a well-formed projection.
544 pub bounds: Vec<QuantifiedInlineBound<I>>,
545
546 /// Where clauses that must hold for the projection to be well-formed.
547 pub where_clauses: Vec<QuantifiedWhereClause<I>>,
548}
549
550impl<I: Interner> AssociatedTyDatum<I> {
551 /// Returns the associated ty's bounds applied to the projection type, e.g.:
552 ///
553 /// ```notrust
554 /// Implemented(<?0 as Foo>::Item<?1>: Sized)
555 /// ```
556 ///
557 /// these quantified where clauses are in the scope of the
558 /// `binders` field.
559 pub fn bounds_on_self(&self, interner: I) -> Vec<QuantifiedWhereClause<I>> {
560 let (binders, assoc_ty_datum) = self.binders.as_ref().into();
561 // Create a list `P0...Pn` of references to the binders in
562 // scope for this associated type:
563 let substitution = Substitution::from_iter(
564 interner,
565 binders
566 .iter(interner)
567 .enumerate()
568 .map(|p| p.to_generic_arg(interner)),
569 );
570
571 // The self type will be `<P0 as Foo<P1..Pn>>::Item<Pn..Pm>` etc
572 let self_ty = TyKind::Alias(AliasTy::Projection(ProjectionTy {
573 associated_ty_id: self.id,
574 substitution,
575 }))
576 .intern(interner);
577
578 // Now use that as the self type for the bounds, transforming
579 // something like `type Bar<Pn..Pm>: Debug` into
580 //
581 // ```
582 // <P0 as Foo<P1..Pn>>::Item<Pn..Pm>: Debug
583 // ```
584 assoc_ty_datum
585 .bounds
586 .iter()
587 .flat_map(|b| b.into_where_clauses(interner, self_ty.clone()))
588 .collect()
589 }
590}
591
592/// Represents the *value* of an associated type that is assigned
593/// from within some impl.
594///
595/// ```ignore
596/// impl Iterator for Foo {
597/// type Item = XXX; // <-- represents this line!
598/// }
599/// ```
600#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
601pub struct AssociatedTyValue<I: Interner> {
602 /// Impl in which this associated type value is found. You might
603 /// need to look at this to find the generic parameters defined on
604 /// the impl, for example.
605 ///
606 /// ```ignore
607 /// impl Iterator for Foo { // <-- refers to this impl
608 /// type Item = XXX; // <-- (where this is self)
609 /// }
610 /// ```
611 pub impl_id: ImplId<I>,
612
613 /// Associated type being defined.
614 ///
615 /// ```ignore
616 /// impl Iterator for Foo {
617 /// type Item = XXX; // <-- (where this is self)
618 /// }
619 /// ...
620 /// trait Iterator {
621 /// type Item; // <-- refers to this declaration here!
622 /// }
623 /// ```
624 pub associated_ty_id: AssocTypeId<I>,
625
626 /// Additional binders declared on the associated type itself,
627 /// beyond those from the impl. This would be empty for normal
628 /// associated types, but non-empty for generic associated types.
629 ///
630 /// ```ignore
631 /// impl<T> Iterable for Vec<T> {
632 /// type Iter<'a> = vec::Iter<'a, T>;
633 /// // ^^^^ refers to these generics here
634 /// }
635 /// ```
636 pub value: Binders<AssociatedTyValueBound<I>>,
637}
638
639#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
640pub struct AssociatedTyValueBound<I: Interner> {
641 /// Type that we normalize to. The X in `type Foo<'a> = X`.
642 pub ty: Ty<I>,
643}
644
645/// Represents the bounds for an `impl Trait` type.
646///
647/// ```ignore
648/// opaque type T: A + B = HiddenTy;
649/// ```
650#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
651pub struct OpaqueTyDatum<I: Interner> {
652 /// The placeholder `!T` that corresponds to the opaque type `T`.
653 pub opaque_ty_id: OpaqueTyId<I>,
654
655 /// The type bound to when revealed.
656 pub bound: Binders<OpaqueTyDatumBound<I>>,
657}
658
659#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
660pub struct OpaqueTyDatumBound<I: Interner> {
661 /// Trait bounds for the opaque type. These are bounds that the hidden type must meet.
662 pub bounds: Binders<Vec<QuantifiedWhereClause<I>>>,
663 /// Where clauses that inform well-formedness conditions for the opaque type.
664 /// These are conditions on the generic parameters of the opaque type which must be true
665 /// for a reference to the opaque type to be well-formed.
666 pub where_clauses: Binders<Vec<QuantifiedWhereClause<I>>>,
667}
668
669// The movability of a coroutine: whether a coroutine contains self-references,
670// causing it to be !Unpin
671#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
672pub enum Movability {
673 Static,
674 Movable,
675}
676chalk_ir::copy_fold!(Movability);
677
678/// Represents a coroutine type.
679#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
680pub struct CoroutineDatum<I: Interner> {
681 // Can the coroutine be moved (is Unpin or not)
682 pub movability: Movability,
683 /// All of the nested types for this coroutine. The `Binder`
684 /// represents the types and lifetimes that this coroutine is generic over -
685 /// this behaves in the same way as `AdtDatum.binders`
686 pub input_output: Binders<CoroutineInputOutputDatum<I>>,
687}
688
689/// The nested types for a coroutine. This always appears inside a `CoroutineDatum`
690#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
691pub struct CoroutineInputOutputDatum<I: Interner> {
692 /// The coroutine resume type - a value of this type
693 /// is supplied by the caller when resuming the coroutine.
694 /// Currently, this plays no rule in goal resolution.
695 pub resume_type: Ty<I>,
696 /// The coroutine yield type - a value of this type
697 /// is supplied by the coroutine during a yield.
698 /// Currently, this plays no role in goal resolution.
699 pub yield_type: Ty<I>,
700 /// The coroutine return type - a value of this type
701 /// is supplied by the coroutine when it returns.
702 /// Currently, this plays no role in goal resolution
703 pub return_type: Ty<I>,
704 /// The upvars stored by the coroutine. These represent
705 /// types captured from the coroutine's environment,
706 /// and are stored across all yields. These types (along with the witness types)
707 /// are considered 'constituent types' for the purposes of determining auto trait
708 /// implementations - that its, a coroutine impls an auto trait A
709 /// iff all of its constituent types implement A.
710 pub upvars: Vec<Ty<I>>,
711}
712
713/// The coroutine witness data. Each `CoroutineId` has both a `CoroutineDatum`
714/// and a `CoroutineWitnessDatum` - these represent two distinct types in Rust.
715/// `CoroutineWitnessDatum` is logically 'inside' a coroutine - this only
716/// matters when we treat the witness type as a 'constituent type for the
717/// purposes of determining auto trait implementations.
718#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
719pub struct CoroutineWitnessDatum<I: Interner> {
720 /// This binder is identical to the `input_output` binder in `CoroutineWitness` -
721 /// it binds the types and lifetimes that the coroutine is generic over.
722 /// There is an additional binder inside `CoroutineWitnessExistential`, which
723 /// is treated specially.
724 pub inner_types: Binders<CoroutineWitnessExistential<I>>,
725}
726
727/// The coroutine witness types, together with existentially bound lifetimes.
728/// Each 'witness type' represents a type stored inside the coroutine across
729/// a yield. When a coroutine type is constructed, the precise region relationships
730/// found in the coroutine body are erased. As a result, we are left with existential
731/// lifetimes - each type is parameterized over *some* lifetimes, but we do not
732/// know their precise values.
733///
734/// Unlike the binder in `CoroutineWitnessDatum`, this `Binder` never gets substituted
735/// via an `Ty`. Instead, we handle this `Binders` specially when determining
736/// auto trait impls. See `push_auto_trait_impls_coroutine_witness` for more details.
737#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
738pub struct CoroutineWitnessExistential<I: Interner> {
739 pub types: Binders<Vec<Ty<I>>>,
740}
741
742#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
743pub enum Polarity {
744 Positive,
745 Negative,
746}
747
748chalk_ir::const_visit!(Polarity);
749
750impl Polarity {
751 pub fn is_positive(&self) -> bool {
752 match *self {
753 Polarity::Positive => true,
754 Polarity::Negative => false,
755 }
756 }
757}
758
759/// Indicates the "most permissive" Fn-like trait that the closure implements.
760/// If the closure kind for a closure is FnMut, for example, then the closure
761/// implements FnMut and FnOnce.
762#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
763pub enum ClosureKind {
764 Fn,
765 FnMut,
766 FnOnce,
767}