Hello, I'm a beginner at Rust and I'm experimenting with the xcb library to connect to X11. I had some simple boilerplate code in my main function that I tried to extract into a function:
fn init() -> (xcb::Connection, i32, x::Window, x::Gcontext, &'static x::Setup) {
let (connection, screen_num) = xcb::Connection::connect(None).unwrap();
let window: x::Window = connection.generate_id();
let gc: x::Gcontext = connection.generate_id();
let setup = connection.get_setup();
return(connection, screen_num, window, gc, setup);
}
This, however, yields the error:
error[E0515]: cannot return value referencing local variable `connection`
--> src/main.rs:14:11
|
12 | let setup = connection.get_setup();
| ---------- `connection` is borrowed here
13 |
14 | return(connection, screen_num, window, gc, setup);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
Why does this happen, if the value that's being referenced is also returned by the function? How do I fix this error, or what are some better solutions to this problem?
The problem is that the local variable connection is not the same as the return value. The connection is being moved to the return value, the references to connection are left hanging to a nonexistent connection.
I think you have to create the connection outside of the function and pass it by reference into the function.
Rust does not support returning or storing a value and a reference to the same value together. This is called self-referential type, and it is completely forbidden in safe code, and it's very difficult to hack around it in unsafe code.
The usual solution is to split the function into two parts — one that gets the owned value, and returns only the owned value, and a second function call that gets the value by reference, and can return one or more references to the input arguments it got (it will never be possible to return a reference to data stored in a local variable).