about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-08-07 06:04:36 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-08-07 06:11:12 -0700
commitdbef6e593dfb1b164c6750ee99ca2b80c249c4f5 (patch)
treee4046f2e7cf5eb81dbd6153217e0ed64865ab84a /src
parent793c0a1116af40d8a84941525f148a3d785c3f0c (diff)
downloadrust-dbef6e593dfb1b164c6750ee99ca2b80c249c4f5.tar.gz
rust-dbef6e593dfb1b164c6750ee99ca2b80c249c4f5.zip
move borrowck tests to use ref, fix a few exposed shortcomings
Diffstat (limited to 'src')
-rw-r--r--src/rustc/middle/typeck/check/alt.rs4
-rw-r--r--src/rustc/middle/typeck/check/regionck.rs34
-rw-r--r--src/test/compile-fail/borrowck-binding-mutbl.rs8
-rw-r--r--src/test/compile-fail/borrowck-issue-2657-1.rs2
-rw-r--r--src/test/compile-fail/borrowck-issue-2657-2.rs4
-rw-r--r--src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs4
-rw-r--r--src/test/compile-fail/borrowck-pat-enum-in-box.rs12
-rw-r--r--src/test/compile-fail/borrowck-pat-enum.rs10
-rw-r--r--src/test/compile-fail/borrowck-pat-reassign-binding.rs4
-rw-r--r--src/test/compile-fail/borrowck-pat-reassign-sometimes-binding.rs2
-rw-r--r--src/test/compile-fail/borrowck-unchecked-with-borrow.rs12
-rw-r--r--src/test/run-pass/alt-ref-binding-mut-option.rs8
12 files changed, 59 insertions, 45 deletions
diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs
index 4fb348e598c..cb25cb5382f 100644
--- a/src/rustc/middle/typeck/check/alt.rs
+++ b/src/rustc/middle/typeck/check/alt.rs
@@ -166,7 +166,9 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
             //    ref x | ref const x | ref mut x
             // then the type of x is &M T where M is the mutability
             // and T is the expected type
-            let region_var = fcx.infcx.next_region_var_nb();
+            let region_var =
+                fcx.infcx.next_region_var({lb: some(pcx.block_region),
+                                           ub: none});
             let mt = {ty: expected, mutbl: mutbl};
             let region_ty = ty::mk_rptr(tcx, region_var, mt);
             demand::eqtype(fcx, pat.span, region_ty, typ);
diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs
index 03a27e88c97..e623c3ec0b9 100644
--- a/src/rustc/middle/typeck/check/regionck.rs
+++ b/src/rustc/middle/typeck/check/regionck.rs
@@ -22,6 +22,7 @@ import syntax::print::pprust;
 import infer::{resolve_type, resolve_all, force_all,
                resolve_rvar, force_rvar, fres};
 import middle::kind::check_owned;
+import middle::pat_util::pat_bindings;
 
 enum rcx { rcx_({fcx: @fn_ctxt, mut errors_reported: uint}) }
 type rvt = visit::vt<@rcx>;
@@ -80,7 +81,6 @@ fn regionck_visitor() -> rvt {
                    visit_stmt: visit_stmt,
                    visit_expr: visit_expr,
                    visit_block: visit_block,
-                   visit_pat: visit_pat,
                    visit_local: visit_local
                    with *visit::default_visitor()})
 }
@@ -90,8 +90,26 @@ fn visit_item(_item: @ast::item, &&_rcx: @rcx, _v: rvt) {
 }
 
 fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) {
+    // Check to make sure that the regions in all local variables are
+    // within scope.
+    //
+    // Note: we do this here rather than in visit_pat because we do
+    // not wish to constrain the regions in *patterns* in quite the
+    // same way.  `visit_node()` guarantees that the region encloses
+    // the node in question, which ultimately constraints the regions
+    // in patterns to enclose the match expression as a whole.  But we
+    // want them to enclose the *arm*.  However, regions in patterns
+    // must either derive from the discriminant or a ref pattern: in
+    // the case of the discriminant, the regions will be constrained
+    // when the type of the discriminant is checked.  In the case of a
+    // ref pattern, the variable is created with a suitable lower
+    // bound.
     let e = rcx.errors_reported;
     v.visit_pat(l.node.pat, rcx, v);
+    let def_map = rcx.fcx.ccx.tcx.def_map;
+    do pat_bindings(def_map, l.node.pat) |_bm, id, sp, _path| {
+        visit_node(id, sp, rcx);
+    }
     if e != rcx.errors_reported {
         return; // if decl has errors, skip initializer expr
     }
@@ -102,20 +120,6 @@ fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) {
     }
 }
 
