mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 23:06:23 +00:00
Add check for irrefutable patterns in destructuring locals
This commit is contained in:
parent
985c32ef4c
commit
92240eb25b
@ -3,8 +3,9 @@ import syntax::visit;
|
||||
|
||||
fn check_crate(tcx: &ty::ctxt, crate: &@crate) {
|
||||
let v =
|
||||
@{visit_expr: bind check_expr(tcx, _, _, _)
|
||||
with *visit::default_visitor[()]()};
|
||||
@{visit_expr: bind check_expr(tcx, _, _, _),
|
||||
visit_local: bind check_local(tcx, _, _, _)
|
||||
with *visit::default_visitor[()]()};
|
||||
visit::visit_crate(*crate, (), visit::mk_vt(v));
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
@ -92,6 +93,38 @@ fn pattern_supersedes(tcx: &ty::ctxt, a: &@pat, b: &@pat) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(tcx: &ty::ctxt, loc: &@local, s: &(), v: &visit::vt[()]) {
|
||||
visit::visit_local(loc, s, v);
|
||||
if is_refutable(tcx, loc.node.pat) {
|
||||
tcx.sess.span_err(loc.node.pat.span,
|
||||
"refutable pattern in local binding");
|
||||
}
|
||||
}
|
||||
|
||||
fn is_refutable(tcx: &ty::ctxt, pat: &@pat) -> bool {
|
||||
alt pat.node {
|
||||
pat_wild. | pat_bind(_) { ret false; }
|
||||
pat_lit(_) { ret true; }
|
||||
pat_box(sub) { ret is_refutable(tcx, sub); }
|
||||
pat_rec(fields, _) {
|
||||
for field: field_pat in fields {
|
||||
if is_refutable(tcx, field.pat) { ret true; }
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
pat_tag(_, args) {
|
||||
let vdef = variant_def_ids(tcx.def_map.get(pat.id));
|
||||
if std::ivec::len(ty::tag_variants(tcx, vdef.tg)) != 1u {
|
||||
ret true;
|
||||
}
|
||||
for p: @pat in args {
|
||||
if is_refutable(tcx, p) { ret true; }
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
|
@ -1198,8 +1198,6 @@ fn gather_locals(ccx: &@crate_ctxt, f: &ast::_fn, id: &ast::node_id,
|
||||
local_names: &hashmap[ast::node_id, ast::ident],
|
||||
nvi: @mutable int, nid: ast::node_id, ident: &ast::ident,
|
||||
ty_opt: option::t[ty::t]) {
|
||||
// FIXME DESTR
|
||||
if locals.contains_key(nid) { ret; }
|
||||
let var_id = next_var_id(nvi);
|
||||
locals.insert(nid, var_id);
|
||||
local_names.insert(nid, ident);
|
||||
|
Loading…
Reference in New Issue
Block a user