9a48bd2f21
typestate now drops constraints correctly in the post-state of a move expression or a declaration whose op is a move. It doesn't yet drop constraints mentioning variables that get updated. To do this, I had to change typestate to use trit-vectors instead of bit-vectors, because for every constraint, there are three possible values: known-to-be-false (e.g. after x <- y, init(y) is known-to-be-false), known-to-be-true, and unknown. Before, we conflated known-to-be-false with unknown. But move requires them to be treated differently. Consider: (program a) (a1) x = 1; (a2) y <- x; (a3) log x; (program b) (b1) x = 1; (b2) y <- z; (b3) log x; With only two values, the postcondition of statement a2 for constraint init(x) is the same as that of b2: 0. But in (a2)'s postcondition, init(x) *must* be false, but in (b2)'s condition, it's just whatever it was in the postcondition of the preceding statement.
6 lines
128 B
Rust
6 lines
128 B
Rust
// error-pattern: Unsatisfied precondition constraint (for example, init(x
|
|
fn main() {
|
|
auto x = @5;
|
|
auto y <- x;
|
|
log *x;
|
|
} |