@@ -14,8 +14,8 @@ use smallvec::{smallvec, SmallVec};
14
14
use span:: { Edition , EditionedFileId } ;
15
15
use stdx:: never;
16
16
use 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 ,
19
19
} ;
20
20
use text_edit:: TextEdit ;
21
21
@@ -29,10 +29,10 @@ mod closing_brace;
29
29
mod closure_captures;
30
30
mod closure_ret;
31
31
mod discriminant;
32
- mod fn_lifetime_fn;
33
32
mod generic_param;
34
33
mod implicit_drop;
35
34
mod implicit_static;
35
+ mod lifetime;
36
36
mod param_name;
37
37
mod range_exclusive;
38
38
@@ -94,8 +94,8 @@ pub(crate) fn inlay_hints(
94
94
} ;
95
95
let famous_defs = FamousDefs ( & sema, scope. krate ( ) ) ;
96
96
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) ;
99
99
match range_limit {
100
100
// FIXME: This can miss some hints that require the parent of the range to calculate
101
101
Some ( range) => match file. covering_element ( range) {
@@ -111,6 +111,12 @@ pub(crate) fn inlay_hints(
111
111
acc
112
112
}
113
113
114
+ #[ derive( Default ) ]
115
+ struct InlayHintCtx {
116
+ lifetime_stacks : Vec < Vec < SmolStr > > ,
117
+ is_param_list : bool ,
118
+ }
119
+
114
120
pub ( crate ) fn inlay_hints_resolve (
115
121
db : & RootDatabase ,
116
122
file_id : FileId ,
@@ -131,8 +137,8 @@ pub(crate) fn inlay_hints_resolve(
131
137
let famous_defs = FamousDefs ( & sema, scope. krate ( ) ) ;
132
138
let mut acc = Vec :: new ( ) ;
133
139
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) ;
136
142
137
143
let mut res = file. clone ( ) ;
138
144
let res = loop {
@@ -146,9 +152,11 @@ pub(crate) fn inlay_hints_resolve(
146
152
acc. into_iter ( ) . find ( |hint| hasher ( hint) == hash)
147
153
}
148
154
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.
149
157
fn hints (
150
158
hints : & mut Vec < InlayHint > ,
151
- parent_impl : & mut Option < ast :: Impl > ,
159
+ ctx : & mut InlayHintCtx ,
152
160
famous_defs @ FamousDefs ( sema, _) : & FamousDefs < ' _ , ' _ > ,
153
161
config : & InlayHintsConfig ,
154
162
file_id : EditionedFileId ,
@@ -157,12 +165,30 @@ fn hints(
157
165
let node = match node {
158
166
WalkEvent :: Enter ( node) => node,
159
167
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
162
175
}
163
176
return ;
164
177
}
165
178
} ;
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
+
166
192
closing_brace:: hints ( hints, sema, config, file_id, node. clone ( ) ) ;
167
193
if let Some ( any_has_generic_args) = ast:: AnyHasGenericArgs :: cast ( node. clone ( ) ) {
168
194
generic_param:: hints ( hints, sema, config, any_has_generic_args) ;
@@ -183,7 +209,7 @@ fn hints(
183
209
closure_ret:: hints( hints, famous_defs, config, file_id, it)
184
210
} ,
185
211
ast:: Expr :: RangeExpr ( it) => range_exclusive:: hints( hints, famous_defs, config, file_id, it) ,
186
- _ => None ,
212
+ _ => Some ( ( ) ) ,
187
213
}
188
214
} ,
189
215
ast:: Pat ( it) => {
@@ -200,24 +226,27 @@ fn hints(
200
226
Some ( ( ) )
201
227
} ,
202
228
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
- } ,
208
229
ast:: Item :: Fn ( it) => {
209
230
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)
211
232
} ,
212
233
// static type elisions
213
234
ast:: Item :: Static ( it) => implicit_static:: hints( hints, famous_defs, config, file_id, Either :: Left ( it) ) ,
214
235
ast:: Item :: Const ( it) => implicit_static:: hints( hints, famous_defs, config, file_id, Either :: Right ( it) ) ,
215
236
ast:: Item :: Enum ( it) => discriminant:: enum_hints( hints, famous_defs, config, file_id, it) ,
216
237
_ => None ,
217
238
} ,
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 ( ( ) ) ,
221
250
}
222
251
} ;
223
252
}
0 commit comments