-
Notifications
You must be signed in to change notification settings - Fork 0
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
Comments: Learn Unsafe Rust from My Mistakes #49
Comments
I went through a similar journey when I first started using Rust. In fact, I contributed the original I'm happy to hear that this function is now unnecessary as it now works for somewhat arbitrary iterator chains, as proposed by @alexcrichton on the original PR: rust-lang/rust#15302 (comment). The optimization you allude to happens in the following file: library/alloc/src/vec/in_place_collect.rs. It took me a couple of minutes to find. :) It was apparently added in rust-lang/rust#70793. Thanks for your interesting blog post. :) |
@tbu- Oh cool, it's always nice to hear that other devs shared some of the struggle. Thanks for taking the time to find the sources and provide more context. |
Hi! I think this example is misleading: let mut x = 10;
let p1: *mut i32 = &mut x;
let p2: *mut i32 = &mut x;
unsafe {
// ...
} The text around it seems to imply that we created two usable pointers, but |
Hey @GoldsteinE , good point. I should just be able to replace the second line by |
Yeah, that should work (the relevant part is that they’re |
Oh yeah, sorry that's what I meant to say... |
Small nitpic: As leaking destructors isn't unsound in rust, the "first" version of the function is sound (or at least panic safe). This can be shown by writing a semantically equivalent function using safe rust only, by forcing everything to happen inside fn safe_map_in_place<T, U, F>(v: Vec<T>, f: F) -> Vec<U>
where
F: Fn(T) -> U,
{
let mut v = ManuallyDrop::new(v.into_iter().map(f));
let mut u = ManuallyDrop::new(Vec::new());
u.extend(&mut *v);
ManuallyDrop::into_inner(u)
} This behaviour is certainly incorrect due to being surprising and would be easy to misuse in the presence of other unsafe code that relied on destructors being ran, but clearly safe while unwinding. Miri refuses to accept this wasteful attitude towards owned recourses, but with a little bit of trickery (or turning off memory leak tracking), it too sees that nothing bad is actually going on. |
@MalbaCato hey thanks for the comment, I have questions. First if all I think you're right that soundness does not guarantee that destructors are run. I should have stated that more clearly. The other thing is that I am staring at your example (which is beautiful btw), but I don't understand why it would guarantee in place mapping? Meaning why would vector u reuse the memory allocated for vector v. Not saying that isn't the case, just saying I don't understand what about the code would guarantee it. Could you explain it a bit more? |
Comments for this article go here :)
The text was updated successfully, but these errors were encountered: