@@ -14,8 +14,8 @@ use smallvec::{smallvec, SmallVec};
1414use span:: { Edition , EditionedFileId } ;
1515use stdx:: never;
1616use syntax:: {
17- ast:: { self , AstNode } ,
18- match_ast, NodeOrToken , SyntaxNode , TextRange , TextSize , WalkEvent ,
17+ ast:: { self , AstNode , HasGenericParams } ,
18+ format_smolstr , match_ast, NodeOrToken , SmolStr , SyntaxNode , TextRange , TextSize , WalkEvent ,
1919} ;
2020use text_edit:: TextEdit ;
2121
@@ -29,10 +29,10 @@ mod closing_brace;
2929mod closure_captures;
3030mod closure_ret;
3131mod discriminant;
32- mod fn_lifetime_fn;
3332mod generic_param;
3433mod implicit_drop;
3534mod implicit_static;
35+ mod lifetime;
3636mod param_name;
3737mod range_exclusive;
3838
@@ -94,8 +94,8 @@ pub(crate) fn inlay_hints(
9494 } ;
9595 let famous_defs = FamousDefs ( & sema, scope. krate ( ) ) ;
9696
97- let parent_impl = & mut None ;
98- let hints = |node| hints ( & mut acc, parent_impl , & famous_defs, config, file_id, node) ;
97+ let ctx = & mut InlayHintCtx :: default ( ) ;
98+ let hints = |node| hints ( & mut acc, ctx , & famous_defs, config, file_id, node) ;
9999 match range_limit {
100100 // FIXME: This can miss some hints that require the parent of the range to calculate
101101 Some ( range) => match file. covering_element ( range) {
@@ -111,6 +111,12 @@ pub(crate) fn inlay_hints(
111111 acc
112112}
113113
114+ #[ derive( Default ) ]
115+ struct InlayHintCtx {
116+ lifetime_stacks : Vec < Vec < SmolStr > > ,
117+ is_param_list : bool ,
118+ }
119+
114120pub ( crate ) fn inlay_hints_resolve (
115121 db : & RootDatabase ,
116122 file_id : FileId ,
@@ -131,8 +137,8 @@ pub(crate) fn inlay_hints_resolve(
131137 let famous_defs = FamousDefs ( & sema, scope. krate ( ) ) ;
132138 let mut acc = Vec :: new ( ) ;
133139
134- let parent_impl = & mut None ;
135- let hints = |node| hints ( & mut acc, parent_impl , & famous_defs, config, file_id, node) ;
140+ let ctx = & mut InlayHintCtx :: default ( ) ;
141+ let hints = |node| hints ( & mut acc, ctx , & famous_defs, config, file_id, node) ;
136142
137143 let mut res = file. clone ( ) ;
138144 let res = loop {
@@ -146,9 +152,11 @@ pub(crate) fn inlay_hints_resolve(
146152 acc. into_iter ( ) . find ( |hint| hasher ( hint) == hash)
147153}
148154
155+ // FIXME: At some point when our hir infra is fleshed out enough we should flip this and traverse the
156+ // HIR instead of the syntax tree.
149157fn hints (
150158 hints : & mut Vec < InlayHint > ,
151- parent_impl : & mut Option < ast :: Impl > ,
159+ ctx : & mut InlayHintCtx ,
152160 famous_defs @ FamousDefs ( sema, _) : & FamousDefs < ' _ , ' _ > ,
153161 config : & InlayHintsConfig ,
154162 file_id : EditionedFileId ,
@@ -157,12 +165,30 @@ fn hints(
157165 let node = match node {
158166 WalkEvent :: Enter ( node) => node,
159167 WalkEvent :: Leave ( n) => {
160- if ast:: Impl :: can_cast ( n. kind ( ) ) {
161- parent_impl. take ( ) ;
168+ if ast:: AnyHasGenericParams :: can_cast ( n. kind ( ) ) {
169+ ctx. lifetime_stacks . pop ( ) ;
170+ // pop
171+ }
172+ if ast:: ParamList :: can_cast ( n. kind ( ) ) {
173+ ctx. is_param_list = false ;
174+ // pop
162175 }
163176 return ;
164177 }
165178 } ;
179+
180+ if let Some ( node) = ast:: AnyHasGenericParams :: cast ( node. clone ( ) ) {
181+ let params = node
182+ . generic_param_list ( )
183+ . map ( |it| {
184+ it. lifetime_params ( )
185+ . filter_map ( |it| it. lifetime ( ) . map ( |it| format_smolstr ! ( "{}" , & it. text( ) [ 1 ..] ) ) )
186+ . collect ( )
187+ } )
188+ . unwrap_or_default ( ) ;
189+ ctx. lifetime_stacks . push ( params) ;
190+ }
191+
166192 closing_brace:: hints ( hints, sema, config, file_id, node. clone ( ) ) ;
167193 if let Some ( any_has_generic_args) = ast:: AnyHasGenericArgs :: cast ( node. clone ( ) ) {
168194 generic_param:: hints ( hints, sema, config, any_has_generic_args) ;
@@ -183,7 +209,7 @@ fn hints(
183209 closure_ret:: hints( hints, famous_defs, config, file_id, it)
184210 } ,
185211 ast:: Expr :: RangeExpr ( it) => range_exclusive:: hints( hints, famous_defs, config, file_id, it) ,
186- _ => None ,
212+ _ => Some ( ( ) ) ,
187213 }
188214 } ,
189215 ast:: Pat ( it) => {
@@ -200,24 +226,27 @@ fn hints(
200226 Some ( ( ) )
201227 } ,
202228 ast:: Item ( it) => match it {
203- // FIXME: record impl lifetimes so they aren't being reused in assoc item lifetime inlay hints
204- ast:: Item :: Impl ( impl_) => {
205- * parent_impl = Some ( impl_) ;
206- None
207- } ,
208229 ast:: Item :: Fn ( it) => {
209230 implicit_drop:: hints( hints, famous_defs, config, file_id, & it) ;
210- fn_lifetime_fn :: hints ( hints, famous_defs, config, file_id, it)
231+ lifetime :: fn_hints ( hints, ctx , famous_defs, config, file_id, it)
211232 } ,
212233 // static type elisions
213234 ast:: Item :: Static ( it) => implicit_static:: hints( hints, famous_defs, config, file_id, Either :: Left ( it) ) ,
214235 ast:: Item :: Const ( it) => implicit_static:: hints( hints, famous_defs, config, file_id, Either :: Right ( it) ) ,
215236 ast:: Item :: Enum ( it) => discriminant:: enum_hints( hints, famous_defs, config, file_id, it) ,
216237 _ => None ,
217238 } ,
218- // FIXME: fn-ptr type, dyn fn type, and trait object type elisions
219- ast:: Type ( _) => None ,
220- _ => None ,
239+ // FIXME: trait object type elisions
240+ ast:: Type ( ty) => match ty {
241+ ast:: Type :: FnPtrType ( ptr) => lifetime:: fn_ptr_hints( hints, ctx, famous_defs, config, file_id, ptr) ,
242+ ast:: Type :: PathType ( path) => lifetime:: fn_path_hints( hints, ctx, famous_defs, config, file_id, path) ,
243+ _ => Some ( ( ) ) ,
244+ } ,
245+ ast:: ParamList ( _) => {
246+ ctx. is_param_list = true ;
247+ Some ( ( ) )
248+ } ,
249+ _ => Some ( ( ) ) ,
221250 }
222251 } ;
223252}
0 commit comments