Repository: intellij-rust/intellij-rust
Issue: Incorrect duplicate parameter name error

## Environment

* **Intellij-Rust plugin version:** v0.2.0.2114-183
* **Rust toolchain version:** rustc 1.33.0-nightly (a2b0f247b 2018-12-30)
* **IDE name and version:** CLion 2018.3.3
* **Operating system:** Windows 10 1809

## Problem description

A function taking another function as callback where parameter names match will fail the plugin's check for duplicate names, but pass rustc's.

## Steps to reproduce

```rust
fn foo(a: i32, b: fn (a: i32)) {}
```

This reports an error in the IDE but not to `cargo check`.


Changed files:
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 f9464cbe1..802ccfb03 100644
--- a/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
+++ b/src/main/kotlin/org/rust/ide/annotator/RsErrorAnnotator.kt
@@ -438,11 +438,13 @@ private fun checkDuplicates(holder: AnnotationHolder, element: RsNameIdentifierO
 }
 
 private fun AnnotationSession.duplicatesByNamespace(owner: PsiElement, recursively: Boolean): Map<Namespace, Set<PsiElement>> {
+    if (owner.parent is RsFnPointerType) return emptyMap()
+
     val fileMap = fileDuplicatesMap()
     fileMap[owner]?.let { return it }
 
     val duplicates: Map<Namespace, Set<PsiElement>> =
-        owner.namedChildren(recursively)
+        owner.namedChildren(recursively, stopAt = RsFnPointerType::class.java)
             .filter { it !is RsExternCrateItem } // extern crates can have aliases.
             .filter { it.name != null }
             .flatMap { it.namespaced }
@@ -466,12 +468,18 @@ private fun AnnotationSession.duplicatesByNamespace(owner: PsiElement, recursive
     return duplicates
 }
 
-private fun PsiElement.namedChildren(recursively: Boolean): Sequence<RsNamedElement> =
-    if (recursively) {
-        descendantsOfType<RsNamedElement>().asSequence()
-    } else {
-        children.asSequence().filterIsInstance<RsNamedElement>()
+private fun PsiElement.namedChildren(recursively: Boolean, stopAt: Class<*>? = null): Sequence<RsNamedElement> {
+    val result = mutableListOf<RsNamedElement>()
+    fun go(element: PsiElement) {
+        if (stopAt?.isInstance(element) == true) return
+        for (child in element.children) {
+            if (child is RsNamedElement) result.add(child)
+            if (recursively) go(child)
+        }
     }
+    go(this)
+    return result.asSequence()
+}
 
 private val DUPLICATES_BY_SCOPE = Key<MutableMap<
     PsiElement,
diff --git a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
index ffd5723c1..e42cae384 100644
--- a/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/RsErrorAnnotatorTest.kt
@@ -493,6 +493,7 @@ class RsErrorAnnotatorTest : RsAnnotatorTestBase(RsErrorAnnotator::class.java) {
                   b: bool,
                   <error>a</error>: f64) {}
         fn tuples(<error>a</error>: u8, (b, (<error>a</error>, c)): (u16, (u32, u64))) {}
+        fn fn_ptrs(x: i32, y: fn (x: i32, y: i32), z: fn (x: i32, x: i32)) {}
     """)
 
     fun `test undeclared label E0426`() = checkErrors("""