diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 923dca6466..c2b2fbef75 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -99,17 +99,20 @@ impl HirDisplay for Function { } // FIXME: Use resolved `param.ty` once we no longer discard lifetimes + let body = db.body(self.id.into()); for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) { - let local = param.as_local(db).map(|it| it.name(db)); if !first { f.write_str(", ")?; } else { first = false; } - match local { - Some(name) => write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?, - None => f.write_str("_: ")?, - } + + let pat_id = body.params[param.idx - body.self_param.is_some() as usize]; + let pat_str = + body.pretty_print_pat(db.upcast(), self.id.into(), pat_id, true, f.edition()); + f.write_str(&pat_str)?; + + f.write_str(": ")?; type_ref.hir_fmt(f)?; } diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index f4528dd754..d1e51a2d28 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -8742,3 +8742,118 @@ fn foo() { "#]], ); } + + +#[test] +fn test_hover_function_with_pat_param() { + check( + r#"fn test_1$0((start_range, end_range): (u32, u32), a: i32) {}"#, + expect![[r#" + *test_1* + + ```rust + test + ``` + + ```rust + fn test_1((start_range, end_range): (u32, u32), a: i32) + ``` + "#]], + ); + + // Test case with tuple pattern and mutable parameters + check( + r#"fn test_2$0((mut x, y): (i32, i32)) {}"#, + expect![[r#" + *test_2* + + ```rust + test + ``` + + ```rust + fn test_2((mut x, y): (i32, i32)) + ``` + "#]], + ); + + // Test case with a pattern in a reference type + check( + r#"fn test_3$0(&(a, b): &(i32, i32)) {}"#, + expect![[r#" + *test_3* + + ```rust + test + ``` + + ```rust + fn test_3(&(a, b): &(i32, i32)) + ``` + "#]], + ); + + // Test case with complex pattern (struct destructuring) + check( + r#"struct Point { x: i32, y: i32 } fn test_4$0(Point { x, y }: Point) {}"#, + expect![[r#" + *test_4* + + ```rust + test + ``` + + ```rust + fn test_4(Point { x: x, y: y, }: Point) + ``` + "#]], + ); + + // Test case with a nested pattern + check( + r#"fn test_5$0(((a, b), c): ((i32, i32), i32)) {}"#, + expect![[r#" + *test_5* + + ```rust + test + ``` + + ```rust + fn test_5(((a, b), c): ((i32, i32), i32)) + ``` + "#]], + ); + + // Test case with an unused variable in the pattern + check( + r#"fn test_6$0((_, y): (i32, i64)) {}"#, + expect![[r#" + *test_6* + + ```rust + test + ``` + + ```rust + fn test_6((_, y): (i32, i64)) + ``` + "#]], + ); + + // Test case with a complex pattern involving both tuple and struct + check( + r#"struct Foo { a: i32, b: i32 } fn test_7$0((x, Foo { a, b }): (i32, Foo)) {}"#, + expect![[r#" + *test_7* + + ```rust + test + ``` + + ```rust + fn test_7((x, Foo { a: a, b: b, }): (i32, Foo)) + ``` + "#]], + ); +}