diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index f10a2a258fe9b285e61d0f7a7cb4fb33edb9aca6..8f254287d24e02944a1db321cd3bc35e150d3be7 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -639,15 +639,14 @@ fn check_captured_variables(this: @mut CheckLoanCtxt, span: span) { let cap_vars = this.bccx.capture_map.get(&closure_id); for cap_vars.iter().advance |cap_var| { + let var_id = ast_util::def_id_of_def(cap_var.def).node; + let var_path = @LpVar(var_id); + this.check_if_path_is_moved(closure_id, span, + MovedInCapture, var_path); match cap_var.mode { - moves::CapRef | moves::CapCopy => { - let var_id = ast_util::def_id_of_def(cap_var.def).node; - let lp = @LpVar(var_id); - this.check_if_path_is_moved(closure_id, span, - MovedInCapture, lp); - } + moves::CapRef | moves::CapCopy => {} moves::CapMove => { - check_by_move_capture(this, closure_id, cap_var); + check_by_move_capture(this, closure_id, cap_var, var_path); } } } @@ -655,9 +654,8 @@ fn check_captured_variables(this: @mut CheckLoanCtxt, fn check_by_move_capture(this: @mut CheckLoanCtxt, closure_id: ast::node_id, - cap_var: &moves::CaptureVar) { - let var_id = ast_util::def_id_of_def(cap_var.def).node; - let move_path = @LpVar(var_id); + cap_var: &moves::CaptureVar, + move_path: @LoanPath) { let move_err = this.analyze_move_out_from(closure_id, move_path); match move_err { MoveOk => {} diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index c3b35aba5181be6254e2d0956a77e058ef85a0f8..2342b60ace05bf58070b94ae7fb76d97ba6c5dc2 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -385,7 +385,6 @@ pub fn vars_created_since_snapshot(&mut self, snapshot: uint) pub fn tainted(&mut self, snapshot: uint, r0: Region) -> ~[Region] { /*! - * * Computes all regions that have been related to `r0` in any * way since the snapshot `snapshot` was taken---`r0` itself * will be the first entry. This is used when checking whether diff --git a/src/test/compile-fail/borrowck-move-by-capture.rs b/src/test/compile-fail/borrowck-move-by-capture.rs index 4ee824d1d49ad6cd6a6d999018e6603f4ac36305..ecb18993d9300a1db9266e29c42b48d313ddc973 100644 --- a/src/test/compile-fail/borrowck-move-by-capture.rs +++ b/src/test/compile-fail/borrowck-move-by-capture.rs @@ -4,8 +4,10 @@ pub fn main() { let _f: @fn() -> int = || *foo + 5; //~^ ERROR cannot move `foo` + // FIXME(#2202) - Due to the way that borrowck treats closures, + // you get two error reports here. let bar = ~3; let _g = || { //~ ERROR capture of moved value - let _h: @fn() -> int = || *bar; + let _h: @fn() -> int = || *bar; //~ ERROR capture of moved value }; } diff --git a/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs new file mode 100644 index 0000000000000000000000000000000000000000..5e789e99c0559a30411ebce4a7a6b7c08157e599 --- /dev/null +++ b/src/test/compile-fail/borrowck-move-moved-value-into-closure.rs @@ -0,0 +1,10 @@ +fn call_f(f: ~fn:Send() -> int) -> int { + f() +} + +fn main() { + let t = ~3; + + call_f(|| { *t + 1 }); + call_f(|| { *t + 1 }); //~ ERROR capture of moved value +} diff --git a/src/test/run-pass/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck-move-by-capture-ok.rs new file mode 100644 index 0000000000000000000000000000000000000000..095e2ba6fea4b0e688f4004de6230189ef181f4c --- /dev/null +++ b/src/test/run-pass/borrowck-move-by-capture-ok.rs @@ -0,0 +1,5 @@ +pub fn main() { + let bar = ~3; + let h: @fn() -> int = || *bar; + assert_eq!(h(), 3); +}