That's low-level code implementing a wrapper around the underlying libc socket API; there's no alternative to unsafe blocks there as it wraps a legacy API written in C.
The "this is safe" comment is just a (very verbose) explanation as to why the wrapper code is doing the correct thing. Notably, there's another similar comment just above it. In fact, looking through the file if anything I'm quite impressed at how carefully it's written.
Author here: one of the policies we tried to stick to when writing unsafe code was to document each case. It can be tedious but it encourages having less unsafe code and makes the author really think about if this unsafe code is really meeting the same guarantees as safe Rust according to https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html
I've also found this to be a really good approach to unsafe. Declare why something is actually safe and you may realize it isn't. It also helps when writing tests to assert safety - you have a comment explaining exactly the invariants you need to test.
// This is safe since we check the return value.
let sock = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) };
if sock < 0 {
return Err(Error::CreateSocket(IoError::last_os_error()));
}
I think in this case it would be better to put the return value check within the unsafe block, this way the unsafety does not "leak out" of the block, so to speak, so it is easier to audit. Of course in such a trivial case it does not matter much.
I think it's best to keep unsafe blocks as small as possible. Within an unsafe block there is undefined behavior, so you want to get out of there ASAP.
Personally I disagree, but mostly because I think the `unsafe` model Rust has is worth much less then people give it credit for.
For one, there is the current problems of documentation - it's not documented what features/invariants the optimizer and language actually require to be true, and the nitty gritty details are very fuzzy, so switching from `unsafe` to `safe` is error prone and you're going to get it wrong. The more you do it, the more likely it is your code will be broken in the future when you find out something you thought was OK isn't actually something the Rust devs like or isn't something they wanted you doing. If you do more of the `unsafe` work in one big `unsafe` block rather then jumping in and out, you're less likely to have issues in the future because there's less points where you have to ensure all the Rust invariants are met.
But the bigger detail for me is that, even if the above problem is fixed, `unsafe` doesn't really denote the areas we would consider the `unsafe` areas anyway, so "getting out of there ASAP" is not always a helpful mindset and can easily be counter-productive and result in you marking things `safe` when they're not actually `safe`. For example, dereferencing a pointer is `unsafe`, but doing pointer-arithmetic is `safe`. So you can easily just wrap the dereference in an `unsafe` block and your technically good to go (You can even wrap it in a pretty interface, like I've seen people do). But all the spots where you do pointer-arithmetic can easily introduce bugs into your `unsafe` code, making it hardly any better than C code that could have the same problem (Half the point of using Rust is to avoid bugs from unchecked pointer-arithmetic!).
My point being, just because your `unsafe` blocks are small doesn't tell you anything about the correctness of them, and it likely means they rely on outside information to be correct. And if that is the case, then that outside code is effectively just as dangerous as your `unsafe` code. This may be obvious to you, and I apologize if it is, but this is an issue/misconception I see a lot. IMO, you should mark anything `unsafe` if using it within the bounds of `safe` Rust could potentially cause `unsafe` code to fail, even if the code itself is completely `safe` code. Only if you have an interface the meets all the invariants that Rust requires should you allow it to be considered `safe`.
Speaking of policies, here's a question I've had for a while now: Google has rather (in)famous style guides for various languages; based on your experience with Google's codebases, have you given any thought to what a hypothetical "Google Rust Style Guide" would look like?
(When I've pondered this question before, "document every instance of `unsafe`" has been one of my policies (as obvious as it may seem), so I think you're on the right track!)
Not sure why you're downvoted because it's a perfectly reasonable question.
Rust's safety guarantees are mostly there to prevent you from making a certain class of coding errors. "unsafe" means that you've disabled those protections, but that just means that you have to be extra careful not to make those mistakes, and that people reviewing your code need to spend extra time to make sure that you haven't made those mistakes.
I take the exact opposite view: The goal of Rust is to give you tools to manager you unsafe code. Writing Rust code that avoids `unsafe` is counteracting its raison d'etre.
> // This is safe; nothing else will use or hold onto the raw sock fd.
> Ok(unsafe { net::UdpSocket::from_raw_fd(sock) })
https://chromium.googlesource.com/chromiumos/platform/crosvm...