@@ -209,7 +209,7 @@ fn hints(
209209) {
210210 closing_brace:: hints ( hints, sema, config, file_id, node. clone ( ) ) ;
211211 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) ;
213213 }
214214
215215 match_ast ! {
@@ -300,22 +300,23 @@ pub struct InlayHintsConfig {
300300 pub closing_brace_hints_min_lines : Option < usize > ,
301301 pub fields_to_resolve : InlayFieldsToResolve ,
302302}
303+
303304impl 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 > {
305306 if self . fields_to_resolve . resolve_text_edits {
306- Lazy :: Lazy
307+ LazyProperty :: Lazy
307308 } else {
308309 let edit = finish ( ) ;
309310 never ! ( edit. is_empty( ) , "inlay hint produced an empty text edit" ) ;
310- Lazy :: Computed ( edit)
311+ LazyProperty :: Computed ( edit)
311312 }
312313 }
313314
314- fn lazy_tooltip ( & self , finish : impl FnOnce ( ) -> InlayTooltip ) -> Lazy < InlayTooltip > {
315+ fn lazy_tooltip ( & self , finish : impl FnOnce ( ) -> InlayTooltip ) -> LazyProperty < InlayTooltip > {
315316 if self . fields_to_resolve . resolve_hint_tooltip
316317 && self . fields_to_resolve . resolve_label_tooltip
317318 {
318- Lazy :: Lazy
319+ LazyProperty :: Lazy
319320 } else {
320321 let tooltip = finish ( ) ;
321322 never ! (
@@ -326,7 +327,20 @@ impl InlayHintsConfig {
326327 . is_empty( ) ,
327328 "inlay hint produced an empty tooltip"
328329 ) ;
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 )
330344 }
331345 }
332346}
@@ -441,23 +455,23 @@ pub struct InlayHint {
441455 /// The actual label to show in the inlay hint.
442456 pub label : InlayHintLabel ,
443457 /// Text edit to apply when "accepting" this inlay hint.
444- pub text_edit : Option < Lazy < TextEdit > > ,
458+ pub text_edit : Option < LazyProperty < TextEdit > > ,
445459 /// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
446460 /// hint does not support resolving.
447461 pub resolve_parent : Option < TextRange > ,
448462}
449463
450464/// A type signaling that a value is either computed, or is available for computation.
451465#[ derive( Clone , Debug ) ]
452- pub enum Lazy < T > {
466+ pub enum LazyProperty < T > {
453467 Computed ( T ) ,
454468 Lazy ,
455469}
456470
457- impl < T > Lazy < T > {
471+ impl < T > LazyProperty < T > {
458472 pub fn computed ( self ) -> Option < T > {
459473 match self {
460- Lazy :: Computed ( it) => Some ( it) ,
474+ LazyProperty :: Computed ( it) => Some ( it) ,
461475 _ => None ,
462476 }
463477 }
@@ -508,8 +522,8 @@ pub struct InlayHintLabel {
508522impl InlayHintLabel {
509523 pub fn simple (
510524 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 > > ,
513527 ) -> InlayHintLabel {
514528 InlayHintLabel {
515529 parts : smallvec ! [ InlayHintLabelPart { text: s. into( ) , linked_location, tooltip } ] ,
@@ -593,33 +607,37 @@ pub struct InlayHintLabelPart {
593607 /// refers to (not necessarily the location itself).
594608 /// When setting this, no tooltip must be set on the containing hint, or VS Code will display
595609 /// them both.
596- pub linked_location : Option < FileRange > ,
610+ pub linked_location : Option < LazyProperty < FileRange > > ,
597611 /// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
598612 /// hover requests to show.
599- pub tooltip : Option < Lazy < InlayTooltip > > ,
613+ pub tooltip : Option < LazyProperty < InlayTooltip > > ,
600614}
601615
602616impl std:: hash:: Hash for InlayHintLabelPart {
603617 fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
604618 self . text . hash ( state) ;
605- self . linked_location . hash ( state) ;
619+ self . linked_location . is_some ( ) . hash ( state) ;
606620 self . tooltip . is_some ( ) . hash ( state) ;
607621 }
608622}
609623
610624impl fmt:: Debug for InlayHintLabelPart {
611625 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
612626 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+ }
614630 Self { text, linked_location, tooltip } => f
615631 . debug_struct ( "InlayHintLabelPart" )
616632 . field ( "text" , text)
617633 . field ( "linked_location" , linked_location)
618634 . field (
619635 "tooltip" ,
620636 & 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 => "" ,
623641 } ) ,
624642 )
625643 . finish ( ) ,
@@ -632,7 +650,8 @@ struct InlayHintLabelBuilder<'a> {
632650 db : & ' a RootDatabase ,
633651 result : InlayHintLabel ,
634652 last_part : String ,
635- location : Option < FileRange > ,
653+ resolve : bool ,
654+ location : Option < LazyProperty < FileRange > > ,
636655}
637656
638657impl fmt:: Write for InlayHintLabelBuilder < ' _ > {
@@ -645,11 +664,16 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
645664 fn start_location_link ( & mut self , def : ModuleDefId ) {
646665 never ! ( self . location. is_some( ) , "location link is already started" ) ;
647666 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+ } ) ;
653677 }
654678
655679 fn end_location_link ( & mut self ) {
@@ -735,6 +759,7 @@ fn label_of_ty(
735759 last_part : String :: new ( ) ,
736760 location : None ,
737761 result : InlayHintLabel :: default ( ) ,
762+ resolve : config. fields_to_resolve . resolve_label_location ,
738763 } ;
739764 let _ = rec ( sema, famous_defs, config. max_length , ty, & mut label_builder, config, edition) ;
740765 let r = label_builder. finish ( ) ;
@@ -783,7 +808,7 @@ fn ty_to_text_edit(
783808 ty : & hir:: Type ,
784809 offset_to_insert : TextSize ,
785810 prefix : impl Into < String > ,
786- ) -> Option < Lazy < TextEdit > > {
811+ ) -> Option < LazyProperty < TextEdit > > {
787812 // FIXME: Limit the length and bail out on excess somehow?
788813 let rendered = sema
789814 . scope ( node_for_hint)
0 commit comments