Skip to content

Commit af5d3cc

Browse files
authored
Merge pull request #2524 from topecongiro/issue-2523
Do not unindent code block in comments with unformattable macro
2 parents 124f03b + 2188b46 commit af5d3cc

File tree

6 files changed

+68
-8
lines changed

6 files changed

+68
-8
lines changed

src/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,6 +2652,7 @@ impl<'a> ToExpr for MacroArg {
26522652
MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
26532653
MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
26542654
MacroArg::Pat(..) => false,
2655+
MacroArg::Item(..) => len == 1,
26552656
}
26562657
}
26572658
}

src/lib.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,23 @@ pub fn format_snippet(snippet: &str, config: &Config) -> Option<String> {
597597
}
598598
}
599599

600+
const FN_MAIN_PREFIX: &str = "fn main() {\n";
601+
602+
fn enclose_in_main_block(s: &str, config: &Config) -> String {
603+
let indent = Indent::from_width(config, config.tab_spaces());
604+
FN_MAIN_PREFIX.to_owned() + &indent.to_string(config)
605+
+ &s.lines()
606+
.collect::<Vec<_>>()
607+
.join(&indent.to_string_with_newline(config)) + "\n}"
608+
}
609+
600610
/// Format the given code block. Mainly targeted for code block in comment.
601611
/// The code block may be incomplete (i.e. parser may be unable to parse it).
602612
/// To avoid panic in parser, we wrap the code block with a dummy function.
603613
/// The returned code block does *not* end with newline.
604614
pub fn format_code_block(code_snippet: &str, config: &Config) -> Option<String> {
605615
// Wrap the given code block with `fn main()` if it does not have one.
606-
let fn_main_prefix = "fn main() {\n";
607-
let snippet = fn_main_prefix.to_owned() + code_snippet + "\n}";
616+
let snippet = enclose_in_main_block(code_snippet, config);
608617
let mut result = String::with_capacity(snippet.len());
609618
let mut is_first = true;
610619

@@ -613,7 +622,7 @@ pub fn format_code_block(code_snippet: &str, config: &Config) -> Option<String>
613622
let formatted = format_snippet(&snippet, config)?;
614623
// 2 = "}\n"
615624
let block_len = formatted.len().checked_sub(2).unwrap_or(0);
616-
for line in formatted[fn_main_prefix.len()..block_len].lines() {
625+
for line in formatted[FN_MAIN_PREFIX.len()..block_len].lines() {
617626
if !is_first {
618627
result.push('\n');
619628
} else {

src/macros.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
use std::collections::HashMap;
2323

2424
use config::lists::*;
25-
use syntax::ast;
25+
use syntax::{ast, ptr};
2626
use syntax::codemap::{BytePos, Span};
2727
use syntax::parse::new_parser_from_tts;
2828
use syntax::parse::parser::Parser;
@@ -39,6 +39,7 @@ use lists::{itemize_list, write_list, ListFormatting};
3939
use overflow;
4040
use rewrite::{Rewrite, RewriteContext};
4141
use shape::{Indent, Shape};
42+
use spanned::Spanned;
4243
use utils::{format_visibility, mk_sp, wrap_str};
4344

4445
const FORCED_BRACKET_MACROS: &[&str] = &["vec!"];
@@ -71,9 +72,21 @@ impl MacroStyle {
7172

7273
#[derive(Debug)]
7374
pub enum MacroArg {
74-
Expr(ast::Expr),
75-
Ty(ast::Ty),
76-
Pat(ast::Pat),
75+
Expr(ptr::P<ast::Expr>),
76+
Ty(ptr::P<ast::Ty>),
77+
Pat(ptr::P<ast::Pat>),
78+
// `parse_item` returns `Option<ptr::P<ast::Item>>`.
79+
Item(Option<ptr::P<ast::Item>>),
80+
}
81+
82+
impl Rewrite for ast::Item {
83+
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
84+
let mut visitor = ::visitor::FmtVisitor::from_context(context);
85+
visitor.block_indent = shape.indent;
86+
visitor.last_pos = self.span().lo();
87+
visitor.visit_item(self);
88+
Some(visitor.buffer)
89+
}
7790
}
7891

7992
impl Rewrite for MacroArg {
@@ -82,6 +95,7 @@ impl Rewrite for MacroArg {
8295
MacroArg::Expr(ref expr) => expr.rewrite(context, shape),
8396
MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
8497
MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
98+
MacroArg::Item(ref item) => item.as_ref().and_then(|item| item.rewrite(context, shape)),
8599
}
86100
}
87101
}
@@ -97,7 +111,7 @@ fn parse_macro_arg(parser: &mut Parser) -> Option<MacroArg> {
97111
} else {
98112
// Parsing succeeded.
99113
*parser = cloned_parser;
100-
return Some(MacroArg::$macro_arg((*x).clone()));
114+
return Some(MacroArg::$macro_arg(x.clone()));
101115
}
102116
}
103117
Err(mut e) => {
@@ -111,6 +125,7 @@ fn parse_macro_arg(parser: &mut Parser) -> Option<MacroArg> {
111125
parse_macro_arg!(Expr, parse_expr);
112126
parse_macro_arg!(Ty, parse_ty);
113127
parse_macro_arg!(Pat, parse_pat);
128+
parse_macro_arg!(Item, parse_item);
114129

115130
None
116131
}

src/spanned.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ impl Spanned for MacroArg {
187187
MacroArg::Expr(ref expr) => expr.span(),
188188
MacroArg::Ty(ref ty) => ty.span(),
189189
MacroArg::Pat(ref pat) => pat.span(),
190+
MacroArg::Item(ref item) => item.as_ref().unwrap().span(),
190191
}
191192
}
192193
}

tests/source/issue-2523.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// rustfmt-normalize_comments: true
2+
3+
// Do not unindent macro calls in comment with unformattable syntax.
4+
//! ```rust
5+
//! let x = 3 ;
6+
//! some_macro!(pub fn fn foo() (
7+
//! println!("Don't unindent me!");
8+
//! ));
9+
//! ```
10+
11+
// Format items that appear as arguments of macro call.
12+
//! ```rust
13+
//! let x = 3 ;
14+
//! some_macro!(pub fn foo() {
15+
//! println!("Don't unindent me!");
16+
//! });
17+
//! ```

tests/target/issue-2523.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// rustfmt-normalize_comments: true
2+
3+
// Do not unindent macro calls in comment with unformattable syntax.
4+
//! ```rust
5+
//! let x = 3;
6+
//! some_macro!(pub fn fn foo() (
7+
//! println!("Don't unindent me!");
8+
//! ));
9+
//! ```
10+
11+
// Format items that appear as arguments of macro call.
12+
//! ```rust
13+
//! let x = 3;
14+
//! some_macro!(pub fn foo() {
15+
//! println!("Don't unindent me!");
16+
//! });
17+
//! ```

0 commit comments

Comments
 (0)