@@ -3501,11 +3501,38 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3501
3501
actual)
3502
3502
} ,
3503
3503
expr_t, None ) ;
3504
+ suggest_field_names( expr_t, field, tcx) ;
3504
3505
}
3505
3506
3506
3507
fcx. write_error( expr. id) ;
3507
3508
}
3508
3509
3510
+ fn suggest_field_names<' tcx>( t : ty:: t,
3511
+ field : & ast:: SpannedIdent ,
3512
+ tcx : & ty:: ctxt < ' tcx > ) {
3513
+ let id = ty:: ty_to_def_id ( t) . unwrap( ) ;
3514
+ let ident = token:: get_ident( field. node) ;
3515
+ let name = ident. get( ) ;
3516
+ // only find fits with at least one matching letter
3517
+ let mut best_dist = name. len( ) ;
3518
+ let mut best = vec ! [ ] ;
3519
+ let fields = ty:: lookup_struct_fields( tcx, id) ;
3520
+ for elem in fields. iter( ) {
3521
+ let n = elem. name. as_str( ) ;
3522
+ let dist = n. lev_distance( name) ;
3523
+ if dist < best_dist {
3524
+ best = vec ! [ n] ;
3525
+ best_dist = dist;
3526
+ } else if dist == best_dist {
3527
+ best. push ( n) ;
3528
+ }
3529
+ }
3530
+ for n in best. iter ( ) {
3531
+ tcx. sess . span_help ( field. span ,
3532
+ format ! ( "did you mean `{}`?" , n) . as_slice ( ) ) ;
3533
+ }
3534
+ }
3535
+
3509
3536
// Check tuple index expressions
3510
3537
fn check_tup_field ( fcx : & FnCtxt ,
3511
3538
expr : & ast:: Expr ,
@@ -3601,6 +3628,8 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
3601
3628
} ,
3602
3629
struct_ty,
3603
3630
None ) ;
3631
+ // FIXME: suggest_field_names also displays already defined fields
3632
+ suggest_field_names ( struct_ty, & field. ident , tcx) ;
3604
3633
error_happened = true ;
3605
3634
}
3606
3635
Some ( ( _, true ) ) => {
0 commit comments