diff options
| -rw-r--r-- | src/librustc/middle/cfg/construct.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/liveness.rs | 16 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/ty.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/trans/debuginfo.rs | 6 | ||||
| -rw-r--r-- | src/librustc_trans/trans/expr.rs | 46 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 43 |
8 files changed, 102 insertions, 29 deletions
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index fe8e90bc32c..f50790f7e9b 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -439,8 +439,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { start.iter().chain(end.iter()).map(|x| &**x)) } - ast::ExprRange(..) => { - self.tcx.sess.span_bug(expr.span, "non-desugared range"); + ast::ExprRange(ref start, ref end) => { + let fields = Some(&**start).into_iter() + .chain(end.as_ref().map(|e| &**e).into_iter()); + self.straightline(expr, pred, fields) } ast::ExprUnary(_, ref e) if self.is_method_call(expr) => { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6a2bb2fc5a3..bf939e98338 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -465,8 +465,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { assert!(overloaded); } - ast::ExprRange(..) => { - self.tcx().sess.span_bug(expr.span, "non-desugared range"); + ast::ExprRange(ref start, ref end) => { + self.consume_expr(&**start); + end.as_ref().map(|e| self.consume_expr(&**e)); } ast::ExprCall(ref callee, ref args) => { // callee(args) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index fe2d7d47cb9..f59a67e2e80 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -486,9 +486,6 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ast::ExprWhileLet(..) => { ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); } - ast::ExprRange(..) => { - ir.tcx.sess.span_bug(expr.span, "non-desugared range"); - } ast::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 {}", @@ -517,7 +514,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) | ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) | - ast::ExprSlice(..) => { + ast::ExprSlice(..) | ast::ExprRange(..) => { visit::walk_expr(ir, expr); } } @@ -1200,8 +1197,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&**e1, succ) } - ast::ExprRange(..) => { - self.ir.tcx.sess.span_bug(expr.span, "non-desugared range"); + ast::ExprRange(ref e1, ref e2) => { + let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ)); + self.propagate_through_expr(&**e1, succ) } ast::ExprBox(None, ref e) | @@ -1496,7 +1494,8 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) | ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | - ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | ast::ExprSlice(..) => { + ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | + ast::ExprSlice(..) | ast::ExprRange(..) => { visit::walk_expr(this, expr); } ast::ExprIfLet(..) => { @@ -1505,9 +1504,6 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ast::ExprWhileLet(..) => { this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); } - ast::ExprRange(..) => { - this.ir.tcx.sess.span_bug(expr.span, "non-desugared range"); - } } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index e605471fc06..932a124ed33 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -541,7 +541,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { ast::ExprAddrOf(..) | ast::ExprCall(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) | ast::ExprClosure(..) | ast::ExprRet(..) | - ast::ExprUnary(..) | ast::ExprSlice(..) | + ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprRange(..) | ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) | ast::ExprBinary(..) | ast::ExprWhile(..) | @@ -559,9 +559,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { ast::ExprWhileLet(..) => { self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet"); } - ast::ExprRange(..) => { - self.tcx().sess.span_bug(expr.span, "non-desugared range"); - } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4c5d3cb5c74..236312dac6e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4257,6 +4257,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprCall(..) | ast::ExprMethodCall(..) | ast::ExprStruct(..) | + ast::ExprRange(..) | ast::ExprTup(..) | ast::ExprIf(..) | ast::ExprMatch(..) | @@ -4273,9 +4274,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprWhileLet(..) => { tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet"); } - ast::ExprRange(..) => { - tcx.sess.span_bug(expr.span, "non-desugared range"); - } ast::ExprLit(ref lit) if lit_is_str(&**lit) => { RvalueDpsExpr diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f402f1d7c31..8fadaa05203 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3494,9 +3494,9 @@ fn populate_scope_map(cx: &CrateContext, end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map)); } - ast::ExprRange(..) => { - cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ - Found unexpanded range."); + ast::ExprRange(ref start, ref end) => { + walk_expr(cx, &**start, scope_stack, scope_map); + end.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map)); } ast::ExprVec(ref init_expressions) | diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 3388a7623e3..6f9990a3e9e 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -39,7 +39,7 @@ use back::abi; use llvm::{mod, ValueRef}; use middle::def; use middle::mem_categorization::Typer; -use middle::subst::{mod, Subst}; +use middle::subst::{mod, Subst, Substs}; use trans::{_match, adt, asm, base, callee, closure, consts, controlflow}; use trans::base::*; use trans::build::*; @@ -66,6 +66,7 @@ use trans::type_::Type; use syntax::{ast, ast_util, codemap}; use syntax::print::pprust::{expr_to_string}; use syntax::ptr::P; +use syntax::parse::token; use std::rc::Rc; // Destinations @@ -1048,8 +1049,49 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, base.as_ref().map(|e| &**e), expr.span, expr.id, + node_id_type(bcx, expr.id), dest) } + ast::ExprRange(ref start, ref end) => { + // FIXME it is just not right that we are synthesising ast nodes in + // trans. Shudder. + fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field { + ast::Field { + ident: codemap::dummy_spanned(token::str_to_ident(field_name)), + expr: expr, + span: codemap::DUMMY_SP, + } + } + + // A range just desugars into a struct. + let (did, fields) = match end { + &Some(ref end) => { + // Desugar to Range + let fields = vec!(make_field("start", start.clone()), + make_field("end", end.clone())); + (tcx.lang_items.range_struct(), fields) + } + &None => { + // Desugar to RangeFrom + let fields = vec!(make_field("start", start.clone())); + (tcx.lang_items.range_from_struct(), fields) + } + }; + + if let Some(did) = did { + let substs = Substs::new_type(vec![node_id_type(bcx, start.id)], vec![]); + trans_struct(bcx, + fields.as_slice(), + None, + expr.span, + expr.id, + ty::mk_struct(tcx, did, substs), + dest) + } else { + tcx.sess.span_bug(expr.span, + "No lang item for ranges (how did we get this far?)") + } + } ast::ExprTup(ref args) => { let numbered_fields: Vec<(uint, &ast::Expr)> = args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect(); @@ -1347,10 +1389,10 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, base: Option<&ast::Expr>, expr_span: codemap::Span, expr_id: ast::NodeId, + ty: Ty<'tcx>, dest: Dest) -> Block<'blk, 'tcx> { let _icx = push_ctxt("trans_rec"); - let ty = node_id_type(bcx, expr_id); let tcx = bcx.tcx(); with_field_tys(tcx, ty, Some(expr_id), |discr, field_tys| { let mut need_base = Vec::from_elem(field_tys.len(), true); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 02811861551..4a10954729d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4238,7 +4238,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, check_expr(fcx, e); let e_t = fcx.expr_ty(e); if ty::type_is_error(e_t) { - fcx.write_ty(id, e_t); + fcx.write_ty(e.id, e_t); some_err = true; } }; @@ -4278,8 +4278,45 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } } } - ast::ExprRange(..) => { - tcx.sess.span_bug(expr.span, "non-desugared range"); + ast::ExprRange(ref start, ref end) => { + let mut some_err = false; + + check_expr(fcx, &**start); + let t_start = fcx.expr_ty(&**start); + if ty::type_is_error(t_start) { + fcx.write_ty(start.id, t_start); + some_err = true; + } + + if let &Some(ref e) = end { + check_expr_has_type(fcx, &**e, t_start); + let t_end = fcx.expr_ty(&**e); + if ty::type_is_error(t_end) { + fcx.write_ty(e.id, t_end); + some_err = true; + } + } + + // Note that we don't check the type of the start/end satisfy any + // bounds because right the range structs do not have any. If we add + // some bounds, then we'll need to check `t_start` against them here. + + if !some_err { + // Find the did from the appropriate lang item. + let did = if end.is_some() { + // Range + fcx.tcx().lang_items.range_struct() + } else { + // RangeFrom + fcx.tcx().lang_items.range_from_struct() + }; + if let Some(did) = did { + let substs = Substs::new_type(vec![t_start], vec![]); + fcx.write_ty(id, ty::mk_struct(tcx, did, substs)); + } else { + fcx.write_ty(id, ty::mk_err()); + } + } } } |
