Misleading error message with Result<_> and mutable references


#1

Hello!
I have done simple Resource Manager to load textures and accidentally I ran into issue.
Manager was just simple HashMap and something that can loads textures from hard drive into memory.

fn load(&mut self, details: String) -> Result<Rc<Texture<'l>>, String> {
     //this doesn`t matter imo
    result
}

But when i changed it into:

fn load(&mut self, details: String) -> <Rc<Texture<'l>>{
     //this doesn`t matter imo
    result.unwrap()
}

Then on second and third usage of function I got:

error[E0499]: cannot borrow `manager` as mutable more than once at a time                                                             
--> src/main.rs:115:20                                                                                                             
    |                                                                                                                                 
113 |     let texture = manager.load("animbg.png".to_string());                                                                        
    |                   ------- first mutable borrow occurs here                                                                      
114 |                                                                                                                                 
115 |     let texture2 = manager.load("arrow.png".to_string());                                                                             
    |                    ^^^^^^^ second mutable borrow occurs here                                                                    
...                                                                                                                                   
347 | }                                                                                                                               
    | - first borrow ends here                                                                                                        
                                                                                                                                  
error[E0499]: cannot borrow `manager` as mutable more than once at a time                                                             
--> src/main.rs:117:20                                                                                                             
    |                                                                                                                                 
113 |     let texture = manager.load("animbg.png".to_string());                                                                        
    |                   ------- first mutable borrow occurs here                                                                      
...                                                                                                                                   
117 |     let texture3 = manager.load("foo.png".to_string());                                                                               
    |                    ^^^^^^^ second mutable borrow occurs here                                                                    
...                                                                                                                                   
347 | }                                                                                                                               
    | - first borrow ends here                                                                                                        
                                                                                                                                  
error: aborting due to 2 previous errors  

Line 347 is end of file of course.
fn load obviously needs mutable self since it is changing HashMap.
And this problem doesn`t appear if I just leave it as Result<_> and unwrap() at usage.

In my opinion it is at least very confisuing, does anybody know why is this happening?
I can of course put more code if needed. Anyway I mainly took SDL2 ResourceManager example.

Wowo


#2

Could you please post a minimal viable example that shows this via playground?


#3

So I tried to recreate the issue:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d9d1df5e3f181cf04bb2fdf4b859791e

And everything works fine, only difference is instead of String I`ve got Texture<'l>

So back to my code, lil changes aand it also works same way -_-"
Sorry now I have no idea how to duplicate the “issue” if it was a case anyway :confused:

I think I should somehow delete the topic? :confused:
Sorry for thrashing the forum!

Wowo


#4

Could you simulate the lifetime with a dummy struct.

Something like this

struct HasLifetime<'l> {
    lifetime: &'l (),
}

and you can make it like this

HasLifetime { lifetime: &() }

This is definitely a lifetime issue around lifetime 'l, so removing it will remove the problem.


#5

You could also try to remove the lifetime from Texture, and this would solve the issue.

If it is possible, could you post a link to your code?


#6

Imo it would be easier also, but I will need to ask you to wait until tomorrow. I will ask if I can set my repository to public. :slight_smile:

Wowo


#7

Ok


#8

Got a response from my professor and sadly I shouldn’t set repository to public before giving it to official check.
As the issue is no more and I can not reproduce it let`s close the topic for now at least.

For future issues promise to create minimal playground example before posting. :slight_smile:
Wowo