Repository: rust-lang/rustfmt (Rust)

Issue:
Running cargo fmt seems to break some macro expansion
Running cargo fmt on [Plume-org/Plume](https://github.com/Plume-org/Plume) breaks it. It seems to remove curly braces around the macro invocation, which make macro expansion fail with `unexpected end of macro invocation`

Step to reproduce :
```sh
$ git clone https://github.com/Plume-org/Plume
$ cd Plume
$ cargo check #compile fine
$ cargo fmt --all
$ cargo check #fail
```
Reproducible with `rustfmt 0.8.2-nightly (5e59925 2018-07-02)` (specified by `rust-toolchain`) and `rustfmt 0.99.2-nightly (5c9a2b6 2018-08-07)` via `+nightly`



Discussion:
A minimal example:

```rust
fn main() {
    foo!(|_| { () });
}
```

becomes

```rust
fn main() {
    foo!(|_| ());
}
```
Another case is `stringify!((foo+))`, where rustfmt removes the `+`.
Why does it even change that? Because it looks like a trait object type?
> Because it looks like a trait object type?

I think so. I am surprised to find out that the trailing plus is allowed on a trait object type.
@topecongiro Pretty much on any separated list, the separator can be trailing, in Rust.



Patch:
diff --git a/src/closures.rs b/src/closures.rs
index e29a412a515..008b884bcb2 100644
--- a/src/closures.rs
+++ b/src/closures.rs
@@ -59,7 +59,7 @@ pub fn rewrite_closure(
         }
 
         let result = match fn_decl.output {
-            ast::FunctionRetTy::Default(_) => {
+            ast::FunctionRetTy::Default(_) if !context.inside_macro() => {
                 try_rewrite_without_block(body, &prefix, context, shape, body_shape)
             }
             _ => None,
@@ -306,6 +306,7 @@ pub fn rewrite_last_closure(
         let body = match body.node {
             ast::ExprKind::Block(ref block, _)
                 if !is_unsafe_block(block)
+                    && !context.inside_macro()
                     && is_simple_block(block, Some(&body.attrs), context.source_map) =>
             {
                 stmt_expr(&block.stmts[0]).unwrap_or(body)
diff --git a/src/types.rs b/src/types.rs
index d27d1f13f98..8cfba778a48 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -583,7 +583,13 @@ impl Rewrite for ast::Ty {
                 let is_dyn = tobj_syntax == ast::TraitObjectSyntax::Dyn;
                 // 4 is length of 'dyn '
                 let shape = if is_dyn { shape.offset_left(4)? } else { shape };
-                let res = bounds.rewrite(context, shape)?;
+                let mut res = bounds.rewrite(context, shape)?;
+                // We may have falsely removed a trailing `+` inside macro call.
+                if context.inside_macro() && bounds.len() == 1 {
+                    if context.snippet(self.span).ends_with('+') && !res.ends_with('+') {
+                        res.push('+');
+                    }
+                }
                 if is_dyn {
                     Some(format!("dyn {}", res))
                 } else {


Test patch:
diff --git a/tests/source/macros.rs b/tests/source/macros.rs
index 07934255bac..29d8f066126 100644
--- a/tests/source/macros.rs
+++ b/tests/source/macros.rs
@@ -466,3 +466,8 @@ static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> =
         RefCell::new(RootedTraceableSet::new(1234)) ;
 
 ] ;
+
+fn issue3004() {
+    foo!(|_| { (  ) });
+    stringify!(( foo+ ));
+}
diff --git a/tests/target/macros.rs b/tests/target/macros.rs
index 061d1746422..bc15a86cf34 100644
--- a/tests/target/macros.rs
+++ b/tests/target/macros.rs
@@ -1043,3 +1043,8 @@ thread_local![
     static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> =
         RefCell::new(RootedTraceableSet::new(1234));
 ];
+
+fn issue3004() {
+    foo!(|_| { () });
+    stringify!((foo+));
+}