Repository: intellij-rust/intellij-rust
Issue: Marks Fn* implementing unit struct call like function as an error.

<!--
Hello and thank you for the issue!
If you would like to report a bug, we have added some points below that you can fill out.
Feel free to remove all the irrelevant text to request a new feature.
-->

## Environment

* **IntelliJ Rust plugin version:** v0.2.101.2129-191
* **Rust toolchain version:** `rustc 1.35.0-nightly (3de010678 2019-04-11)`
* **IDE name and version:** CLion 2019.1.4 and Intellij IDEA
* **Operating system:** Windows 10

## Problem description
While developing [overloadable](https://github.com/OptimisticPeach/overloadable), I noticed that intellij cannot understand a situation such as the following:

- `struct x;`
- We implement `FnOnce<()> for x`.
- We try to call `x` as if it were a function:
```rust
x();
```
But we get
```
Expected function, found `x` [E0618]
```
It should be callable, just not like a standard function, as though what we're saying is 
```rust
let x_ = x;
(x as FnOnce<()>)::call(x_, ());
```
## Steps to reproduce
This minimal example causes the error:
```rust
struct Foo;
impl FnOnce<()> for Foo {
    type Output = ();
    fn call_once(self, (): ()) {}
}

fn bar() {
    Foo();
}
```
And trying to use my crate (overloadable) also breaks it. 

Thanks for intellij-rust! This is an awesome plugin!

Changed files:
src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt, src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt, src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt

diff --git a/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt b/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
index 287df2800..dab48c123 100644
--- a/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
+++ b/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
@@ -28,6 +28,7 @@ import org.rust.lang.core.resolve.knownItems
 import org.rust.lang.core.resolve.namespaces
 import org.rust.lang.core.resolve.ref.deepResolve
 import org.rust.lang.core.types.TraitRef
+import org.rust.lang.core.types.asTy
 import org.rust.lang.core.types.inference
 import org.rust.lang.core.types.ty.*
 import org.rust.lang.core.types.type
@@ -152,7 +153,7 @@ class RsErrorAnnotator : RsAnnotatorBase(), HighlightRangeExtension {
         checkNotCallingDrop(o, holder)
         val deepResolve = path.reference.deepResolve()
         val owner = deepResolve as? RsFieldsOwner ?: return
-        if (owner.tupleFields == null) {
+        if (owner.tupleFields == null && !owner.implLookup.isAnyFn(owner.asTy())) {
             RsDiagnostic.ExpectedFunction(o).addToHolder(holder)
         }
     }
diff --git a/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt b/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
index ee3f48683..492f853dd 100644
--- a/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
+++ b/src/main/kotlin/org/rust/lang/core/resolve/ImplLookup.kt
@@ -729,6 +729,11 @@ class ImplLookup(
     fun isDefault(ty: Ty): Boolean = ty.isTraitImplemented(items.Default)
     fun isPartialEq(ty: Ty, rhsType: Ty = ty): Boolean = ty.isTraitImplemented(items.PartialEq, rhsType)
     fun isIntoIterator(ty: Ty): Boolean = ty.isTraitImplemented(items.IntoIterator)
+    fun isFn(ty: Ty): Boolean = ty.isTraitImplemented(items.Fn)
+    fun isFnOnce(ty: Ty): Boolean = ty.isTraitImplemented(items.FnOnce)
+    fun isFnMut(ty: Ty): Boolean = ty.isTraitImplemented(items.FnMut)
+    fun isAnyFn(ty: Ty): Boolean = isFn(ty) || isFnOnce(ty) || isFnMut(ty)
+
 
     private fun Ty.isTraitImplemented(trait: RsTraitItem?, vararg subst: Ty): Boolean {
         if (trait == null) return false
diff --git a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
index ad05984cb..17485ccbc 100644
--- a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
@@ -1644,6 +1644,73 @@ class RsErrorAnnotatorTest : RsAnnotatorTestBase(RsErrorAnnotator::class.java) {
         }
     """)
 
+    fun `test expected function on a impl NotFn E0618`() = checkErrors("""
+        struct Foo;
+        trait NotFn<Args> {
+            type Output;
+            fn call(&self, args: Args) -> Self::Output;
+        }
+        impl NotFn<()> for Foo {
+            type Output = ();
+            fn call(&self, (): ()) {}
+        }
+        
+        fn bar() {
+            <error descr="Expected function, found `Foo` [E0618]">Foo</error>();
+        }
+    """)
+
+    fun `test expected function on a impl FnOnce E0618`() = checkErrors("""
+        struct Foo;
+        #[lang = "fn_once"]
+        trait FnOnce<Args> {
+            type Output;
+            fn call_once(self, args: Args) -> Self::Output;
+        }
+        impl FnOnce<()> for Foo {
+            type Output = ();
+            fn call_once(self, (): ()) {}
+        }
+        
+        fn bar() {
+            Foo();
+        }
+    """)
+
+    fun `test expected function on a impl FnMut E0618`() = checkErrors("""
+        struct Foo;
+        #[lang = "fn_mut"]
+        trait FnMut<Args> {
+            type Output;
+            fn call(&mut self, args: Args) -> Self::Output;
+        }
+        impl FnMut<()> for Foo {
+            type Output = ();
+            fn call(&mut self, (): ()) {}
+        }
+        
+        fn bar() {
+            Foo();
+        }
+    """)
+
+    fun `test expected function on a impl Fn E0618`() = checkErrors("""
+        struct Foo;
+        #[lang = "fn"]
+        trait Fn<Args> {
+            type Output;
+            fn call(&self, args: Args) -> Self::Output;
+        }
+        impl Fn<()> for Foo {
+            type Output = ();
+            fn call(&self, (): ()) {}
+        }
+        
+        fn bar() {
+            Foo();
+        }
+    """)
+
     @MockRustcVersion("1.34.0")
     fun `test label_break_value 1`() = checkErrors("""
         fn main() {