-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spurious "borrow might be used .. when [variable] is dropped and runs the destructor" #70919
Comments
Similar issue in current rustc, my code involves std RwLock and match
the error makes no sense, i drop it manually right above. I can't find a way to subjugate the compiler. |
Probably the same underlying issue affects this example (playground): enum Either<L, R> {
Left(L),
Right(R),
}
struct One<'a>(&'a mut [u8]);
impl<'a> One<'a> {
fn step(self) -> Either<Two<'a>, OneSave> { unimplemented!() }
}
impl<'a> Drop for One<'a> {
fn drop(&mut self) {}
}
struct OneSave;
impl OneSave {
fn resume(self, _: &mut [u8]) -> One<'_> { unimplemented!() }
}
struct Two<'a>(&'a mut [u8]);
impl<'a> Two<'a> {
fn step(self) -> One<'a> { unimplemented!() }
}
fn grow(_: &mut Vec<u8>) -> &mut [u8] { unimplemented!() }
pub fn go(stuff: &mut Vec<u8>) {
let mut one = One(stuff);
loop {
let two = loop {
one = match one.step() {
Either::Left(x) => break x,
Either::Right(save) => save.resume(grow(stuff)),
};
};
one = two.step();
}
} error[E0499]: cannot borrow `*stuff` as mutable more than once at a time
--> src/lib.rs:44:57
|
39 | let mut one = One(stuff);
| ----- first mutable borrow occurs here
...
42 | one = match one.step() {
| --- first borrow might be used here, when `one` is dropped and runs the `Drop` code for type `One`
43 | Either::Left(x) => break x,
44 | Either::Right(save) => save.resume(grow(stuff)),
| ^^^^^ second mutable borrow occurs here This compiles if you remove the |
Minimized: struct WrapperWithDrop<'a>(&'a mut bool);
impl<'a> Drop for WrapperWithDrop<'a> {
fn drop(&mut self) {}
}
fn main() {
let mut base = true;
let mut wrapper = WrapperWithDrop(&mut base);
loop {
drop(wrapper);
base = false;
wrapper = WrapperWithDrop(&mut base);
}
} |
Add regression tests for issue 70919 Desugaring DropAndReplace at MIR build (rust-lang#107844) fixed rust-lang#70919. Add regressions tests, borrowed from rust-lang#102078, to ensure we check for this in the future. cc `@Aaron1011`
This usage can be removed since the issue was fixed: rust-lang/rust#70919
This usage can be removed since the issue was fixed: rust-lang/rust#70919
Playground
produces:
(Same error with
-Zpolonius
.)The error messages are wrong: the assignment to
inner
can never run a destructor, since the previous value ofinner
was dropped earlier on.And AFAICT this code is sound and ought to be accepted.
The text was updated successfully, but these errors were encountered: