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