Skip to content

Commit 5d1b223

Browse files
author
oliver
committed
librustc: hint close matches on accessing nonexisting fields
1 parent 6f4c11b commit 5d1b223

File tree

1 file changed

+29
-0
lines changed
  • src/librustc_typeck/check

1 file changed

+29
-0
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)