Repository: dtolnay/async-trait (rust)

Issue:
Failed to resolve `self` in path
Macro doesn't handle when `self` is used as path.
```rust
use async_trait::async_trait; // 0.1.48

fn bar() {}

#[async_trait]
trait Foo {
    async fn bar(&self) {
        self::bar()
    }
}
```
```rust
error[E0433]: failed to resolve: use of undeclared crate or module `__self`
 --> src/lib.rs:8:9
  |
8 |         self::bar()
  |         ^^^^ use of undeclared crate or module `__self`
```
[Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9567f3a7c893e1eb8da5256043246c9b)

Pull request description:
Preserve `self` as segment of path
Fixes #158.

Patch:
diff --git a/src/receiver.rs b/src/receiver.rs
index 64ab65e..7f837f4 100644
--- a/src/receiver.rs
+++ b/src/receiver.rs
@@ -2,7 +2,7 @@ use proc_macro2::{Group, Span, TokenStream, TokenTree};
 use std::iter::FromIterator;
 use syn::visit_mut::{self, VisitMut};
 use syn::{
-    Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, PatPath, Receiver, Signature, Token,
+    Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, PatPath, Path, Receiver, Signature, Token,
     TypePath,
 };
 
@@ -139,6 +139,16 @@ impl VisitMut for ReplaceSelf {
         self.prepend_underscore_to_self(i);
     }
 
+    fn visit_path_mut(&mut self, p: &mut Path) {
+        if p.segments.len() == 1 {
+            // Replace `self`, but not `self::function`.
+            self.visit_ident_mut(&mut p.segments[0].ident);
+        }
+        for segment in &mut p.segments {
+            self.visit_path_arguments_mut(&mut segment.arguments);
+        }
+    }
+
     fn visit_item_mut(&mut self, i: &mut Item) {
         // Visit `macro_rules!` because locally defined macros can refer to
         // `self`. Otherwise, do not recurse into nested items.


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index af33b14..5af9f6d 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1321,3 +1321,17 @@ pub mod issue154 {
         }
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/158
+pub mod issue158 {
+    use async_trait::async_trait;
+
+    fn f() {}
+
+    #[async_trait]
+    pub trait Trait {
+        async fn f(&self) {
+            self::f()
+        }
+    }
+}