diff options
Diffstat (limited to 'src/librustc/middle/check_match.rs')
| -rw-r--r-- | src/librustc/middle/check_match.rs | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index fb797a02795..9b751447504 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -863,9 +863,18 @@ fn default(cx: &MatchCheckCtxt, r: &[@Pat]) -> Option<Vec<@Pat> > { fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) { visit::walk_local(cx, loc, ()); - if is_refutable(cx, loc.pat) { - cx.tcx.sess.span_err(loc.pat.span, - "refutable pattern in local binding"); + + let name = match loc.source { + LocalLet => "local", + LocalFor => "`for` loop" + }; + + let mut spans = vec![]; + find_refutable(cx, loc.pat, &mut spans); + + for span in spans.iter() { + cx.tcx.sess.span_err(*span, + format!("refutable pattern in {} binding", name).as_slice()); } // Check legality of move bindings. @@ -879,53 +888,65 @@ fn check_fn(cx: &mut MatchCheckCtxt, sp: Span) { visit::walk_fn(cx, kind, decl, body, sp, ()); for input in decl.inputs.iter() { - if is_refutable(cx, input.pat) { - cx.tcx.sess.span_err(input.pat.span, + let mut spans = vec![]; + find_refutable(cx, input.pat, &mut spans); + + for span in spans.iter() { + cx.tcx.sess.span_err(*span, "refutable pattern in function argument"); } } } -fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool { +fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) { + macro_rules! this_pattern { + () => { + { + spans.push(pat.span); + return + } + } + } let opt_def = cx.tcx.def_map.borrow().find_copy(&pat.id); match opt_def { Some(DefVariant(enum_id, _, _)) => { if ty::enum_variants(cx.tcx, enum_id).len() != 1u { - return true; + this_pattern!() } } - Some(DefStatic(..)) => return true, + Some(DefStatic(..)) => this_pattern!(), _ => () } match pat.node { PatUniq(sub) | PatRegion(sub) | PatIdent(_, _, Some(sub)) => { - is_refutable(cx, sub) + find_refutable(cx, sub, spans) } - PatWild | PatWildMulti | PatIdent(_, _, None) => { false } + PatWild | PatWildMulti | PatIdent(_, _, None) => {} PatLit(lit) => { match lit.node { ExprLit(lit) => { match lit.node { - LitNil => false, // `()` - _ => true, + LitNil => {} // `()` + _ => this_pattern!(), } } - _ => true, + _ => this_pattern!(), } } - PatRange(_, _) => { true } + PatRange(_, _) => { this_pattern!() } PatStruct(_, ref fields, _) => { - fields.iter().any(|f| is_refutable(cx, f.pat)) - } - PatTup(ref elts) => { - elts.iter().any(|elt| is_refutable(cx, *elt)) + for f in fields.iter() { + find_refutable(cx, f.pat, spans); + } } - PatEnum(_, Some(ref args)) => { - args.iter().any(|a| is_refutable(cx, *a)) + PatTup(ref elts) | PatEnum(_, Some(ref elts))=> { + for elt in elts.iter() { + find_refutable(cx, *elt, spans) + } } - PatEnum(_,_) => { false } - PatVec(..) => { true } + PatEnum(_,_) => {} + PatVec(..) => { this_pattern!() } } } |
