Skip to content

Cannot borrow as mutable despite DerefMut #51886

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

Closed
smcmurray opened this issue Jun 28, 2018 · 4 comments
Closed

Cannot borrow as mutable despite DerefMut #51886

smcmurray opened this issue Jun 28, 2018 · 4 comments
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@smcmurray
Copy link

smcmurray commented Jun 28, 2018

May be related to #17501

use std::ops::{Deref, DerefMut};

struct Test(Box<FnMut()>);

impl Deref for Test {
    type Target = Box<FnMut()>;
    fn deref(&self)->&Self::Target {
        &self.0
    }
}

impl DerefMut for Test {
    fn deref_mut(&mut self)-> &mut Box<FnMut()> {
        &mut self.0
    }
}

fn main() {
    let mut t = Test(Box::new(move || ()));
    (t.0)();
    t();
}

Rust 2015:

error[E0596]: cannot borrow immutable `Box` content as mutable
  --> src/main.rs:21:5
   |
21 |     t();
   |     ^ cannot borrow as mutable

Rust 2018:

error[E0596]: cannot borrow data in a `&` reference as mutable
  --> src/main.rs:21:5
   |
21 |     t();
   |     ^ cannot borrow as mutable
@cuviper
Copy link
Member

cuviper commented Jun 29, 2018

FWIW, I tried to hide the Box aspect, but it also fails with type Target = dyn FnMut().

@csmoe csmoe added the A-borrow-checker Area: The borrow checker label Jul 14, 2018
@kuviman
Copy link

kuviman commented Mar 7, 2019

It looks like anything but Box<T: FnMut()> and T: FnMut() itself, cause this error:

fn foo<F: FnMut(), W: Deref<Target = F> + DerefMut>(mut f: W) {
    f()
}
warning: variable does not need to be mutable
 --> src/lib.rs:3:53
  |
3 | fn foo<F: FnMut(), W: Deref<Target = F> + DerefMut>(mut f: W) {
  |                                                     ----^
  |                                                     |
  |                                                     help: remove this `mut`
  |
  = note: #[warn(unused_mut)] on by default

error[E0596]: cannot borrow data in a `&` reference as mutable
 --> src/lib.rs:4:5
  |
4 |     f()
  |     ^ cannot borrow as mutable

Based on the warning, it looks like only Deref is being considered, and DerefMut is not

@cuviper
Copy link
Member

cuviper commented Mar 8, 2019

It's happy if you force DerefMut like this: (&mut *t)()

@JohnTitor JohnTitor added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 2, 2019
@rylev
Copy link
Member

rylev commented Jun 10, 2021

Triage: This no longer seems to be an issue as both code samples from above compile successfully now. This seems to have been fixed in 1.46.

@rylev rylev closed this as completed Jun 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants