Repository: intellij-rust/intellij-rust
Issue: E0747 is not detected if order of arguments is wrong 

## Environment

* **IntelliJ Rust plugin version:** 0.4.163.4319-213-nightly
* **Rust toolchain version:** 1.59.0-nightly (0b42deacc 2021-12-09) x86_64-apple-darwin
* **IDE name and version:** CLion 2021.3 (CL-213.5744.254)
* **Operating system:** macOS 11.5.1
* **Macro expansion engine:** new
* **Name resolution engine:** new
* **Additional experimental features:** org.rust.cargo.features.settings.gutter, org.rust.cargo.evaluate.build.scripts, org.rust.macros.proc

## Problem description
Error is not detected if order of arguments is wrong 

## Steps to reproduce
There is a piece of code
```rust
mod foo {
    pub struct X<'a, 'b, 'c, T> {
        a: &'a str,
        b: &'b str,
        c: &'c str,
        t: T,
    }
}

fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
```
## Expected Results
E0747 is detected

## Actual Results
E0747 is not detected.

> error[E0747]: type provided when a lifetime was expected
>   --> src/main.rs:10:37
>    |
> 10 | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
>    |       

                          

Related to #8144 

Changed files:
src/main/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspection.kt
src/test/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspectionTest.kt

diff --git a/src/main/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspection.kt b/src/main/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspection.kt
index 221de5f29..dfd052c79 100644
--- a/src/main/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspection.kt
+++ b/src/main/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspection.kt
@@ -32,15 +32,34 @@ class RsWrongGenericArgumentsOrderInspection : RsLocalInspectionTool() {
         if (actualArguments == null) return
         val parameterList = declaration.typeParameterList ?: return
 
-        val params = parameterList.stubChildrenOfType<RsGenericParameter>().filterNot { it is RsLifetimeParameter }
-        val args = actualArguments.stubChildrenOfType<RsElement>().filter { it is RsTypeReference || it is RsExpr }
+        val explicitLifetimes = actualArguments.lifetimeArguments.isNotEmpty()
+
+        val params = parameterList.stubChildrenOfType<RsGenericParameter>().filter { param ->
+            when (param) {
+                is RsTypeParameter -> true
+                is RsConstParameter -> true
+                is RsLifetimeParameter -> explicitLifetimes
+                else -> false
+            }
+        }
+
+        val args = actualArguments.stubChildrenOfType<RsElement>().filter { arg ->
+            when (arg) {
+                is RsTypeReference -> true
+                is RsExpr -> true
+                is RsLifetime -> explicitLifetimes
+                else -> false
+            }
+        }
 
         val typeArguments = actualArguments.typeArguments
         val constArguments = actualArguments.constArguments
+        val lifetimeArguments = actualArguments.lifetimeArguments
 
         fun kindName(arg: RsElement): String = when (arg) {
             in typeArguments -> "Type"
             in constArguments -> "Constant"
+            in lifetimeArguments -> "Lifetime"
             else -> error("impossible")
         }
 
@@ -48,6 +67,7 @@ class RsWrongGenericArgumentsOrderInspection : RsLocalInspectionTool() {
             val text = when {
                 param is RsTypeParameter && arg !in typeArguments -> "${kindName(arg)} provided when a type was expected"
                 param is RsConstParameter && arg !in constArguments -> "${kindName(arg)} provided when a constant was expected"
+                param is RsLifetimeParameter && arg !in lifetimeArguments -> "${kindName(arg)} provided when a lifetime was expected"
                 else -> continue
             }
             val fixes = if (param is RsConstParameter && arg is RsTypeReference) {
diff --git a/src/test/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspectionTest.kt b/src/test/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspectionTest.kt
index df3ae4aac..3ad327bb5 100644
--- a/src/test/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspectionTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/RsWrongGenericArgumentsOrderInspectionTest.kt
@@ -8,20 +8,42 @@ package org.rust.ide.inspections
 class RsWrongGenericArgumentsOrderInspectionTest : RsInspectionsTestBase(RsWrongGenericArgumentsOrderInspection::class) {
 
     fun `test mismatch (expr)`() = checkByText("""
-        struct Foo<T>(T);
-        struct Bar<const N: i32>;
+        struct SFoo<T>(T);
+        struct SBar<const N: i32>;
+        struct SBaz<'a>(&'a str);
+
+        trait TFoo<T> {}
+        trait TBar<const N: i32> {}
+        trait TBaz<'a> {}
+
         fn foo<T>() {}
         fn bar<const N: i32>() {}
-        fn baz<'a, T, const N: i32>(
-            p1: Foo<T>,
-            p2: Foo<<error descr="Constant provided when a type was expected [E0747]">N</error>>,
-            p3: Bar<<error descr="Type provided when a constant was expected [E0747]">T</error>>,
-            p4: Bar<N>
-        ) {
+        fn baz<'a>() {}
+
+        impl<T> TFoo<T> for SFoo<T> {}
+        impl<const N: i32> TFoo<<error descr="Constant provided when a type was expected [E0747]">N</error>> for SFoo<<error descr="Constant provided when a type was expected [E0747]">N</error>> {}
+        impl<'a> TFoo<<error descr="Lifetime provided when a type was expected [E0747]">'a</error>> for SFoo<<error descr="Lifetime provided when a type was expected [E0747]">'a</error>> {}
+
+        impl<T> TBar<<error descr="Type provided when a constant was expected [E0747]">T</error>> for SBar<<error descr="Type provided when a constant was expected [E0747]">T</error>> {}
+        impl<const N: i32> TBar<N> for SBar<N> {}
+        impl<'a> TBar<<error descr="Lifetime provided when a constant was expected [E0747]">'a</error>> for SBar<<error descr="Lifetime provided when a constant was expected [E0747]">'a</error>> {}
+
+        impl<T> TBaz<T> for SBaz<T> {}
+        impl<const N: i32> TBaz<N> for SBaz<N> {}
+        impl<'a> TBaz<'a> for SBaz<'a> {}
+
+        fn test<'a, T, const N: i32>() {
             foo::<T>();
             foo::<<error descr="Constant provided when a type was expected [E0747]">N</error>>();
+            foo::<<error descr="Lifetime provided when a type was expected [E0747]">'a</error>>();
+
             bar::<<error descr="Type provided when a constant was expected [E0747]">T</error>>();
             bar::<N>();
+            bar::<<error descr="Lifetime provided when a constant was expected [E0747]">'a</error>>();
+
+            baz::<T>();
+            baz::<N>();
+            baz::<'a>();
         }
     """)