From 767ed1a71f07e869e07bde138845e16b320908ec Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 8 Apr 2014 16:59:18 -0700 Subject: [PATCH] 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 --- src/librustc/middle/borrowck/mod.rs | 3 ++- src/test/compile-fail/issue-10398.rs | 19 +++++++++++++++++++ src/test/compile-fail/issue-11925.rs | 2 +- src/test/compile-fail/issue-12041.rs | 21 +++++++++++++++++++++ src/test/compile-fail/issue-12127.rs | 18 ++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/issue-10398.rs create mode 100644 src/test/compile-fail/issue-12041.rs create mode 100644 src/test/compile-fail/issue-12127.rs diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 6f4f2f6345eb4..cf558c6afe396 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -274,12 +274,13 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> { match cmt.cat { mc::cat_rvalue(..) | mc::cat_static_item | - mc::cat_copied_upvar(_) => { + mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => { None } mc::cat_local(id) | mc::cat_arg(id) | + mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) | mc::cat_upvar(ty::UpvarId {var_id: id, ..}, _) => { Some(@LpVar(id)) } diff --git a/src/test/compile-fail/issue-10398.rs b/src/test/compile-fail/issue-10398.rs new file mode 100644 index 0000000000000..a58c88737b604 --- /dev/null +++ b/src/test/compile-fail/issue-10398.rs @@ -0,0 +1,19 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x = ~1; + let f: proc() = proc() { + let _a = x; + drop(x); + //~^ ERROR: use of moved value: `x` + }; + f(); +} diff --git a/src/test/compile-fail/issue-11925.rs b/src/test/compile-fail/issue-11925.rs index 06a976ecf3d30..0b8eaa5b831c0 100644 --- a/src/test/compile-fail/issue-11925.rs +++ b/src/test/compile-fail/issue-11925.rs @@ -11,7 +11,7 @@ fn main() { let r = { let x = ~42; - let f = proc() &x; //~ ERROR: borrowed value does not live long enough + let f = proc() &x; //~ ERROR: `x` does not live long enough f() }; diff --git a/src/test/compile-fail/issue-12041.rs b/src/test/compile-fail/issue-12041.rs new file mode 100644 index 0000000000000..9ad593673120d --- /dev/null +++ b/src/test/compile-fail/issue-12041.rs @@ -0,0 +1,21 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let (tx, rx) = channel(); + spawn(proc() { + loop { + let tx = tx; + //~^ ERROR: use of moved value: `tx` + tx.send(1); + } + }); +} + diff --git a/src/test/compile-fail/issue-12127.rs b/src/test/compile-fail/issue-12127.rs new file mode 100644 index 0000000000000..7889242577029 --- /dev/null +++ b/src/test/compile-fail/issue-12127.rs @@ -0,0 +1,18 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let f = proc() {}; + (proc() { + f(); + f(); + //~^ ERROR: use of moved value: `f` + })() +}