@@ -3345,11 +3345,38 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
33453345 actual)
33463346 } ,
33473347 expr_t, None ) ;
3348+ suggest_field_names ( expr_t, field, tcx) ;
33483349 }
33493350
33503351 fcx. write_error ( expr. id ) ;
33513352 }
33523353
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+
33533380 // Check tuple index expressions
33543381 fn check_tup_field ( fcx : & FnCtxt ,
33553382 expr : & ast:: Expr ,
@@ -3445,6 +3472,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
34453472 } ,
34463473 struct_ty,
34473474 None ) ;
3475+ // FIXME: suggest_field_names also displays already defined fields
3476+ suggest_field_names ( struct_ty, & field. ident , tcx) ;
34483477 error_happened = true ;
34493478 }
34503479 Some ( ( _, true ) ) => {
0 commit comments