-fn visit_pat(p: @ast::pat, &&rcx: @rcx, v: rvt) {
-    let fcx = rcx.fcx;
-    match p.node {
-      ast::pat_ident(_, path, _)
-      if !pat_util::pat_is_variant(fcx.ccx.tcx.def_map, p) => {
-        debug!{"visit_pat binding=%s", *path.idents[0]};
-        visit_node(p.id, p.span, rcx);
-      }
-      _ => ()
-    }
-
-    visit::visit_pat(p, rcx, v);
-}
-
 fn visit_block(b: ast::blk, &&rcx: @rcx, v: rvt) {
     visit::visit_block(b, rcx, v);
 }
diff --git a/src/test/compile-fail/borrowck-binding-mutbl.rs b/src/test/compile-fail/borrowck-binding-mutbl.rs
index 57c0375f4e4..c8ed3f143df 100644
--- a/src/test/compile-fail/borrowck-binding-mutbl.rs
+++ b/src/test/compile-fail/borrowck-binding-mutbl.rs
@@ -1,13 +1,13 @@
-fn impure(_v: ~[int]) {
+fn impure(_v: &[int]) {
 }
 
 fn main() {
     let x = {mut f: ~[3]};
 
     match x {
-      {f: v} => {
-        impure(v); //~ ERROR illegal borrow unless pure: unique value in aliasable, mutable location
+      {f: ref mut v} => {
+        impure(*v); //~ ERROR illegal borrow unless pure
         //~^ NOTE impure due to access to impure function
       }
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/borrowck-issue-2657-1.rs b/src/test/compile-fail/borrowck-issue-2657-1.rs
index f8cbb52d996..9bfc4cc1d0d 100644
--- a/src/test/compile-fail/borrowck-issue-2657-1.rs
+++ b/src/test/compile-fail/borrowck-issue-2657-1.rs
@@ -1,7 +1,7 @@
 fn main() {
 let x = some(~1);
 match x { //~ NOTE loan of immutable local variable granted here
-  some(y) => {
+  some(ref y) => {
     let _a <- x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
   }
   _ => {}
diff --git a/src/test/compile-fail/borrowck-issue-2657-2.rs b/src/test/compile-fail/borrowck-issue-2657-2.rs
index ab6e63174aa..1444889bc75 100644
--- a/src/test/compile-fail/borrowck-issue-2657-2.rs
+++ b/src/test/compile-fail/borrowck-issue-2657-2.rs
@@ -1,8 +1,8 @@
 fn main() {
 let x = some(~1);
 match x {
-  some(y) => {
-    let _b <- y; //~ ERROR moving out of pattern binding
+  some(ref y) => {
+    let _b <- *y; //~ ERROR moving out of dereference of immutable & pointer
   }
   _ => {}
 }
diff --git a/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs b/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs
index ef696048219..8655ea0ab70 100644
--- a/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs
+++ b/src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs
@@ -6,8 +6,8 @@ fn main() {
     let x = ~node({mut a: ~empty});
     // Create a cycle!
     match check *x { //~ NOTE loan of immutable local variable granted here
-      node(y) => {
+      node(ref y) => {
         y.a <- x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
       }
     };
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/borrowck-pat-enum-in-box.rs b/src/test/compile-fail/borrowck-pat-enum-in-box.rs
index cd4893f87f2..84a78580141 100644
--- a/src/test/compile-fail/borrowck-pat-enum-in-box.rs
+++ b/src/test/compile-fail/borrowck-pat-enum-in-box.rs
@@ -1,13 +1,13 @@
 fn match_imm_box(v: &const @option<int>) -> int {
     match *v {
-      @some(i) => {i}
+      @some(ref i) => {*i}
       @none => {0}
     }
 }
 
 fn match_const_box(v: &const @const option<int>) -> int {
     match *v {
-      @some(i) => { i } // ok because this is pure
+      @some(ref i) => { *i } // ok because this is pure
       @none => {0}
     }
 }
@@ -16,8 +16,8 @@ pure fn pure_process(_i: int) {}
 
 fn match_const_box_and_do_pure_things(v: &const @const option<int>) {
     match *v {
-      @some(i) => {
-        pure_process(i)
+      @some(ref i) => {
+        pure_process(*i)
       }
       @none => {}
     }
@@ -27,8 +27,8 @@ fn process(_i: int) {}
 
 fn match_const_box_and_do_bad_things(v: &const @const option<int>) {
     match *v {
-      @some(i) => { //~ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
-        process(i) //~ NOTE impure due to access to impure function
+      @some(ref i) => { //~ ERROR illegal borrow unless pure
+        process(*i) //~ NOTE impure due to access to impure function
       }
       @none => {}
     }
diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/compile-fail/borrowck-pat-enum.rs
index b29321ed818..bc30a2f13db 100644
--- a/src/test/compile-fail/borrowck-pat-enum.rs
+++ b/src/test/compile-fail/borrowck-pat-enum.rs
@@ -1,7 +1,7 @@
 fn match_ref(&&v: option<int>) -> int {
     match v {
-      some(i) => {
-        i
+      some(ref i) => {
+        *i
       }
       none => {0}
     }
@@ -16,7 +16,7 @@ fn match_ref_unused(&&v: option<int>) {
 
 fn match_const_reg(v: &const option<int>) -> int {
     match *v {
-      some(i) => {i} // OK because this is pure
+      some(ref i) => {*i} // OK because this is pure
       none => {0}
     }
 }
@@ -33,7 +33,7 @@ fn match_const_reg_unused(v: &const option<int>) {
 
 fn match_const_reg_impure(v: &const option<int>) {
     match *v {
-      some(i) => {impure(i)} //~ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
+      some(ref i) => {impure(*i)} //~ ERROR illegal borrow unless pure
       //~^ NOTE impure due to access to impure function
       none => {}
     }
@@ -41,7 +41,7 @@ fn match_const_reg_impure(v: &const option<int>) {
 
 fn match_imm_reg(v: &option<int>) {
     match *v {
-      some(i) => {impure(i)} // OK because immutable
+      some(ref i) => {impure(*i)} // OK because immutable
       none => {}
     }
 }
diff --git a/src/test/compile-fail/borrowck-pat-reassign-binding.rs b/src/test/compile-fail/borrowck-pat-reassign-binding.rs
index 02604f65227..fb3f13f909a 100644
--- a/src/test/compile-fail/borrowck-pat-reassign-binding.rs
+++ b/src/test/compile-fail/borrowck-pat-reassign-binding.rs
@@ -4,9 +4,9 @@ fn main() {
     let mut x: option<int> = none;
     match x { //~ NOTE loan of mutable local variable granted here
       none => {}
-      some(i) => {
+      some(ref i) => {
         // Not ok: i is an outstanding ptr into x.
-        x = some(i+1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
+        x = some(*i+1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
       }
     }
     copy x; // just to prevent liveness warnings
diff --git a/src/test/compile-fail/borrowck-pat-reassign-sometimes-binding.rs b/src/test/compile-fail/borrowck-pat-reassign-sometimes-binding.rs
index 42dd5024603..e0d96fb9e26 100644
--- a/src/test/compile-fail/borrowck-pat-reassign-sometimes-binding.rs
+++ b/src/test/compile-fail/borrowck-pat-reassign-sometimes-binding.rs
@@ -8,7 +8,7 @@ fn main() {
         // fact no outstanding loan of x!
         x = some(0);
       }
-      some(i) => {
+      some(ref i) => {
         x = some(1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
       }
     }
diff --git a/src/test/compile-fail/borrowck-unchecked-with-borrow.rs b/src/test/compile-fail/borrowck-unchecked-with-borrow.rs
index 86a855de6f1..aa16a272645 100644
--- a/src/test/compile-fail/borrowck-unchecked-with-borrow.rs
+++ b/src/test/compile-fail/borrowck-unchecked-with-borrow.rs
@@ -3,10 +3,10 @@ fn impure(_i: int) {}
 // check that unchecked alone does not override borrowck:
 fn foo(v: &const option<int>) {
     match *v {
-      some(i) => {
-        //~^ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
+      some(ref i) => {
+        //~^ ERROR illegal borrow unless pure
         unchecked {
-            impure(i); //~ NOTE impure due to access to impure function
+            impure(*i); //~ NOTE impure due to access to impure function
         }
       }
       none => {
@@ -16,9 +16,9 @@ fn foo(v: &const option<int>) {
 
 fn bar(v: &const option<int>) {
     match *v {
-      some(i) => {
+      some(ref i) => {
         unsafe {
-            impure(i);
+            impure(*i);
         }
       }
       none => {
@@ -27,4 +27,4 @@ fn bar(v: &const option<int>) {
 }
 
 fn main() {
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/alt-ref-binding-mut-option.rs b/src/test/run-pass/alt-ref-binding-mut-option.rs
new file mode 100644
index 00000000000..c81d87f3464
--- /dev/null
+++ b/src/test/run-pass/alt-ref-binding-mut-option.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut v = some(22);
+    match v {
+      none => {}
+      some(ref mut p) => { *p += 1; }
+    }
+    assert v == some(23);
+}