@@ -3501,11 +3501,38 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
35013501 actual)
35023502 } ,
35033503 expr_t, None ) ;
3504+ suggest_field_names( expr_t, field, tcx) ;
35043505 }
35053506
35063507 fcx. write_error( expr. id) ;
35073508 }
35083509
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+
35093536 // Check tuple index expressions
35103537 fn check_tup_field ( fcx : & FnCtxt ,
35113538 expr : & ast:: Expr ,
@@ -3601,6 +3628,8 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
36013628 } ,
36023629 struct_ty,
36033630 None ) ;
3631+ // FIXME: suggest_field_names also displays already defined fields
3632+ suggest_field_names ( struct_ty, & field. ident , tcx) ;
36043633 error_happened = true ;
36053634 }
36063635 Some ( ( _, true ) ) => {
0 commit comments