]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-solve/src/display/bounds.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / chalk-solve / src / display / bounds.rs
CommitLineData
3dfed10e
XL
1//! Writer logic for `where` clauses and other bounds.
2//!
3//! Contains logic for writing the various forms of `Foo: Bar`.
4use std::fmt::{Display, Formatter, Result};
5
6use crate::rust_ir::*;
7use chalk_ir::{interner::Interner, *};
8use itertools::Itertools;
9
10use super::{
11 display_trait_with_assoc_ty_value, display_type_with_generics, render_trait::RenderAsRust,
12 state::InternalWriterState,
13};
14use crate::split::Split;
15
16impl<I: Interner> RenderAsRust<I> for InlineBound<I> {
17 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
18 match self {
19 // Foo: Vec<T>
20 InlineBound::TraitBound(trait_bound) => trait_bound.fmt(s, f),
21 // Foo: Iterator<Item=Foo>
22 InlineBound::AliasEqBound(eq_bound) => eq_bound.fmt(s, f),
23 }
24 }
25}
26
27impl<I: Interner> RenderAsRust<I> for TraitBound<I> {
28 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
29 display_type_with_generics(s, self.trait_id, &self.args_no_self).fmt(f)
30 }
31}
32
33impl<I: Interner> RenderAsRust<I> for AliasEqBound<I> {
34 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
35 display_trait_with_assoc_ty_value(
36 s,
37 s.db().associated_ty_data(self.associated_ty_id),
38 &self.trait_bound.args_no_self,
39 &self.parameters,
40 &self.value,
41 )
42 .fmt(f)
43 }
44}
45
46impl<I: Interner> RenderAsRust<I> for QuantifiedWhereClause<I> {
47 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
48 let interner = s.db().interner();
49 let s = &s.add_debrujin_index(None);
50 if !self.binders.is_empty(interner) {
51 write!(
52 f,
53 "forall<{}> ",
54 s.binder_var_display(&self.binders).format(", ")
55 )?;
56 }
57 self.skip_binders().fmt(s, f)
58 }
59}
60
61impl<I: Interner> RenderAsRust<I> for QuantifiedInlineBound<I> {
62 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
63 let interner = s.db().interner();
64 let s = &s.add_debrujin_index(None);
65 if !self.binders.is_empty(&interner) {
66 write!(
67 f,
68 "forall<{}> ",
69 s.binder_var_display(&self.binders).format(", ")
70 )?;
71 }
72 self.skip_binders().fmt(s, f)
73 }
74}
75
76impl<I: Interner> RenderAsRust<I> for Vec<QuantifiedWhereClause<I>> {
77 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
78 write!(
79 f,
80 "{}",
81 self.iter()
82 .map(|where_clause| { format!("{}{}", s.indent(), where_clause.display(s)) })
83 .format(",\n")
84 )?;
85 Ok(())
86 }
87}
88
89impl<I: Interner> RenderAsRust<I> for WhereClause<I> {
90 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
91 match self {
92 WhereClause::Implemented(trait_ref) => trait_ref.fmt(s, f),
93 WhereClause::AliasEq(alias_eq) => alias_eq.fmt(s, f),
94 WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f),
95 WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f),
96 }
97 }
98}
99
100/// This renders `TraitRef` as a clause in a where clause, as opposed to its
101/// usage in other places.
102impl<I: Interner> RenderAsRust<I> for TraitRef<I> {
103 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
104 let interner = s.db().interner();
105 write!(
106 f,
107 "{}: {}",
108 self.self_type_parameter(interner).display(s),
109 display_type_with_generics(
110 s,
111 self.trait_id,
112 &self.substitution.as_slice(interner)[1..]
113 )
114 )
115 }
116}
117
118/// This renders `AliasEq` as a clause in a where clause, as opposed to its
119/// usage in other places.
120impl<I: Interner> RenderAsRust<I> for AliasEq<I> {
121 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
122 // we have: X: Y<A1, A2, A3, Z<B1, B2, B3>=D>
123 // B1, B2, B3, X, A1, A2, A3 are put into alias_eq.alias.substitution
124 // D is alias_eq.ty
125 // Z is alias_eq.alias.associated_ty_id
126 // Y is also packed into alias_eq.alias.associated_ty_id
127 // Now, we split out A*, Y/Z and B*:
128 // trait_params is X, A1, A2, A3,
129 // assoc_type_params is B1, B2, B3,
130 // assoc_ty_datum stores info about Y and Z.
131 match &self.alias {
132 AliasTy::Projection(projection_ty) => {
133 let (assoc_ty_datum, trait_params, assoc_type_params) =
134 s.db().split_projection(&projection_ty);
135 // An alternate form might be `<{} as {}<{}>>::{}<{}> = {}` (with same
136 // parameter ordering). This alternate form would require type equality
137 // constraints (https://github.com/rust-lang/rust/issues/20041).
138 write!(
139 f,
140 "{}: {}",
141 trait_params[0].display(s),
142 display_trait_with_assoc_ty_value(
143 s,
144 assoc_ty_datum,
145 &trait_params[1..],
146 assoc_type_params,
147 &self.ty
148 ),
149 )
150 }
151 AliasTy::Opaque(_) => todo!("opaque types"),
152 }
153 }
154}
155
156impl<I: Interner> RenderAsRust<I> for LifetimeOutlives<I> {
157 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
158 // a': 'b
159 write!(f, "{}: {}", self.a.display(s), self.b.display(s))
160 }
161}
162
163impl<I: Interner> RenderAsRust<I> for TypeOutlives<I> {
164 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
165 // T: 'a
166 write!(f, "{}: {}", self.ty.display(s), self.lifetime.display(s))
167 }
168}