about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-03-14 18:28:50 -0400
committerNiko Matsakis <niko@alum.mit.edu>2012-03-14 20:46:36 -0400
commite702d2019131a51630ee5f46ccff4a3bd31e178a (patch)
treeb742f67c1705289da21297ad89869d3523997494
parent6b35875dca67e5dd1e8f986c8528ffbf973fdcbb (diff)
downloadrust-e702d2019131a51630ee5f46ccff4a3bd31e178a.tar.gz
rust-e702d2019131a51630ee5f46ccff4a3bd31e178a.zip
allow immut vars to be moved. enforce mut vars after stage0 in std.
-rw-r--r--mk/target.mk10
-rw-r--r--src/libstd/uv.rs8
-rw-r--r--src/rustc/middle/mutbl.rs17
3 files changed, 25 insertions, 10 deletions
diff --git a/mk/target.mk b/mk/target.mk
index 1d7fcbeaabf..d61477368ac 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -9,6 +9,13 @@
 # runtime rather than the runtime from the working directory.
 USE_SNAPSHOT_RUNTIME=0
 
+# Do not use --enforce-mut-vars in stage0, for now, as the snapshot
+# has an older version of the check.
+ENFORCE_MUT_VARS_0=
+ENFORCE_MUT_VARS_1=--enforce-mut-vars
+ENFORCE_MUT_VARS_2=--enforce-mut-vars
+ENFORCE_MUT_VARS_3=--enforce-mut-vars
+
 define TARGET_STAGE_N
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/intrinsics.ll: \
@@ -38,7 +45,8 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB): \
         $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \
 		$$(TSREQ$(1)_T_$(2)_H_$(3))
 	@$$(call E, compile_and_link: $$@)
-	$$(STAGE$(1)_T_$(2)_H_$(3)) --enforce-mut-vars -o $$@ $$< && touch $$@
+	$$(STAGE$(1)_T_$(2)_H_$(3)) $$(ENFORCE_MUT_VARS_$(1)) \
+		-o $$@ $$< && touch $$@
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM): \
 		rustllvm/$(2)/$$(CFG_RUSTLLVM)
diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs
index fd54f7d9291..026a9edb6a8 100644
--- a/src/libstd/uv.rs
+++ b/src/libstd/uv.rs
@@ -339,7 +339,7 @@ fn async_init (
     lp: uv_loop,
     async_cb: fn~(uv_handle),
     after_cb: fn~(uv_handle)) {
-    let mut msg = msg_async_init(async_cb, after_cb);
+    let msg = msg_async_init(async_cb, after_cb);
     let loop_chan = get_loop_chan_from_uv_loop(lp);
     comm::send(loop_chan, msg);
 }
@@ -363,7 +363,7 @@ fn close(h: uv_handle, cb: fn~()) {
 }
 
 fn timer_init(lp: uv_loop, after_cb: fn~(uv_handle)) {
-    let mut msg = msg_timer_init(after_cb);
+    let msg = msg_timer_init(after_cb);
     let loop_chan = get_loop_chan_from_uv_loop(lp);
     comm::send(loop_chan, msg);
 }
@@ -372,7 +372,7 @@ fn timer_start(the_timer: uv_handle, timeout: u32, repeat:u32,
                timer_cb: fn~(uv_handle)) {
     alt the_timer {
       uv_timer(id, lp) {
-        let mut msg = msg_timer_start(id, timeout, repeat, timer_cb);
+        let msg = msg_timer_start(id, timeout, repeat, timer_cb);
         let loop_chan = get_loop_chan_from_uv_loop(lp);
         comm::send(loop_chan, msg);
       }
@@ -387,7 +387,7 @@ fn timer_stop(the_timer: uv_handle, after_cb: fn~(uv_handle)) {
     alt the_timer {
       uv_timer(id, lp) {
         let loop_chan = get_loop_chan_from_uv_loop(lp);
-        let mut msg = msg_timer_stop(id, after_cb);
+        let msg = msg_timer_stop(id, after_cb);
         comm::send(loop_chan, msg);
       }
       _ {
diff --git a/src/rustc/middle/mutbl.rs b/src/rustc/middle/mutbl.rs
index 821b4a73402..5e8a6a1aa45 100644
--- a/src/rustc/middle/mutbl.rs
+++ b/src/rustc/middle/mutbl.rs
@@ -176,7 +176,7 @@ fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) {
       expr_fn(_, _, _, cap) {
         for moved in cap.moves {
             let def = cx.tcx.def_map.get(moved.id);
-            alt is_immutable_def(cx, def) {
+            alt is_illegal_to_modify_def(cx, def, msg_move_out) {
               some(name) { mk_err(cx, moved.span, msg_move_out, moved.name); }
               _ { }
             }
@@ -192,7 +192,7 @@ fn check_lval(cx: @ctx, dest: @expr, msg: msg) {
     alt dest.node {
       expr_path(p) {
         let def = cx.tcx.def_map.get(dest.id);
-        alt is_immutable_def(cx, def) {
+        alt is_illegal_to_modify_def(cx, def, msg) {
           some(name) { mk_err(cx, dest.span, msg, name); }
           _ { }
         }
@@ -278,7 +278,9 @@ fn check_bind(cx: @ctx, f: @expr, args: [option<@expr>]) {
     }
 }
 
-fn is_immutable_def(cx: @ctx, def: def) -> option<str> {
+// returns some if the def cannot be modified.  the kind of modification is
+// indicated by `msg`.
+fn is_illegal_to_modify_def(cx: @ctx, def: def, msg: msg) -> option<str> {
     alt def {
       def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) |
       def_use(_) {
@@ -295,8 +297,12 @@ fn is_immutable_def(cx: @ctx, def: def) -> option<str> {
         let ty = ty::node_id_to_type(cx.tcx, node_id);
         let proto = ty::ty_fn_proto(ty);
         ret alt proto {
-          proto_any | proto_block { is_immutable_def(cx, *inner) }
-          _ { some("upvar") }
+          proto_any | proto_block {
+            is_illegal_to_modify_def(cx, *inner, msg)
+          }
+          proto_bare | proto_uniq | proto_box {
+            some("upvar")
+          }
         };
       }
 
@@ -304,6 +310,7 @@ fn is_immutable_def(cx: @ctx, def: def) -> option<str> {
       // here and then guarantee in the typestate pass that immutable local
       // variables are assigned at most once.  But this requires a new kind of
       // propagation (def. not assigned), so I didn't do that.
+      def_local(_, false) if msg == msg_move_out { none }
       def_local(_, false) if cx.tcx.sess.opts.enforce_mut_vars {
         some("immutable local variable")
       }