summaryrefslogtreecommitdiffstats
path: root/tests/ui/borrowck/borrow-immutable-upvar-mutation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/borrowck/borrow-immutable-upvar-mutation.rs')
-rw-r--r--tests/ui/borrowck/borrow-immutable-upvar-mutation.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/tests/ui/borrowck/borrow-immutable-upvar-mutation.rs b/tests/ui/borrowck/borrow-immutable-upvar-mutation.rs
new file mode 100644
index 000000000..a3350024e
--- /dev/null
+++ b/tests/ui/borrowck/borrow-immutable-upvar-mutation.rs
@@ -0,0 +1,56 @@
+#![feature(unboxed_closures, tuple_trait)]
+
+// Tests that we can't assign to or mutably borrow upvars from `Fn`
+// closures (issue #17780)
+
+fn set(x: &mut usize) {
+ *x = 5;
+}
+
+fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ f
+}
+fn to_fn_mut<A: std::marker::Tuple, F: FnMut<A>>(f: F) -> F {
+ f
+}
+
+fn main() {
+ // By-ref captures
+ {
+ let mut x = 0;
+ let _f = to_fn(|| x = 42); //~ ERROR cannot assign
+
+ let mut y = 0;
+ let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow
+
+ let mut z = 0;
+ let _h = to_fn_mut(|| {
+ set(&mut z);
+ to_fn(|| z = 42); //~ ERROR cannot assign
+ });
+ }
+
+ // By-value captures
+ {
+ let mut x = 0;
+ let _f = to_fn(move || x = 42); //~ ERROR cannot assign
+
+ let mut y = 0;
+ let _g = to_fn(move || set(&mut y)); //~ ERROR cannot borrow
+
+ let mut z = 0;
+ let _h = to_fn_mut(move || {
+ set(&mut z);
+ to_fn(move || z = 42);
+ //~^ ERROR cannot assign
+ });
+ }
+}
+
+fn foo() -> Box<dyn Fn() -> usize> {
+ let mut x = 0;
+ Box::new(move || {
+ x += 1; //~ ERROR cannot assign
+ x
+ })
+}