Skip to content

rustc loosing track of DerefMut impl on nested type #68590

Closed
@programmerjake

Description

@programmerjake

The following code should compile but doesn't. With only 9 nesting levels, I wouldn't expect to be running into deref-limits yet.

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

trait DynTrait {
    fn f(&mut self);
}

struct Base<'a> {
    dyn_trait: &'a mut dyn DynTrait,
}

macro_rules! impl_type {
    ($derived:ident, $base:ident) => {
        struct $derived<'a> {
            base: $base<'a>,
        }
        
        impl<'a> Deref for $derived<'a> {
            type Target = $base<'a>;
            fn deref(&self) -> &$base<'a> {
                &self.base
            }
        }
        
        impl<'a> DerefMut for $derived<'a> {
            fn deref_mut(&mut self) -> &mut $base<'a> {
                &mut self.base
            }
        }
    };
}

impl_type!(Level1, Base);
impl_type!(Level2, Level1);
impl_type!(Level3, Level2);
impl_type!(Level4, Level3);
impl_type!(Level5, Level4);
impl_type!(Level6, Level5);
impl_type!(Level7, Level6);
impl_type!(Level8, Level7);
impl_type!(Level9, Level8);

fn take_dyn_trait(dyn_trait: &mut dyn DynTrait) {}

fn f<'a>(value: &mut Level9<'a>) {
    // uncomment following line to make compile
    //let value: &mut Base = value;
    take_dyn_trait(value.dyn_trait);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
warning: unused variable: `dyn_trait`
  --> src/lib.rs:42:19
   |
42 | fn take_dyn_trait(dyn_trait: &mut dyn DynTrait) {}
   |                   ^^^^^^^^^ help: consider prefixing with an underscore: `_dyn_trait`
   |
   = note: `#[warn(unused_variables)]` on by default

error[E0596]: cannot borrow data in a dereference of `Level1<'_>` as mutable
  --> src/lib.rs:47:20
   |
47 |     take_dyn_trait(value.dyn_trait);
   |                    ^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Level1<'_>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0596`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemC-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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions