I've run into a lifetime problem, which doesn't seem to have a solution that won't involve polluting future implementations of a trait with explicit inferred lifetime parameters.
The problem is that I have two implementations of an update trait; App
which requires extra explicit lifetime bounds and Simple
whose lifetime bounds can be inferred by the compiler. But because of App
's impl requirements I need to explicitly add inferred bounds to Simple
's implementation. So, my question is, is there a way to implement Update
for App
that doesn't require that I pollute the rest of my library with lifetime bounds.
I've included the full playground below with a simplified version of my program.
struct Buffer<'a> {
data: &'a mut i32,
}
struct Keymap<T> {
func: fn(&mut T),
}
struct App<'borrow, 'short, 'buffer> {
keymap: &'borrow mut Keymap<BufferAndUi<'short, 'buffer>>,
buffer: &'borrow mut Buffer<'buffer>,
}
struct Ui<'ctx> {
ctx: &'ctx mut f32,
}
impl<'ctx> Ui<'ctx> {
fn set_id(&mut self, id: f32) {
*self.ctx = id;
}
fn print(&self) {
println!("{}", self.ctx)
}
}
struct BufferAndUi<'borrow, 'b> {
id: i32,
buffer: &'borrow mut Buffer<'b>,
ui: &'borrow mut Ui<'b>,
}
trait Update<'a, 'func> {
fn update(self, ui: &'func mut Ui<'a>);
}
impl<'app: 'inner_borrow, 'inner_borrow, 'buffer, 'func: 'inner_borrow> Update<'buffer, 'func> for App<'app, 'inner_borrow, 'buffer> {
fn update(self, ui: &'func mut Ui<'buffer>) {
*ui.ctx = 0.0;
println!("{}", ui.ctx);
(self.keymap.func)(&mut BufferAndUi::<'inner_borrow, 'buffer> {
id: 1,
buffer: self.buffer,
ui,
});
}
}
struct Simple {
id: f32,
}
impl Update<'_, '_> for Simple {
fn update(self, ui: &mut Ui) {
ui.set_id(self.id);
ui.print();
}
}
fn print_value(input: &mut BufferAndUi) {
*input.buffer.data = 10;
println!("{} {} {}", input.buffer.data, input.ui.ctx, input.id);
}
fn main() {
let mut keymap = Keymap { func: print_value };
let mut buffer = Buffer { data: &mut 0 };
let app = App {
keymap: &mut keymap,
buffer: &mut buffer,
};
let mut ui = Ui { ctx: &mut 10.0 };
app.update(&mut ui);
let simple = Simple { id: 5.0 };
simple.update(&mut ui);
}