It's important to note that the `unsafe` keyword is poorly named. What it does is unlock a few more capabilities at the cost of upholding the invariants the spec requires. It should really be called "assured" or something. The programmer is taking the wheel from the compiler and promising to drive safely.
As for why there is unsafe in the kernel? There are things, especially in a kernel, that cannot be expressed in safe Rust.
Still, having smaller sections of unsafe is a boon because you isolate these locations of elevated power, meaning they are auditable and obvious. Rust also excels at wrapping unsafe in safe abstractions that are impossible to misuse. A common comparison point is that in C your entire program is effectively unsafe, whereas in Rust it's a subset.
EDIT: Hacker News has limited my ability to respond. Please keep in mind that Rust has a large number of active fans, who may have biases for whatever reasons.
> Still, having smaller sections of unsafe is a boon because you isolate these locations of elevated power, meaning they are auditable and obvious.
The Rustonomicon makes it very clear that it is generally insufficient to only verify correctness of Rust-unsafe blocks. If the absence of UB in a Rust-unsafe block depends on Rust-not-unsafe code in the surrounding module, potentially the whole module has to be verified for correctness. And that assumes that the module has correct encapsulation, otherwise even more may have to be verified. And a single buggy change to Rust-not-unsafe code can cause UB, if a Rust-unsafe block somewhere depends on that code to be correct.
You need unsafe Rust for FFI - interfacing with the rest of the kernel which is still C, uses raw pointers, has no generics, doesn't track ownership, etc. One day there might enough Rust in the kernel to have pure-Rust subsystems APIs which would no longer require unsafe blocks to use. This would reverse the requirements as C would be a second class citizen with these APIs (not that C would notice or care). How far Rust is to get pushed remains to be seen but it might a long time to get there.
I was referring to the current unsafe blocks used for Rust->C FFI. Obviously OS code in any language will need to perform low-level operations, those unsafe blocks are never going away.
> I was referring to the current unsafe blocks used for Rust->C FFI.
You need direct shared mutable memory access with runtime locking even in the pure-Rust parts. That's kinda what OSes need, actually. Some things (Maybe DMA, possibly Page Table mutation, register saving/loading, as a few examples) can't be compile-time checked.
In fact, I would guess that if you gradually moved the Linux code over to Rust, at the end of it you'd still have maybe 50% of it in unsafe blocks.
So, no - your claim is no different than "if it compiles it works".
Rust is very nice for encapsulation. C isn't great at that work, and of course it can't express the idea that whatever we've encapsulated is now safe to use this way, in C everything looks equally safe/ unsafe.
It's worth noting that "aliasing" in Rust and C typically mean completely unrelated things.
Strict aliasing in C roughly means that if you initialize memory as a particular type, you can only access it as that type or one of a list of aliasable types look like char. Rust has no such restriction, and has no concept of strict aliasing like this. In Rust, "type aliasing" is allowed, so long as you respect size, alignment, and representability rules.
Aliasing safety in Rust roughly means that you can not have an exclusive reference to an object if any other reference is active for that reference (reality is a little bit more involved than that, but not a lot). C has no such rule.
It's very unfortunate that such similar names were given to these different concepts.
No. Aliasing is a single idea, an alias is another name for the same thing. The concept translates well from its usual English meaning.
The C "strict aliasing" rule is that with important exceptions the name for a thing of type T cannot also be an alias to a thing of type S, and char is an important exception. Linux deliberately switches off this rule.
Rust's rule is that there mustn't be mutable aliases. We will see why that's important in a moment.
Aliasing is an impediment to compiler optimisation. If you've been watching Matt's "Advent of Compiler Optimisation" videos (or reading the accompanying text) it's been covered a little bit in that, Matt uses C and C++ in those videos, so if you're scared of Rust you needn't fear that in the AoCO
But why mutation? Well, the optimisations concern modification. The optimiser does its job by rewriting what you asked for as something (possibly not something you could have expressed at all in your chosen language) that has the same effect but is faster or smaller. Rewrites which avoid "spilling" a register (writing its value to memory) often improve both size and speed of the software, but if there is aliasing then spilling will be essential because the other aliases are referring to the same memory. If there's no modification it doesn't matter, copies are all identical anyway.
Fair enough, I meant in terms of what rules and restrictions exist around aliasing, which are different between the two, but my wording was indeed off.