X-Git-Url: https://git.ralfj.de/web.git/blobdiff_plain/4ae5e63b997a5662ebe0bad613e4c433f23399ea..6443ef4c3c06040c29466c96e372abd8fec8e458:/ralf/_posts/2017-07-17-types-as-contracts.md diff --git a/ralf/_posts/2017-07-17-types-as-contracts.md b/ralf/_posts/2017-07-17-types-as-contracts.md index 8ad613f..2d5e3c4 100644 --- a/ralf/_posts/2017-07-17-types-as-contracts.md +++ b/ralf/_posts/2017-07-17-types-as-contracts.md @@ -29,8 +29,8 @@ I'd like to propose that the fundamental reason this is UB is the *type* of the Borrowing some terminology from related fields, we can see the function type as stating a *contract*: The `&mut` say that `simple` expects to be called with non-aliasing pointers. If we violate the contract, all bets are off. -To realize this idea, we need to define, for every type, what is the contract associated with that type. When are elements of any given type *valid*? -For some types, that's simple: `i32` is any four-byte value. `bool` is one byte, either `0` or `1`. +To realize this idea, we need to define, for every type, what is the contract associated with that type. When is some piece of storage *valid* at any given type? +For some types, that's simple: `i32` is any fully initialized four-byte value. `bool` is one byte, either `0` (representing `false`) or `1` (representing `true`). Compound types like `(T, U)` are defined in terms of their constituent types: The first component must be a valid `T`, the second component a valid `U`. Where it gets interesting is the reference types: `&mut T` says that we have a (non-null, properly aligned) pointer. @@ -366,7 +366,6 @@ One potential middle-ground here is having a function attribute that controls wh I have described a mechanism to validate the contract expressed by Rust's types, in particular, the uniqueness and read-only guarantees provided by reference types. This validation describes what (safe) code can assume about its variables at run-time, and it enables some code motion optimizations that would otherwise require whole-program alias analysis. - I said before that I think providing a way to *detect* UB is crucial, and the framework laid out above is designed with this in mind. In fact, I have been working on a miri-based implementation of this mechanism: [This rustc branch](https://github.com/RalfJung/rust/tree/mir-validate) adds the new `Validate` statement to MIR and adds a MIR pass to insert validation statements as described above, while [this miri branch](https://github.com/RalfJung/miri/tree/mir-validate) adds memory locks to miri and implements type-based validation. @@ -395,8 +394,12 @@ Congratulations! You have reached the end of this blog post. Thanks a lot for reading. If you have any comments, please raise them -- the entire purpose of this post is to get the proposal out there so that we can see if this approach can suit the needs of Rust programmers and compiler writers alike. -If there are explanations you think are missing or confusing, please bring that up as well; I may then update this post accordingly. -The concrete proposal will sure need some fixing here and there, but my hope is that the general approach of a contract-like, type-driven validation mechanism ends up being useful. +If there are explanations you think are missing or confusing, please bring that up as well; I may then update this post accordingly or add a note in the [forum](https://internals.rust-lang.org/t/types-as-contracts/5562) for any ammendments that turned out to be necessary. +The concrete proposal will sure need some fixing here and there. +It is also not complete yet. +I already mentioned that there are open questions around unsafe code. +Other areas of future work include `static` variables and the `NonZero` type. +Nevertheless, my hope is that the general approach of a contract-like, type-driven validation mechanism ends up being useful. So, keep the comments flowing -- and safe hacking. #### Footnotes