From 4eac6fe21e1f82b1cc3c528b6a4b241fe5509b40 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 7 Apr 2023 17:23:03 +0000 Subject: [PATCH] Add test for `a.f(|this| a.g())` --- .../issue-109271-pass-self-into-closure.rs | 38 ++++++++++ ...issue-109271-pass-self-into-closure.stderr | 75 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 tests/ui/borrowck/issue-109271-pass-self-into-closure.rs create mode 100644 tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs new file mode 100644 index 00000000000..16167914512 --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs @@ -0,0 +1,38 @@ +#![allow(unused)] +struct S; + +impl S { + fn call(&mut self, f: impl FnOnce((), &mut Self)) { + // change state or something ... + f((), self); + // change state or something ... + } + + fn get(&self) {} + fn set(&mut self) {} +} + +fn main() { + let mut v = S; + + v.call(|(), this: &mut S| v.get()); + //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable + v.call(|(), this: &mut S| v.set()); + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + v.call(|(), this: &mut S| { + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + _ = v; + v.set(); + v.get(); + S::get(&v); + + use std::ops::Add; + let v = 0u32; + _ = v + v; + _ = v.add(3); + }); +} diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr new file mode 100644 index 00000000000..8abbecad02a --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr @@ -0,0 +1,75 @@ +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/issue-109271-pass-self-into-closure.rs:18:5 + | +LL | v.call(|(), this: &mut S| v.get()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:20:5 + | +LL | v.call(|(), this: &mut S| v.set()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:20:12 + | +LL | v.call(|(), this: &mut S| v.set()); + | -------^^^^^^^^^^^^^^^^^^--------- + | | | | | + | | | | second borrow occurs due to use of `v` in closure + | | | second mutable borrow occurs here + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:24:5 + | +LL | v.call(|(), this: &mut S| { + | ^ ---- ------------------ first mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - first borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______^ second mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:24:12 + | +LL | v.call(|(), this: &mut S| { + | - ---- ^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - second borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______- first mutable borrow occurs here + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0499, E0502. +For more information about an error, try `rustc --explain E0499`.