From 45fd623762aca093ab913ed3a8fcd13c5798005d Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Fri, 3 Oct 2014 00:41:24 -0400 Subject: [PATCH] Handle `while let` desugaring --- src/librustc/diagnostics.rs | 3 ++- src/librustc/lint/builtin.rs | 3 ++- src/librustc/middle/cfg/construct.rs | 4 +++ src/librustc/middle/check_match.rs | 30 +++++++++++++++-------- src/librustc/middle/expr_use_visitor.rs | 4 +++ src/librustc/middle/liveness.rs | 10 ++++++++ src/librustc/middle/mem_categorization.rs | 3 +++ src/librustc/middle/trans/debuginfo.rs | 5 ++++ src/librustc/middle/ty.rs | 3 +++ src/librustc/middle/typeck/check/mod.rs | 3 +++ src/librustc/util/ppaux.rs | 3 +++ src/librustc_back/svh.rs | 1 + 12 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b39c41521683..0ccfc7e80f60 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -150,5 +150,6 @@ register_diagnostics!( E0161, E0162, E0163, - E0164 + E0164, + E0165 ) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index e0e16390e353..988b128e31d5 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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), diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index a9a3981ab5fc..b573c4e59487 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -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] diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 297640707687..dde3f3281f09 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -261,20 +261,30 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[(Vec>, 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 => (), diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6cfdac93efc8..6f179e0624fe 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2176cd565894..90973dfaa002 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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"); + } } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index fa494b357c19..4a1c4aaa8951 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -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"); + } } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 43c989982996..d81f78f23ffa 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -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); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index cea74c6573d5..9a51b258ae46 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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 diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 68bb3fcf9454..07a56ad46203 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6898eb17e917..459e7eb093e7 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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) } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 35e42e3c54b2..3c28cac6c6f7 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -294,6 +294,7 @@ mod svh_visitor { // just syntactic artifacts, expanded away by time of SVH. ExprIfLet(..) => unreachable!(), + ExprWhileLet(..) => unreachable!(), ExprMac(..) => unreachable!(), } }