[solved] Cannot infer lifetime vs borrowing more than once errors


#1

hi,

I’m writing a small 2D game engine in Rust as a learning project, this is the first time I need to seek for forum help.

I have a “Cannot infer lifetime” error and following the suggestions given by the compiler lead to a “borrow more than once” error. I’ve tried playing around with lifetimes but always I hit some dead end.

There are many answers for questions like this in SO, but none seems to work for my case.

Here is a minimalistic version that reproduces the situation

any help getting this to compile is highly appreciated!


#2

This is a version that works: https://play.rust-lang.org/?gist=8e1fe645387e2e73cd36&version=stable

Basically, you don’t need a lifetime 'k associated with the trait, but it can be local to the handle method and only connect the lifetime of its self reference and the lifetime of the references inside the DrawList.


#3

it works, thanks!


#4

Actually still not solved – my full code touches self.tasks after looping through the tasks and calling handle on each. This causes cannot borrow self.tasks as immutable because it is also borrowed as mutable at line 40.

I now added a println! to simulate this in this version:

https://play.rust-lang.org/?gist=52e29d4a925de73900a3&version=stable

seems calling handle on the traits causes the borrow to not end somehow after the loop.

any ideas?


#5

That borrow is tied to the DrawList lifetime parameter, so it spans to the end of Engine::handle.


#6

makes sense, that borrow lives for as long as drawlist lives. So I understand that but still got no solution. I tried to pass drawlist as a parameter, and tried to inline all this function in the caller. Always after creating it I cannot touch self.

Also I cannot clone the list as it contains types which are not mine (from an external crate, Glium, opengl stuff)

any strategies known to solve such cases?


#7

A Cell or RefCell can be an “easy” workaround, because it allows you to work with immutable references. But then it’s up to you to ensure that a RefCell that is borrowed mutably isn’t borrowed again.


#8

actually a little refactoring solved the problem. I separated the sprite behavior logic which needs mutation and the drawing which doesn’t need it. This actually resulted in an a better design!

Rust is like the anti technical debt language, it requires a bit more work but the result has little debt indeed. I’m also starting to get a feel for what works and what not.

So, thanks for the help!