Repository: intellij-rust/intellij-rust
Issue: Incorrect `Elide lifetimes` suggestion with associated type lifetimes inside `Fn` trait

## Environment

* **IntelliJ Rust plugin version:** 0.4.187.5156-223-nightly
* **Rust toolchain version:** 1.66.0 (69f9c33d7 2022-12-12) x86_64-unknown-linux-gnu
* **IDE name and version:** CLion 2022.3.1 (CL-223.8214.51)
* **Operating system:** Linux 6.1.6-zen1-1-zen
* **Macro expansion:** enabled
* **Additional experimental features:** org.rust.macros.proc.attr, org.rust.cargo.emulate.terminal, org.rust.macros.proc

## Problem description
Appling `Elide lifetimes` suggestion results in incorrect code (E0107 missing generics for associated type).
Introduced in #9842

## Steps to reproduce
```rust
trait Trait {
    type AssocType<'a>;
    fn foo<'a>(_: &'a str, _: impl Fn(Self::AssocType<'a>)) -> &'a i32 { unimplemented!() }
}
```

Changed files:
src/main/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspection.kt
src/test/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspectionTest.kt

diff --git a/src/main/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspection.kt b/src/main/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspection.kt
index a64062254..432c52ea7 100644
--- a/src/main/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspection.kt
+++ b/src/main/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspection.kt
@@ -146,11 +146,23 @@ private class LifetimesCollector(val isForInputParams: Boolean = false) : RsRecu
     override fun visitElement(element: RsElement) {
         if (abort) return
         if (element is RsItemElement) return  // ignore nested items
-        if (element is RsFnPointerType) return  // ignore `fn(&i32)`
-        if (element is RsPath && element.valueParameterList != null) return  // ignore `Fn(&i32)`
+        if (processFnPointerOrFnTrait(element)) return
         element.forEachChild { it.accept(this) }
     }
 
+    private fun processFnPointerOrFnTrait(element: RsElement): Boolean {
+        val isFnPointer = element is RsFnPointerType  // `fn(...)`
+        val isFnTrait = element is RsPath && element.valueParameterList != null  // `Fn(...)`
+        if (!isFnPointer && !isFnTrait) return false
+
+        // Ignore parameter lifetimes `Fn(&'a i32)` but process path lifetimes `Fn(Self::AssocType<'a>)`
+        for (path in element.descendantsOfType<RsPath>()) {
+            collectAnonymousLifetimes(path)
+            path.typeArgumentList?.lifetimeList?.forEach(::record)
+        }
+        return true
+    }
+
     private fun record(lifetime: RsLifetime?) {
         lifetimes.add(lifetime.typedName.toReferenceLifetime())
     }
diff --git a/src/test/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspectionTest.kt b/src/test/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspectionTest.kt
index 6cac2e935..8f1311580 100644
--- a/src/test/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspectionTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/lints/RsNeedlessLifetimesInspectionTest.kt
@@ -44,18 +44,32 @@ class RsNeedlessLifetimesInspectionTest : RsInspectionsTestBase(RsNeedlessLifeti
         fn <caret>foo(x: &str) -> Box<&str> { unimplemented!() }
     """)
 
-    fun `test one input lifetime 4 (fn pointer)`() = doTest("""
+    fun `test one input lifetime (fn pointer with parameter lifetime)`() = doTest("""
         /*weak_warning*/fn /*caret*/foo<'a>(s: &'a str, b: fn(&'a i32)) -> &'a i32/*weak_warning**/ { unimplemented!() }
     """, """
         fn foo(s: &str, b: fn(&i32)) -> &i32 { unimplemented!() }
     """)
 
-    fun `test one input lifetime 5 (Fn trait)`() = doTest("""
+    fun `test one input lifetime (Fn trait with parameter lifetime)`() = doTest("""
         /*weak_warning*/fn /*caret*/foo<'a>(s: &'a str, b: impl Fn(&'a i32)) -> &'a i32/*weak_warning**/ { unimplemented!() }
     """, """
         fn foo(s: &str, b: impl Fn(&i32)) -> &i32 { unimplemented!() }
     """)
 
+    fun `test one input lifetime (fn pointer with path lifetime)`() = doTest("""
+        trait Trait {
+            type AssocType<'a>;
+            fn foo<'a>(_: &'a str, _: fn(Self::AssocType<'a>)) -> &'a i32 { unimplemented!() }
+        }
+    """)
+
+    fun `test one input lifetime (Fn trait with path lifetime)`() = doTest("""
+        trait Trait {
+            type AssocType<'a>;
+            fn foo<'a>(_: &'a str, _: impl Fn(Self::AssocType<'a>)) -> &'a i32 { unimplemented!() }
+        }
+    """)
+
     fun `test no input lifetimes`() = doTest("""
         fn foo() -> &str { unimplemented!() }
     """)