-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect unsafe code example in standard library #77220
Comments
Eventually Rust will need pre-conditions and post-conditions to verify statically and automatically that (most) invariants of unsafe functions hold :-) |
Isn't the point of unsafe code that you yourself uphold the invariants? |
yeah, afaict the safety conditions of fn set_len<T>(v: &mut Vec<T>, len: usize) {
v.len = len;
if let Some(last) = v.last() {
let _x: ManuallyDrop<T> = unsafe {
std::ptr::read(last as *const T as *const ManuallyDrop<T>)
};
// put copy of a `T` on the stack,
// requires that that value satisfies the language invariants of `T`
} We "obviously" do not do this, but I guess cc @rust-lang/wg-unsafe-code-guidelines on what's the right wording here. |
Currently yes, but surely that isn't a requirement. Having some mechanical ways to avoid some bugs in unsafe{} sections will be very good, even if it doesn't cover everything. There are people working on the formalization of (unsafe) Rust semantics that have this purposes too. And in some cases it's not that hard, is well within the capabilities of other research languages, like here: The second SAFETY note says:
Zig language gives pointers a static alignment annotation in the type system. And probably the annotations of a language like Why3 are enough for the other part. |
@leonardo-m I think this discussion is irrelevant to the issue. What we should be discussing is what to do; change set_len safety guarantees, because "We 'obviously' do not do this", or change the example. I'm leaning towards making the safety guarantees for set_len less strict, because that would allow for more flexible usage of the function. |
However, changing the safety on the |
The real heart of things is that code within the module is allowed to break the safety invariant as long as they don't break the validity invariant. As long as things are all put back together properly by the end of the function. |
A code example is not within the module |
Ah my mistake! I thought this was a vector construction method on the vec type. If this is anywhere else at all then the two lines need to be swapped so that |
Exactly. Give that However, to make the example code correct, we'd additionally have to say that All of this is a roundabout way to say that |
Note that we currently have a debug assert in set_len for If we want to change the safety guarantees here we probably should remove that debug_assert (even if they aren't actually part of the std used with rustup afaik) |
@lcnr good point. Or we could say that a length larger than the capacity is insta-UB (library UB). |
If |
Not sure if it's worth the complexity to have all these edge cases when |
Yes, probably.
|
Is needing to move the |
We should just move the line in the example. Complicating the method's rules would be a bad time. |
See "Code 15" this paper for another example of "calling |
No strong opinion from my side, I just didn't want to unnecessarily exclude existing unsafe code that is using |
Improve the example for ptr::copy Fixes rust-lang#77220
Improve the example for ptr::copy Fixes rust-lang#77220
The safety clause on the
Vec::set_len
function says that:However, the code example for
std::ptr::copy
violates the second ruleThe
set_len
is called before the values are initialized with the copy.This could be fixed by either making the safety clause for
set_len
more inclusive, so that as long as you don't use the vector before initializing the values it's considered safe, or by switching thedst.set_len(elts);
andptr::copy(ptr, dst.as_mut_ptr(), alts);
lines around in the example.The text was updated successfully, but these errors were encountered: