Repository: racer-rust/racer (language: rust)

Issue:
Does not find generic functions with interior impl blocks
Version: `racer 2.1.25`

Minimal example:
```rust
trait Foo {
    fn bar(&self);
}

struct X;
impl X {
    fn new<U>(_: U) -> X {
        struct A;
        impl Foo for A {
            fn bar(&self) {}
        }
        X
    }
}

fn main() {
    let x = X::~new(0);
}
```

Code completion at the tilde gives no results. As far as I can find, this only happens when the trait `Foo` has functions with a `self` parameter, when the function `new` has a generic type parameter, and when there's an `impl` block for the trait inside the function.

Output with tracing:
```$ env RUST_LOG=racer=trace racer complete 17 15 main.rs
DEBUG 2019-08-09T06:48:22.313255476Z: racer::util: Getting rust source path. Trying env var RUST_SRC_PATH.
DEBUG 2019-08-09T06:48:22.313324082Z: racer::util: Nope. Trying rustc --print sysroot and appending lib/rustlib/src/rust/src to that.
PREFIX 208,208,
DEBUG 2019-08-09T06:48:22.389887523Z: racer::core: Path: contextstr is |X|, searchstr is ||
DEBUG 2019-08-09T06:48:22.389896150Z: racer::scopes: [find_stmt_start] now we are in scope BytePos(192) ~ BytePos(208)
DEBUG 2019-08-09T06:48:22.389900015Z: racer::core: Complete path with stmt: "let x = X::"
DEBUG 2019-08-09T06:48:22.389905015Z: racer::core: path: P[X::], prefix: None
DEBUG 2019-08-09T06:48:22.389914066Z: racer::nameres: resolve_path P[X::] "main.rs" BytePos(208) StartsWith
DEBUG 2019-08-09T06:48:22.389919746Z: racer::nameres: resolve_path P[X] "main.rs" BytePos(208) ExactMatch
DEBUG 2019-08-09T06:48:22.389928918Z: racer::nameres: search_local_scopes PathSegment { name: "X", generics: [], output: None } "main.rs" BytePos(208) ExactMatch Crate | Mod | Space | Enum | Struct | Union | Trait | TypeDef | HasField | Type | PathParen
DEBUG 2019-08-09T06:48:22.389936110Z: racer::nameres: searching scope Crate | Mod | Space | Enum | Struct | Union | Trait | TypeDef | HasField | Type | PathParen start: BytePos(192) point: Some(BytePos(208)) 'X' "main.rs" ExactMatch local: true
DEBUG 2019-08-09T06:48:22.389949366Z: racer::nameres: [run_matchers_on_blob] cxt: MatchCxt { filepath: "main.rs", search_str: "X", range: ByteRange(197..215), search_type: ExactMatch, is_local: true }, namespace: Crate | Mod | Space | Enum | Struct | Union | Trait | TypeDef | HasField | Type | PathParen
TRACE 2019-08-09T06:48:22.389963812Z: racer::nameres: Closure definition match is looking for `X` in 26 characters
DEBUG 2019-08-09T06:48:22.389967437Z: racer::nameres: search_scope found matches ExactMatch []
DEBUG 2019-08-09T06:48:22.389971395Z: racer::nameres: search_scope_headers for |X| pt: BytePos(191)
DEBUG 2019-08-09T06:48:22.389975327Z: racer::scopes: [find_stmt_start] now we are in scope BytePos(0) ~ BytePos(191)
DEBUG 2019-08-09T06:48:22.389981418Z: racer::nameres: search_scope_headers preblock is |fn main() |
DEBUG 2019-08-09T06:48:22.389984902Z: racer::nameres: search_fn_args: found start of fn!! BytePos(181) |impl blah {fn main() {}}| X
DEBUG 2019-08-09T06:48:22.389989753Z: racer::nameres: searching scope Crate | Mod | Space | Enum | Struct | Union | Trait | TypeDef | HasField | Type | PathParen start: BytePos(0) point: Some(BytePos(208)) 'X' "main.rs" ExactMatch local: true
DEBUG 2019-08-09T06:48:22.389998084Z: racer::nameres: [run_matchers_on_blob] cxt: MatchCxt { filepath: "main.rs", search_str: "X", range: ByteRange(34..43), search_type: ExactMatch, is_local: true }, namespace: Crate | Mod | Space | Enum | Struct | Union | Trait | TypeDef | HasField | Type | PathParen
DEBUG 2019-08-09T06:48:22.390004747Z: racer::matchers: found a struct |X|
DEBUG 2019-08-09T06:48:22.390015635Z: racer::nameres: [resolve_path] context: Some(Match ["X", "main.rs", BytePos(41), true, Struct(GenericsArgs([])), |struct X;|]), last_seg: PathSegment { name: "", generics: [], output: None }
DEBUG 2019-08-09T06:48:22.390022590Z: racer::nameres: context: Match ["X", "main.rs", BytePos(41), true, Struct(GenericsArgs([])), |struct X;|]
DEBUG 2019-08-09T06:48:22.390027347Z: racer::nameres: search_for_impls BytePos(41), X, "main.rs"
DEBUG 2019-08-09T06:48:22.390197890Z: racer::nameres: [run_matchers_on_blob] cxt: MatchCxt { filepath: "main.rs", search_str: "", range: ByteRange(57..177), search_type: StartsWith, is_local: true }, namespace: Const | Static | Func | Impl
TRACE 2019-08-09T06:48:22.390210843Z: racer::typeinf: searching fn args for self: |>(_: U) -> X {
        struct A;
        impl Foo for A {
            fn bar(&self) {}
        }
        X
    }| true
END
```


Discussion / hints:

Fix patch:
diff --git a/src/racer/typeinf.rs b/src/racer/typeinf.rs
index 9f267f49..4b8b693e 100644
--- a/src/racer/typeinf.rs
+++ b/src/racer/typeinf.rs
@@ -80,7 +80,7 @@ pub fn first_param_is_self(blob: &str) -> bool {
                 Some(..) => 0,
             };
             if let Some(start) = blob[skip_generic..].find('(') {
-                let start = BytePos::from(start).increment();
+                let start = BytePos::from(skip_generic + start).increment();
                 let end = scopes::find_closing_paren(blob, start);
                 let is_self = txt_matches(SearchType::ExactMatch, "self", &blob[start.0..end.0]);
                 trace!(


Test patch:
diff --git a/tests/system.rs b/tests/system.rs
index 57988797..4f7e7b76 100644
--- a/tests/system.rs
+++ b/tests/system.rs
@@ -1977,6 +1977,27 @@ fn finds_self_param_when_fn_has_generic_closure_arg() {
     assert_eq!("map", got.matchstr);
 }
 
+#[test]
+fn completes_static_method_containing_self() {
+    let src = "
+    struct X;
+    
+    impl X {
+        fn foo<T>(_: T) {
+            struct Y;
+            impl Y {
+                fn bar(&self) {}
+            }
+        }
+    }
+
+    X::~foo(0);
+    ";
+
+    let got = get_definition(src, None);
+    assert_eq!("foo", got.matchstr);
+}
+
 #[test]
 fn completes_methods_on_deref_generic_type() {
     let modsrc = "