Repository: rust-lang/rust-analyzer
Pull request #18809 (2025-01-01 12:41:25)

internal: Do not render closure ids in hover messages
They are not useful


Patch:
diff --git a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
index 4313cc1ac9..56dd6cf29a 100644
--- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
@@ -17,7 +17,7 @@ use syntax::{
 };
 
 use crate::{
-    utils::{does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block},
+    utils::{does_nested_pattern, does_pat_match_variant, unwrap_trivial_block},
     AssistContext, AssistId, AssistKind, Assists,
 };
 
@@ -163,7 +163,7 @@ fn make_else_arm(
                 Some(it) => {
                     if does_pat_match_variant(pat, &it.sad_pattern()) {
                         it.happy_pattern_wildcard()
-                    } else if does_pat_variant_nested_or_literal(ctx, pat) {
+                    } else if does_nested_pattern(pat) {
                         make::wildcard_pat().into()
                     } else {
                         it.sad_pattern()
@@ -702,11 +702,11 @@ fn main() {
     }
 
     #[test]
-    fn test_if_let_with_match_nested_tuple_struct() {
+    fn nested_type() {
         check_assist(
             replace_if_let_with_match,
             r#"
-//- minicore: result, option
+//- minicore: result
 fn foo(x: Result<i32, ()>) {
     let bar: Result<_, ()> = Ok(Some(1));
     $0if let Ok(Some(_)) = bar {
@@ -724,700 +724,6 @@ fn foo(x: Result<i32, ()>) {
         _ => (),
     }
 }
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-struct MyStruct(i32, i32);
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2));
-    $0if let Ok(MyStruct(a, b)) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-struct MyStruct(i32, i32);
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2));
-    match bar {
-        Ok(MyStruct(a, b)) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_slice() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<&[i32], ()>) {
-    let foo: Result<&[_], ()> = Ok(&[0, 1, 2]);
-    $0if let Ok([]) = foo {
-        ()
-    } else {
-        ()
-    }
-}
-        "#,
-            r#"
-fn foo(x: Result<&[i32], ()>) {
-    let foo: Result<&[_], ()> = Ok(&[0, 1, 2]);
-    match foo {
-        Ok([]) => (),
-        _ => (),
-    }
-}
-        "#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<[&'static str; 2], ()>) {
-    let foobar: Result<_, ()> = Ok(["foo", "bar"]);
-    $0if let Ok([_, "bar"]) = foobar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<[&'static str; 2], ()>) {
-    let foobar: Result<_, ()> = Ok(["foo", "bar"]);
-    match foobar {
-        Ok([_, "bar"]) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<[&'static str; 2], ()>) {
-    let foobar: Result<_, ()> = Ok(["foo", "bar"]);
-    $0if let Ok([..]) = foobar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<[&'static str; 2], ()>) {
-    let foobar: Result<_, ()> = Ok(["foo", "bar"]);
-    match foobar {
-        Ok([..]) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<&[&'static str], ()>) {
-    let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
-    $0if let Ok([a, ..]) = foobar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<&[&'static str], ()>) {
-    let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
-    match foobar {
-        Ok([a, ..]) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<&[&'static str], ()>) {
-    let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
-    $0if let Ok([a, .., b, c]) = foobar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<&[&'static str], ()>) {
-    let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]);
-    match foobar {
-        Ok([a, .., b, c]) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<Option<[&'static str; 2]>, ()>) {
-    let foobar: Result<_, ()> = Ok(Some(["foo", "bar"]));
-    $0if let Ok(Some([_, "bar"])) = foobar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<Option<[&'static str; 2]>, ()>) {
-    let foobar: Result<_, ()> = Ok(Some(["foo", "bar"]));
-    match foobar {
-        Ok(Some([_, "bar"])) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_literal() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<&'static str, ()>) {
-    let bar: Result<&_, ()> = Ok("bar");
-    $0if let Ok("foo") = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<&'static str, ()>) {
-    let bar: Result<&_, ()> = Ok("bar");
-    match bar {
-        Ok("foo") => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_tuple() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32, i32), ()>) {
-    let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
-    $0if let Ok((1, second, third)) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32, i32), ()>) {
-    let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
-    match bar {
-        Ok((1, second, third)) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32, i32), ()>) {
-    let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
-    $0if let Ok((first, second, third)) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32, i32), ()>) {
-    let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3));
-    match bar {
-        Ok((first, second, third)) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_or() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(1 | 2) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(1 | 2) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 2));
-    $0if let Ok((b, a) | (a, b)) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 2));
-    match bar {
-        Ok((b, a) | (a, b)) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 2));
-    $0if let Ok((1, a) | (a, 2)) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 2));
-    match bar {
-        Ok((1, a) | (a, 2)) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_range() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(1..2) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(1..2) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_paren() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 1));
-    $0if let Ok(((1, 2))) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 1));
-    match bar {
-        Ok(((1, 2))) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 1));
-    $0if let Ok(((a, b))) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<(i32, i32), ()>) {
-    let bar: Result<(i32, i32), ()> = Ok((1, 1));
-    match bar {
-        Ok(((a, b))) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_macro() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    macro_rules! is_42 {
-        () => {
-            42
-        };
-    }
-
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(is_42!()) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    macro_rules! is_42 {
-        () => {
-            42
-        };
-    }
-
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(is_42!()) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_path() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-enum MyEnum {
-    Foo,
-    Bar,
-}
-
-fn foo(x: Result<MyEnum, ()>) {
-    let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo);
-    $0if let Ok(MyEnum::Foo) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-enum MyEnum {
-    Foo,
-    Bar,
-}
-
-fn foo(x: Result<MyEnum, ()>) {
-    let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo);
-    match bar {
-        Ok(MyEnum::Foo) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_record() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    $0if let Ok(MyStruct { foo, bar }) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    match bar {
-        Ok(MyStruct { foo, bar }) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    $0if let Ok(MyStruct { foo, bar: 12 }) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    match bar {
-        Ok(MyStruct { foo, bar: 12 }) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    $0if let Ok(MyStruct { foo, .. }) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-struct MyStruct {
-    foo: i32,
-    bar: i32,
-}
-
-fn foo(x: Result<MyStruct, ()>) {
-    let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 });
-    match bar {
-        Ok(MyStruct { foo, .. }) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-enum MyEnum {
-    Foo(i32, i32),
-    Bar { a: i32, b: i32 },
-}
-
-fn foo(x: Result<MyEnum, ()>) {
-    let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2));
-    $0if let Ok(MyEnum::Bar { a, b }) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-enum MyEnum {
-    Foo(i32, i32),
-    Bar { a: i32, b: i32 },
-}
-
-fn foo(x: Result<MyEnum, ()>) {
-    let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2));
-    match bar {
-        Ok(MyEnum::Bar { a, b }) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn test_if_let_with_match_nested_ident() {
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(a @ 1..2) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(a @ 1..2) => (),
-        _ => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(a) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(a) => (),
-        Err(_) => (),
-    }
-}
-"#,
-        );
-
-        check_assist(
-            replace_if_let_with_match,
-            r#"
-//- minicore: result
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    $0if let Ok(a @ b @ c @ d) = bar {
-        ()
-    } else {
-        ()
-    }
-}
-"#,
-            r#"
-fn foo(x: Result<i32, ()>) {
-    let bar: Result<i32, ()> = Ok(1);
-    match bar {
-        Ok(a @ b @ c @ d) => (),
-        Err(_) => (),
-    }
-}
 "#,
         );
     }
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index ce0bd46e6f..3c26b04359 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -316,73 +316,43 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool {
     pat_head == var_head
 }
 
