diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 5c39c9fa74d0a..0e10155beb470 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -462,15 +462,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.straightline(expr, pred, [r, l].iter().map(|&e| &**e)) } + ast::ExprBox(Some(ref l), ref r) | ast::ExprIndex(ref l, ref r) | ast::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier self.straightline(expr, pred, [l, r].iter().map(|&e| &**e)) } - ast::ExprBox(ref p, ref e) => { - self.straightline(expr, pred, [p, e].iter().map(|&e| &**e)) - } - + ast::ExprBox(None, ref e) | ast::ExprAddrOf(_, ref e) | ast::ExprCast(ref e, _) | ast::ExprUnary(_, ref e) | diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 746a6fc6e70a2..2cb78beff4c85 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -631,7 +631,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { } ast::ExprBox(ref place, ref base) => { - self.consume_expr(&**place); + match *place { + Some(ref place) => self.consume_expr(&**place), + None => {} + } self.consume_expr(&**base); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 31bcdff9cd593..c76d9bc6b1faa 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1199,7 +1199,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ast::ExprIndex(ref l, ref r) | ast::ExprBinary(_, ref l, ref r) | - ast::ExprBox(ref l, ref r) => { + ast::ExprBox(Some(ref l), ref r) => { let r_succ = self.propagate_through_expr(&**r, succ); self.propagate_through_expr(&**l, r_succ) } @@ -1210,6 +1210,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&**e1, succ) } + ast::ExprBox(None, ref e) | ast::ExprAddrOf(_, ref e) | ast::ExprCast(ref e, _) | ast::ExprUnary(_, ref e) | diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 50c324c49c382..b5a8f4869e25c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4320,12 +4320,13 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprLit(_) | // Note: LitStr is carved out above ast::ExprUnary(..) | + ast::ExprBox(None, _) | ast::ExprAddrOf(..) | ast::ExprBinary(..) => { RvalueDatumExpr } - ast::ExprBox(ref place, _) => { + ast::ExprBox(Some(ref place), _) => { // Special case `Box` for now: let definition = match tcx.def_map.borrow().get(&place.id) { Some(&def) => def, diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 3f8c951786dfa..c97e6a09529ec 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3472,7 +3472,8 @@ fn populate_scope_map(cx: &CrateContext, walk_expr(cx, &**sub_exp, scope_stack, scope_map), ast::ExprBox(ref place, ref sub_expr) => { - walk_expr(cx, &**place, scope_stack, scope_map); + place.as_ref().map( + |e| walk_expr(cx, &**e, scope_stack, scope_map)); walk_expr(cx, &**sub_expr, scope_stack, scope_map); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 482284c07dc02..4b2e91977fbfc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3658,22 +3658,25 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let tcx = fcx.ccx.tcx; let id = expr.id; match expr.node { - ast::ExprBox(ref place, ref subexpr) => { - check_expr(fcx, &**place); + ast::ExprBox(ref opt_place, ref subexpr) => { + opt_place.as_ref().map(|place|check_expr(fcx, &**place)); check_expr(fcx, &**subexpr); let mut checked = false; - if let ast::ExprPath(ref path) = place.node { - // FIXME(pcwalton): For now we hardcode the two permissible - // places: the exchange heap and the managed heap. - let definition = lookup_def(fcx, path.span, place.id); - let def_id = definition.def_id(); - let referent_ty = fcx.expr_ty(&**subexpr); - if tcx.lang_items.exchange_heap() == Some(def_id) { - fcx.write_ty(id, ty::mk_uniq(tcx, referent_ty)); - checked = true + opt_place.as_ref().map(|place| match place.node { + ast::ExprPath(ref path) => { + // FIXME(pcwalton): For now we hardcode the two permissible + // places: the exchange heap and the managed heap. + let definition = lookup_def(fcx, path.span, place.id); + let def_id = definition.def_id(); + let referent_ty = fcx.expr_ty(&**subexpr); + if tcx.lang_items.exchange_heap() == Some(def_id) { + fcx.write_ty(id, ty::mk_uniq(tcx, referent_ty)); + checked = true + } } - } + _ => {} + }); if !checked { span_err!(tcx.sess, expr.span, E0066, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 206fb26eb55cb..98d858babb171 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -696,7 +696,7 @@ pub struct Expr { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Expr_ { /// First expr is the place; second expr is the value. - ExprBox(P, P), + ExprBox(Option>, P), ExprVec(Vec>), ExprCall(P, Vec>), ExprMethodCall(SpannedIdent, Vec>, Vec>), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8a578c2cb05c0..7d2acd08d9430 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1282,7 +1282,7 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> id: folder.new_id(id), node: match node { ExprBox(p, e) => { - ExprBox(folder.fold_expr(p), folder.fold_expr(e)) + ExprBox(p.map(|e|folder.fold_expr(e)), folder.fold_expr(e)) } ExprVec(exprs) => { ExprVec(exprs.move_map(|x| folder.fold_expr(x))) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b9ef3fdbd49a3..6e3cfe5854a40 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2888,7 +2888,7 @@ impl<'a> Parser<'a> { } let subexpression = self.parse_prefix_expr(); hi = subexpression.span.hi; - ex = ExprBox(place, subexpression); + ex = ExprBox(Some(place), subexpression); return self.mk_expr(lo, hi, ex); } } @@ -2896,6 +2896,9 @@ impl<'a> Parser<'a> { // Otherwise, we use the unique pointer default. let subexpression = self.parse_prefix_expr(); hi = subexpression.span.hi; + // FIXME (pnkfelix): After working out kinks with box + // desugaring, should be `ExprBox(None, subexpression)` + // instead. ex = self.mk_unary(UnUniq, subexpression); } _ => return self.parse_dot_or_call_expr() diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index db122f271a9c4..4f45b69883ba1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1495,7 +1495,7 @@ impl<'a> State<'a> { ast::ExprBox(ref p, ref e) => { try!(word(&mut self.s, "box")); try!(word(&mut self.s, "(")); - try!(self.print_expr(&**p)); + try!(p.as_ref().map_or(Ok(()), |e|self.print_expr(&**e))); try!(self.word_space(")")); try!(self.print_expr(&**e)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3535c6e267eba..f5a86bafea12a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -739,7 +739,7 @@ pub fn walk_mac<'v, V: Visitor<'v>>(_: &mut V, _: &'v Mac) { pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { match expression.node { ExprBox(ref place, ref subexpression) => { - visitor.visit_expr(&**place); + place.as_ref().map(|e|visitor.visit_expr(&**e)); visitor.visit_expr(&**subexpression) } ExprVec(ref subexpressions) => {