Repository: intellij-rust/intellij-rust
Issue: "Implement members" lost parentheses on types during code generation

## Environment

* **IntelliJ Rust plugin version:**
  0.4.158.4203-212
* **Rust toolchain version:**
  stable-x86_64-unknown-linux-gnu (default)
  rustc 1.56.1 (59eed8a2a 2021-11-01)
* **IDE name and version:**
  CLion 2021.2.3
  Build #CL-212.5457.51, built on October 14, 2021
* **Operating system:**
  Linux 5.10.74-gentoo
  Current Desktop: KDE

## Problem description
Implementing function `fn source(&self) -> Option<&(dyn Error + 'static)>` from trait `std::error::Error` using IDE gives an error:
* Expected implementation signature: `fn source(&self) -> Option<&(dyn Error + 'static)>`
* Actual implementation signature: `fn source(&self) -> Option<&dyn Error + 'static>`

## Steps to reproduce
1. Start with this file:
```rust
#[derive(Debug)]
struct SomeError {}

impl std::fmt::Display for SomeError {
    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        todo!()
    }
}

impl std::error::Error for SomeError {
    // place text cursor here
}
```

2. Stand at designated point
3. Press `<Ctrl+I>` to open "Implement members" window
4. Select `source` function
5. Press "OK" or `<Enter>`
6. Next code will be generated:
```rust
    fn source(&self) -> Option<&dyn error::Error + 'static> {
        todo!()
    }
```
7. Try to compile. Next error will be shown:
```
error: ambiguous `+` in a type
  --> src/a.rs:13:33
   |
13 |     fn source(&self) -> Option<&dyn Error + 'static> {
   |                                 ^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Error + 'static)`
```

Changed files:
src/test/kotlin/org/rust/ide/refactoring/implementMembers/ImplementMembersHandlerTest.kt
src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt

diff --git a/src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt b/src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt
index 29a7cbf0a..325ff2c87 100644
--- a/src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt
+++ b/src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt
@@ -239,8 +239,14 @@ open class RsPsiRenderer(
         }
     }
 
-    open fun appendTypeReference(sb: StringBuilder, ref: RsTypeReference) {
-        when (val type = ref.skipParens()) {
+    open fun appendTypeReference(sb: StringBuilder, type: RsTypeReference) {
+        when (type) {
+            is RsParenType -> {
+                sb.append("(")
+                type.typeReference?.let { appendTypeReference(sb, it) }
+                sb.append(")")
+            }
+
             is RsTupleType -> {
                 val types = type.typeReferenceList
                 if (types.size == 1) {
@@ -317,10 +323,7 @@ open class RsPsiRenderer(
             is RsMacroType -> {
                 appendPath(sb, type.macroCall.path)
                 sb.append("!(")
-                val macroBody = type.macroCall.macroBody
-                if (macroBody != null) {
-                    sb.append(macroBody)
-                }
+                type.macroCall.macroBody?.let { sb.append(it) }
                 sb.append(")")
             }
         }
diff --git a/src/test/kotlin/org/rust/ide/refactoring/implementMembers/ImplementMembersHandlerTest.kt b/src/test/kotlin/org/rust/ide/refactoring/implementMembers/ImplementMembersHandlerTest.kt
index 8915e74b8..6a901a770 100644
--- a/src/test/kotlin/org/rust/ide/refactoring/implementMembers/ImplementMembersHandlerTest.kt
+++ b/src/test/kotlin/org/rust/ide/refactoring/implementMembers/ImplementMembersHandlerTest.kt
@@ -1774,6 +1774,30 @@ class ImplementMembersHandlerTest : RsTestBase() {
         }
     """)
 
+    fun `test type reference parentheses`() = doTest("""
+        trait T {}
+        trait Foo {
+            fn foo() -> &(dyn T + 'static);
+        }
+        struct S;
+        impl Foo for S {
+            /*caret*/
+        }
+    """, listOf(
+        ImplementMemberSelection("foo() -> &(dyn T + 'static)", byDefault = true)
+    ), """
+        trait T {}
+        trait Foo {
+            fn foo() -> &(dyn T + 'static);
+        }
+        struct S;
+        impl Foo for S {
+            fn foo() -> &(dyn T + 'static) {
+                todo!()
+            }
+        }
+    """)
+
     private data class ImplementMemberSelection(val member: String, val byDefault: Boolean, val isSelected: Boolean = byDefault)
 
     private fun doTest(