Reputation: 5522
In the following code example the compiler can work out that the if
blocks aren't reachable, and yet it still gives me an error.
const A_MODE: bool = false; // I manually edit this to switch "modes"
fn main() {
let a: Vec<u32>;
if A_MODE {
a = vec![1,2,3];
}
if A_MODE {
println!("a: {:?}", a); // error: borrow of possibly uninitialized variable
}
}
I thought that maybe the compiler was really trying to tell me that I need to initialize a
at some point, but this compiles fine:
fn main() {
let a: Vec<u32>;
println!("Finished.");
}
Is the error just because the Rust compiler isn't smart enough yet, or does this behaviour have some purpose? Is there any simple workaround which results in a similar code structure?
I know that I could restructure the code to make it work, but for my purposes the above structure is the most straight-forward and intuitive. My current work-around is to comment and uncomment code blocks, which isn't fun. Thanks!
Upvotes: 2
Views: 827
Reputation: 8214
The compiler does not expand constant expressions in the phase for validating lifetime and ownership, so it is not "obvious" to the compiler.
If you really don't want to run that block, you might want to use #[cfg]
(or the cfg-if crate if you like if syntax).
fn main() {
let a: Vec<u32>;
#[cfg(a-mode)] {
a = vec![1,2,3];
}
#[cfg(a-mode)] {
println!("a: {:?}", a); // error: borrow of possibly uninitialized variable
}
}
This way, it will compile both usages without branching at all if a-mode cfg is set, and will not compile either of them otherwise.
The compiler is aware that constant expression conditions never change, but that is handled at a later phase of the compilation for optimizations like removing branching.
Upvotes: 4