1 //! Writer logic for `where` clauses and other bounds.
3 //! Contains logic for writing the various forms of `Foo: Bar`.
4 use std
::fmt
::{Display, Formatter, Result}
;
7 use chalk_ir
::{interner::Interner, *}
;
8 use itertools
::Itertools
;
11 display_trait_with_assoc_ty_value
, display_type_with_generics
, render_trait
::RenderAsRust
,
12 state
::InternalWriterState
,
14 use crate::split
::Split
;
16 impl<I
: Interner
> RenderAsRust
<I
> for InlineBound
<I
> {
17 fn fmt(&self, s
: &InternalWriterState
<'_
, I
>, f
: &'_
mut Formatter
<'_
>) -> Result
{
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
),
27 impl<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
)
33 impl<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(
37 s
.db().associated_ty_data(self.associated_ty_id
),
38 &self.trait_bound
.args_no_self
,
46 impl<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
) {
54 s
.binder_var_display(&self.binders
).format(", ")
57 self.skip_binders().fmt(s
, f
)
61 impl<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
) {
69 s
.binder_var_display(&self.binders
).format(", ")
72 self.skip_binders().fmt(s
, f
)
76 impl<I
: Interner
> RenderAsRust
<I
> for Vec
<QuantifiedWhereClause
<I
>> {
77 fn fmt(&self, s
: &InternalWriterState
<'_
, I
>, f
: &'_
mut Formatter
<'_
>) -> Result
{
82 .map(|where_clause
| { format!("{}{}
", s.indent(), where_clause.display(s)) })
89 impl<I: Interner> RenderAsRust<I> for WhereClause<I> {
90 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
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),
100 /// This renders `TraitRef` as a clause in a where clause, as opposed to its
101 /// usage in other places.
102 impl<I: Interner> RenderAsRust<I> for TraitRef<I> {
103 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
104 let interner = s.db().interner();
108 self.self_type_parameter(interner).display(s),
109 display_type_with_generics(
112 &self.substitution.as_slice(interner)[1..]
118 /// This renders `AliasEq` as a clause in a where clause, as opposed to its
119 /// usage in other places.
120 impl<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
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.
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).
141 trait_params[0].display(s),
142 display_trait_with_assoc_ty_value(
151 AliasTy::Opaque(_) => todo!("opaque types
"),
156 impl<I: Interner> RenderAsRust<I> for LifetimeOutlives<I> {
157 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
159 write!(f, "{}
: {}
", self.a.display(s), self.b.display(s))
163 impl<I: Interner> RenderAsRust<I> for TypeOutlives<I> {
164 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
166 write!(f, "{}
: {}
", self.ty.display(s), self.lifetime.display(s))