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

Issue:
`E0061` was not detected
## Environment

* **IntelliJ Rust plugin version:** `0.2.126.SNAPSHOT-201-dev`
* **Rust toolchain version:** `rustc 1.46.0-nightly (feb3536eb 2020-06-09)` 
* **IDE name and version:** `IntelliJ IDEA 2020.1.2 (Ultimate Edition)`
* **Operating system:** `Windows 10 10.0`

## Problem description
```rust
use rand::{Rng, thread_rng};

fn main() {
    let mut rng = thread_rng();

    println!("{}", rng.gen_bool()); // No error here
}
```

```rust
error[E0061]: this function takes 1 argument but 0 arguments were supplied
 --> src\main.rs:6:24
  |
6 |     println!("{}", rng.gen_bool());
  |                        ^^^^^^^^- supplied 0 arguments
  |                        |
  |                        expected 1 argument
```


Discussion / hints:
Related to this line of code:

https://github.com/intellij-rust/intellij-rust/blob/4c55740646481883dd032b778aa15dad966f3523/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt#L1171
E0061 is turned off for trait methods because of errors in name resolution. It's stated in the original commit/PR that introduced the
E0061 annotation. I checked the example that was failing a few years ago and it still fails, so it should probably stay turned off for now.
Oh, [`test ignores trait implementations E0061` test](https://github.com/intellij-rust/intellij-rust/blob/ed366d911bfecca3ed9cd875b06301c8314fa1b6/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt#L336) is really interesting! I think I still don't understand the Rust type inference algorithms because I don't understand why it should be resolved to `Foo1`!
Oh, I found the reason. We don't add implicit `T: Sized` bounds to generics. 

Fix patch:
diff --git a/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt b/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
index 0ef2550dffe..b600b7db872 100644
--- a/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
+++ b/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
@@ -1762,8 +1762,6 @@ fun RsCallExpr.getFunctionCallContext(): FunctionCallContext? {
     return when (val calleeType = expr.adjustedType) {
         is TyFunctionDef -> {
             val callable = calleeType.def
-            val owner = callable.owner
-            if (owner.isTraitImpl) return null
             val count = callable.parameterTypes.size
             val s = if (callable.selfParameter != null) 1 else 0
             val functionType = if (callable.isVariadic) {
@@ -1790,7 +1788,7 @@ fun RsMethodCall.getFunctionCallContext(): FunctionCallContext? {
     val fn = reference.resolve() as? RsFunction ?: return null
     return fn.valueParameterList?.valueParameterList?.size?.let {
         FunctionCallContext(it, if (fn.isVariadic) FunctionType.VARIADIC_FUNCTION else FunctionType.FUNCTION, fn)
-    }.takeIf { fn.owner.isInherentImpl }
+    }
 }
 
 private fun isValidSelfSuperPrefix(path: RsPath): Boolean {


Test patch:
diff --git a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
index 75686ecb64a..e5b792dcf42 100644
--- a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
@@ -406,9 +406,8 @@ class RsErrorAnnotatorTest : RsAnnotatorTestBase(RsErrorAnnotator::class) {
         }
     """)
 
-    // We would like to cover such cases, but the resolve engine has some flaws at the moment,
-    // so just ignore trait implementations to remove false positives
-    fun `test ignores trait implementations E0061`() = checkErrors("""
+    @ProjectDescriptor(WithStdlibRustProjectDescriptor::class)
+    fun `test trait implementations E0061`() = checkErrors("""
         trait Foo1 { fn foo(&self); }
         trait Foo2 { fn foo(&self, a: u8); }
         struct Bar;
@@ -418,11 +417,32 @@ class RsErrorAnnotatorTest : RsAnnotatorTestBase(RsErrorAnnotator::class) {
         impl<T> Foo2 for Box<T> {
             fn foo(&self, a: u8) {}
         }
-        type BFoo1<'a> = Box<Foo1 + 'a>;
+        type BFoo1<'a> = Box<dyn Foo1 + 'a>;
 
         fn main() {
             let bar: BFoo1 = Box::new(Bar);
-            bar.foo();   // Resolves to Foo2.foo() for Box<T>, though Foo1.foo() for Bar is the correct one
+            bar.foo();
+            bar.foo(/*error descr="This function takes 0 parameters but 1 parameter was supplied [E0061]"*/1/*error**/);
+        }
+    """)
+
+    fun `test trait implementation E0061`() = checkErrors("""
+        trait Foo { fn foo(&self); }
+        struct Bar;
+        impl Foo for Bar {
+            fn foo(&self) {}
+        }
+
+        fn main() {
+            let bar = Bar {};
+            bar.foo();
+            bar.foo(/*error descr="This function takes 0 parameters but 1 parameter was supplied [E0061]"*/1/*error**/);
+
+            Foo::foo(&bar);
+            Foo::foo(&bar, /*error descr="This function takes 1 parameter but 2 parameters were supplied [E0061]"*/1/*error**/);
+
+            Bar::foo(&bar);
+            Bar::foo(&bar, /*error descr="This function takes 1 parameter but 2 parameters were supplied [E0061]"*/1/*error**/);
         }
     """)
 
diff --git a/src/test/kotlin/org/rust/ide/annotator/fixes/ReplaceWithStdMemDropFixTest.kt b/src/test/kotlin/org/rust/ide/annotator/fixes/ReplaceWithStdMemDropFixTest.kt
index d3857e64717..9c6cd21e8ed 100644
--- a/src/test/kotlin/org/rust/ide/annotator/fixes/ReplaceWithStdMemDropFixTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/fixes/ReplaceWithStdMemDropFixTest.kt
@@ -52,7 +52,7 @@ class ReplaceWithStdMemDropFixTest : RsAnnotatorTestBase(RsErrorAnnotator::class
 
         fn main() {
             let mut x = X {};
-            <error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">X::drop/*caret*/</error>(&mut x, 123, "foo");
+            <error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">X::drop/*caret*/</error>(&mut x, /*error*/123, "foo"/*error**/);
         }
     """, """
         struct X;
@@ -173,7 +173,7 @@ class ReplaceWithStdMemDropFixTest : RsAnnotatorTestBase(RsErrorAnnotator::class
 
         fn main() {
             let mut x = X {};
-            x.<error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">drop/*caret*/</error>(123, "foo");
+            x.<error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">drop/*caret*/</error>(/*error*/123, "foo"/*error**/);
         }
     """, """
         struct X;
@@ -248,7 +248,7 @@ class ReplaceWithStdMemDropFixTest : RsAnnotatorTestBase(RsErrorAnnotator::class
         }
 
         fn main() {
-            XFactory {}.create_x(123).<error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">drop/*caret*/</error>(123, "foo");
+            XFactory {}.create_x(123).<error descr="Explicit calls to `drop` are forbidden. Use `std::mem::drop` instead [E0040]">drop/*caret*/</error>(/*error*/123, "foo"/*error**/);
         }
     """, """
         struct X;