]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-solve-0.55.0/src/display/items.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / vendor / chalk-solve-0.55.0 / src / display / items.rs
CommitLineData
3dfed10e
XL
1//! Writer logic for top level items.
2//!
3//! Contains code specific to top-level items and other structures specific to a
4//! single top-level item.
5
6use std::fmt::{Formatter, Result};
7
8use crate::rust_ir::*;
9use crate::split::Split;
10use chalk_ir::interner::Interner;
11use itertools::Itertools;
12
13use super::{
14 display_self_where_clauses_as_bounds, display_type_with_generics, render_trait::RenderAsRust,
15 state::InternalWriterState,
16};
17
18/// Used in `AdtDatum` and `TraitDatum` to write n flags from a flags struct
19/// to a writer. Each flag field turns into an if expression + write!, so we can
20/// just list the names and not repeat this pattern over and over.
21///
22/// This macro will error if unknown flags are specified. This will also error
23/// if any flags are missing.
24///
25/// # Usage
26///
27/// ```rust,ignore
28/// write_flags!(f, self.flags, XFlags { red, green })
29/// ```
30///
31/// Turns into
32///
33/// ```rust,ignore
34/// match self.flags {
35/// XFlags { red, green } => {
36/// if red {
37/// write!(f, "#[red]")?;
38/// }
39/// if green {
40/// write!(f, "#[green]")?;
41/// }
42/// }
43/// }
44/// ```
45macro_rules! write_flags {
46 ($writer:ident, $val:expr, $struct_name:ident { $($n:ident $(: $extra_arg:tt)?),* }) => {
47 match $val {
48 // if any fields are missing, the destructuring will error
49 $struct_name {
50 $($n,)*
51 } => {
52 $(if $n {
53 write!($writer, "#[{}]\n", write_flags!(@default $n $(: $extra_arg)*))?;
54 })*
55 }
56 }
57 };
58 (@default $n:ident : $name:literal) => {
59 $name
60 };
61 (@default $n:ident ) => {
62 stringify!($n)
63 };
64}
65
29967ef6
XL
66impl<'a, I: Interner> RenderAsRust<I> for (&'a GeneratorDatum<I>, &'a GeneratorWitnessDatum<I>) {
67 fn fmt(&self, _s: &InternalWriterState<'_, I>, _f: &'_ mut Formatter<'_>) -> Result {
68 unimplemented!()
69 }
70}
71
3dfed10e
XL
72impl<I: Interner> RenderAsRust<I> for AdtDatum<I> {
73 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
74 // When support for Self in structs is added, self_binding should be
75 // changed to Some(0)
76 let s = &s.add_debrujin_index(None);
77 let value = self.binders.skip_binders();
78
79 // flags
80 write_flags!(
81 f,
82 self.flags,
83 AdtFlags {
84 // Ordering matters
85 upstream,
86 fundamental,
87 phantom_data
88 }
89 );
90
91 // repr
92 let repr = s.db().adt_repr(self.id);
93
5869c6ff
XL
94 if repr.c {
95 write!(f, "#[repr(C)]")?;
96 }
97 if repr.packed {
98 write!(f, "#[repr(packed)]")?;
99 }
100 if let Some(t) = &repr.int {
101 write!(f, "#[repr({})]", t.display(s))?;
102 }
3dfed10e
XL
103
104 // name
105 match self.kind {
106 AdtKind::Struct => write!(f, "struct {}", self.id.display(s),)?,
107 AdtKind::Enum => write!(f, "enum {}", self.id.display(s),)?,
108 AdtKind::Union => write!(f, "union {}", self.id.display(s),)?,
109 }
110 write_joined_non_empty_list!(f, "<{}>", s.binder_var_display(&self.binders.binders), ", ")?;
111
112 // where clauses
113 if !value.where_clauses.is_empty() {
114 let s = &s.add_indent();
115 write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
116 } else {
117 write!(f, " ")?;
118 }
119
120 // body
121 write!(f, "{{")?;
122 let s = &s.add_indent();
123 match self.kind {
124 AdtKind::Struct | AdtKind::Union => {
125 write_joined_non_empty_list!(
126 f,
127 "\n{}\n",
128 value.variants[0]
129 .fields
130 .iter()
131 .enumerate()
132 .map(|(idx, field)| {
133 format!("{}field_{}: {}", s.indent(), idx, field.display(s))
134 }),
135 ",\n"
136 )?;
137 }
138 AdtKind::Enum => {
139 for (variant_idx, variant) in value.variants.iter().enumerate() {
140 write!(f, "\n{}variant_{} {{", s.indent(), variant_idx)?;
141 let s = &s.add_indent();
142 write_joined_non_empty_list!(
143 f,
144 "\n{}\n",
145 variant.fields.iter().enumerate().map(|(idx, field)| {
146 format!("{}field_{}: {}", s.indent(), idx, field.display(s))
147 }),
148 ",\n"
149 )?;
150 write!(f, "{}}},", s.indent())?;
151 }
152 }
153 }
154 write!(f, "}}")?;
155 Ok(())
156 }
157}
158
159impl<I: Interner> RenderAsRust<I> for Polarity {
160 fn fmt(&self, _s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
161 if !self.is_positive() {
162 write!(f, "!")?;
163 }
164 Ok(())
165 }
166}
167
168impl<I: Interner> RenderAsRust<I> for TraitDatum<I> {
169 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
170 let s = &s.add_debrujin_index(Some(0));
171 let value = self.binders.skip_binders();
172
173 // flags
174 write_flags!(
175 f,
176 self.flags,
177 TraitFlags {
178 auto,
179 marker,
180 upstream,
181 fundamental,
182 non_enumerable,
183 coinductive
184 }
185 );
186
187 // object safe
188 if s.db().is_object_safe(self.id) {
189 writeln!(f, "#[object_safe]")?;
190 }
191
192 // well-known
193 if let Some(well_known) = self.well_known {
194 let name = match well_known {
195 WellKnownTrait::Sized => "sized",
196 WellKnownTrait::Copy => "copy",
197 WellKnownTrait::Clone => "clone",
198 WellKnownTrait::Drop => "drop",
199 WellKnownTrait::FnOnce => "fn_once",
200 WellKnownTrait::FnMut => "fn_mut",
201 WellKnownTrait::Fn => "fn",
202 WellKnownTrait::Unsize => "unsize",
1b1a35ee
XL
203 WellKnownTrait::Unpin => "unpin",
204 WellKnownTrait::CoerceUnsized => "coerce_unsized",
5869c6ff 205 WellKnownTrait::DiscriminantKind => "discriminant_kind",
3dfed10e
XL
206 };
207 writeln!(f, "#[lang({})]", name)?;
208 }
209
210 // trait declaration
211 let binders = s.binder_var_display(&self.binders.binders).skip(1);
212 write!(f, "trait {}", self.id.display(s))?;
213 write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
214
215 // where clauses
216 if !value.where_clauses.is_empty() {
217 let s = &s.add_indent();
218 write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
219 } else {
220 write!(f, " ")?;
221 }
222
223 // body
224 write!(f, "{{")?;
225 let s = &s.add_indent();
226 write_joined_non_empty_list!(
227 f,
228 "\n{}\n",
229 self.associated_ty_ids.iter().map(|assoc_ty_id| {
230 let assoc_ty_data = s.db().associated_ty_data(*assoc_ty_id);
231 format!("{}{}", s.indent(), (*assoc_ty_data).display(s))
232 }),
233 "\n"
234 )?;
235 write!(f, "}}")?;
236 Ok(())
237 }
238}
239
240impl<I: Interner> RenderAsRust<I> for ImplDatum<I> {
241 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
242 let interner = s.db().interner();
243
244 let s = &s.add_debrujin_index(None);
245 let binders = s.binder_var_display(&self.binders.binders);
246 let value = self.binders.skip_binders();
247
248 // annotations
249 // #[upstream]
250 // ^^^^^^^^^^^
251 // impl<T> Foo<T> for Bar<T> where T: Baz { }
252 if self.impl_type == ImplType::External {
253 writeln!(f, "#[upstream]")?;
254 }
255
256 // impl keyword
257 // impl<T> Foo<T> for Bar<T> where T: Baz { }
258 // ^^^^
259 write!(f, "impl")?;
260 let trait_ref = &value.trait_ref;
261
262 // generic binders
263 // impl<T> Foo<T> for Bar<T> where T: Baz
264 // ^^^
265 write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
266
267 // trait, type and parameters
268 // impl<T> Foo<T> for Bar<T> where T: Baz { }
269 // ^^^^^^^^^^^^^^^^^
270 let full_trait_name = display_type_with_generics(
271 s,
272 trait_ref.trait_id,
273 // Ignore automatically added Self parameter by skipping first parameter
274 &trait_ref.substitution.as_slice(interner)[1..],
275 );
276 write!(
277 f,
278 " {}{} for {}",
279 self.polarity.display(s),
280 full_trait_name,
281 trait_ref.self_type_parameter(interner).display(s)
282 )?;
283
284 // where clauses
285 // impl<T> Foo<T> for Bar<T> where T: Baz { }
286 // ^^^^^^^^^^^^
287 if !value.where_clauses.is_empty() {
288 let s = &s.add_indent();
289 write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
290 } else {
291 write!(f, " ")?;
292 }
293
294 // body
295 // impl<T> Foo<T> for Bar<T> where T: Baz { }
296 // ^^^
297 write!(f, "{{")?;
298 {
299 let s = &s.add_indent();
300 let assoc_ty_values = self.associated_ty_value_ids.iter().map(|assoc_ty_value| {
301 s.db()
302 .associated_ty_value(*assoc_ty_value)
303 .display(s)
304 .to_string()
305 });
306 write_joined_non_empty_list!(f, "\n{}\n", assoc_ty_values, "\n")?;
307 }
308 write!(f, "}}")?;
309 Ok(())
310 }
311}
312
313impl<I: Interner> RenderAsRust<I> for OpaqueTyDatum<I> {
314 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
315 let s = &s.add_debrujin_index(None);
316 let bounds = self.bound.skip_binders();
317 write!(f, "opaque type {}", self.opaque_ty_id.display(s))?;
318 write_joined_non_empty_list!(f, "<{}>", s.binder_var_display(&self.bound.binders), ", ")?;
319 {
320 let s = &s.add_debrujin_index(Some(0));
321 let clauses = bounds.bounds.skip_binders();
322 write!(
323 f,
324 ": {} = ",
325 display_self_where_clauses_as_bounds(s, clauses)
326 )?;
327 }
328 write!(
329 f,
330 "{};",
331 s.db().hidden_opaque_type(self.opaque_ty_id).display(s)
332 )?;
333 Ok(())
334 }
335}
336
337impl<I: Interner> RenderAsRust<I> for AssociatedTyDatum<I> {
338 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
339 // In lowering, a completely new empty environment is created for each
340 // AssociatedTyDatum, and it's given generic parameters for each generic
341 // parameter that its trait had. We want to map the new binders for
342 // those generic parameters back into their original names. To do that,
343 // first find their original names (trait_binder_names), then the names
344 // they have inside the AssociatedTyDatum (assoc_ty_names_for_trait_params),
345 // and then add that mapping to the WriterState when writing bounds and
346 // where clauses.
347 let trait_datum = s.db().trait_datum(self.trait_id);
348 // inverted Debrujin indices for the trait's parameters in the trait
349 // environment
350 let trait_param_names_in_trait_env = s.binder_var_indices(&trait_datum.binders.binders);
351 let s = &s.add_debrujin_index(None);
352 // inverted Debrujin indices for the trait's parameters in the
353 // associated type environment
354 let param_names_in_assoc_ty_env = s
355 .binder_var_indices(&self.binders.binders)
356 .collect::<Vec<_>>();
357 // inverted Debrujin indices to render the trait's parameters in the
358 // associated type environment
359 let (trait_param_names_in_assoc_ty_env, _) = s
360 .db()
361 .split_associated_ty_parameters(&param_names_in_assoc_ty_env, self);
362
363 let s = &s.add_parameter_mapping(
364 trait_param_names_in_assoc_ty_env.iter().copied(),
365 trait_param_names_in_trait_env,
366 );
367
368 // rendered names for the associated type's generics in the associated
369 // type environment
370 let binder_display_in_assoc_ty = s
371 .binder_var_display(&self.binders.binders)
372 .collect::<Vec<_>>();
373
374 let (_, assoc_ty_params) = s
375 .db()
376 .split_associated_ty_parameters(&binder_display_in_assoc_ty, self);
377 write!(f, "type {}", self.id.display(s))?;
378 write_joined_non_empty_list!(f, "<{}>", assoc_ty_params, ", ")?;
379
380 let datum_bounds = &self.binders.skip_binders();
381
382 if !datum_bounds.bounds.is_empty() {
383 write!(f, ": ")?;
384 }
385
386 // bounds is `A: V, B: D, C = E`?
387 // type Foo<A: V, B:D, C = E>: X + Y + Z;
388 let bounds = datum_bounds
389 .bounds
390 .iter()
391 .map(|bound| bound.display(s).to_string())
392 .format(" + ");
393 write!(f, "{}", bounds)?;
394
395 // where_clause is 'X: Y, Z: D'
396 // type Foo<...>: ... where X: Y, Z: D;
397
398 // note: it's a quantified clause b/c we could have `for<'a> T: Foo<'a>`
399 // within 'where'
400 if !datum_bounds.where_clauses.is_empty() {
401 let where_s = &s.add_indent();
402 let where_clauses = datum_bounds.where_clauses.display(where_s);
403 write!(f, "\n{}where\n{}", s.indent(), where_clauses)?;
404 }
405 write!(f, ";")?;
406 Ok(())
407 }
408}
409
410impl<I: Interner> RenderAsRust<I> for AssociatedTyValue<I> {
411 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
412 // see comments for a similar empty env operation in AssociatedTyDatum's
413 // impl of RenderAsRust.
414 let assoc_ty_data = s.db().associated_ty_data(self.associated_ty_id);
415 let impl_datum = s.db().impl_datum(self.impl_id);
416
417 let impl_param_names_in_impl_env = s.binder_var_indices(&impl_datum.binders.binders);
418
419 let s = &s.add_debrujin_index(None);
420 let value = self.value.skip_binders();
421
422 let param_names_in_assoc_ty_value_env = s
423 .binder_var_indices(&self.value.binders)
424 .collect::<Vec<_>>();
425
426 let (impl_params_in_assoc_ty_value_env, _assoc_ty_value_params) = s
427 .db()
428 .split_associated_ty_value_parameters(&param_names_in_assoc_ty_value_env, self);
429
430 let s = &s.add_parameter_mapping(
431 impl_params_in_assoc_ty_value_env.iter().cloned(),
432 impl_param_names_in_impl_env,
433 );
434
435 let display_params = s
436 .binder_var_display(&self.value.binders)
437 .collect::<Vec<_>>();
438
439 let (_impl_display, assoc_ty_value_display) = s
440 .db()
441 .split_associated_ty_value_parameters(&display_params, self);
442
443 write!(f, "{}type {}", s.indent(), assoc_ty_data.id.display(s))?;
444 write_joined_non_empty_list!(f, "<{}>", &assoc_ty_value_display, ", ")?;
445 write!(f, " = {};", value.ty.display(s))?;
446 Ok(())
447 }
448}
449
450impl<I: Interner> RenderAsRust<I> for FnDefDatum<I> {
451 fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
452 let s = &s.add_debrujin_index(None);
453 let bound_datum = self.binders.skip_binders();
454
455 // declaration
456 // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
457 // ^^^^^^
458 write!(f, "fn {}", s.db().fn_def_name(self.id))?;
459
460 // binders
461 // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
462 // ^^^
463 let binders = s.binder_var_display(&self.binders.binders);
464 write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
465
466 {
467 let s = &s.add_debrujin_index(None);
468 let inputs_and_output = bound_datum.inputs_and_output.skip_binders();
469
470 // arguments
471 // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
472 // ^^^^^^^^^^^^^^^^^^^
473 let arguments = inputs_and_output
474 .argument_types
475 .iter()
476 .enumerate()
477 .map(|(idx, arg)| format!("arg_{}: {}", idx, arg.display(s)))
478 .format(", ");
479
480 write!(f, "({})", arguments)?;
481
482 // return Type
483 // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
484 // ^^^^^^^^^^^^^
485 write!(f, " -> {}", inputs_and_output.return_type.display(s))?;
486 }
487
488 // where clause
489 // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
490 // ^^^^^^^^^^^^
491 if !bound_datum.where_clauses.is_empty() {
492 let s = &s.add_indent();
493 write!(f, "\nwhere\n{}", bound_datum.where_clauses.display(s))?;
494 }
495
496 write!(f, ";")?;
497
498 Ok(())
499 }
500}