custom message for refutable patterns in for loops
This commit is contained in:
parent
5e1820f346
commit
76362f0a0e
6 changed files with 38 additions and 9 deletions
|
@ -1163,6 +1163,7 @@ impl LintPass for UnusedParens {
|
|||
ast::MatchSource::Normal => (head, "`match` head expression", true),
|
||||
ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true),
|
||||
ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true),
|
||||
ast::MatchSource::ForLoopDesugar => (head, "`for` head expression", true),
|
||||
},
|
||||
ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
|
||||
ast::ExprAssign(_, ref value) => (value, "assigned value", false),
|
||||
|
|
|
@ -221,7 +221,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
|
|||
.flat_map(|arm| arm.0.iter())
|
||||
.map(|pat| vec![&**pat])
|
||||
.collect();
|
||||
check_exhaustive(cx, ex.span, &matrix);
|
||||
check_exhaustive(cx, ex.span, &matrix, source);
|
||||
},
|
||||
ast::ExprForLoop(ref pat, _, _, _) => {
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx);
|
||||
|
@ -327,6 +327,14 @@ fn check_arms(cx: &MatchCheckCtxt,
|
|||
span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern");
|
||||
},
|
||||
|
||||
ast::MatchSource::ForLoopDesugar => {
|
||||
// this is a bug, because on `match iter.next()` we cover
|
||||
// `Some(<head>)` and `None`. It's impossible to have an unreachable
|
||||
// pattern
|
||||
// (see libsyntax/ext/expand.rs for the full expansion of a for loop)
|
||||
cx.tcx.sess.span_bug(pat.span, "unreachable for-loop pattern")
|
||||
},
|
||||
|
||||
ast::MatchSource::Normal => {
|
||||
span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
|
||||
},
|
||||
|
@ -351,7 +359,7 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
|
||||
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) {
|
||||
match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
let witness = match &pats[] {
|
||||
|
@ -359,10 +367,29 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
|
|||
[] => DUMMY_WILD_PAT,
|
||||
_ => unreachable!()
|
||||
};
|
||||
span_err!(cx.tcx.sess, sp, E0004,
|
||||
"non-exhaustive patterns: `{}` not covered",
|
||||
pat_to_string(witness)
|
||||
);
|
||||
match source {
|
||||
ast::MatchSource::ForLoopDesugar => {
|
||||
// `witness` has the form `Some(<head>)`, peel off the `Some`
|
||||
let witness = match witness.node {
|
||||
ast::PatEnum(_, Some(ref pats)) => match &pats[] {
|
||||
[ref pat] => &**pat,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
span_err!(cx.tcx.sess, sp, E0297,
|
||||
"refutable pattern in `for` loop binding: \
|
||||
`{}` not covered",
|
||||
pat_to_string(witness));
|
||||
},
|
||||
_ => {
|
||||
span_err!(cx.tcx.sess, sp, E0004,
|
||||
"non-exhaustive patterns: `{}` not covered",
|
||||
pat_to_string(witness)
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
NotUseful => {
|
||||
// This is good, wildcard pattern isn't reachable
|
||||
|
|
|
@ -100,6 +100,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
|
|||
ast::ExprMethodCall(..) => "method call",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
|
||||
ast::ExprMatch(..) => "match",
|
||||
_ => "expression",
|
||||
},
|
||||
|
|
|
@ -788,6 +788,7 @@ pub enum MatchSource {
|
|||
Normal,
|
||||
IfLetDesugar { contains_else_clause: bool },
|
||||
WhileLetDesugar,
|
||||
ForLoopDesugar,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
||||
|
|
|
@ -288,8 +288,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
|||
fld.cx.expr_call(span, fld.cx.expr_path(next_path), vec![ref_mut_iter]);
|
||||
let arms = vec![pat_arm, break_arm];
|
||||
|
||||
// FIXME(japaric) This should use `ForLoopDesugar` as MatchSource
|
||||
fld.cx.expr_match(pat_span, next_expr, arms)
|
||||
fld.cx.expr(pat_span,
|
||||
ast::ExprMatch(next_expr, arms, ast::MatchSource::ForLoopDesugar))
|
||||
};
|
||||
|
||||
// `[opt_ident]: loop { ... }`
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
fn main() {
|
||||
for
|
||||
&1is //~ ERROR refutable pattern in `for` loop binding
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue