Handle while let desugaring

This commit is contained in:
John Gallagher 2014-10-03 00:41:24 -04:00
parent 660cf18070
commit 45fd623762
12 changed files with 60 additions and 12 deletions

View file

@ -150,5 +150,6 @@ register_diagnostics!(
E0161,
E0162,
E0163,
E0164
E0164,
E0165
)

View file

@ -1082,7 +1082,8 @@ impl LintPass for UnnecessaryParens {
ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
ast::ExprMatch(ref head, _, source) => match source {
ast::MatchNormal => (head, "`match` head expression", true),
ast::MatchIfLetDesugar => (head, "`if let` head expression", true)
ast::MatchIfLetDesugar => (head, "`if let` head expression", true),
ast::MatchWhileLetDesugar => (head, "`while let` head expression", true),
},
ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
ast::ExprAssign(_, ref value) => (value, "assigned value", false),

View file

@ -259,6 +259,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
expr_exit
}
ast::ExprWhileLet(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(ref pat, ref head, ref body, _) => {
//
// [pred]

View file

@ -261,20 +261,30 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[(Vec<P<Pat>>, Option<&Expr>)], source
match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
NotUseful => {
if source == MatchIfLetDesugar {
if printed_if_let_err {
// we already printed an irrefutable if-let pattern error.
// We don't want two, that's just confusing.
} else {
match source {
MatchIfLetDesugar => {
if printed_if_let_err {
// we already printed an irrefutable if-let pattern error.
// We don't want two, that's just confusing.
} else {
// find the first arm pattern so we can use its span
let &(ref first_arm_pats, _) = &arms[0];
let first_pat = first_arm_pats.get(0);
let span = first_pat.span;
span_err!(cx.tcx.sess, span, E0162, "irrefutable if-let pattern");
printed_if_let_err = true;
}
},
MatchWhileLetDesugar => {
// find the first arm pattern so we can use its span
let &(ref first_arm_pats, _) = &arms[0];
let first_pat = first_arm_pats.get(0);
let span = first_pat.span;
span_err!(cx.tcx.sess, span, E0162, "irrefutable if-let pattern");
printed_if_let_err = true;
}
} else {
span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern");
span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern");
},
_ => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
}
}
Useful => (),

View file

@ -429,6 +429,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
self.walk_block(&**blk);
}
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(ref pat, ref head, ref blk, _) => {
// The pattern lives as long as the block.
debug!("walk_expr for loop case: blk id={}", blk.id);

View file

@ -484,6 +484,9 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ExprIfLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ExprWhileLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
debug!("adding local variable {} from for loop with bm {:?}",
@ -1022,6 +1025,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
}
ExprWhileLet(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ExprForLoop(ref pat, ref head, ref blk, _) => {
let ln = self.propagate_through_loop(expr, ForLoop(&**pat), &**blk, succ);
self.propagate_through_expr(&**head, ln)
@ -1480,6 +1487,9 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ExprIfLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ExprWhileLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
}
}

View file

@ -530,6 +530,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
ast::ExprIfLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
}
}

View file

@ -3496,6 +3496,11 @@ fn populate_scope_map(cx: &CrateContext,
})
}
ast::ExprWhileLet(..) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
Found unexpanded while-let.");
}
ast::ExprForLoop(ref pattern, ref head, ref body, _) => {
walk_expr(cx, &**head, scope_stack, scope_map);

View file

@ -3615,6 +3615,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
ast::ExprIfLet(..) => {
tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhileLet(..) => {
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
RvalueDpsExpr

View file

@ -4116,6 +4116,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_nil(id);
}
}
ast::ExprWhileLet(..) => {
tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(ref pat, ref head, ref block, _) => {
check_expr(fcx, &**head);
let typ = lookup_method_for_for_loop(fcx, &**head, expr.id);

View file

@ -93,6 +93,9 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
explain_span(cx, "method call", expr.span)
},
ast::ExprMatch(_, _, ast::MatchIfLetDesugar) => explain_span(cx, "if let", expr.span),
ast::ExprMatch(_, _, ast::MatchWhileLetDesugar) => {
explain_span(cx, "while let", expr.span)
},
ast::ExprMatch(..) => explain_span(cx, "match", expr.span),
_ => explain_span(cx, "expression", expr.span)
}

View file

@ -294,6 +294,7 @@ mod svh_visitor {
// just syntactic artifacts, expanded away by time of SVH.
ExprIfLet(..) => unreachable!(),
ExprWhileLet(..) => unreachable!(),
ExprMac(..) => unreachable!(),
}
}