@@ -57,19 +57,19 @@ pub enum InlayKind {
57
57
TypeHint ,
58
58
}
59
59
60
- // FIXME: This should live somewhere more general
61
- #[ derive( Debug ) ]
62
- pub enum RangeOrOffset {
63
- Range ( TextRange ) ,
64
- Offset ( TextSize ) ,
65
- }
66
-
67
60
#[ derive( Debug ) ]
68
61
pub struct InlayHint {
69
62
pub range : TextRange ,
70
63
pub kind : InlayKind ,
71
64
pub label : String ,
72
- pub hover_trigger : Option < RangeOrOffset > ,
65
+ pub tooltip : Option < InlayTooltip > ,
66
+ }
67
+
68
+ #[ derive( Debug ) ]
69
+ pub enum InlayTooltip {
70
+ String ( String ) ,
71
+ HoverRanged ( FileId , TextRange ) ,
72
+ HoverOffset ( FileId , TextSize ) ,
73
73
}
74
74
75
75
// Feature: Inlay Hints
@@ -109,7 +109,7 @@ pub(crate) fn inlay_hints(
109
109
110
110
let mut acc = Vec :: new ( ) ;
111
111
112
- let hints = |node| hints ( & mut acc, & sema, config, node) ;
112
+ let hints = |node| hints ( & mut acc, & sema, config, file_id , node) ;
113
113
match range_limit {
114
114
Some ( FileRange { range, .. } ) => match file. covering_element ( range) {
115
115
NodeOrToken :: Token ( _) => return acc,
@@ -128,24 +128,25 @@ fn hints(
128
128
hints : & mut Vec < InlayHint > ,
129
129
sema : & Semantics < RootDatabase > ,
130
130
config : & InlayHintsConfig ,
131
+ file_id : FileId ,
131
132
node : SyntaxNode ,
132
133
) {
133
134
let famous_defs = match sema. scope ( & node) {
134
135
Some ( it) => FamousDefs ( sema, it. krate ( ) ) ,
135
136
None => return ,
136
137
} ;
137
138
138
- closing_brace_hints ( hints, sema, config, node. clone ( ) ) ;
139
+ closing_brace_hints ( hints, sema, config, file_id , node. clone ( ) ) ;
139
140
match_ast ! {
140
141
match node {
141
142
ast:: Expr ( expr) => {
142
- chaining_hints( hints, sema, & famous_defs, config, & expr) ;
143
+ chaining_hints( hints, sema, & famous_defs, config, file_id , & expr) ;
143
144
match expr {
144
145
ast:: Expr :: CallExpr ( it) => param_name_hints( hints, sema, config, ast:: Expr :: from( it) ) ,
145
146
ast:: Expr :: MethodCallExpr ( it) => {
146
147
param_name_hints( hints, sema, config, ast:: Expr :: from( it) )
147
148
}
148
- ast:: Expr :: ClosureExpr ( it) => closure_ret_hints( hints, sema, & famous_defs, config, it) ,
149
+ ast:: Expr :: ClosureExpr ( it) => closure_ret_hints( hints, sema, & famous_defs, config, file_id , it) ,
149
150
// We could show reborrows for all expressions, but usually that is just noise to the user
150
151
// and the main point here is to show why "moving" a mutable reference doesn't necessarily move it
151
152
ast:: Expr :: PathExpr ( _) => reborrow_hints( hints, sema, config, & expr) ,
@@ -155,7 +156,7 @@ fn hints(
155
156
ast:: Pat ( it) => {
156
157
binding_mode_hints( hints, sema, config, & it) ;
157
158
if let ast:: Pat :: IdentPat ( it) = it {
158
- bind_pat_hints( hints, sema, config, & it) ;
159
+ bind_pat_hints( hints, sema, config, file_id , & it) ;
159
160
}
160
161
Some ( ( ) )
161
162
} ,
@@ -169,6 +170,7 @@ fn closing_brace_hints(
169
170
acc : & mut Vec < InlayHint > ,
170
171
sema : & Semantics < RootDatabase > ,
171
172
config : & InlayHintsConfig ,
173
+ file_id : FileId ,
172
174
node : SyntaxNode ,
173
175
) -> Option < ( ) > {
174
176
let min_lines = config. closing_brace_hints_min_lines ?;
@@ -263,7 +265,7 @@ fn closing_brace_hints(
263
265
range : closing_token. text_range ( ) ,
264
266
kind : InlayKind :: ClosingBraceHint ,
265
267
label,
266
- hover_trigger : name_offset. map ( RangeOrOffset :: Offset ) ,
268
+ tooltip : name_offset. map ( |it| InlayTooltip :: HoverOffset ( file_id , it ) ) ,
267
269
} ) ;
268
270
269
271
None
@@ -282,7 +284,7 @@ fn lifetime_fn_hints(
282
284
range : t. text_range ( ) ,
283
285
kind : InlayKind :: LifetimeHint ,
284
286
label,
285
- hover_trigger : None ,
287
+ tooltip : Some ( InlayTooltip :: String ( "Elided lifetime" . into ( ) ) ) ,
286
288
} ;
287
289
288
290
let param_list = func. param_list ( ) ?;
@@ -428,20 +430,22 @@ fn lifetime_fn_hints(
428
430
( Some ( gpl) , allocated_lifetimes) => {
429
431
let angle_tok = gpl. l_angle_token ( ) ?;
430
432
let is_empty = gpl. generic_params ( ) . next ( ) . is_none ( ) ;
431
- acc. push ( mk_lt_hint (
432
- angle_tok,
433
- format ! (
433
+ acc. push ( InlayHint {
434
+ range : angle_tok. text_range ( ) ,
435
+ kind : InlayKind :: LifetimeHint ,
436
+ label : format ! (
434
437
"{}{}" ,
435
438
allocated_lifetimes. iter( ) . format( ", " ) ,
436
439
if is_empty { "" } else { ", " }
437
440
) ,
438
- ) ) ;
441
+ tooltip : Some ( InlayTooltip :: String ( "Elided lifetimes" . into ( ) ) ) ,
442
+ } ) ;
439
443
}
440
444
( None , allocated_lifetimes) => acc. push ( InlayHint {
441
445
range : func. name ( ) ?. syntax ( ) . text_range ( ) ,
442
446
kind : InlayKind :: GenericParamListHint ,
443
447
label : format ! ( "<{}>" , allocated_lifetimes. iter( ) . format( ", " ) , ) . into ( ) ,
444
- hover_trigger : None ,
448
+ tooltip : Some ( InlayTooltip :: String ( "Elided lifetimes" . into ( ) ) ) ,
445
449
} ) ,
446
450
}
447
451
Some ( ( ) )
@@ -452,6 +456,7 @@ fn closure_ret_hints(
452
456
sema : & Semantics < RootDatabase > ,
453
457
famous_defs : & FamousDefs ,
454
458
config : & InlayHintsConfig ,
459
+ file_id : FileId ,
455
460
closure : ast:: ClosureExpr ,
456
461
) -> Option < ( ) > {
457
462
if !config. closure_return_type_hints {
@@ -475,7 +480,7 @@ fn closure_ret_hints(
475
480
kind : InlayKind :: ClosureReturnTypeHint ,
476
481
label : hint_iterator ( sema, & famous_defs, config, & ty)
477
482
. unwrap_or_else ( || ty. display_truncated ( sema. db , config. max_length ) . to_string ( ) ) ,
478
- hover_trigger : None ,
483
+ tooltip : Some ( InlayTooltip :: HoverRanged ( file_id , param_list . syntax ( ) . text_range ( ) ) ) ,
479
484
} ) ;
480
485
Some ( ( ) )
481
486
}
@@ -502,7 +507,7 @@ fn reborrow_hints(
502
507
range : expr. syntax ( ) . text_range ( ) ,
503
508
kind : InlayKind :: ImplicitReborrowHint ,
504
509
label : label. to_string ( ) ,
505
- hover_trigger : None ,
510
+ tooltip : Some ( InlayTooltip :: String ( "Compiler inserted reborrow" . into ( ) ) ) ,
506
511
} ) ;
507
512
Some ( ( ) )
508
513
}
@@ -512,6 +517,7 @@ fn chaining_hints(
512
517
sema : & Semantics < RootDatabase > ,
513
518
famous_defs : & FamousDefs ,
514
519
config : & InlayHintsConfig ,
520
+ file_id : FileId ,
515
521
expr : & ast:: Expr ,
516
522
) -> Option < ( ) > {
517
523
if !config. chaining_hints {
@@ -561,7 +567,7 @@ fn chaining_hints(
561
567
label : hint_iterator ( sema, & famous_defs, config, & ty) . unwrap_or_else ( || {
562
568
ty. display_truncated ( sema. db , config. max_length ) . to_string ( )
563
569
} ) ,
564
- hover_trigger : Some ( RangeOrOffset :: Range ( expr. syntax ( ) . text_range ( ) ) ) ,
570
+ tooltip : Some ( InlayTooltip :: HoverRanged ( file_id , expr. syntax ( ) . text_range ( ) ) ) ,
565
571
} ) ;
566
572
}
567
573
}
@@ -586,24 +592,23 @@ fn param_name_hints(
586
592
. filter_map ( |( ( param, _ty) , arg) | {
587
593
// Only annotate hints for expressions that exist in the original file
588
594
let range = sema. original_range_opt ( arg. syntax ( ) ) ?;
589
- let param_name = match param? {
590
- Either :: Left ( _ ) => "self" . to_string ( ) ,
595
+ let ( param_name, param_syntax ) = match param. as_ref ( ) ? {
596
+ Either :: Left ( pat ) => ( "self" . to_string ( ) , pat . syntax ( ) ) ,
591
597
Either :: Right ( pat) => match pat {
592
- ast:: Pat :: IdentPat ( it) => it. name ( ) ?. to_string ( ) ,
598
+ ast:: Pat :: IdentPat ( it) => ( it. name ( ) ?. to_string ( ) , pat . syntax ( ) ) ,
593
599
_ => return None ,
594
600
} ,
595
601
} ;
596
- Some ( ( param_name, arg, range) )
602
+ Some ( ( sema . original_range_opt ( param_syntax ) , param_name, arg, range) )
597
603
} )
598
- . filter ( |( param_name, arg, _) | {
604
+ . filter ( |( _ , param_name, arg, _) | {
599
605
!should_hide_param_name_hint ( sema, & callable, param_name, arg)
600
606
} )
601
- . map ( |( param_name, _, FileRange { range, .. } ) | InlayHint {
607
+ . map ( |( param_range , param_name, _, FileRange { range, .. } ) | InlayHint {
602
608
range,
603
609
kind : InlayKind :: ParameterHint ,
604
- label : param_name. into ( ) ,
605
- // FIXME: Show hover for parameter
606
- hover_trigger : None ,
610
+ label : param_name,
611
+ tooltip : param_range. map ( |it| InlayTooltip :: HoverOffset ( it. file_id , it. range . start ( ) ) ) ,
607
612
} ) ;
608
613
609
614
acc. extend ( hints) ;
@@ -633,7 +638,7 @@ fn binding_mode_hints(
633
638
range,
634
639
kind : InlayKind :: BindingModeHint ,
635
640
label : r. to_string ( ) ,
636
- hover_trigger : None ,
641
+ tooltip : Some ( InlayTooltip :: String ( "Inferred binding mode" . into ( ) ) ) ,
637
642
} ) ;
638
643
} ) ;
639
644
match pat {
@@ -648,7 +653,7 @@ fn binding_mode_hints(
648
653
range,
649
654
kind : InlayKind :: BindingModeHint ,
650
655
label : bm. to_string ( ) ,
651
- hover_trigger : None ,
656
+ tooltip : Some ( InlayTooltip :: String ( "Inferred binding mode" . into ( ) ) ) ,
652
657
} ) ;
653
658
}
654
659
_ => ( ) ,
@@ -661,6 +666,7 @@ fn bind_pat_hints(
661
666
acc : & mut Vec < InlayHint > ,
662
667
sema : & Semantics < RootDatabase > ,
663
668
config : & InlayHintsConfig ,
669
+ file_id : FileId ,
664
670
pat : & ast:: IdentPat ,
665
671
) -> Option < ( ) > {
666
672
if !config. type_hints {
@@ -699,7 +705,10 @@ fn bind_pat_hints(
699
705
} ,
700
706
kind : InlayKind :: TypeHint ,
701
707
label,
702
- hover_trigger : pat. name ( ) . map ( |it| it. syntax ( ) . text_range ( ) ) . map ( RangeOrOffset :: Range ) ,
708
+ tooltip : pat
709
+ . name ( )
710
+ . map ( |it| it. syntax ( ) . text_range ( ) )
711
+ . map ( |it| InlayTooltip :: HoverRanged ( file_id, it) ) ,
703
712
} ) ;
704
713
705
714
Some ( ( ) )
0 commit comments