D has various parts that are not easy to find unless you’re a D programmer for some time. D Value Range Analysis works only inside a single expression, a simple example (here 155 is OK, 156 is a compile-time error):
ubyte foo1(in uint x) {
return x % 101 + 155; // OK
}
ubyte foo2(in uint x) {
return x % 101 + 156; // Error
}
void main() {}
See the compiler error:
https://dpaste.dzfl.pl/3767fcbe05e2
The kind of Value Range Analysis I’d like for Rust is similar, but I’d like the range value to be carried between different expressions. To simplify the analysis the value range should not be carried outside a function (for this it’s better to use contrats or static analysis tools external to the compiler), and should be computed only for constants (let but not let mut). When the flow analysis becomes too much long inside very large functions with a very high complexity I think it’s OK stop the computation of a value range after an amount of time.
In Rust the value range should not be used as in D to perform implicit type conversions (like in the D example above that contains an implicit but lossless u32->u8 conversion in the foo1 function) but allow code like:
fn foo1(x: u32) -> u8 {
u8::from(x % 101 + 155)
}
fn main() {}
The from perform a lossless explicit cast.