Skip to content

Commit f90228b

Browse files
committed
make all arguments modes immutable
note: you can still move from copy/move mode args
1 parent 4737543 commit f90228b

File tree

6 files changed

+109
-15
lines changed

6 files changed

+109
-15
lines changed

src/libcore/dvec.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,15 @@ impl extensions<A> for dvec<A> {
131131
impl extensions<A:copy> for dvec<A> {
132132
#[doc = "Append a single item to the end of the list"]
133133
fn push(t: A) {
134-
self.swap { |v| v += [t]; v } // more efficient than v + [t]
134+
self.swap { |v|
135+
let mut v <- v; v += [t]; v // more efficient than v + [t]
136+
}
135137
}
136138

137139
#[doc = "Remove and return the last element"]
138140
fn pop() -> A {
139141
self.borrow { |v|
142+
let mut v <- v;
140143
let result = vec::pop(v);
141144
self.return(v);
142145
result
@@ -157,6 +160,7 @@ impl extensions<A:copy> for dvec<A> {
157160
"]
158161
fn push_slice(ts: [const A]/&, from_idx: uint, to_idx: uint) {
159162
self.swap { |v|
163+
let mut v <- v;
160164
let new_len = vec::len(v) + to_idx - from_idx;
161165
vec::reserve(v, new_len);
162166
let mut i = from_idx;
@@ -232,6 +236,10 @@ impl extensions<A:copy> for dvec<A> {
232236

233237
#[doc = "Overwrites the contents of the element at `idx` with `a`"]
234238
fn grow_set_elt(idx: uint, initval: A, val: A) {
235-
self.swap { |v| vec::grow_set(v, idx, initval, val); v }
239+
self.swap { |v|
240+
let mut v <- v;
241+
vec::grow_set(v, idx, initval, val);
242+
v
243+
}
236244
}
237245
}

src/rustc/middle/borrowck.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -843,11 +843,8 @@ impl methods for check_loan_ctxt {
843843
self.bccx.cmt_to_repr(cmt)];
844844

845845
alt cmt.cat {
846-
// Rvalues and locals can be moved:
847-
cat_rvalue | cat_local(_) { }
848-
849-
// Owned arguments can be moved:
850-
cat_arg(_) if cmt.mutbl == m_mutbl { }
846+
// Rvalues, locals, and arguments can be moved:
847+
cat_rvalue | cat_local(_) | cat_arg(_) { }
851848

852849
// We allow moving out of static items because the old code
853850
// did. This seems consistent with permitting moves out of
@@ -1348,7 +1345,7 @@ impl categorize_methods for borrowck_ctxt {
13481345
lp: none}
13491346
}
13501347
ast::by_move | ast::by_copy {
1351-
{m: m_mutbl,
1348+
{m: m_imm,
13521349
lp: some(@lp_arg(vid))}
13531350
}
13541351
ast::by_ref {
@@ -1506,7 +1503,7 @@ impl categorize_methods for borrowck_ctxt {
15061503
cat_special(sk_heap_upvar) { "upvar" }
15071504
cat_rvalue { "non-lvalue" }
15081505
cat_local(_) { mut_str + " local variable" }
1509-
cat_arg(_) { mut_str + " argument" }
1506+
cat_arg(_) { "argument" }
15101507
cat_deref(_, _, pk) { #fmt["dereference of %s %s pointer",
15111508
mut_str, self.pk_to_sigil(pk)] }
15121509
cat_stack_upvar(_) { mut_str + " upvar" }

src/rustc/middle/liveness.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,10 +1506,7 @@ impl check_methods for @liveness {
15061506
(*self.ir).add_spill(var);
15071507
}
15081508
some(lnk) {
1509-
self.report_illegal_read(span, lnk, var, moved_variable);
1510-
self.tcx.sess.span_note(
1511-
span,
1512-
"move of variable occurred here");
1509+
self.report_illegal_move(span, lnk, var);
15131510
}
15141511
}
15151512
}
@@ -1637,6 +1634,44 @@ impl check_methods for @liveness {
16371634
}
16381635
}
16391636

1637+
fn report_illegal_move(move_span: span,
1638+
lnk: live_node_kind,
1639+
var: variable) {
1640+
1641+
// the only time that it is possible to have a moved variable
1642+
// used by lnk_exit would be arguments or fields in a ctor.
1643+
// we give a slightly different error message in those cases.
1644+
if lnk == lnk_exit {
1645+
let vk = self.ir.var_kinds[*var];
1646+
alt vk {
1647+
vk_arg(_, name, _) {
1648+
self.tcx.sess.span_err(
1649+
move_span,
1650+
#fmt["illegal move from argument `%s`, which is not \
1651+
copy or move mode", name]);
1652+
ret;
1653+
}
1654+
vk_field(name) {
1655+
self.tcx.sess.span_err(
1656+
move_span,
1657+
#fmt["illegal move from field `%s`", name]);
1658+
ret;
1659+
}
1660+
vk_local(*) | vk_self | vk_implicit_ret {
1661+
self.tcx.sess.span_bug(
1662+
move_span,
1663+
#fmt["illegal reader (%?) for `%?`",
1664+
lnk, vk]);
1665+
}
1666+
}
1667+
}
1668+
1669+
self.report_illegal_read(move_span, lnk, var, moved_variable);
1670+
self.tcx.sess.span_note(
1671+
move_span, "move of variable occurred here");
1672+
1673+
}
1674+
16401675
fn report_illegal_read(chk_span: span,
16411676
lnk: live_node_kind,
16421677
var: variable,
@@ -1658,7 +1693,8 @@ impl check_methods for @liveness {
16581693
span,
16591694
#fmt["use of %s: `%s`", msg, name]);
16601695
}
1661-
lnk_exit | lnk_vdef(_) {
1696+
lnk_exit |
1697+
lnk_vdef(_) {
16621698
self.tcx.sess.span_bug(
16631699
chk_span,
16641700
#fmt["illegal reader: %?", lnk]);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
fn take(-_x: int) { }
2+
3+
fn from_by_value_arg(++x: int) {
4+
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
5+
}
6+
7+
fn from_by_mut_ref_arg(&x: int) {
8+
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
9+
}
10+
11+
fn from_by_ref_arg(&&x: int) {
12+
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
13+
}
14+
15+
fn from_copy_arg(+x: int) {
16+
take(x);
17+
}
18+
19+
fn from_move_arg(-x: int) {
20+
take(x);
21+
}
22+
23+
fn main() {
24+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Note: it would be nice to give fewer warnings in these cases.
2+
3+
fn mutate_by_mut_ref(&x: uint) {
4+
x = 0u;
5+
}
6+
7+
fn mutate_by_ref(&&x: uint) {
8+
//!^ WARNING unused variable: `x`
9+
x = 0u; //! ERROR assigning to argument
10+
}
11+
12+
fn mutate_by_val(++x: uint) {
13+
//!^ WARNING unused variable: `x`
14+
x = 0u; //! ERROR assigning to argument
15+
}
16+
17+
fn mutate_by_copy(+x: uint) {
18+
//!^ WARNING unused variable: `x`
19+
x = 0u; //! ERROR assigning to argument
20+
//!^ WARNING value assigned to `x` is never read
21+
}
22+
23+
fn mutate_by_move(-x: uint) {
24+
//!^ WARNING unused variable: `x`
25+
x = 0u; //! ERROR assigning to argument
26+
//!^ WARNING value assigned to `x` is never read
27+
}
28+
29+
fn main() {
30+
}

src/test/run-pass/argument-passing.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ fn f1(a: {mut x: int}, &b: int, -c: int) -> int {
22
let r = a.x + b + c;
33
a.x = 0;
44
b = 10;
5-
c = 20;
65
ret r;
76
}
87

0 commit comments

Comments
 (0)