Skip to content

Commit 4eca284

Browse files
authored
Merge pull request #1933 from topecongiro/attributes-on-stmt
Format and preserve attributes on `ast::Stmt`
2 parents e780532 + 5280583 commit 4eca284

File tree

7 files changed

+140
-125
lines changed

7 files changed

+140
-125
lines changed

src/expr.rs

+25-35
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,10 @@ pub fn format_expr(
130130
ExprType::Statement => {
131131
if is_unsafe_block(block) {
132132
block.rewrite(context, shape)
133-
} else {
133+
} else if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
134134
// Rewrite block without trying to put it in a single line.
135-
if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
136-
return rw;
137-
}
135+
rw
136+
} else {
138137
let prefix = try_opt!(block_prefix(context, block, shape));
139138
rewrite_block_with_visitor(context, &prefix, block, shape)
140139
}
@@ -181,17 +180,11 @@ pub fn format_expr(
181180
)
182181
}
183182
}
184-
ast::ExprKind::Yield(ref opt_expr) => {
185-
if let Some(ref expr) = *opt_expr {
186-
rewrite_unary_prefix(context, "yield ", &**expr, shape)
187-
} else {
188-
wrap_str(
189-
"yield".to_string(),
190-
context.config.max_width(),
191-
shape,
192-
)
193-
}
194-
}
183+
ast::ExprKind::Yield(ref opt_expr) => if let Some(ref expr) = *opt_expr {
184+
rewrite_unary_prefix(context, "yield ", &**expr, shape)
185+
} else {
186+
wrap_str("yield".to_string(), context.config.max_width(), shape)
187+
},
195188
ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
196189
rewrite_closure(capture, fn_decl, body, expr.span, context, shape)
197190
}
@@ -293,17 +286,17 @@ pub fn format_expr(
293286
shape,
294287
),
295288
ast::ExprKind::Catch(ref block) => {
296-
if let rewrite @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape)
297-
{
298-
return rewrite;
289+
if let rw @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape) {
290+
rw
291+
} else {
292+
// 9 = `do catch `
293+
let budget = shape.width.checked_sub(9).unwrap_or(0);
294+
Some(format!(
295+
"{}{}",
296+
"do catch ",
297+
try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
298+
))
299299
}
300-
// 9 = `do catch `
301-
let budget = shape.width.checked_sub(9).unwrap_or(0);
302-
Some(format!(
303-
"{}{}",
304-
"do catch ",
305-
try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
306-
))
307300
}
308301
};
309302

@@ -883,16 +876,13 @@ impl Rewrite for ast::Stmt {
883876
""
884877
};
885878

886-
format_expr(
887-
ex,
888-
match self.node {
889-
ast::StmtKind::Expr(_) => ExprType::SubExpression,
890-
ast::StmtKind::Semi(_) => ExprType::Statement,
891-
_ => unreachable!(),
892-
},
893-
context,
894-
try_opt!(shape.sub_width(suffix.len())),
895-
).map(|s| s + suffix)
879+
let expr_type = match self.node {
880+
ast::StmtKind::Expr(_) => ExprType::SubExpression,
881+
ast::StmtKind::Semi(_) => ExprType::Statement,
882+
_ => unreachable!(),
883+
};
884+
let shape = try_opt!(shape.sub_width(suffix.len()));
885+
format_expr(ex, expr_type, context, shape).map(|s| s + suffix)
896886
}
897887
ast::StmtKind::Mac(..) | ast::StmtKind::Item(..) => None,
898888
};

