> But surely those assumptions cease to hold if you're the one defining the memory model, and most of your code involves shuffling memory around inside of `unsafe` blocks.
True! But I think your characterization here of an OS kernel is incorrect. Certainly there will be more unsafe in an OS kernel than in your average user space application, but it should still be the minority of code. One thing that Rust documentation/tutorials frequently ram into your head in the chapters about unsafe is that you should be using unsafe only sparingly, to build small, auditable, hopefully-safe abstractions that the rest of your code -- safe code -- can use to get its work done.
That's just as true in a kernel context (and perhaps even more critical to understand and internalize there) as in user space.
> if those guarantees break, Rust will panic and crash, which - in a kernel - would mean bringing down the entire system [...] Linus Torvalds has noted some of his issues with Rust in kernel dev, and he's in a pretty good place to render his opinion.
And this is why the team working on The Rust-in-Linux project have been working with the Rust maintainers to provide alternate APIs that don't panic, and instead return errors, in these situations. Torvalds' feedback has been instrumental in driving these changes. The fact that Rust is in the kernel now is a testament to the fact that this feedback has been taken to heart, and Rust has seen improvements because of it.
> In a kernel context, even things like 'let' might fail
No, that's absolutely false, and breathless statements like these feel a bit disingenuous. Even `let s = String::new()` cannot fail, as all it does is move a stack pointer. I think perhaps you intend to mean that the expression on the rhs of a let statement can sometimes fail? Sure, and that's just like any other statement or expression. But, again, this is why we now have a bunch of "try_"-prefixed variants of common memory-allocating things that return an error instead of panicking.
> ... or you check for and try to catch these errors, which - well - is no different from C at that point
That's not even a little bit true. C has no built-in error checking mechanisms, or even a way to build safe, ergonomic error checking. If I call kmalloc() from C, I have to explicitly check for NULL. I can very easily forget to do so, and the compiler won't help me. If I call a similar "try_alloc()"-style function from Rust, it will return a Result, and the compiler will not let me do something with that allocated memory without explicitly handling a possible error.
> a better choice for a modern greenfield kernel would be one of the strictly functional languages: Haskell, OCaml, etc.
I suppose it depends on what your goals are. If you want to build the next Linux (or something more modest, but still quite popular), then probably not; you're not going to find enough people who are competent in or even interested in languages Haskell or OCaml to build a strong contributor base.
If you're instead doing research or are building something for niche use cases, then sure, that could work.
Some very fair points! I think there's more warts in Rust than just these, but if indeed Rust can be incorporated into Linux sanely and productively, I think it will be a net positive.
I respectfully disagree on the Haskell front. C is a significantly better known language then Rust, but you're advocating for Rust due to certain memory guarantees it provides. I think a similar argument can be made for languages like Haskell, and the formal mathematical guarantees they provide. Interestingly, Haskell was the language used to prototype seL4, which was then rewritten in C for performance, but the logic of the original Haskell implementation was used to formally verify parts of the later C one.[0] Imho, Rust is a (fantastic) attempt to make Algolians safer, but strictly functional languages like Haskell obviate many of the issues of Algolian languages in the first place.
On your last point, I'm unsure there's really much interest in making the next Linux, outside major corps who bristle at the GPL - e.g. Google's Zircon, notably written in C and C++ and first deployed in 2021. I think kernel dev largely divides into two camps: (i) hobbyist / academic kernels, which will be a homecoming parade of languages and designs (and rightly so); and (ii) production kernels, of which there are very few, written in C and C-likes, and conservative by design. Anything too new and unusual should probably prove its mettle in the former group before it graduates into the latter.
True! But I think your characterization here of an OS kernel is incorrect. Certainly there will be more unsafe in an OS kernel than in your average user space application, but it should still be the minority of code. One thing that Rust documentation/tutorials frequently ram into your head in the chapters about unsafe is that you should be using unsafe only sparingly, to build small, auditable, hopefully-safe abstractions that the rest of your code -- safe code -- can use to get its work done.
That's just as true in a kernel context (and perhaps even more critical to understand and internalize there) as in user space.
> if those guarantees break, Rust will panic and crash, which - in a kernel - would mean bringing down the entire system [...] Linus Torvalds has noted some of his issues with Rust in kernel dev, and he's in a pretty good place to render his opinion.
And this is why the team working on The Rust-in-Linux project have been working with the Rust maintainers to provide alternate APIs that don't panic, and instead return errors, in these situations. Torvalds' feedback has been instrumental in driving these changes. The fact that Rust is in the kernel now is a testament to the fact that this feedback has been taken to heart, and Rust has seen improvements because of it.
> In a kernel context, even things like 'let' might fail
No, that's absolutely false, and breathless statements like these feel a bit disingenuous. Even `let s = String::new()` cannot fail, as all it does is move a stack pointer. I think perhaps you intend to mean that the expression on the rhs of a let statement can sometimes fail? Sure, and that's just like any other statement or expression. But, again, this is why we now have a bunch of "try_"-prefixed variants of common memory-allocating things that return an error instead of panicking.
> ... or you check for and try to catch these errors, which - well - is no different from C at that point
That's not even a little bit true. C has no built-in error checking mechanisms, or even a way to build safe, ergonomic error checking. If I call kmalloc() from C, I have to explicitly check for NULL. I can very easily forget to do so, and the compiler won't help me. If I call a similar "try_alloc()"-style function from Rust, it will return a Result, and the compiler will not let me do something with that allocated memory without explicitly handling a possible error.
> a better choice for a modern greenfield kernel would be one of the strictly functional languages: Haskell, OCaml, etc.
I suppose it depends on what your goals are. If you want to build the next Linux (or something more modest, but still quite popular), then probably not; you're not going to find enough people who are competent in or even interested in languages Haskell or OCaml to build a strong contributor base.
If you're instead doing research or are building something for niche use cases, then sure, that could work.