@@ -209,7 +209,7 @@ fn hints(
209
209
) {
210
210
closing_brace:: hints ( hints, sema, config, file_id, node. clone ( ) ) ;
211
211
if let Some ( any_has_generic_args) = ast:: AnyHasGenericArgs :: cast ( node. clone ( ) ) {
212
- generic_param:: hints ( hints, sema , config, any_has_generic_args) ;
212
+ generic_param:: hints ( hints, famous_defs , config, any_has_generic_args) ;
213
213
}
214
214
215
215
match_ast ! {
@@ -300,22 +300,23 @@ pub struct InlayHintsConfig {
300
300
pub closing_brace_hints_min_lines : Option < usize > ,
301
301
pub fields_to_resolve : InlayFieldsToResolve ,
302
302
}
303
+
303
304
impl InlayHintsConfig {
304
- fn lazy_text_edit ( & self , finish : impl FnOnce ( ) -> TextEdit ) -> Lazy < TextEdit > {
305
+ fn lazy_text_edit ( & self , finish : impl FnOnce ( ) -> TextEdit ) -> LazyProperty < TextEdit > {
305
306
if self . fields_to_resolve . resolve_text_edits {
306
- Lazy :: Lazy
307
+ LazyProperty :: Lazy
307
308
} else {
308
309
let edit = finish ( ) ;
309
310
never ! ( edit. is_empty( ) , "inlay hint produced an empty text edit" ) ;
310
- Lazy :: Computed ( edit)
311
+ LazyProperty :: Computed ( edit)
311
312
}
312
313
}
313
314
314
- fn lazy_tooltip ( & self , finish : impl FnOnce ( ) -> InlayTooltip ) -> Lazy < InlayTooltip > {
315
+ fn lazy_tooltip ( & self , finish : impl FnOnce ( ) -> InlayTooltip ) -> LazyProperty < InlayTooltip > {
315
316
if self . fields_to_resolve . resolve_hint_tooltip
316
317
&& self . fields_to_resolve . resolve_label_tooltip
317
318
{
318
- Lazy :: Lazy
319
+ LazyProperty :: Lazy
319
320
} else {
320
321
let tooltip = finish ( ) ;
321
322
never ! (
@@ -326,7 +327,20 @@ impl InlayHintsConfig {
326
327
. is_empty( ) ,
327
328
"inlay hint produced an empty tooltip"
328
329
) ;
329
- Lazy :: Computed ( tooltip)
330
+ LazyProperty :: Computed ( tooltip)
331
+ }
332
+ }
333
+
334
+ /// This always reports a resolvable location, so only use this when it is very likely for a
335
+ /// location link to actually resolve but where computing `finish` would be costly.
336
+ fn lazy_location_opt (
337
+ & self ,
338
+ finish : impl FnOnce ( ) -> Option < FileRange > ,
339
+ ) -> Option < LazyProperty < FileRange > > {
340
+ if self . fields_to_resolve . resolve_label_location {
341
+ Some ( LazyProperty :: Lazy )
342
+ } else {
343
+ finish ( ) . map ( LazyProperty :: Computed )
330
344
}
331
345
}
332
346
}
@@ -441,23 +455,23 @@ pub struct InlayHint {
441
455
/// The actual label to show in the inlay hint.
442
456
pub label : InlayHintLabel ,
443
457
/// Text edit to apply when "accepting" this inlay hint.
444
- pub text_edit : Option < Lazy < TextEdit > > ,
458
+ pub text_edit : Option < LazyProperty < TextEdit > > ,
445
459
/// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
446
460
/// hint does not support resolving.
447
461
pub resolve_parent : Option < TextRange > ,
448
462
}
449
463
450
464
/// A type signaling that a value is either computed, or is available for computation.
451
465
#[ derive( Clone , Debug ) ]
452
- pub enum Lazy < T > {
466
+ pub enum LazyProperty < T > {
453
467
Computed ( T ) ,
454
468
Lazy ,
455
469
}
456
470
457
- impl < T > Lazy < T > {
471
+ impl < T > LazyProperty < T > {
458
472
pub fn computed ( self ) -> Option < T > {
459
473
match self {
460
- Lazy :: Computed ( it) => Some ( it) ,
474
+ LazyProperty :: Computed ( it) => Some ( it) ,
461
475
_ => None ,
462
476
}
463
477
}
@@ -508,8 +522,8 @@ pub struct InlayHintLabel {
508
522
impl InlayHintLabel {
509
523
pub fn simple (
510
524
s : impl Into < String > ,
511
- tooltip : Option < Lazy < InlayTooltip > > ,
512
- linked_location : Option < FileRange > ,
525
+ tooltip : Option < LazyProperty < InlayTooltip > > ,
526
+ linked_location : Option < LazyProperty < FileRange > > ,
513
527
) -> InlayHintLabel {
514
528
InlayHintLabel {
515
529
parts : smallvec ! [ InlayHintLabelPart { text: s. into( ) , linked_location, tooltip } ] ,
@@ -593,33 +607,37 @@ pub struct InlayHintLabelPart {
593
607
/// refers to (not necessarily the location itself).
594
608
/// When setting this, no tooltip must be set on the containing hint, or VS Code will display
595
609
/// them both.
596
- pub linked_location : Option < FileRange > ,
610
+ pub linked_location : Option < LazyProperty < FileRange > > ,
597
611
/// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
598
612
/// hover requests to show.
599
- pub tooltip : Option < Lazy < InlayTooltip > > ,
613
+ pub tooltip : Option < LazyProperty < InlayTooltip > > ,
600
614
}
601
615
602
616
impl std:: hash:: Hash for InlayHintLabelPart {
603
617
fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
604
618
self . text . hash ( state) ;
605
- self . linked_location . hash ( state) ;
619
+ self . linked_location . is_some ( ) . hash ( state) ;
606
620
self . tooltip . is_some ( ) . hash ( state) ;
607
621
}
608
622
}
609
623
610
624
impl fmt:: Debug for InlayHintLabelPart {
611
625
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
612
626
match self {
613
- Self { text, linked_location : None , tooltip : None | Some ( Lazy :: Lazy ) } => text. fmt ( f) ,
627
+ Self { text, linked_location : None , tooltip : None | Some ( LazyProperty :: Lazy ) } => {
628
+ text. fmt ( f)
629
+ }
614
630
Self { text, linked_location, tooltip } => f
615
631
. debug_struct ( "InlayHintLabelPart" )
616
632
. field ( "text" , text)
617
633
. field ( "linked_location" , linked_location)
618
634
. field (
619
635
"tooltip" ,
620
636
& tooltip. as_ref ( ) . map_or ( "" , |it| match it {
621
- Lazy :: Computed ( InlayTooltip :: String ( it) | InlayTooltip :: Markdown ( it) ) => it,
622
- Lazy :: Lazy => "" ,
637
+ LazyProperty :: Computed (
638
+ InlayTooltip :: String ( it) | InlayTooltip :: Markdown ( it) ,
639
+ ) => it,
640
+ LazyProperty :: Lazy => "" ,
623
641
} ) ,
624
642
)
625
643
. finish ( ) ,
@@ -632,7 +650,8 @@ struct InlayHintLabelBuilder<'a> {
632
650
db : & ' a RootDatabase ,
633
651
result : InlayHintLabel ,
634
652
last_part : String ,
635
- location : Option < FileRange > ,
653
+ resolve : bool ,
654
+ location : Option < LazyProperty < FileRange > > ,
636
655
}
637
656
638
657
impl fmt:: Write for InlayHintLabelBuilder < ' _ > {
@@ -645,11 +664,16 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
645
664
fn start_location_link ( & mut self , def : ModuleDefId ) {
646
665
never ! ( self . location. is_some( ) , "location link is already started" ) ;
647
666
self . make_new_part ( ) ;
648
- let Some ( location) = ModuleDef :: from ( def) . try_to_nav ( self . db ) else { return } ;
649
- let location = location. call_site ( ) ;
650
- let location =
651
- FileRange { file_id : location. file_id , range : location. focus_or_full_range ( ) } ;
652
- self . location = Some ( location) ;
667
+
668
+ self . location = Some ( if self . resolve {
669
+ LazyProperty :: Lazy
670
+ } else {
671
+ LazyProperty :: Computed ( {
672
+ let Some ( location) = ModuleDef :: from ( def) . try_to_nav ( self . db ) else { return } ;
673
+ let location = location. call_site ( ) ;
674
+ FileRange { file_id : location. file_id , range : location. focus_or_full_range ( ) }
675
+ } )
676
+ } ) ;
653
677
}
654
678
655
679
fn end_location_link ( & mut self ) {
@@ -735,6 +759,7 @@ fn label_of_ty(
735
759
last_part : String :: new ( ) ,
736
760
location : None ,
737
761
result : InlayHintLabel :: default ( ) ,
762
+ resolve : config. fields_to_resolve . resolve_label_location ,
738
763
} ;
739
764
let _ = rec ( sema, famous_defs, config. max_length , ty, & mut label_builder, config, edition) ;
740
765
let r = label_builder. finish ( ) ;
@@ -783,7 +808,7 @@ fn ty_to_text_edit(
783
808
ty : & hir:: Type ,
784
809
offset_to_insert : TextSize ,
785
810
prefix : impl Into < String > ,
786
- ) -> Option < Lazy < TextEdit > > {
811
+ ) -> Option < LazyProperty < TextEdit > > {
787
812
// FIXME: Limit the length and bail out on excess somehow?
788
813
let rendered = sema
789
814
. scope ( node_for_hint)
0 commit comments