X-Git-Url: https://git.ralfj.de/web.git/blobdiff_plain/dff74489f29090aaf852e8e21910b683b8950b71..7fad530d10920cdd874584d4111bcb046ffad34c:/personal/_posts/2018-07-19-const.md diff --git a/personal/_posts/2018-07-19-const.md b/personal/_posts/2018-07-19-const.md index a2f9552..0a3ad30 100644 --- a/personal/_posts/2018-07-19-const.md +++ b/personal/_posts/2018-07-19-const.md @@ -95,9 +95,9 @@ We will definitely want to allow this code. Why should `==` or `%` not be const-safe? Well, we could call our function as follows: {% highlight rust %} -is_eight_mod_256(Box::new(0).into_raw() as usize); +is_eight_mod_256(Box::into_raw(Box::new(0)) as usize); {% endhighlight %} -That statement is certainly *not* const-safe as the result depends on where exactly the allocator puts our `Box`. +That statement is certainly *not* const-safe as the result depends on where exactly the allocator puts our [`Box`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html). However, we want to blame the `as usize` for this issue, not the `is_eight_mod_256`. The solution is for the const type system to not just have separate rules about which operations are allowed, we also must change our notion of which values are "valid" for a given type. @@ -190,7 +190,7 @@ As usual when writing `unsafe` code, we have to be careful not to violate the sa We have to manually ensure that, *if* our inputs are const-valid, then we will not trigger a CTFE error and return a const-valid result. For this example, the reason no CTFE error can arise is that references cannot dangle. We can thus provide `ptr_eq` as an abstraction that is entirely safe to use in const context, even though it contains a potentially const-unsafe operation. -This is, again, in perfect analogy with types like `Vec` being entirely safe to use from safe Rust even though `Vec` internally uses plenty of potentially unsafe operations. +This is, again, in perfect analogy with types like [`Vec`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html) being entirely safe to use from safe Rust even though `Vec` internally uses plenty of potentially unsafe operations. Whenever I said above that some operation must be rejected by the const type system, what that really means is that the operation should be unsafe in const context. Even pointer-to-integer casts can be used internally in const-safe code, for example to pack additional bits into the aligned part of a pointer in a perfectly deterministic way. @@ -216,7 +216,7 @@ Const soundness already says that this is a way to ensure const safety. I propose to only ever promote values that are *safely* const-well-typed. (So, we will not promote values involving const-unsafe operations even when we are in an unsafe block.) When there are function calls, the function must be a safe `const fn` and all arguments, again, const-well-typed. -For example, `&is_eight_mod_256(13)` would be promoted but `&is_eight_mod_256(Box::new(0).into_raw() as usize)` would not. +For example, `&is_eight_mod_256(13)` would be promoted but `&is_eight_mod_256(Box::into_raw(Box::new(0)) as usize)` would not. As usual for type systems, this is an entirely local analysis that does not look into other functions' bodies. Assuming our const type system is sound, the only way we could possibly have a CTFE error from promotion is when there is a safe `const fn` with an unsound `unsafe` block.