From f96a2a2ca16a44f869336f7e28fc261551c1184c Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 5 Oct 2012 22:07:53 -0700 Subject: [PATCH] Remove by-mutable-ref mode from the compiler and test cases. Closes #3513 --- doc/rust.md | 10 +++----- src/libsyntax/ast.rs | 2 +- src/libsyntax/parse/obsolete.rs | 7 +++++- src/libsyntax/parse/parser.rs | 11 ++++---- src/libsyntax/print/pprust.rs | 1 - src/rustc/metadata/tydecode.rs | 1 - src/rustc/metadata/tyencode.rs | 1 - src/rustc/middle/borrowck/check_loans.rs | 2 +- src/rustc/middle/borrowck/gather_loans.rs | 4 --- src/rustc/middle/kind.rs | 13 +++------- src/rustc/middle/liveness.rs | 25 +++---------------- src/rustc/middle/mem_categorization.rs | 3 --- src/rustc/middle/trans/base.rs | 2 +- src/rustc/middle/trans/callee.rs | 2 +- src/rustc/middle/trans/meth.rs | 2 +- src/rustc/middle/trans/reflect.rs | 1 - src/rustc/middle/trans/type_use.rs | 2 +- .../bench/task-perf-word-count-generic.rs | 16 ++++++------ .../compile-fail/deprecated-mode-fn-arg.rs | 6 ++--- .../compile-fail/unnamed_argument_mode.rs | 5 +--- src/test/run-pass/argument-passing.rs | 8 +++--- src/test/run-pass/fn-bare-assign.rs | 8 +++--- src/test/run-pass/lazy-and-or.rs | 4 +-- src/test/run-pass/mutable-alias-vec.rs | 8 +++--- src/test/run-pass/unique-fn-arg-mut.rs | 6 ++--- src/test/run-pass/writealias.rs | 4 +-- 26 files changed, 59 insertions(+), 95 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 31c52300312c6..66552c29017fd 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2784,14 +2784,12 @@ aside a copy of that value to refer to. If this is not semantically safe (for example, if the referred-to value contains mutable fields), it will reject the program. If the compiler deems copying the value expensive, it will warn. -A function can be declared to take an argument by mutable reference. This -allows the function to write to the slot that the reference refers to. - -An example function that accepts an value by mutable reference: +A function with an argument of type `&mut T`, for some type `T`, can write to +the slot that its argument refers to. An example of such a function is: ~~~~~~~~ -fn incr(&i: int) { - i = i + 1; +fn incr(i: &mut int) { + *i = *i + 1; } ~~~~~~~~ diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e17b52fb27d17..a50189cf5989a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -574,7 +574,7 @@ impl inferable : cmp::Eq { // "resolved" mode: the real modes. #[auto_serialize] -enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy } +enum rmode { by_ref, by_val, by_move, by_copy } impl rmode : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 782535f5c2b2c..828d498ca3c23 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -22,7 +22,8 @@ pub enum ObsoleteSyntax { ObsoleteClassMethod, ObsoleteClassTraits, ObsoletePrivSection, - ObsoleteModeInFnType + ObsoleteModeInFnType, + ObsoleteByMutRefMode } impl ObsoleteSyntax : cmp::Eq { @@ -94,6 +95,10 @@ impl parser : ObsoleteReporter { "to use a (deprecated) mode in a fn type, you should \ give the argument an explicit name (like `&&v: int`)" ), + ObsoleteByMutRefMode => ( + "by-mutable-reference mode", + "Declare an argument of type &mut T instead" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6bee9190a832f..22c25186c9182 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -20,13 +20,13 @@ use obsolete::{ ObsoleteLowerCaseKindBounds, ObsoleteLet, ObsoleteFieldTerminator, ObsoleteStructCtor, ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits, - ObsoleteModeInFnType + ObsoleteModeInFnType, ObsoleteByMutRefMode }; use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move, bitand, bitor, bitxor, blk, blk_check_mode, bound_const, bound_copy, bound_send, bound_trait, bound_owned, box, by_copy, - by_move, by_mutbl_ref, by_ref, by_val, capture_clause, + by_move, by_ref, by_val, capture_clause, capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item, class_immutable, class_mutable, crate, crate_cfg, crate_directive, decl, decl_item, decl_local, @@ -570,9 +570,10 @@ impl parser { fn parse_arg_mode() -> mode { if self.eat(token::BINOP(token::AND)) { - self.span_fatal(copy self.last_span, - ~"Obsolete syntax has no effect"); - expl(by_mutbl_ref) + self.obsolete(copy self.span, + ObsoleteByMutRefMode); + // Bogus mode, but doesn't matter since it's an error + expl(by_ref) } else if self.eat(token::BINOP(token::MINUS)) { expl(by_move) } else if self.eat(token::ANDAND) { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d08b20eed843e..bff356e5cb727 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1688,7 +1688,6 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl, fn mode_to_str(m: ast::mode) -> ~str { match m { - ast::expl(ast::by_mutbl_ref) => ~"&", ast::expl(ast::by_move) => ~"-", ast::expl(ast::by_ref) => ~"&&", ast::expl(ast::by_val) => ~"++", diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs index f3fa0e3f3507f..1375ff2d0be08 100644 --- a/src/rustc/metadata/tydecode.rs +++ b/src/rustc/metadata/tydecode.rs @@ -394,7 +394,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg { fn parse_mode(st: @pstate) -> ast::mode { let m = ast::expl(match next(st) { - '&' => ast::by_mutbl_ref, '-' => ast::by_move, '+' => ast::by_copy, '=' => ast::by_ref, diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs index 611ffb598ae5c..69689b16e1542 100644 --- a/src/rustc/metadata/tyencode.rs +++ b/src/rustc/metadata/tyencode.rs @@ -333,7 +333,6 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) { fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) { match ty::resolved_mode(cx.tcx, m) { - by_mutbl_ref => w.write_char('&'), by_move => w.write_char('-'), by_copy => w.write_char('+'), by_ref => w.write_char('='), diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 5ff2a8933a91d..cc8d89a8ace76 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -529,7 +529,7 @@ impl check_loan_ctxt { ast::by_move => { self.check_move_out(*arg); } - ast::by_mutbl_ref | ast::by_ref | + ast::by_ref | ast::by_copy | ast::by_val => { } } diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index 327db51518be5..5dfde8c9af649 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -115,10 +115,6 @@ fn req_loans_in_expr(ex: @ast::expr, let scope_r = ty::re_scope(ex.id); for vec::each2(args, arg_tys) |arg, arg_ty| { match ty::resolved_mode(self.tcx(), arg_ty.mode) { - ast::by_mutbl_ref => { - let arg_cmt = self.bccx.cat_expr(*arg); - self.guarantee_valid(arg_cmt, m_mutbl, scope_r); - } ast::by_ref => { let arg_cmt = self.bccx.cat_expr(*arg); self.guarantee_valid(arg_cmt, m_imm, scope_r); diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index 9aff382775c85..e2b85441a8fda 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -323,7 +323,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| { match ty::arg_mode(cx.tcx, *arg_t) { by_copy => maybe_copy(cx, args[i], None), - by_ref | by_val | by_mutbl_ref | by_move => () + by_ref | by_val | by_move => () } i += 1u; } @@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { Some(ref mme) => { match ty::arg_mode(cx.tcx, mme.self_arg) { by_copy => maybe_copy(cx, lhs, None), - by_ref | by_val | by_mutbl_ref | by_move => () + by_ref | by_val | by_move => () } } _ => () @@ -465,14 +465,7 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) { cx.tcx.sess.span_err(sp, msg); } } - def_arg(_, mode) => { - match ty::resolved_mode(cx.tcx, mode) { - by_ref | by_val | by_move | by_copy => { /* ok */ } - by_mutbl_ref => { - cx.tcx.sess.span_err(sp, msg); - } - } - } + def_arg(*) => { /* ok */ } def_upvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); } diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index 6b39a21a7ba57..12d63cdacbf67 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -398,7 +398,7 @@ impl IrMaps { (*v).push(id); } - Arg(_, _, by_ref) | Arg(_, _, by_mutbl_ref) | + Arg(_, _, by_ref) | Arg(_, _, by_val) | Self | Field(_) | ImplicitRet | Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => { debug!("--but it is not owned"); @@ -919,7 +919,7 @@ impl Liveness { // inputs passed by & mode should be considered live on exit: for decl.inputs.each |arg| { match ty::resolved_mode(self.tcx, arg.mode) { - by_mutbl_ref | by_ref | by_val => { + by_ref | by_val => { // These are "non-owned" modes, so register a read at // the end. This will prevent us from moving out of // such variables but also prevent us from registering @@ -1573,7 +1573,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f)); for vec::each2(args, targs) |arg_expr, arg_ty| { match ty::resolved_mode(self.tcx, arg_ty.mode) { - by_val | by_copy | by_ref | by_mutbl_ref => {} + by_val | by_copy | by_ref => {} by_move => { self.check_move_from_expr(*arg_expr, vt); } @@ -1865,24 +1865,7 @@ impl @Liveness { fn warn_about_unused_args(sp: span, decl: fn_decl, entry_ln: LiveNode) { for decl.inputs.each |arg| { let var = self.variable(arg.id, arg.ty.span); - match ty::resolved_mode(self.tcx, arg.mode) { - by_mutbl_ref => { - // for mutable reference arguments, something like - // x = 1; - // is not worth warning about, as it has visible - // side effects outside the fn. - match self.assigned_on_entry(entry_ln, var) { - Some(_) => { /*ok*/ } - None => { - // but if it is not written, it ought to be used - self.warn_about_unused(sp, entry_ln, var); - } - } - } - by_val | by_ref | by_move | by_copy => { - self.warn_about_unused(sp, entry_ln, var); - } - } + self.warn_about_unused(sp, entry_ln, var); } } diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs index fe465db1312c6..dc5874ea2cfae 100644 --- a/src/rustc/middle/mem_categorization.rs +++ b/src/rustc/middle/mem_categorization.rs @@ -523,9 +523,6 @@ impl &mem_categorization_ctxt { // m: mutability of the argument // lp: loan path, must be none for aliasable things let {m,lp} = match ty::resolved_mode(self.tcx, mode) { - ast::by_mutbl_ref => { - {m: m_mutbl, lp: None} - } ast::by_move | ast::by_copy => { {m: m_imm, lp: Some(@lp_arg(vid))} } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index afa008fdbb77b..95711f8da36a7 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1503,7 +1503,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt, // the event it's not truly needed. let llarg; match ty::resolved_mode(tcx, arg_ty.mode) { - ast::by_ref | ast::by_mutbl_ref => { + ast::by_ref => { llarg = raw_llarg; } ast::by_move | ast::by_copy => { diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs index e7b4dd171e316..c851c5bc72508 100644 --- a/src/rustc/middle/trans/callee.rs +++ b/src/rustc/middle/trans/callee.rs @@ -592,7 +592,7 @@ fn trans_arg_expr(bcx: block, DoAutorefArg => { val = arg_datum.to_ref_llval(bcx); } DontAutorefArg => { match arg_mode { - ast::by_ref | ast::by_mutbl_ref => { + ast::by_ref => { val = arg_datum.to_ref_llval(bcx); } diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs index b4a64abeed7e7..d8a2fda4d14be 100644 --- a/src/rustc/middle/trans/meth.rs +++ b/src/rustc/middle/trans/meth.rs @@ -154,7 +154,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id, typeck::method_trait(_, off, vstore) => { trans_trait_callee(bcx, callee_id, off, self, vstore) } - typeck::method_self(_, off) => { + typeck::method_self(*) => { bcx.tcx().sess.span_bug(self.span, ~"self method call"); } } diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs index 3996f0ff5ee2c..c105caecaebbe 100644 --- a/src/rustc/middle/trans/reflect.rs +++ b/src/rustc/middle/trans/reflect.rs @@ -210,7 +210,6 @@ impl reflector { ast::expl(e) => match e { ast::by_ref => 1u, ast::by_val => 2u, - ast::by_mutbl_ref => 3u, ast::by_move => 4u, ast::by_copy => 5u } diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 8eabf26e21786..ee247eb5db79f 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -53,7 +53,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) by_val | by_move | by_copy => { type_needs(cx, use_repr, arg.ty); } - by_ref | by_mutbl_ref => {} + by_ref => {} } } } diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 97b031c6024aa..30add8c730c72 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -144,7 +144,7 @@ mod map_reduce { fn start_mappers( map: &mapper, - &ctrls: ~[ctrl_proto::server::open], + ctrls: &mut ~[ctrl_proto::server::open], inputs: &~[K1]) -> ~[joinable_task] { @@ -213,9 +213,9 @@ mod map_reduce { let mut is_done = false; fn get(p: Port>, - &ref_count: int, &is_done: bool) + ref_count: &mut int, is_done: &mut bool) -> Option { - while !is_done || ref_count > 0 { + while !*is_done || *ref_count > 0 { match recv(p) { emit_val(v) => { // error!("received %d", v); @@ -223,16 +223,16 @@ mod map_reduce { } done => { // error!("all done"); - is_done = true; + *is_done = true; } - addref => { ref_count += 1; } - release => { ref_count -= 1; } + addref => { *ref_count += 1; } + release => { *ref_count -= 1; } } } return None; } - (*reduce)(&key, || get(p, ref_count, is_done) ); + (*reduce)(&key, || get(p, &mut ref_count, &mut is_done) ); } fn map_reduce( @@ -246,7 +246,7 @@ mod map_reduce { // to do the rest. let reducers = map::HashMap(); - let mut tasks = start_mappers(&map, ctrl, &inputs); + let mut tasks = start_mappers(&map, &mut ctrl, &inputs); let mut num_mappers = vec::len(inputs) as int; while num_mappers > 0 { diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs index 2c20e604f502f..bb466e2c00b80 100644 --- a/src/test/compile-fail/deprecated-mode-fn-arg.rs +++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs @@ -1,11 +1,9 @@ #[forbid(deprecated_mode)]; -fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode - //~^ WARNING Obsolete syntax has no effect +fn foo(_f: fn(&i: int)) { //~ ERROR by-mutable-reference mode } -type Bar = fn(&i: int); //~ ERROR explicit mode - //~^ WARNING Obsolete syntax has no effect +type Bar = fn(&i: int); //~ ERROR by-mutable-reference mode fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/unnamed_argument_mode.rs b/src/test/compile-fail/unnamed_argument_mode.rs index 36e6edc96f996..77d40aae6a273 100644 --- a/src/test/compile-fail/unnamed_argument_mode.rs +++ b/src/test/compile-fail/unnamed_argument_mode.rs @@ -1,11 +1,8 @@ -//error-pattern: mismatched types +//error-pattern: by-mutable-reference mode fn bad(&a: int) { } -// unnamed argument &int is now parsed x: &int -// it's not parsed &x: int anymore - fn called(f: fn(&int)) { } diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs index 2a83986345517..e8aaf88374f94 100644 --- a/src/test/run-pass/argument-passing.rs +++ b/src/test/run-pass/argument-passing.rs @@ -1,10 +1,10 @@ // xfail-fast #[legacy_modes]; -fn f1(a: {mut x: int}, &b: int, -c: int) -> int { - let r = a.x + b + c; +fn f1(a: {mut x: int}, b: &mut int, -c: int) -> int { + let r = a.x + *b + c; a.x = 0; - b = 10; + *b = 10; return r; } @@ -12,7 +12,7 @@ fn f2(a: int, f: fn(int)) -> int { f(1); return a; } fn main() { let mut a = {mut x: 1}, b = 2, c = 3; - assert (f1(a, b, c) == 6); + assert (f1(a, &mut b, c) == 6); assert (a.x == 0); assert (b == 10); assert (f2(a.x, |x| a.x = 50 ) == 0); diff --git a/src/test/run-pass/fn-bare-assign.rs b/src/test/run-pass/fn-bare-assign.rs index ae6b1a1079ff7..71996552d0cce 100644 --- a/src/test/run-pass/fn-bare-assign.rs +++ b/src/test/run-pass/fn-bare-assign.rs @@ -1,15 +1,15 @@ -fn f(i: int, &called: bool) { +fn f(i: int, called: &mut bool) { assert i == 10; - called = true; + *called = true; } -fn g(f: extern fn(int, &v: bool), &called: bool) { +fn g(f: extern fn(int, v: &mut bool), called: &mut bool) { f(10, called); } fn main() { let mut called = false; let h = f; - g(h, called); + g(h, &mut called); assert called == true; } \ No newline at end of file diff --git a/src/test/run-pass/lazy-and-or.rs b/src/test/run-pass/lazy-and-or.rs index 7ad71854dc421..3e84c9f6f726a 100644 --- a/src/test/run-pass/lazy-and-or.rs +++ b/src/test/run-pass/lazy-and-or.rs @@ -1,12 +1,12 @@ -fn incr(&x: int) -> bool { x += 1; assert (false); return false; } +fn incr(x: &mut int) -> bool { *x += 1; assert (false); return false; } fn main() { let x = 1 == 2 || 3 == 3; assert (x); let mut y: int = 10; - log(debug, x || incr(y)); + log(debug, x || incr(&mut y)); assert (y == 10); if true && x { assert (true); } else { assert (false); } } diff --git a/src/test/run-pass/mutable-alias-vec.rs b/src/test/run-pass/mutable-alias-vec.rs index e54197ccc6b5d..d5b1eef993e1d 100644 --- a/src/test/run-pass/mutable-alias-vec.rs +++ b/src/test/run-pass/mutable-alias-vec.rs @@ -3,13 +3,13 @@ // -*- rust -*- extern mod std; -fn grow(&v: ~[int]) { v += ~[1]; } +fn grow(v: &mut ~[int]) { *v += ~[1]; } fn main() { let mut v: ~[int] = ~[]; - grow(v); - grow(v); - grow(v); + grow(&mut v); + grow(&mut v); + grow(&mut v); let len = vec::len::(v); log(debug, len); assert (len == 3 as uint); diff --git a/src/test/run-pass/unique-fn-arg-mut.rs b/src/test/run-pass/unique-fn-arg-mut.rs index 8d9386d70fff7..36d1d689f5fb8 100644 --- a/src/test/run-pass/unique-fn-arg-mut.rs +++ b/src/test/run-pass/unique-fn-arg-mut.rs @@ -1,9 +1,9 @@ -fn f(&i: ~int) { - i = ~200; +fn f(i: &mut ~int) { + *i = ~200; } fn main() { let mut i = ~100; - f(i); + f(&mut i); assert *i == 200; } \ No newline at end of file diff --git a/src/test/run-pass/writealias.rs b/src/test/run-pass/writealias.rs index 9dba2e2adfdcb..eb3fa602f12ac 100644 --- a/src/test/run-pass/writealias.rs +++ b/src/test/run-pass/writealias.rs @@ -4,10 +4,10 @@ // -*- rust -*- type point = {x: int, y: int, mut z: int}; -fn f(&p: point) { p.z = 13; } +fn f(p: &mut point) { p.z = 13; } fn main() { let mut x: point = {x: 10, y: 11, mut z: 12}; - f(x); + f(&mut x); assert (x.z == 13); }