@@ -5,13 +5,15 @@ use std::collections::BTreeSet;
5
5
6
6
use either:: Either ;
7
7
use hir:: {
8
- AssocItem , DisplayTarget , GenericParam , HirDisplay , ModuleDef , PathResolution , Semantics , Trait ,
8
+ AssocItem , DisplayTarget , GenericDef , GenericParam , HirDisplay , ModuleDef , PathResolution ,
9
+ Semantics , Trait ,
9
10
} ;
10
11
use ide_db:: {
11
12
FilePosition , FxIndexMap ,
12
13
active_parameter:: { callable_for_arg_list, generic_def_for_node} ,
13
14
documentation:: { Documentation , HasDocs } ,
14
15
} ;
16
+ use itertools:: Itertools ;
15
17
use span:: Edition ;
16
18
use stdx:: format_to;
17
19
use syntax:: {
@@ -175,6 +177,20 @@ fn signature_help_for_call(
175
177
hir:: CallableKind :: Function ( func) => {
176
178
res. doc = func. docs ( db) ;
177
179
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
+
178
194
fn_params = Some ( match callable. receiver_param ( db) {
179
195
Some ( _self) => func. params_without_self ( db) ,
180
196
None => func. assoc_fn_params ( db) ,
@@ -183,15 +199,34 @@ fn signature_help_for_call(
183
199
hir:: CallableKind :: TupleStruct ( strukt) => {
184
200
res. doc = strukt. docs ( db) ;
185
201
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
+ }
186
211
}
187
212
hir:: CallableKind :: TupleEnumVariant ( variant) => {
188
213
res. doc = variant. docs ( db) ;
189
214
format_to ! (
190
215
res. signature,
191
- "enum {}::{} " ,
216
+ "enum {}" ,
192
217
variant. parent_enum( db) . name( db) . display( db, edition) ,
193
- variant. name( db) . display( db, edition)
194
218
) ;
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) )
195
230
}
196
231
hir:: CallableKind :: Closure ( closure) => {
197
232
let fn_trait = closure. fn_trait ( db) ;
@@ -339,6 +374,20 @@ fn signature_help_for_generics(
339
374
340
375
buf. clear ( ) ;
341
376
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
+ }
342
391
res. push_generic_param ( & buf) ;
343
392
}
344
393
if let hir:: GenericDef :: Trait ( tr) = generics_def {
@@ -815,8 +864,8 @@ fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
815
864
fn bar() { foo($03, ); }
816
865
"# ,
817
866
expect ! [ [ r#"
818
- fn foo(x: i32, y: U) -> u32
819
- ^^^^^^ ----
867
+ fn foo<T, U> (x: i32, y: U) -> u32
868
+ ^^^^^^ ----
820
869
"# ] ] ,
821
870
) ;
822
871
}
@@ -829,7 +878,7 @@ fn foo<T>() -> T where T: Copy + Display {}
829
878
fn bar() { foo($0); }
830
879
"# ,
831
880
expect ! [ [ r#"
832
- fn foo() -> T
881
+ fn foo<T> () -> T
833
882
"# ] ] ,
834
883
) ;
835
884
}
@@ -1279,8 +1328,8 @@ fn main() {
1279
1328
}
1280
1329
"# ,
1281
1330
expect ! [ [ r#"
1282
- struct S({unknown})
1283
- ^^^^^^^^^
1331
+ struct S<T> ({unknown})
1332
+ ^^^^^^^^^
1284
1333
"# ] ] ,
1285
1334
) ;
1286
1335
}
@@ -1375,7 +1424,7 @@ id! {
1375
1424
fn test() { S.foo($0); }
1376
1425
"# ,
1377
1426
expect ! [ [ r#"
1378
- fn foo(&'a mut self)
1427
+ fn foo<'a> (&'a mut self)
1379
1428
"# ] ] ,
1380
1429
) ;
1381
1430
}
@@ -1724,8 +1773,8 @@ fn sup() {
1724
1773
}
1725
1774
"# ,
1726
1775
expect ! [ [ r#"
1727
- fn test(&mut self, val: V)
1728
- ^^^^^^
1776
+ fn test<V> (&mut self, val: V)
1777
+ ^^^^^^
1729
1778
"# ] ] ,
1730
1779
) ;
1731
1780
}
@@ -1901,8 +1950,8 @@ fn f() {
1901
1950
}
1902
1951
"# ,
1903
1952
expect ! [ [ r#"
1904
- fn foo(x: Wrap<impl Trait<U>>)
1905
- ^^^^^^^^^^^^^^^^^^^^^^
1953
+ fn foo<U> (x: Wrap<impl Trait<U>>)
1954
+ ^^^^^^^^^^^^^^^^^^^^^^
1906
1955
"# ] ] ,
1907
1956
) ;
1908
1957
}
@@ -2394,4 +2443,96 @@ fn main() {
2394
2443
"# ] ] ,
2395
2444
) ;
2396
2445
}
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
2397
2514
}
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