Skip to content

Commit 40fcbba

Browse files
committed
Change struct expr pretty printing to match rustfmt style
1 parent 63406ac commit 40fcbba

File tree

3 files changed

+83
-31
lines changed

3 files changed

+83
-31
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod delimited;
12
mod expr;
23
mod item;
34

@@ -23,6 +24,8 @@ use rustc_span::{BytePos, FileName, Span};
2324

2425
use std::borrow::Cow;
2526

27+
pub use self::delimited::IterDelimited;
28+
2629
pub enum MacHeader<'a> {
2730
Path(&'a ast::Path),
2831
Keyword(&'static str),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::iter::Peekable;
2+
use std::mem;
3+
use std::ops::Deref;
4+
5+
pub struct Delimited<I: Iterator> {
6+
is_first: bool,
7+
iter: Peekable<I>,
8+
}
9+
10+
pub trait IterDelimited: Iterator + Sized {
11+
fn delimited(self) -> Delimited<Self> {
12+
Delimited { is_first: true, iter: self.peekable() }
13+
}
14+
}
15+
16+
impl<I: Iterator> IterDelimited for I {}
17+
18+
pub struct IteratorItem<T> {
19+
value: T,
20+
pub is_first: bool,
21+
pub is_last: bool,
22+
}
23+
24+
impl<I: Iterator> Iterator for Delimited<I> {
25+
type Item = IteratorItem<I::Item>;
26+
27+
fn next(&mut self) -> Option<Self::Item> {
28+
let value = self.iter.next()?;
29+
let is_first = mem::replace(&mut self.is_first, false);
30+
let is_last = self.iter.peek().is_none();
31+
Some(IteratorItem { value, is_first, is_last })
32+
}
33+
}
34+
35+
impl<T> Deref for IteratorItem<T> {
36+
type Target = T;
37+
38+
fn deref(&self) -> &Self::Target {
39+
&self.value
40+
}
41+
}

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+39-31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::pp::Breaks::{Consistent, Inconsistent};
2-
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
1+
use crate::pp::Breaks::Inconsistent;
2+
use crate::pprust::state::{AnnNode, IterDelimited, PrintState, State, INDENT_UNIT};
33

44
use rustc_ast::ptr::P;
55
use rustc_ast::util::parser::{self, AssocOp, Fixity};
@@ -117,38 +117,46 @@ impl<'a> State<'a> {
117117
} else {
118118
self.print_path(path, true, 0);
119119
}
120+
self.nbsp();
120121
self.word("{");
121-
self.commasep_cmnt(
122-
Consistent,
123-
fields,
124-
|s, field| {
125-
s.print_outer_attributes(&field.attrs);
126-
s.ibox(INDENT_UNIT);
127-
if !field.is_shorthand {
128-
s.print_ident(field.ident);
129-
s.word_space(":");
130-
}
131-
s.print_expr(&field.expr);
132-
s.end();
133-
},
134-
|f| f.span,
135-
);
136-
match rest {
137-
ast::StructRest::Base(_) | ast::StructRest::Rest(_) => {
138-
self.ibox(INDENT_UNIT);
139-
if !fields.is_empty() {
140-
self.word(",");
141-
self.space();
142-
}
143-
self.word("..");
144-
if let ast::StructRest::Base(ref expr) = *rest {
145-
self.print_expr(expr);
146-
}
147-
self.end();
122+
let has_rest = match rest {
123+
ast::StructRest::Base(_) | ast::StructRest::Rest(_) => true,
124+
ast::StructRest::None => false,
125+
};
126+
if fields.is_empty() && !has_rest {
127+
self.word("}");
128+
return;
129+
}
130+
self.cbox(0);
131+
for field in fields.iter().delimited() {
132+
self.maybe_print_comment(field.span.hi());
133+
self.print_outer_attributes(&field.attrs);
134+
if field.is_first {
135+
self.space_if_not_bol();
136+
}
137+
if !field.is_shorthand {
138+
self.print_ident(field.ident);
139+
self.word_nbsp(":");
140+
}
141+
self.print_expr(&field.expr);
142+
if !field.is_last || has_rest {
143+
self.word_space(",");
144+
} else {
145+
self.trailing_comma();
148146
}
149-
ast::StructRest::None if !fields.is_empty() => self.word(","),
150-
_ => {}
151147
}
148+
if has_rest {
149+
if fields.is_empty() {
150+
self.space();
151+
}
152+
self.word("..");
153+
if let ast::StructRest::Base(expr) = rest {
154+
self.print_expr(expr);
155+
}
156+
self.space();
157+
}
158+
self.offset(-INDENT_UNIT);
159+
self.end();
152160
self.word("}");
153161
}
154162

0 commit comments

Comments
 (0)