@@ -3345,11 +3345,38 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3345
3345
actual)
3346
3346
} ,
3347
3347
expr_t, None ) ;
3348
+ suggest_field_names ( expr_t, field, tcx) ;
3348
3349
}
3349
3350
3350
3351
fcx. write_error ( expr. id ) ;
3351
3352
}
3352
3353
3354
+ fn suggest_field_names < ' tcx > ( t : ty:: t ,
3355
+ field : & ast:: SpannedIdent ,
3356
+ tcx : & ty:: ctxt < ' tcx > ) {
3357
+ let id = ty:: ty_to_def_id ( t) . unwrap ( ) ;
3358
+ let ident = token:: get_ident ( field. node ) ;
3359
+ let name = ident. get ( ) ;
3360
+ // only find fits with at least one matching letter
3361
+ let mut best_dist = name. len ( ) ;
3362
+ let mut best = vec ! [ ] ;
3363
+ let fields = ty:: lookup_struct_fields ( tcx, id) ;
3364
+ for elem in fields. iter ( ) {
3365
+ let n = elem. name . as_str ( ) ;
3366
+ let dist = n. lev_distance ( name) ;
3367
+ if dist < best_dist {
3368
+ best = vec ! [ n] ;
3369
+ best_dist = dist;
3370
+ } else if dist == best_dist {
3371
+ best. push ( n) ;
3372
+ }
3373
+ }
3374
+ for n in best. iter ( ) {
3375
+ tcx. sess . span_help ( field. span ,
3376
+ format ! ( "did you mean `{}`?" , n) . as_slice ( ) ) ;
3377
+ }
3378
+ }
3379
+
3353
3380
// Check tuple index expressions
3354
3381
fn check_tup_field ( fcx : & FnCtxt ,
3355
3382
expr : & ast:: Expr ,
@@ -3445,6 +3472,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3445
3472
} ,
3446
3473
struct_ty,
3447
3474
None ) ;
3475
+ // FIXME: suggest_field_names also displays already defined fields
3476
+ suggest_field_names ( struct_ty, & field. ident , tcx) ;
3448
3477
error_happened = true ;
3449
3478
}
3450
3479
Some ( ( _, true ) ) => {
0 commit comments