enum NumberOrNothing {
Nothing,
Number(i32),
}
fn vec_min(vec: Vec<i32>) -> NumberOrNothing {
let mut min = Nothing;
for e in vec {
min = Number( match min {
Nothing => e,
Number(n) => get_mix(n),
})**;**
}
min
}
For the min assignment statement in the FOR loop, if I miss the ";" in the end by neglect, it will become a legal expression and no any error in syntax, but it is really a logical error. In other language, the compiler will help to warn us, but Rust not. So how to avoid this error, especially in a long function. Thanks in advance.
In general, I think forgetting a semicolon cannot introduce logic errors. It will in general lead to syntax or type errors at compile time, except for a return type of () (where it is equivalent).
Half of me wants to say, yes, I think so too. (I mean, it's pretty much what I would have posted if notriddle wasn't such a speedy ninja!)
The other half says: Challenge accepted.
I can think of an example using the experimental -> impl Trait syntax:
#![feature(conservative_impl_trait)]
// Substitute Debug with e.g. serde::Serialize
// for a slightly more sinister example
use std::fmt::Debug;
fn foo_semi() -> impl Debug { 3; }
fn foo_nosemi() -> impl Debug { 3 }
fn main() {
println!("{:?}", foo_semi());
println!("{:?}", foo_nosemi());
}
()
3
And of course, an existential type can be simulated with a generic callback, so here's a non-nightly example:
fn bar_semi() { let x = {3;}; println!("{:?}", x); }
fn bar_nosemi() { let x = {3 }; println!("{:?}", x); }
fn main() { bar_semi(); bar_nosemi(); }
What I'm curious about though is whether there is an example that involves an expression which isn't at the end of a block; i.e. can removing a semicolon from stmt; stmt; turn it into one big statement with different semantics? Or does the grammar prevent this?
I'm inclined to think it's the latter, because I don't think I've ever run into such a problem...