I'm porting an old project to Rust, and faced a problem I couldn't find a solution for. The only similar thing I found is this, which doesn't answer the actual question. The underlying problem is this:
struct A {
a: Box<i32>,
b: Box<i32>
}
impl A {
fn get_a(&mut self) -> &mut Box<i32> { &mut self.a }
fn get_b(&mut self) -> &mut Box<i32> { &mut self.b }
}
fn main() {
let mut a = A{ a: Box::new(42), b: Box::new(28) };
// This compiles:
//let af = &mut a.a;
//let bf = &mut a.b;
// This doesn't!
let af = a.get_a();
let bf = a.get_b();
println!("{}", af);
println!("{}", bf);
}
In my real world code I have this:
struct GlyphPlacer {
bitmap: Bitmap,
bitmaps: Vec<(char, GlyphBitmap)>,
current_scanline_buffer: usize,
scanline_buffers: [Vec<Scanline>; 2]
}
impl GlyphPlacer {
// ...
fn immutable_scanline_buffer(&self) -> &Vec<Scanline> {
&self.scanline_buffers[self.current_scanline_buffer]
}
fn draw_scanlines(&mut self) {
for scanline in self.immutable_scanline_buffer() {
// error: cannot borrow `self.bitmap` as mutable because `*self` is also borrowed as immutable [E0502]
self.bitmap.draw_scanline(*scanline);
}
}
}
Which compiles only if I inline the implementation of theimmutable_scanline_buffer()
method, and only because the draw_scanline()
method is a method of the self.bitmap
field, not the actual GlyphPlacer
struct:
fn draw_scanlines(&mut self) {
for scanline in &self.scanline_buffers[self.current_scanline_buffer] {
self.bitmap.draw_scanline(*scanline);
}
}
I understand why is this happening, but how to handle cases like this? I can not separate those two fields, because they are just parts of implementation of GlyphPlacer
, and I can't always copy-paste code like that, because the implementation of functions like immutable_scanline_buffer()
can't always be so short.