To clear up possible misunderstandings: We are talking about a lint. Even though the compiler output says “error:
” this is not a true compilation error, but instead just a lint, i.e. the kind of thing that’s generally responsible for many of the helpful warning:
s you’ll get when using Rust. There are some “deny-by-default” lints, which means that the lint level is set to deny by default, something that’s also possible manually with any other lint. For example
#![deny(unused_variables)]
fn main() {
let x = 1;
}
will output
error: unused variable: `x`
--> src/main.rs:4:9
|
4 | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
note: the lint level is defined here
--> src/main.rs:1:9
|
1 | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
and not compile successfully. But of course, this code is not actually suffering from a true/hard compilation error.
Lints are generally acting on a best-effort basis (which explains the somewhat inconsistently triggering lint for different array-like types that you are experiencing here), they can have (though usually shouldn’t, if they are enabled by default) false positives, and there will very commonly be “false negatives” in the form of “equally bad” situations not covered by the lint. The case you are running ito could be considered a form of “false negative”. Another example could be something like
#![deny(unused_variables)]
fn main() {
let x = 1;
drop(x);
}
which will no longer lint, even though using an integer via drop
arguably is not much of an actual usage at all.
The reason why some lints are deny-by-default is that the code they fire on is considered to be so bad or buggy that building and/or running is commonly not considered worth the effort. Still, you can change the behavior if you want. If you degrade it to a warning, then
#![warn(unconditional_panic)]
fn main() {
let mut arr_0: [u32; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let ptr_0 = Box::new(arr_0);
let ptr_v = ptr_0[11];
let arr_v = arr_0[11];//warns
println!("v:{}", ptr_v);
}
will, too, compile just fine.
Another way in which deny-by-default lints differ from errors is that they will not make compilation fail if they happen in any dependency of your main crate. Cargo achieves this behavior by applying lint capping, silencing all (well… at least most) warnings (and errors from otherwise denied lints), because the person compiling the code is assumed not to be the developer of the dependency in question. This behavior also ensures that changes to the Rust compiler regarding lint behavior can happen without breakage. Rust can even introduce “error:
”s from deny-by-default lints without all that much breakage, because such changes will not prevent any dependent crates from building, and even the crate itself can still be build without any source code changes e.g. by using the --cap-lints
flag appropriately.