Skip to content

Commit 767ed1a

Browse files
committed
rustc: Prevent repeated moves out of proc upvars
This fixes the categorization of the upvars of procs (represented internally as once fns) to consider usage to require a loan. In doing so, upvars are no longer allowed to be moved out of repeatedly in loops and such. Closes #10398 Closes #12041 Closes #12127
1 parent 02f5121 commit 767ed1a

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

src/librustc/middle/borrowck/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,13 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> {
274274
match cmt.cat {
275275
mc::cat_rvalue(..) |
276276
mc::cat_static_item |
277-
mc::cat_copied_upvar(_) => {
277+
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
278278
None
279279
}
280280

281281
mc::cat_local(id) |
282282
mc::cat_arg(id) |
283+
mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) |
283284
mc::cat_upvar(ty::UpvarId {var_id: id, ..}, _) => {
284285
Some(@LpVar(id))
285286
}

src/test/compile-fail/issue-10398.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let x = ~1;
13+
let f: proc() = proc() {
14+
let _a = x;
15+
drop(x);
16+
//~^ ERROR: use of moved value: `x`
17+
};
18+
f();
19+
}

src/test/compile-fail/issue-11925.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
fn main() {
1212
let r = {
1313
let x = ~42;
14-
let f = proc() &x; //~ ERROR: borrowed value does not live long enough
14+
let f = proc() &x; //~ ERROR: `x` does not live long enough
1515
f()
1616
};
1717

src/test/compile-fail/issue-12041.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let (tx, rx) = channel();
13+
spawn(proc() {
14+
loop {
15+
let tx = tx;
16+
//~^ ERROR: use of moved value: `tx`
17+
tx.send(1);
18+
}
19+
});
20+
}
21+

src/test/compile-fail/issue-12127.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let f = proc() {};
13+
(proc() {
14+
f();
15+
f();
16+
//~^ ERROR: use of moved value: `f`
17+
})()
18+
}

0 commit comments

Comments
 (0)