diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 68e40c75da84..e6d1a0ca27c4 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -92,7 +92,8 @@ fn classify(e: @expr, ast::expr_vstore_fixed(_) | ast::expr_vstore_slice => classify(e, def_map, tcx), ast::expr_vstore_uniq | - ast::expr_vstore_box => non_const + ast::expr_vstore_box | + ast::expr_vstore_mut_box => non_const } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index c6b5b9fbfe0f..2e4d95acdfbd 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -392,7 +392,8 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); match expr.node { - ast::expr_vstore(contents, ast::expr_vstore_box) => { + ast::expr_vstore(contents, ast::expr_vstore_box) | + ast::expr_vstore(contents, ast::expr_vstore_mut_box) => { return tvec::trans_uniq_or_managed_vstore(bcx, heap_shared, expr, contents); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 5f27e8665dd4..7d6f937f82d1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3187,6 +3187,7 @@ fn expr_kind(tcx: ctxt, ast::expr_addr_of(*) | ast::expr_binary(*) | ast::expr_vstore(_, ast::expr_vstore_box) | + ast::expr_vstore(_, ast::expr_vstore_mut_box) | ast::expr_vstore(_, ast::expr_vstore_uniq) => { RvalueDatumExpr } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index f80b655a860b..4d0fdcdca406 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -176,13 +176,14 @@ fn ast_ty_to_ty( let tcx = self.tcx(); match a_seq_ty.ty.node { - // to convert to an e{vec,str}, there can't be a - // mutability argument - _ if a_seq_ty.mutbl != ast::m_imm => (), ast::ty_vec(mt) => { - return ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, mt), vst); + let mut mt = ast_mt_to_mt(self, rscope, mt); + if a_seq_ty.mutbl == ast::m_mutbl { + mt = { ty: mt.ty, mutbl: ast::m_mutbl }; + } + return ty::mk_evec(tcx, mt, vst); } - ast::ty_path(path, id) => { + ast::ty_path(path, id) if a_seq_ty.mutbl == ast::m_imm => { match tcx.def_map.find(id) { Some(ast::def_prim_ty(ast::ty_str)) => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); diff --git a/src/librustc/middle/typeck/check.rs b/src/librustc/middle/typeck/check.rs index ee93c7fccef9..b24550f2bc64 100644 --- a/src/librustc/middle/typeck/check.rs +++ b/src/librustc/middle/typeck/check.rs @@ -1705,9 +1705,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, } ast::expr_vec(args, mutbl) => { let tt = ast_expr_vstore_to_vstore(fcx, ev, args.len(), vst); + let mutability; + match vst { + ast::expr_vstore_mut_box => mutability = ast::m_mutbl, + _ => mutability = mutbl + } let t: ty::t = fcx.infcx().next_ty_var(); for args.each |e| { bot |= check_expr_with(fcx, *e, t); } - ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt) + ty::mk_evec(tcx, {ty: t, mutbl: mutability}, tt) } ast::expr_repeat(element, count_expr, mutbl) => { let count = ty::eval_repeat_count(tcx, count_expr, expr.span); @@ -2721,7 +2726,7 @@ fn ast_expr_vstore_to_vstore(fcx: @fn_ctxt, e: @ast::expr, n: uint, ty::vstore_fixed(u) } ast::expr_vstore_uniq => ty::vstore_uniq, - ast::expr_vstore_box => ty::vstore_box, + ast::expr_vstore_box | ast::expr_vstore_mut_box => ty::vstore_box, ast::expr_vstore_slice => { let r = fcx.infcx().next_region_var(e.span, e.id); ty::vstore_slice(r) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index da28e349a563..353bb26ea9ea 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -645,6 +645,7 @@ enum expr_vstore { expr_vstore_fixed(Option), // [1,2,3,4] expr_vstore_uniq, // ~[1,2,3,4] expr_vstore_box, // @[1,2,3,4] + expr_vstore_mut_box, // @mut [1,2,3,4] expr_vstore_slice // &[1,2,3,4] } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 925934d165f6..f340a52a4e7d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -38,7 +38,8 @@ use ast::{_mod, add, arg, arm, attribute, expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac, expr_paren, expr_path, expr_rec, expr_repeat, expr_ret, expr_swap, expr_struct, expr_tup, expr_unary, expr_unary_move, - expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl, + expr_vec, expr_vstore, expr_vstore_mut_box, expr_while, + extern_fn, field, fn_decl, foreign_item, foreign_item_const, foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited, item, item_, item_class, item_const, item_enum, item_fn, @@ -1450,8 +1451,11 @@ impl Parser { hi = e.span.hi; // HACK: turn @[...] into a @-evec ex = match e.node { - expr_vec(*) | expr_lit(@{node: lit_str(_), span: _}) - if m == m_imm => expr_vstore(e, expr_vstore_box), + expr_vec(*) if m == m_mutbl => + expr_vstore(e, expr_vstore_mut_box), + expr_vec(*) if m == m_imm => expr_vstore(e, expr_vstore_box), + expr_lit(@{node: lit_str(_), span: _}) if m == m_imm => + expr_vstore(e, expr_vstore_box), _ => expr_unary(box(m), e) }; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b4a5407c0024..e0523613ee66 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1027,6 +1027,10 @@ fn print_expr_vstore(s: ps, t: ast::expr_vstore) { ast::expr_vstore_fixed(None) => word(s.s, ~"_"), ast::expr_vstore_uniq => word(s.s, ~"~"), ast::expr_vstore_box => word(s.s, ~"@"), + ast::expr_vstore_mut_box => { + word(s.s, ~"@"); + word(s.s, ~"mut"); + } ast::expr_vstore_slice => word(s.s, ~"&"), } } diff --git a/src/test/compile-fail/borrowck-mut-boxed-vec.rs b/src/test/compile-fail/borrowck-mut-boxed-vec.rs new file mode 100644 index 000000000000..cd36bedfa241 --- /dev/null +++ b/src/test/compile-fail/borrowck-mut-boxed-vec.rs @@ -0,0 +1,7 @@ +fn main() { + let v = @mut [ 1, 2, 3 ]; + for v.each |_x| { //~ ERROR illegal borrow + v[1] = 4; + } +} + diff --git a/src/test/run-pass/new-vstore-mut-box-syntax.rs b/src/test/run-pass/new-vstore-mut-box-syntax.rs new file mode 100644 index 000000000000..6b77d778eb95 --- /dev/null +++ b/src/test/run-pass/new-vstore-mut-box-syntax.rs @@ -0,0 +1,5 @@ +fn main() { + let x: @mut [int] = @mut [ 1, 2, 3 ]; + +} +