Skip to content

Commit

Permalink
Remove by-mutable-ref mode from the compiler
Browse files Browse the repository at this point in the history
and test cases. Closes #3513
  • Loading branch information
catamorphism committed Oct 6, 2012
1 parent 0599929 commit f96a2a2
Show file tree
Hide file tree
Showing 26 changed files with 59 additions and 95 deletions.
10 changes: 4 additions & 6 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ impl<T:cmp::Eq> inferable<T> : 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) {
Expand Down
7 changes: 6 additions & 1 deletion src/libsyntax/parse/obsolete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ pub enum ObsoleteSyntax {
ObsoleteClassMethod,
ObsoleteClassTraits,
ObsoletePrivSection,
ObsoleteModeInFnType
ObsoleteModeInFnType,
ObsoleteByMutRefMode
}

impl ObsoleteSyntax : cmp::Eq {
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 6 additions & 5 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
1 change: 0 additions & 1 deletion src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => ~"++",
Expand Down
1 change: 0 additions & 1 deletion src/rustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion src/rustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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('='),
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/rustc/middle/borrowck/gather_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 3 additions & 10 deletions src/rustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
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;
}
Expand All @@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
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 => ()
}
}
_ => ()
Expand Down Expand Up @@ -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);
}
Expand Down
25 changes: 4 additions & 21 deletions src/rustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/rustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Expand Down
1 change: 0 additions & 1 deletion src/rustc/middle/trans/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/middle/trans/type_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {}
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/test/bench/task-perf-word-count-generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod map_reduce {
fn start_mappers<K1: Copy Send, K2: Hash IterBytes Eq Const Copy Send,
V: Copy Send>(
map: &mapper<K1, K2, V>,
&ctrls: ~[ctrl_proto::server::open<K2, V>],
ctrls: &mut ~[ctrl_proto::server::open<K2, V>],
inputs: &~[K1])
-> ~[joinable_task]
{
Expand Down Expand Up @@ -213,26 +213,26 @@ mod map_reduce {
let mut is_done = false;

fn get<V: Copy Send>(p: Port<reduce_proto<V>>,
&ref_count: int, &is_done: bool)
ref_count: &mut int, is_done: &mut bool)
-> Option<V> {
while !is_done || ref_count > 0 {
while !*is_done || *ref_count > 0 {
match recv(p) {
emit_val(v) => {
// error!("received %d", v);
return Some(v);
}
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<K1: Copy Send, K2: Hash IterBytes Eq Const Copy Send, V: Copy Send>(
Expand All @@ -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 {
Expand Down
6 changes: 2 additions & 4 deletions src/test/compile-fail/deprecated-mode-fn-arg.rs
Original file line number Diff line number Diff line change
@@ -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() {
}
5 changes: 1 addition & 4 deletions src/test/compile-fail/unnamed_argument_mode.rs
Original file line number Diff line number Diff line change
@@ -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)) {
}

Expand Down
8 changes: 4 additions & 4 deletions src/test/run-pass/argument-passing.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// 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;
}

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);
Expand Down
8 changes: 4 additions & 4 deletions src/test/run-pass/fn-bare-assign.rs
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit f96a2a2

Please sign in to comment.