Skip to content

as *mut _ does not cause by-mut place evaluation, causing an error stating DerefMut is not implemented, but it is #86262

Open

Description

@CAD97

Given the code:

#![allow(unused_mut)]

use core::mem::ManuallyDrop;

pub struct RefWrapper<'a, T: ?Sized> {
    slot: &'a mut T,
}

impl<'a, T: ?Sized> RefWrapper<'a, T> {
    pub fn into_raw(this: Self) -> *mut T {
        let mut this = ManuallyDrop::new(this);
        // let this = &mut *this;
        this.slot as *mut T
    }
}

The current output is:

error[E0596]: cannot borrow data in a dereference of `ManuallyDrop<RefWrapper<'_, T>>` as mutable
  --> src/lib.rs:13:9
   |
13 |         this.slot as *mut T
   |         ^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `ManuallyDrop<RefWrapper<'_, T>>`

Ideally, this should just work1. Uncommenting the commented line to add an explicit mutable reborrow allows the code to work as intended. But even if it can't work, the error is clearly very unhelpful, as the issue isn't the lack of DerefMut, but that the compiler selected a shared Deref evaluation of the place.

@rustbot modify labels +C-bug +D-incorrect

Footnotes

  1. Importantly, just work and produce a pointer with valid mut provenance. It would be technically correct but misleading to allow &mut T as *mut T behind a shared reference to behave like &mut T as *const T as *mut T. The actually useful behavior is for the fact that as *mut is a by-mut use of the this.slot place to flow back into the selection of whether to evaluate the this.slot place by-ref (via Deref) or by-mut (via DerefMut) the same way other by-mut place usage does. ↩

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jun 13, 2021
  2. added
    C-bugCategory: This is a bug.
    D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
    on Jun 13, 2021
  3. estebank commented on Jan 9, 2023

    @estebank
    Contributor

    Triage: no change

  4. CAD97 commented on Jan 9, 2023

    @CAD97
    ContributorAuthor

    I believe the change implemented in #86647 is the correct fix; namely, considering an as *mut _ use of a place a by-mut usage for the purpose of selecting whether Deref or DerefMut is used in autoborrow evaluation of the place.

    For comparison, writing ptr::from_mut(this.slot) (docs instead, compiles as expected.

    That PR stalled waiting for lang/compiler confirmation of the change's impact.

    Since this does indeed have lang implications,

    @rustbot modify labels +T-lang

    If we can get team confirmation that #86647 did indeed have the correct approach, I can rebase and resubmit.

  5. changed the title [-]Bad error: DerefMut is not implemented, but it is[/-] [+]`as *mut _` does not cause by-`mut` place evaluation, causing an error stating `DerefMut` is not implemented, but it is[/+] on Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.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