-pub(crate) fn does_pat_variant_nested_or_literal(ctx: &AssistContext<'_>, pat: &ast::Pat) -> bool {
-    check_pat_variant_nested_or_literal_with_depth(ctx, pat, 0)
-}
-
-fn check_pat_variant_from_enum(ctx: &AssistContext<'_>, pat: &ast::Pat) -> bool {
-    ctx.sema.type_of_pat(pat).map_or(true, |ty: hir::TypeInfo| {
-        ty.adjusted().as_adt().map_or(false, |adt| matches!(adt, hir::Adt::Enum(_)))
-    })
-}
+pub(crate) fn does_nested_pattern(pat: &ast::Pat) -> bool {
+    let depth = calc_depth(pat, 0);
 
-fn check_pat_variant_nested_or_literal_with_depth(
-    ctx: &AssistContext<'_>,
-    pat: &ast::Pat,
-    depth_after_refutable: usize,
-) -> bool {
-    if depth_after_refutable > 1 {
+    if 1 < depth {
         return true;
     }
+    false
+}
 
+fn calc_depth(pat: &ast::Pat, depth: usize) -> usize {
     match pat {
-        ast::Pat::RestPat(_) | ast::Pat::WildcardPat(_) | ast::Pat::RefPat(_) => false,
-
-        ast::Pat::LiteralPat(_)
-        | ast::Pat::RangePat(_)
+        ast::Pat::IdentPat(_)
+        | ast::Pat::BoxPat(_)
+        | ast::Pat::RestPat(_)
+        | ast::Pat::LiteralPat(_)
         | ast::Pat::MacroPat(_)
+        | ast::Pat::OrPat(_)
+        | ast::Pat::ParenPat(_)
         | ast::Pat::PathPat(_)
-        | ast::Pat::BoxPat(_)
-        | ast::Pat::ConstBlockPat(_) => true,
-
-        ast::Pat::IdentPat(ident_pat) => ident_pat.pat().map_or(false, |pat| {
-            check_pat_variant_nested_or_literal_with_depth(ctx, &pat, depth_after_refutable)
-        }),
-        ast::Pat::ParenPat(paren_pat) => paren_pat.pat().map_or(true, |pat| {
-            check_pat_variant_nested_or_literal_with_depth(ctx, &pat, depth_after_refutable)
-        }),
-        ast::Pat::TuplePat(tuple_pat) => tuple_pat.fields().any(|pat| {
-            check_pat_variant_nested_or_literal_with_depth(ctx, &pat, depth_after_refutable)
-        }),
-        ast::Pat::RecordPat(record_pat) => {
-            let adjusted_next_depth =
-                depth_after_refutable + if check_pat_variant_from_enum(ctx, pat) { 1 } else { 0 };
-            record_pat.record_pat_field_list().map_or(true, |pat| {
-                pat.fields().any(|pat| {
-                    pat.pat().map_or(true, |pat| {
-                        check_pat_variant_nested_or_literal_with_depth(
-                            ctx,
-                            &pat,
-                            adjusted_next_depth,
-                        )
-                    })
-                })
-            })
-        }
-        ast::Pat::OrPat(or_pat) => or_pat.pats().any(|pat| {
-            check_pat_variant_nested_or_literal_with_depth(ctx, &pat, depth_after_refutable)
-        }),
-        ast::Pat::TupleStructPat(tuple_struct_pat) => {
-            let adjusted_next_depth =
-                depth_after_refutable + if check_pat_variant_from_enum(ctx, pat) { 1 } else { 0 };
-            tuple_struct_pat.fields().any(|pat| {
-                check_pat_variant_nested_or_literal_with_depth(ctx, &pat, adjusted_next_depth)
-            })
-        }
-        ast::Pat::SlicePat(slice_pat) => {
-            let mut pats = slice_pat.pats();
-            pats.next() // Edge case for `[..]`
-                .map_or(true, |pat| !matches!(pat, ast::Pat::RestPat(_)) || pats.next().is_some())
+        | ast::Pat::WildcardPat(_)
+        | ast::Pat::RangePat(_)
+        | ast::Pat::RecordPat(_)
+        | ast::Pat::RefPat(_)
+        | ast::Pat::SlicePat(_)
+        | ast::Pat::TuplePat(_)
+        | ast::Pat::ConstBlockPat(_) => depth,
+
+        // FIXME: Other patterns may also be nested. Currently it simply supports only `TupleStructPat`
+        ast::Pat::TupleStructPat(pat) => {
+            let mut max_depth = depth;
+            for p in pat.fields() {
+                let d = calc_depth(&p, depth + 1);
+                if d > max_depth {
+                    max_depth = d
+                }
+            }
+            max_depth
         }
     }
 }
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 03ab9d1ba4..9d55827fe2 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -890,12 +890,11 @@ fn closure_ty(
     } else {
         String::new()
     };
-    let mut markup = format!("```rust\n{}", c.display_with_id(sema.db, edition));
+    let mut markup = format!("```rust\n{}\n```", c.display_with_impl(sema.db, edition));
 
     if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db).into()) {
         push_new_def(hir::Trait::from(trait_).into())
     }
-    format_to!(markup, "\n{}\n```", c.display_with_impl(sema.db, edition),);
     if let Some(layout) =
         render_memory_layout(config.memory_layout, || original.layout(sema.db), |_| None, |_| None)
     {
diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs
index cfe8657fd0..5afb98cb1c 100644
--- a/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/crates/ide/src/inlay_hints/binding_mode.rs
@@ -61,7 +61,6 @@ pub(super) fn hints(
         }
         hint.label.append_str(r);
     });
