Skip to content

spurious "borrow might be used .. when [variable] is dropped and runs the destructor" #70919

@comex

Description

@comex

Playground

use std::rc::Rc; use std::cell::{RefCell, RefMut}; use std::mem::drop; fn huh(x: Rc<RefCell<i32>>) { let mut rc: Rc<RefCell<i32>> = x.clone(); let mut inner: RefMut<'_, i32> = rc.borrow_mut(); loop { drop(inner); drop(rc); rc = x.clone(); inner = rc.borrow_mut(); } }

produces:

error[E0505]: cannot move out of `rc` because it is borrowed --> src/lib.rs:9:14 | 6 | let mut inner: RefMut<'_, i32> = rc.borrow_mut(); | -- borrow of `rc` occurs here ... 9 | drop(rc); | ^^ move out of `rc` occurs here ... 12 | inner = rc.borrow_mut(); | ----- borrow might be used here, when `inner` is dropped and runs the destructor for type `std::cell::RefMut<'_, i32>` error[E0506]: cannot assign to `rc` because it is borrowed --> src/lib.rs:11:9 | 6 | let mut inner: RefMut<'_, i32> = rc.borrow_mut(); | -- borrow of `rc` occurs here ... 11 | rc = x.clone(); | ^^ assignment to borrowed `rc` occurs here 12 | inner = rc.borrow_mut(); | ----- borrow might be used here, when `inner` is dropped and runs the destructor for type `std::cell::RefMut<'_, i32>` 

(Same error with -Zpolonius.)

The error messages are wrong: the assignment to inner can never run a destructor, since the previous value of inner was dropped earlier on.

And AFAICT this code is sound and ought to be accepted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-destructorsArea: Destructors (`Drop`, …)C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions