1use std::fmt::{Formatter, Result};
5
6use crate::split::Split;
7use chalk_ir::{interner::Interner, *};
8use itertools::Itertools;
9
10use super::{
11 display_self_where_clauses_as_bounds, display_type_with_generics, render_trait::RenderAsRust,
12 state::InternalWriterState,
13};
14
15impl<I: Interner> RenderAsRust<I> for TyKind<I> {
16 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
17 let interner = s.db().interner();
18 match self {
19 TyKind::Adt(sid, substitution) => {
20 write!(f, "{}", sid.display(s))?;
21 let parameters = substitution.as_slice(interner);
22 let parameters = parameters.iter().map(|param| param.display(s));
23 write_joined_non_empty_list!(f, "<{}>", parameters, ", ")
24 }
25 TyKind::AssociatedType(assoc_type_id, substitution) => {
26 let datum = s.db().associated_ty_data(*assoc_type_id);
29 assert!(
30 substitution
31 .iter(interner)
32 .filter_map(move |p| p.ty(interner))
33 .count()
34 >= 1,
35 "AssociatedType should have at least 1 parameter"
36 );
37 write!(
38 f,
39 "<{} as {}>::{}",
40 substitution
41 .iter(interner)
42 .filter_map(move |p| p.ty(interner))
43 .next()
44 .unwrap()
45 .display(s),
46 datum.trait_id.display(s),
47 datum.id.display(s),
48 )?;
49 let params = substitution.as_slice(interner);
50 write_joined_non_empty_list!(
51 f,
52 "<{}>",
53 params[1..].iter().map(|ty| ty.display(s)),
54 ","
55 )
56 }
57 TyKind::Scalar(scalar) => write!(f, "{}", scalar.display(s)),
58 TyKind::Tuple(arity, substitution) => {
59 write!(
60 f,
61 "({}{})",
62 substitution
63 .as_slice(interner)
64 .iter()
65 .map(|p| p.display(s))
66 .format(", "),
67 if *arity == 1 {
68 ","
70 } else {
71 ""
72 }
73 )
74 }
75 TyKind::OpaqueType(opaque_ty_id, substitution) => write!(
76 f,
77 "{}",
78 display_type_with_generics(s, *opaque_ty_id, substitution.as_slice(interner))
79 ),
80 TyKind::Raw(mutability, ty) => match mutability {
81 Mutability::Mut => write!(f, "*mut {}", ty.display(s)),
82 Mutability::Not => write!(f, "*const {}", ty.display(s)),
83 },
84 TyKind::Ref(mutability, lifetime, ty) => match mutability {
85 Mutability::Mut => write!(f, "&{} mut {}", lifetime.display(s), ty.display(s)),
86 Mutability::Not => write!(f, "&{} {}", lifetime.display(s), ty.display(s)),
87 },
88 TyKind::Str => write!(f, "str"),
89 TyKind::Slice(ty) => write!(f, "[{}]", ty.display(s)),
90 TyKind::Error => write!(f, "{{error}}"),
91 TyKind::Never => write!(f, "!"),
92
93 TyKind::FnDef(..) => write!(f, "<fn_def>"),
95 TyKind::Closure(..) => write!(f, "<closure>"),
96 TyKind::Foreign(..) => write!(f, "<foreign>"),
97 TyKind::Coroutine(..) => write!(f, "<coroutine>"),
98 TyKind::CoroutineWitness(..) => write!(f, "<coroutine_witness>"),
99
100 TyKind::Array(ty, const_) => write!(f, "[{}; {}]", ty.display(s), const_.display(s),),
101 TyKind::Dyn(dyn_ty) => {
102 {
105 let s = &s.add_debrujin_index(None);
106 let bounds = dyn_ty.bounds.skip_binders();
108
109 write!(
110 f,
111 "dyn {}",
112 display_self_where_clauses_as_bounds(s, bounds.as_slice(interner)),
113 )?;
114 }
115
116 write!(f, " + {}", dyn_ty.lifetime.display(s))?;
117 Ok(())
118 }
119 TyKind::BoundVar(bound_var) => write!(f, "{}", s.display_bound_var(bound_var)),
120 TyKind::InferenceVar(_, _) => write!(f, "_"),
121 TyKind::Alias(alias_ty) => alias_ty.fmt(s, f),
122 TyKind::Function(func) => func.fmt(s, f),
123 TyKind::Placeholder(_) => write!(f, "<placeholder>"),
124 }
125 }
126}
127
128impl<I: Interner> RenderAsRust<I> for AliasTy<I> {
129 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
130 match self {
131 AliasTy::Projection(projection_ty) => projection_ty.fmt(s, f),
132 AliasTy::Opaque(opaque_ty) => opaque_ty.fmt(s, f),
133 }
134 }
135}
136
137impl<I: Interner> RenderAsRust<I> for ProjectionTy<I> {
138 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
139 let (assoc_ty_datum, trait_params, assoc_type_params) = s.db().split_projection(self);
146 write!(
147 f,
148 "<{} as {}>::{}",
149 trait_params[0].display(s),
150 display_type_with_generics(s, assoc_ty_datum.trait_id, &trait_params[1..]),
151 assoc_ty_datum.id.display(s),
152 )?;
153 write_joined_non_empty_list!(
154 f,
155 "<{}>",
156 assoc_type_params.iter().map(|param| param.display(s)),
157 ", "
158 )?;
159 Ok(())
160 }
161}
162
163impl<I: Interner> RenderAsRust<I> for OpaqueTy<I> {
164 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
165 let interner = s.db().interner();
166 write!(
167 f,
168 "{}",
169 display_type_with_generics(s, self.opaque_ty_id, self.substitution.as_slice(interner),)
170 )
171 }
172}
173
174impl<I: Interner> RenderAsRust<I> for FnPointer<I> {
175 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
176 let interner = s.db().interner();
177 let s = &s.add_debrujin_index(None);
178 if self.num_binders > 0 {
179 write!(
180 f,
181 "for<{}> ",
182 (0..self.num_binders)
183 .map(|n| format!("'{}", s.name_for_introduced_bound_var(n)))
184 .format(", ")
185 )?;
186 }
187 let parameters = self.substitution.0.as_slice(interner);
188 write!(
189 f,
190 "fn({}) -> {}",
191 parameters[..parameters.len() - 1]
192 .iter()
193 .map(|param| param.display(s))
194 .format(", "),
195 parameters[parameters.len() - 1].display(s),
196 )
197 }
198}
199
200impl<I: Interner> RenderAsRust<I> for Scalar {
201 fn fmt(&self, _s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
202 use chalk_ir::{FloatTy::*, IntTy::*, UintTy::*};
203 write!(
204 f,
205 "{}",
206 match self {
207 Scalar::Bool => "bool",
208 Scalar::Char => "char",
209 Scalar::Int(int) => match int {
210 Isize => "isize",
211 I8 => "i8",
212 I16 => "i16",
213 I32 => "i32",
214 I64 => "i64",
215 I128 => "i128",
216 },
217 Scalar::Uint(uint) => match uint {
218 Usize => "usize",
219 U8 => "u8",
220 U16 => "u16",
221 U32 => "u32",
222 U64 => "u64",
223 U128 => "u128",
224 },
225 Scalar::Float(float) => match float {
226 F16 => "f16",
227 F32 => "f32",
228 F64 => "f64",
229 F128 => "f128",
230 },
231 }
232 )
233 }
234}
235
236impl<I: Interner> RenderAsRust<I> for LifetimeData<I> {
237 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
238 match self {
239 LifetimeData::BoundVar(v) => write!(f, "'{}", s.display_bound_var(v)),
240 LifetimeData::InferenceVar(_) => write!(f, "'_"),
241 LifetimeData::Placeholder(ix) => {
242 write!(f, "'_placeholder_{}_{}", ix.ui.counter, ix.idx)
243 }
244 LifetimeData::Static => write!(f, "'static"),
245 LifetimeData::Erased => write!(f, "'_"),
246 LifetimeData::Error => write!(f, "'{{error}}"),
247 LifetimeData::Phantom(void, _) => match *void {},
250 }
251 }
252}
253
254impl<I: Interner> RenderAsRust<I> for ConstData<I> {
255 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
256 write!(f, "{}", self.value.display(s))
257 }
258}
259
260impl<I: Interner> RenderAsRust<I> for ConstValue<I> {
261 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
262 match self {
263 ConstValue::BoundVar(v) => write!(f, "{}", s.display_bound_var(v)),
264 ConstValue::InferenceVar(_) => write!(f, "_"),
265 ConstValue::Placeholder(_) => write!(f, "<const placeholder>"),
266 ConstValue::Concrete(value) => write!(f, "{:?}", value.interned),
267 }
268 }
269}
270
271impl<I: Interner> RenderAsRust<I> for GenericArgData<I> {
272 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
273 match self {
274 GenericArgData::Ty(ty) => write!(f, "{}", ty.display(s)),
275 GenericArgData::Lifetime(lt) => write!(f, "{}", lt.display(s)),
276 GenericArgData::Const(const_ty) => write!(f, "{}", const_ty.display(s)),
277 }
278 }
279}
280
281impl<I: Interner> RenderAsRust<I> for Ty<I> {
282 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
283 self.kind(s.db().interner()).fmt(s, f)
285 }
286}
287
288impl<I: Interner> RenderAsRust<I> for Lifetime<I> {
289 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
290 self.data(s.db().interner()).fmt(s, f)
292 }
293}
294
295impl<I: Interner> RenderAsRust<I> for Const<I> {
296 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
297 self.data(s.db().interner()).fmt(s, f)
298 }
299}
300
301impl<I: Interner> RenderAsRust<I> for GenericArg<I> {
302 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
303 self.data(s.db().interner()).fmt(s, f)
305 }
306}