diff --git a/src/expr.rs b/src/expr.rs index 068b8f7fed6..1f8d08704ba 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -190,13 +190,20 @@ pub fn format_expr( rewrite_chain(expr, context, shape) } ast::ExprKind::Mac(ref mac) => { - rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { - wrap_str( - context.snippet(expr.span).to_owned(), - context.config.max_width(), - shape, - ) - }) + let should_skip = context + .skip_macro_names + .contains(&context.snippet(mac.node.path.span).to_owned()); + if should_skip { + None + } else { + rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { + wrap_str( + context.snippet(expr.span).to_owned(), + context.config.max_width(), + shape, + ) + }) + } } ast::ExprKind::Ret(None) => Some("return".to_owned()), ast::ExprKind::Ret(Some(ref expr)) => { @@ -1920,6 +1927,7 @@ pub fn rewrite_assign_rhs_with, R: Rewrite>( offset: shape.offset + last_line_width + 1, ..shape }); + // dbg!( let rhs = choose_rhs( context, ex, diff --git a/src/rewrite.rs b/src/rewrite.rs index df147e0c427..01ba5410896 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -39,6 +39,7 @@ pub struct RewriteContext<'a> { // Used for `format_snippet` pub(crate) macro_rewrite_failure: RefCell, pub(crate) report: FormatReport, + pub skip_macro_names: Vec, } impl<'a> RewriteContext<'a> { diff --git a/src/visitor.rs b/src/visitor.rs index 56a27889c20..ada69d860d8 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -1,7 +1,8 @@ use std::cell::RefCell; -use syntax::parse::ParseSess; +use syntax::parse::{token, ParseSess}; use syntax::source_map::{self, BytePos, Pos, SourceMap, Span}; +use syntax::tokenstream::TokenTree; use syntax::{ast, visit}; use crate::attr::*; @@ -66,6 +67,7 @@ pub struct FmtVisitor<'a> { pub skipped_range: Vec<(usize, usize)>, pub macro_rewrite_failure: bool, pub(crate) report: FormatReport, + pub skip_macro_names: Vec, } impl<'a> Drop for FmtVisitor<'a> { @@ -331,6 +333,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } } } + self.get_skip_macros(&attrs); match item.node { ast::ItemKind::Use(ref tree) => self.format_import(item, tree), @@ -437,7 +440,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ); self.push_rewrite(item.span, rewrite); } - } + }; + self.skip_macro_names.clear(); } pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) { @@ -616,6 +620,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { skipped_range: vec![], macro_rewrite_failure: false, report, + skip_macro_names: vec![], } } @@ -640,10 +645,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ErrorKind::DeprecatedAttr, )], ); - } else if attr.path.segments[0].ident.to_string() == "rustfmt" - && (attr.path.segments.len() == 1 - || attr.path.segments[1].ident.to_string() != "skip") - { + } else if self.is_rustfmt_macro_error(&attr.path.segments) { let file_name = self.source_map.span_to_filename(attr.span).into(); self.report.append( file_name, @@ -671,6 +673,20 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { false } + fn is_rustfmt_macro_error(&self, segments: &Vec) -> bool { + if segments[0].ident.to_string() != "rustfmt" { + return false; + } + + match segments.len() { + 2 => segments[1].ident.to_string() != "skip", + 3 => { + segments[1].ident.to_string() != "skip" || segments[2].ident.to_string() != "macros" + } + _ => false, + } + } + fn walk_mod_items(&mut self, m: &ast::Mod) { self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&m.items)); } @@ -817,6 +833,25 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { snippet_provider: self.snippet_provider, macro_rewrite_failure: RefCell::new(false), report: self.report.clone(), + skip_macro_names: self.skip_macro_names.clone(), + } + } + + pub fn get_skip_macros(&mut self, attrs: &[ast::Attribute]) { + for attr in attrs { + for token in attr.tokens.trees() { + if let TokenTree::Delimited(_, _, stream) = token { + for inner_token in stream.trees() { + if let TokenTree::Token(span, token) = inner_token { + if let token::Token::Ident(_, _) = token { + // FIXME ident.span.lo() and ident.span.hi() are 0 + let macro_name = self.get_context().snippet(span).to_owned(); + self.skip_macro_names.push(macro_name); + } + } + } + } + } } } } diff --git a/tests/source/issue-3434.rs b/tests/source/issue-3434.rs new file mode 100644 index 00000000000..5d753ef0c4d --- /dev/null +++ b/tests/source/issue-3434.rs @@ -0,0 +1,22 @@ +#[rustfmt::skip::macros(html, skip_macro)] +fn main() { + let macro_result1 = html! {
+Hello
+ }.to_string(); + + let macro_result2 = not_skip_macro! {
+Hello
+ }.to_string(); + + skip_macro! { +this is a skip_macro here +}; + + foo(); +} + +fn foo() { + let macro_result1 = html! {
+Hello
+ }.to_string(); +} diff --git a/tests/target/issue-3434.rs b/tests/target/issue-3434.rs new file mode 100644 index 00000000000..44171bb83fb --- /dev/null +++ b/tests/target/issue-3434.rs @@ -0,0 +1,24 @@ +#[rustfmt::skip::macros(html, skip_macro)] +fn main() { + let macro_result1 = html! {
+Hello
+ }.to_string(); + + let macro_result2 = not_skip_macro! {
+ Hello
+ } + .to_string(); + + skip_macro! { +this is a skip_macro here +}; + + foo(); +} + +fn foo() { + let macro_result1 = html! {
+ Hello
+ } + .to_string(); +}