src/imports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a> FmtVisitor<'a> {
260260
) {
261261
let vis = utils::format_visibility(vis);
262262
// 4 = `use `, 1 = `;`
263-
let rw = Shape::indented(self.block_indent, self.config)
263+
let rw = self.shape()
264264
.offset_left(vis.len() + 4)
265265
.and_then(|shape| shape.sub_width(1))
266266
.and_then(|shape| match vp.node {

src/items.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,23 @@ impl Rewrite for ast::Local {
5555

5656
skip_out_of_file_lines_range!(context, self.span);
5757

58-
let mut result = "let ".to_owned();
58+
if contains_skip(&self.attrs) {
59+
return None;
60+
}
61+
62+
let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
63+
let mut result = if attrs_str.is_empty() {
64+
"let ".to_owned()
65+
} else {
66+
try_opt!(combine_strs_with_missing_comments(
67+
context,
68+
&attrs_str,
69+
"let ",
70+
mk_sp(self.attrs.last().map(|a| a.span.hi).unwrap(), self.span.lo),
71+
shape,
72+
false,
73+
))
74+
};
5975

6076
// 4 = "let ".len()
6177
let pat_shape = try_opt!(shape.offset_left(4));
@@ -187,8 +203,7 @@ impl<'a> FmtVisitor<'a> {
187203

188204

189205
fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
190-
let shape = Shape::indented(self.block_indent, self.config);
191-
let rewrite = item.rewrite(&self.get_context(), shape);
206+
let rewrite = item.rewrite(&self.get_context(), self.shape());
192207
self.push_rewrite(item.span(), rewrite);
193208
self.last_pos = item.span.hi;
194209
}
@@ -312,18 +327,11 @@ impl<'a> FmtVisitor<'a> {
312327
""
313328
};
314329

315-
format_expr(
316-
&e,
317-
ExprType::Statement,
318-
&self.get_context(),
319-
Shape::indented(self.block_indent, self.config),
320-
).map(|s| s + suffix)
330+
format_expr(&e, ExprType::Statement, &self.get_context(), self.shape())
331+
.map(|s| s + suffix)
321332
.or_else(|| Some(self.snippet(e.span)))
322333
}
323-
None => stmt.rewrite(
324-
&self.get_context(),
325-
Shape::indented(self.block_indent, self.config),
326-
),
334+
None => stmt.rewrite(&self.get_context(), self.shape()),
327335
}
328336
} else {
329337
None
@@ -421,9 +429,7 @@ impl<'a> FmtVisitor<'a> {
421429
false,
422430
);
423431

424-
let shape = Shape::indented(self.block_indent, self.config)
425-
.sub_width(2)
426-
.unwrap();
432+
let shape = self.shape().sub_width(2).unwrap();
427433
let fmt = ListFormatting {
428434
tactic: DefinitiveListTactic::Vertical,
429435
separator: ",",
@@ -451,7 +457,7 @@ impl<'a> FmtVisitor<'a> {
451457

452458
let context = self.get_context();
453459
let indent = self.block_indent;
454-
let shape = Shape::indented(indent, self.config);
460+
let shape = self.shape();
455461
let attrs_str = try_opt!(field.node.attrs.rewrite(&context, shape));
456462
let lo = field
457463
.node

src/lib.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -91,32 +91,46 @@ macro_rules! span_with_attrs_lo_hi {
9191
}
9292
}
9393
}
94+
9495
macro_rules! span_with_attrs {
9596
($this:ident) => {
9697
span_with_attrs_lo_hi!($this, $this.span.lo, $this.span.hi)
9798
}
9899
}
99100

100-
impl Spanned for ast::Expr {
101-
fn span(&self) -> Span {
102-
span_with_attrs!(self)
101+
macro_rules! implement_spanned {
102+
($this:ty) => {
103+
impl Spanned for $this {
104+
fn span(&self) -> Span {
105+
span_with_attrs!(self)
106+
}
107+
}
103108
}
104109
}
105110

106-
impl Spanned for ast::Item {
107-
fn span(&self) -> Span {
108-
span_with_attrs!(self)
109-
}
110-
}
111+
// Implement `Spanned` for structs with `attrs` field.
112+
implement_spanned!(ast::Expr);
113+
implement_spanned!(ast::Field);
114+
implement_spanned!(ast::ForeignItem);
115+
implement_spanned!(ast::Item);
116+
implement_spanned!(ast::Local);
111117

112118
impl Spanned for ast::Stmt {
113119
fn span(&self) -> Span {
114120
match self.node {
115-
// Cover attributes
121+
ast::StmtKind::Local(ref local) => mk_sp(local.span().lo, self.span.hi),
122+
ast::StmtKind::Item(ref item) => mk_sp(item.span().lo, self.span.hi),
116123
ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
117124
mk_sp(expr.span().lo, self.span.hi)
118125
}
119-
_ => self.span,
126+
ast::StmtKind::Mac(ref mac) => {
127+
let (_, _, ref attrs) = **mac;
128+
if attrs.is_empty() {
129+
self.span
130+
} else {
131+
mk_sp(attrs[0].span.lo, self.span.hi)
132+
}
133+
}
120134
}
121135
}
122136
}
@@ -155,12 +169,6 @@ impl Spanned for ast::StructField {
155169
}
156170
}
157171

158-
impl Spanned for ast::Field {
159-
fn span(&self) -> Span {
160-
span_with_attrs!(self)
161-
}
162-
}
163-
164172
impl Spanned for ast::WherePredicate {
165173
fn span(&self) -> Span {
166174
match *self {
@@ -208,12 +216,6 @@ impl Spanned for ast::TyParamBound {
208216
}
209217
}
210218

211-
impl Spanned for ast::ForeignItem {
212-
fn span(&self) -> Span {
213-
span_with_attrs!(self)
214-
}
215-
}
216-
217219
#[derive(Copy, Clone, Debug)]
218220
pub struct Indent {
219221
// Width of the block indent, in characters. Must be a multiple of

0 commit comments

Comments
 (0)