mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
make all arguments modes immutable
note: you can still move from copy/move mode args
This commit is contained in:
parent
47375439ed
commit
f90228b8a8
@ -131,12 +131,15 @@ impl extensions<A> for dvec<A> {
|
||||
impl extensions<A:copy> for dvec<A> {
|
||||
#[doc = "Append a single item to the end of the list"]
|
||||
fn push(t: A) {
|
||||
self.swap { |v| v += [t]; v } // more efficient than v + [t]
|
||||
self.swap { |v|
|
||||
let mut v <- v; v += [t]; v // more efficient than v + [t]
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Remove and return the last element"]
|
||||
fn pop() -> A {
|
||||
self.borrow { |v|
|
||||
let mut v <- v;
|
||||
let result = vec::pop(v);
|
||||
self.return(v);
|
||||
result
|
||||
@ -157,6 +160,7 @@ impl extensions<A:copy> for dvec<A> {
|
||||
"]
|
||||
fn push_slice(ts: [const A]/&, from_idx: uint, to_idx: uint) {
|
||||
self.swap { |v|
|
||||
let mut v <- v;
|
||||
let new_len = vec::len(v) + to_idx - from_idx;
|
||||
vec::reserve(v, new_len);
|
||||
let mut i = from_idx;
|
||||
@ -232,6 +236,10 @@ impl extensions<A:copy> for dvec<A> {
|
||||
|
||||
#[doc = "Overwrites the contents of the element at `idx` with `a`"]
|
||||
fn grow_set_elt(idx: uint, initval: A, val: A) {
|
||||
self.swap { |v| vec::grow_set(v, idx, initval, val); v }
|
||||
self.swap { |v|
|
||||
let mut v <- v;
|
||||
vec::grow_set(v, idx, initval, val);
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
@ -843,11 +843,8 @@ impl methods for check_loan_ctxt {
|
||||
self.bccx.cmt_to_repr(cmt)];
|
||||
|
||||
alt cmt.cat {
|
||||
// Rvalues and locals can be moved:
|
||||
cat_rvalue | cat_local(_) { }
|
||||
|
||||
// Owned arguments can be moved:
|
||||
cat_arg(_) if cmt.mutbl == m_mutbl { }
|
||||
// Rvalues, locals, and arguments can be moved:
|
||||
cat_rvalue | cat_local(_) | cat_arg(_) { }
|
||||
|
||||
// We allow moving out of static items because the old code
|
||||
// did. This seems consistent with permitting moves out of
|
||||
@ -1348,7 +1345,7 @@ impl categorize_methods for borrowck_ctxt {
|
||||
lp: none}
|
||||
}
|
||||
ast::by_move | ast::by_copy {
|
||||
{m: m_mutbl,
|
||||
{m: m_imm,
|
||||
lp: some(@lp_arg(vid))}
|
||||
}
|
||||
ast::by_ref {
|
||||
@ -1506,7 +1503,7 @@ impl categorize_methods for borrowck_ctxt {
|
||||
cat_special(sk_heap_upvar) { "upvar" }
|
||||
cat_rvalue { "non-lvalue" }
|
||||
cat_local(_) { mut_str + " local variable" }
|
||||
cat_arg(_) { mut_str + " argument" }
|
||||
cat_arg(_) { "argument" }
|
||||
cat_deref(_, _, pk) { #fmt["dereference of %s %s pointer",
|
||||
mut_str, self.pk_to_sigil(pk)] }
|
||||
cat_stack_upvar(_) { mut_str + " upvar" }
|
||||
|
@ -1506,10 +1506,7 @@ impl check_methods for @liveness {
|
||||
(*self.ir).add_spill(var);
|
||||
}
|
||||
some(lnk) {
|
||||
self.report_illegal_read(span, lnk, var, moved_variable);
|
||||
self.tcx.sess.span_note(
|
||||
span,
|
||||
"move of variable occurred here");
|
||||
self.report_illegal_move(span, lnk, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1637,6 +1634,44 @@ impl check_methods for @liveness {
|
||||
}
|
||||
}
|
||||
|
||||
fn report_illegal_move(move_span: span,
|
||||
lnk: live_node_kind,
|
||||
var: variable) {
|
||||
|
||||
// the only time that it is possible to have a moved variable
|
||||
// used by lnk_exit would be arguments or fields in a ctor.
|
||||
// we give a slightly different error message in those cases.
|
||||
if lnk == lnk_exit {
|
||||
let vk = self.ir.var_kinds[*var];
|
||||
alt vk {
|
||||
vk_arg(_, name, _) {
|
||||
self.tcx.sess.span_err(
|
||||
move_span,
|
||||
#fmt["illegal move from argument `%s`, which is not \
|
||||
copy or move mode", name]);
|
||||
ret;
|
||||
}
|
||||
vk_field(name) {
|
||||
self.tcx.sess.span_err(
|
||||
move_span,
|
||||
#fmt["illegal move from field `%s`", name]);
|
||||
ret;
|
||||
}
|
||||
vk_local(*) | vk_self | vk_implicit_ret {
|
||||
self.tcx.sess.span_bug(
|
||||
move_span,
|
||||
#fmt["illegal reader (%?) for `%?`",
|
||||
lnk, vk]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.report_illegal_read(move_span, lnk, var, moved_variable);
|
||||
self.tcx.sess.span_note(
|
||||
move_span, "move of variable occurred here");
|
||||
|
||||
}
|
||||
|
||||
fn report_illegal_read(chk_span: span,
|
||||
lnk: live_node_kind,
|
||||
var: variable,
|
||||
@ -1658,7 +1693,8 @@ impl check_methods for @liveness {
|
||||
span,
|
||||
#fmt["use of %s: `%s`", msg, name]);
|
||||
}
|
||||
lnk_exit | lnk_vdef(_) {
|
||||
lnk_exit |
|
||||
lnk_vdef(_) {
|
||||
self.tcx.sess.span_bug(
|
||||
chk_span,
|
||||
#fmt["illegal reader: %?", lnk]);
|
||||
|
24
src/test/compile-fail/liveness-move-from-args.rs
Normal file
24
src/test/compile-fail/liveness-move-from-args.rs
Normal file
@ -0,0 +1,24 @@
|
||||
fn take(-_x: int) { }
|
||||
|
||||
fn from_by_value_arg(++x: int) {
|
||||
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
|
||||
}
|
||||
|
||||
fn from_by_mut_ref_arg(&x: int) {
|
||||
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
|
||||
}
|
||||
|
||||
fn from_by_ref_arg(&&x: int) {
|
||||
take(x); //! ERROR illegal move from argument `x`, which is not copy or move mode
|
||||
}
|
||||
|
||||
fn from_copy_arg(+x: int) {
|
||||
take(x);
|
||||
}
|
||||
|
||||
fn from_move_arg(-x: int) {
|
||||
take(x);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
30
src/test/compile-fail/mutable-arguments.rs
Normal file
30
src/test/compile-fail/mutable-arguments.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Note: it would be nice to give fewer warnings in these cases.
|
||||
|
||||
fn mutate_by_mut_ref(&x: uint) {
|
||||
x = 0u;
|
||||
}
|
||||
|
||||
fn mutate_by_ref(&&x: uint) {
|
||||
//!^ WARNING unused variable: `x`
|
||||
x = 0u; //! ERROR assigning to argument
|
||||
}
|
||||
|
||||
fn mutate_by_val(++x: uint) {
|
||||
//!^ WARNING unused variable: `x`
|
||||
x = 0u; //! ERROR assigning to argument
|
||||
}
|
||||
|
||||
fn mutate_by_copy(+x: uint) {
|
||||
//!^ WARNING unused variable: `x`
|
||||
x = 0u; //! ERROR assigning to argument
|
||||
//!^ WARNING value assigned to `x` is never read
|
||||
}
|
||||
|
||||
fn mutate_by_move(-x: uint) {
|
||||
//!^ WARNING unused variable: `x`
|
||||
x = 0u; //! ERROR assigning to argument
|
||||
//!^ WARNING value assigned to `x` is never read
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -2,7 +2,6 @@ fn f1(a: {mut x: int}, &b: int, -c: int) -> int {
|
||||
let r = a.x + b + c;
|
||||
a.x = 0;
|
||||
b = 10;
|
||||
c = 20;
|
||||
ret r;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user