diff --git a/src/expr.rs b/src/expr.rs index 679fb309f291..9a0206469275 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2365,11 +2365,24 @@ pub fn wrap_args_with_parens( } } +/// Return true if a function call or a method call represented by the given span ends with a +/// trailing comma. This function is used when rewriting macro, as adding or removing a trailing +/// comma from macro can potentially break the code. fn span_ends_with_comma(context: &RewriteContext, span: Span) -> bool { - let snippet = context.snippet(span); - snippet - .trim_right_matches(|c: char| c == ')' || c.is_whitespace()) - .ends_with(',') + let mut encountered_closing_paren = false; + for c in context.snippet(span).chars().rev() { + match c { + ',' => return true, + ')' => if encountered_closing_paren { + return false; + } else { + encountered_closing_paren = true; + }, + _ if c.is_whitespace() => continue, + _ => return false, + } + } + false } fn rewrite_paren(context: &RewriteContext, subexpr: &ast::Expr, shape: Shape) -> Option { diff --git a/tests/source/macros.rs b/tests/source/macros.rs index 616a275876fd..73044aa7ab2c 100644 --- a/tests/source/macros.rs +++ b/tests/source/macros.rs @@ -21,6 +21,12 @@ fn main() { kaas!(/* comments */ a /* post macro */, b /* another */); trailingcomma!( a , b , c , ); + // Preserve trailing comma only when necessary. + ok!(file.seek( + SeekFrom::Start( + table.map(|table| fixture.offset(table)).unwrap_or(0), + ) + )); noexpr!( i am not an expression, OK? ); diff --git a/tests/target/macros.rs b/tests/target/macros.rs index 394cac3820f3..a15dd14c9fb7 100644 --- a/tests/target/macros.rs +++ b/tests/target/macros.rs @@ -33,6 +33,10 @@ fn main() { ); trailingcomma!(a, b, c,); + // Preserve trailing comma only when necessary. + ok!(file.seek(SeekFrom::Start( + table.map(|table| fixture.offset(table)).unwrap_or(0), + ))); noexpr!( i am not an expression, OK? );