Repository: dtolnay/async-trait (rust)

Issue:
Use parentheses to disambiguate impl Trait
```rust
use async_trait::async_trait;

#[async_trait]
pub trait Trait {
    async fn f(arg: &impl Trait);
}
```

currently fails with:

```console
error: ambiguous `+` in a type
 --> src/main.rs:5:22
  |
5 |     async fn f(arg: &impl Trait);
  |                      ^^^^^^^^^^ help: use parentheses to disambiguate: `(impl 'async_trait + Trait)`
```

Pull request description:
Use parentheses to disambiguate impl Trait
Fixes #204.

Patch:
diff --git a/src/lifetime.rs b/src/lifetime.rs
index d8e8d88..7ceda4f 100644
--- a/src/lifetime.rs
+++ b/src/lifetime.rs
@@ -1,7 +1,9 @@
-use proc_macro2::Span;
+use proc_macro2::{Span, TokenStream};
+use std::mem;
 use syn::visit_mut::{self, VisitMut};
 use syn::{
-    parse_quote_spanned, Expr, GenericArgument, Lifetime, Receiver, TypeImplTrait, TypeReference,
+    parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, Type, TypeImplTrait,
+    TypeParen, TypeReference,
 };
 
 pub struct CollectLifetimes {
@@ -78,6 +80,17 @@ impl VisitMut for AddLifetimeToImplTrait {
         visit_mut::visit_type_impl_trait_mut(self, ty);
     }
 
+    fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) {
+        if let Type::ImplTrait(_) = *ty.elem {
+            let elem = mem::replace(&mut *ty.elem, Type::Verbatim(TokenStream::new()));
+            *ty.elem = Type::Paren(TypeParen {
+                paren_token: token::Paren(ty.and_token.span),
+                elem: Box::new(elem),
+            });
+        }
+        visit_mut::visit_type_reference_mut(self, ty);
+    }
+
     fn visit_expr_mut(&mut self, _e: &mut Expr) {
         // Do not recurse into impl Traits inside of an array length expression.
         //


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 87897b1..6859639 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1439,3 +1439,13 @@ pub mod issue199 {
         assert_eq!(counter.get(), 1);
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/204
+pub mod issue204 {
+    use async_trait::async_trait;
+
+    #[async_trait]
+    pub trait Trait {
+        async fn f(arg: &impl Trait);
+    }
+}