@@ -14,7 +14,7 @@ use ide_db::{
14
14
use itertools:: Itertools ;
15
15
use stdx:: format_to;
16
16
use syntax:: {
17
- algo, ast, match_ast, AstNode , Direction ,
17
+ algo, ast:: { self , RecordPat } , match_ast, AstNode , Direction ,
18
18
SyntaxKind :: { LET_EXPR , LET_STMT } ,
19
19
SyntaxToken , T ,
20
20
} ;
@@ -250,6 +250,58 @@ pub(super) fn keyword(
250
250
Some ( HoverResult { markup, actions } )
251
251
}
252
252
253
+ pub ( super ) fn struct_rest_pat (
254
+ sema : & Semantics < ' _ , RootDatabase > ,
255
+ config : & HoverConfig ,
256
+ expr_or_pat : & Either < ast:: Expr , ast:: Pat > ,
257
+ ) -> Option < HoverResult > {
258
+ let pat = expr_or_pat. as_ref ( ) . right ( ) ?;
259
+
260
+ let mut ancestors = sema. ancestors_with_macros ( pat. syntax ( ) . clone ( ) ) ;
261
+ let _record_pat_field_list = ancestors. next ( ) ?;
262
+ let record_pat = ancestors. next ( ) ?;
263
+ let pattern = sema
264
+ . find_nodes_at_offset_with_descend :: < RecordPat > (
265
+ & record_pat,
266
+ record_pat. text_range ( ) . start ( ) )
267
+ . next ( ) ?;
268
+
269
+ let missing_fields = sema. record_pattern_missing_fields ( & pattern) ;
270
+
271
+ // if there are no missing fields, the end result is a hover that shows ".."
272
+ // should be left in to indicate that there are no more fields in the pattern
273
+ // example, S {a: 1, b: 2, ..} when struct S {a: u32, b: u32}
274
+
275
+ let mut res = HoverResult :: default ( ) ;
276
+ let mut targets: Vec < hir:: ModuleDef > = Vec :: new ( ) ;
277
+ let mut push_new_def = |item : hir:: ModuleDef | {
278
+ if !targets. contains ( & item) {
279
+ targets. push ( item) ;
280
+ }
281
+ } ;
282
+ for ( _, t) in & missing_fields {
283
+ walk_and_push_ty ( sema. db , & t, & mut push_new_def) ;
284
+ }
285
+
286
+ res. markup = {
287
+ let mut s = String :: from ( ".., " ) ;
288
+ for ( f, _) in & missing_fields {
289
+ s += f. display ( sema. db ) . to_string ( ) . as_ref ( ) ;
290
+ s += ", " ;
291
+ }
292
+ // get rid of trailing comma
293
+ if s. len ( ) > 0 { s. truncate ( s. len ( ) - 2 ) ; }
294
+
295
+ if config. markdown ( ) {
296
+ Markup :: fenced_block ( & s)
297
+ } else {
298
+ s. into ( )
299
+ }
300
+ } ;
301
+ res. actions . push ( HoverAction :: goto_type_from_targets ( sema. db , targets) ) ;
302
+ Some ( res)
303
+ }
304
+
253
305
pub ( super ) fn try_for_lint ( attr : & ast:: Attr , token : & SyntaxToken ) -> Option < HoverResult > {
254
306
let ( path, tt) = attr. as_simple_call ( ) ?;
255
307
if !tt. syntax ( ) . text_range ( ) . contains ( token. text_range ( ) . start ( ) ) {
0 commit comments