-    hint.pad_right = was_mut_last;
     let acc_base = acc.len();
     match pat {
         ast::Pat::IdentPat(pat) if pat.ref_token().is_none() && pat.mut_token().is_none() => {
@@ -86,6 +85,7 @@ pub(super) fn hints(
         }
         ast::Pat::OrPat(pat) if !pattern_adjustments.is_empty() && outer_paren_pat.is_none() => {
             hint.label.append_str("(");
+            was_mut_last = false;
             acc.push(InlayHint::closing_paren_after(
                 InlayKind::BindingMode,
                 pat.syntax().text_range(),
@@ -94,6 +94,7 @@ pub(super) fn hints(
         _ => (),
     }
     if !hint.label.parts.is_empty() {
+        hint.pad_right = was_mut_last;
         acc.push(hint);
     }
 


Test patch:
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index aca7bd3751..de5a657bf3 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -348,7 +348,6 @@ fn main() {
         expect![[r#"
             *|*
             ```rust
-            {closure#0}
             impl Fn(i32) -> i32
             ```
             ___
@@ -372,7 +371,6 @@ fn main() {
         expect![[r#"
             *|*
             ```rust
-            {closure#0}
             impl Fn(i32) -> i32
             ```
             ___
@@ -407,7 +405,6 @@ fn main() {
         expect![[r#"
             *|*
             ```rust
-            {closure#0}
             impl FnOnce()
             ```
             ___
@@ -437,7 +434,6 @@ fn main() {
         expect![[r#"
             *|*
             ```rust
-            {closure#0}
             impl FnMut()
             ```
             ___
@@ -463,7 +459,6 @@ fn main() {
 "#,
         expect![[r#"
             ```rust
-            {closure#0}
             impl FnOnce() -> S2
             ```
             ___
@@ -3017,7 +3012,6 @@ fn main() {
         expect![[r#"
             *|*
             ```rust
-            {closure#0}
             impl Fn(i32) -> i32
             ```