Return reference with lifetime bound to a struct's field instead to the struct's

โš“ rust    ๐Ÿ“… 2025-06-12    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 2      

surdeus

This might be a bit of a beginner question, but I would really appreciate the help.
I have a situation in which I have a struct B that contains a field of type A.
However, A comes from an external crate and has a complex, hard to use API.
Therefore, my instinct coming from C++ would be to wrap A's API in a minimal set of methods implemented for B.

This has led me to the following code:

struct A {
    pub x: i32
    // Lots of other fields
}
impl A {
    fn get_x_ref(&self) -> &i32 {
        &self.x
    }
    // Lots of other methods
}

struct B {
    a: A,
    pub y: i32
}
impl B {
    fn get_x_ref(&self) -> &i32 {
        &self.a.get_x_ref()
    }
}

fn main() {
    let mut b = B { a: A { x: 0 }, y: 0 };
    let x = b.get_x_ref();
    b.y += 1;
    println!("{}", x)
}

Which is logically sound but of course gives a compilation error since we are borrowing b by getting a reference to b.a.x, and then trying to borrow it again to increase b.y.

I know of a few solution to this, namely what was described here: After NLL: Interprocedural conflicts ยท baby steps

But all solutions require code refactoring for a problem that i don't think stems from bad code design. And if there is something I really dislike is thinking hard about my code structure only to have to refactor because the compiler is screaming at me.

So my question is: should this design pattern be avoided in Rust because it promotes this type of error (and, in this case, what should it be replaced with?), or are there solutions to this that don't require refactoring "hacks" (either currently, or in progress)?

It seems a shame that a language that incentivises composition as a pattern (as opposed to OOP's inheritance mess) would not have a drop in way to fix this, something that would allow us to tell the compiler that &x is bound to A and cannot be changed by methods of B that don't interact with b.a.

5 posts - 3 participants

Read full topic

๐Ÿท๏ธ rust_feed