@@ -5,13 +5,15 @@ use std::collections::BTreeSet;
55
66use either:: Either ;
77use hir:: {
8- AssocItem , DisplayTarget , GenericParam , HirDisplay , ModuleDef , PathResolution , Semantics , Trait ,
8+ AssocItem , DisplayTarget , GenericDef , GenericParam , HirDisplay , ModuleDef , PathResolution ,
9+ Semantics , Trait ,
910} ;
1011use ide_db:: {
1112 FilePosition , FxIndexMap ,
1213 active_parameter:: { callable_for_arg_list, generic_def_for_node} ,
1314 documentation:: { Documentation , HasDocs } ,
1415} ;
16+ use itertools:: Itertools ;
1517use span:: Edition ;
1618use stdx:: format_to;
1719use syntax:: {
@@ -175,6 +177,20 @@ fn signature_help_for_call(
175177 hir:: CallableKind :: Function ( func) => {
176178 res. doc = func. docs ( db) ;
177179 format_to ! ( res. signature, "fn {}" , func. name( db) . display( db, edition) ) ;
180+
181+ let generic_params = GenericDef :: Function ( func)
182+ . params ( db)
183+ . iter ( )
184+ . filter ( |param| match param {
185+ GenericParam :: TypeParam ( type_param) => !type_param. is_implicit ( db) ,
186+ GenericParam :: ConstParam ( _) | GenericParam :: LifetimeParam ( _) => true ,
187+ } )
188+ . map ( |param| param. display ( db, display_target) )
189+ . join ( ", " ) ;
190+ if !generic_params. is_empty ( ) {
191+ format_to ! ( res. signature, "<{}>" , generic_params) ;
192+ }
193+
178194 fn_params = Some ( match callable. receiver_param ( db) {
179195 Some ( _self) => func. params_without_self ( db) ,
180196 None => func. assoc_fn_params ( db) ,
@@ -183,15 +199,34 @@ fn signature_help_for_call(
183199 hir:: CallableKind :: TupleStruct ( strukt) => {
184200 res. doc = strukt. docs ( db) ;
185201 format_to ! ( res. signature, "struct {}" , strukt. name( db) . display( db, edition) ) ;
202+
203+ let generic_params = GenericDef :: Adt ( strukt. into ( ) )
204+ . params ( db)
205+ . iter ( )
206+ . map ( |param| param. display ( db, display_target) )
207+ . join ( ", " ) ;
208+ if !generic_params. is_empty ( ) {
209+ format_to ! ( res. signature, "<{}>" , generic_params) ;
210+ }
186211 }
187212 hir:: CallableKind :: TupleEnumVariant ( variant) => {
188213 res. doc = variant. docs ( db) ;
189214 format_to ! (
190215 res. signature,
191- "enum {}::{} " ,
216+ "enum {}" ,
192217 variant. parent_enum( db) . name( db) . display( db, edition) ,
193- variant. name( db) . display( db, edition)
194218 ) ;
219+
220+ let generic_params = GenericDef :: Adt ( variant. parent_enum ( db) . into ( ) )
221+ . params ( db)
222+ . iter ( )
223+ . map ( |param| param. display ( db, display_target) )
224+ . join ( ", " ) ;
225+ if !generic_params. is_empty ( ) {
226+ format_to ! ( res. signature, "<{}>" , generic_params) ;
227+ }
228+
229+ format_to ! ( res. signature, "::{}" , variant. name( db) . display( db, edition) )
195230 }
196231 hir:: CallableKind :: Closure ( closure) => {
197232 let fn_trait = closure. fn_trait ( db) ;
@@ -339,6 +374,20 @@ fn signature_help_for_generics(
339374
340375 buf. clear ( ) ;
341376 format_to ! ( buf, "{}" , param. display( db, display_target) ) ;
377+ match param {
378+ GenericParam :: TypeParam ( param) => {
379+ if let Some ( ty) = param. default ( db) {
380+ format_to ! ( buf, " = {}" , ty. display( db, display_target) ) ;
381+ }
382+ }
383+ GenericParam :: ConstParam ( param) => {
384+ if let Some ( expr) = param. default ( db, display_target) . and_then ( |konst| konst. expr ( ) )
385+ {
386+ format_to ! ( buf, " = {}" , expr) ;
387+ }
388+ }
389+ _ => { }
390+ }
342391 res. push_generic_param ( & buf) ;
343392 }
344393 if let hir:: GenericDef :: Trait ( tr) = generics_def {
@@ -815,8 +864,8 @@ fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
815864fn bar() { foo($03, ); }
816865"# ,
817866 expect ! [ [ r#"
818- fn foo(x: i32, y: U) -> u32
819- ^^^^^^ ----
867+ fn foo<T, U> (x: i32, y: U) -> u32
868+ ^^^^^^ ----
820869 "# ] ] ,
821870 ) ;
822871 }
@@ -829,7 +878,7 @@ fn foo<T>() -> T where T: Copy + Display {}
829878fn bar() { foo($0); }
830879"# ,
831880 expect ! [ [ r#"
832- fn foo() -> T
881+ fn foo<T> () -> T
833882 "# ] ] ,
834883 ) ;
835884 }
@@ -1279,8 +1328,8 @@ fn main() {
12791328}
12801329"# ,
12811330 expect ! [ [ r#"
1282- struct S({unknown})
1283- ^^^^^^^^^
1331+ struct S<T> ({unknown})
1332+ ^^^^^^^^^
12841333 "# ] ] ,
12851334 ) ;
12861335 }
@@ -1375,7 +1424,7 @@ id! {
13751424fn test() { S.foo($0); }
13761425"# ,
13771426 expect ! [ [ r#"
1378- fn foo(&'a mut self)
1427+ fn foo<'a> (&'a mut self)
13791428 "# ] ] ,
13801429 ) ;
13811430 }
@@ -1724,8 +1773,8 @@ fn sup() {
17241773}
17251774"# ,
17261775 expect ! [ [ r#"
1727- fn test(&mut self, val: V)
1728- ^^^^^^
1776+ fn test<V> (&mut self, val: V)
1777+ ^^^^^^
17291778 "# ] ] ,
17301779 ) ;
17311780 }
@@ -1901,8 +1950,8 @@ fn f() {
19011950}
19021951"# ,
19031952 expect ! [ [ r#"
1904- fn foo(x: Wrap<impl Trait<U>>)
1905- ^^^^^^^^^^^^^^^^^^^^^^
1953+ fn foo<U> (x: Wrap<impl Trait<U>>)
1954+ ^^^^^^^^^^^^^^^^^^^^^^
19061955 "# ] ] ,
19071956 ) ;
19081957 }
@@ -2394,4 +2443,96 @@ fn main() {
23942443 "# ] ] ,
23952444 ) ;
23962445 }
2446+
2447+ #[ test]
2448+ fn test_tuple_generic_param ( ) {
2449+ check (
2450+ r#"
2451+ struct S<T>(T);
2452+
2453+ fn main() {
2454+ let s: S<$0
2455+ }
2456+ "# ,
2457+ expect ! [ [ r#"
2458+ struct S<T>
2459+ ^
2460+ "# ] ] ,
2461+ ) ;
2462+ }
2463+
2464+ #[ test]
2465+ fn test_enum_generic_param ( ) {
2466+ check (
2467+ r#"
2468+ enum Option<T> {
2469+ Some(T),
2470+ None,
2471+ }
2472+
2473+ fn main() {
2474+ let opt: Option<$0
2475+ }
2476+ "# ,
2477+ expect ! [ [ r#"
2478+ enum Option<T>
2479+ ^
2480+ "# ] ] ,
2481+ ) ;
2482+ }
2483+
2484+ #[ test]
2485+ fn test_enum_variant_generic_param ( ) {
2486+ check (
2487+ r#"
2488+ enum Option<T> {
2489+ Some(T),
2490+ None,
2491+ }
2492+
2493+ fn main() {
2494+ let opt = Option::Some($0);
2495+ }
2496+ "# ,
2497+ expect ! [ [ r#"
2498+ enum Option<T>::Some({unknown})
2499+ ^^^^^^^^^
2500+ "# ] ] ,
2501+ ) ;
2502+ }
2503+
2504+ #[ test]
2505+ fn test_generic_arg_with_default ( ) {
2506+ check (
2507+ r#"
2508+ struct S<T = u8> {
2509+ field: T,
2510+ }
2511+
2512+ fn main() {
2513+ let s: S<$0
23972514}
2515+ "# ,
2516+ expect ! [ [ r#"
2517+ struct S<T = u8>
2518+ ^^^^^^
2519+ "# ] ] ,
2520+ ) ;
2521+
2522+ check (
2523+ r#"
2524+ struct S<const C: u8 = 5> {
2525+ field: C,
2526+ }
2527+
2528+ fn main() {
2529+ let s: S<$0
2530+ }
2531+ "# ,
2532+ expect ! [ [ r#"
2533+ struct S<const C: u8 = 5>
2534+ ^^^^^^^^^^^^^^^
2535+ "# ] ] ,
2536+ ) ;
2537+ }
2538+ }
0 commit comments