5

My use case is a bit more complex than this, but I'm trying to simplify the issue with this abstract example.

Say I have a structure:

struct Foo {
    bar: u32,
    baz: u32,
    ....
}

How can I write a get_bar function which can generalize over the mutability of the self parameter?

Pseudocode:

impl Foo {
    fn<?PT> getBar(&PT self) -> &PT u32 where PT = {mut immut} {
        &PT self.bar
    }
}

If called with a mutable pointer, it would return a mutble pointer to the inner field, if called with an immutable, it would return an immutable.

My goal is to avoid having to define a nonmut and a mut version of each function, by copy pasting code basically:

impl Foo {
    fn get_bar(&self) -> &u32 { &self.bar }
    fn get_bar_mut(&mut self) -> &mut u32 { &mut self.bar }
}

If the body of the function is more complex than this (my case is a recursive function), it gets pretty nasty, and there is a lot of code that is being copy&pasted, something that should be avoided.

Boiethios
  • 38,438
  • 19
  • 134
  • 183
Ákos Vandra-Meyer
  • 1,890
  • 1
  • 23
  • 40
  • 4
    This can't be done in Rust right now. – Peter Hall Jul 12 '18 at 09:37
  • 1
    If you want to avoid duplicating a complex body function, you can probably get somewhere by fully implementing only the immutable version, then having the mutable version call the immutable one with an added unsafe cast to restore mutability on the returned reference. – Jmb Jul 13 '18 at 06:35
  • @Jmb, how would you go to do that? `std::mem::transmute::<&T, &mut T>(value)` does not compile: `error: mutating transmuted &mut T from &T may cause undefined behavior` – Ákos Vandra-Meyer Jul 13 '18 at 15:03
  • 1
    @ÁkosVandra I thought `transmute` would do it directly. Since it doesn't, you can get there with raw pointers: `transmute (value as *const T as *mut T)` works. – Jmb Jul 16 '18 at 06:30

0 Answers0