Looking at the rust rfc for the lightweight clones feature [1]. It took me a while to sort of understand it. Once I did I was excited for the feature but after awhile I was once again struck by the observation that rust is a very complex language to learn.
To me as someone who's not learned either it looks like all the concepts and features of 'true' modern C++ (as opposed to C + a few extra features) spliced with the features and concepts of Haskell.
Yet people seem to like making useful things in it so it must have gotten something right. So I'll probably get around to attempting to really use it again.
In my experience, C++ is a much more complicated language. The 8 ways to initialize something, the 5 types of values (xvalues etc.), inconsistent formatting conventions, inconsistent naming conventions, the rule of 5, exceptions, always remembering to check `this != other` when doing a move assignment operator, perfect forwarding, SFINAE, workarounds for not having a great equivalent to traits, etc. . Part of knowing the language is also knowing the conventions on top that are necessary in order to write it more safely and faster (if your move constructor is not noexcept it'll cause copies to occur when growing a vector of that object), and learning the many non-ideal competing ways that people do things, like error handling.
I mean yes, C++ managed to hit a uncanny overlap of being very overenginered in some aspects which to make it worse haven't focused at all on non-senior/export dev UX while also being underenginered in others aspects :/
They are trying to fix it in recent ~10 years, but they are also adding new clever expert features at the same time, so I kinda see it as a lost cause.
Rust isn't doesn't have "that" much less complexity if you take all the stable (or worse unstable experimental) things it has.
What makes Rust so nice is nearly always(1) if you don't use a feature you don't have to know about it (not so in C++) and if you stumble about a feature you don't know it's not just normally syntax visible but if you use it wrongly it won't segfault or even have a RCE due to out of bounds writes or similar.
So for C++ you have to learn a lot of the stuff upfront, but are not forced to by the compiler, and getting it wrong can have catastrophic consequences.
But for Rust you can learn it (mostly) bit by bit.
It's not perfect, when you go unsafe you are touching on a lot of "modern compiler" complexity which now also need to map to rust guarantees (but also have better save guards/visibility in Rust).
And async doesn't work so well with the bit by bit learning.
But in my personal experience if you don't have a team only consisting of senior C++ devs I would stay far away from C++. On the other hands with the right guidelines/limitations using rust with junior engineers is just fine (the guidelines matter to not get hangup on the wrong things or over-complicate things).
Complexity is not necessarily an automatic dealbreaker for a Rust language proposal—lots of Rust features are complicated because they solve problems that don't admit simple solutions—but the purpose of this particular feature is to make it easier to write code that uses reference-counted pointers and reduce how much stuff the programmer has to keep track of. It doesn't let you do anything you can't already do, it just makes it less clunky. So if people can't easily understand what it does, then that's bad.
As a side note, this might just be a me thing, but I distinguish between "complex" and "complicated". Certain things have an inherently complexity. Stripped to their essence, they're still going to have a lot of moving parts. It's just their nature. However, you can also add complication on top of something that makes it more complex than it needs to be to perform its function. Think "complication" in the watchmaker's sense. It might be neat to add a dial that shows the number of weeks since your last dentist appointment, but you don't really need that to have a functional wristwatch, and its presence makes the whole thing a lot more finicky and fragile than it would otherwise be.
Complexity is fine. Sometimes we're working on complex problems without simple, straightforward, correct solutions. I do try to avoid complications, though.
I find that Rust is a language that feels insurmountable when you examine it from a distance but once you get your hands dirty it feels natural very quickly.
Case in point, my first read on lifetimes just left me confused. So I used Rc<> everywhere and made a perfectly functional program. Picking up lifetimes after mastering the basics made it a lot easier. Most people won't even need to care about lightweight clones.
> Case in point, my first read on lifetimes just left me confused. So I used Rc<> everywhere and made a perfectly functional program.
Curious, did you run into lifetime issues or just started wrapping everything in Rc<> after reading about lifetimes? Wrapping everything in Rc<> isn't even a bad thing, that's what you have to when you do WASM in a browser.
I still find it confusing sometimes because you're not setting lifetime, you're just giving it a name so that the compiler can reason about it.
Like saying something 'static doesn't make it static, it supposed to mean "live until program closes", but you can totally create things with 'static and free them before program exits.
Pretty good observation. I think the getting to know Rust documentation should just start with this. Use forget about lifetimes and just use Rc<> when needed.
It is much more complex than C, sure. But it's so much simpler than C++ and you won't find yourself digging through the reference, or standard, or whatever to understand the code you are writing. It's very close to the sweet spot of "not complex enough to make you bald, not simple enough to make your code complex" while also making correctness the default.
Aside from the complexity not being possible to misuse (which is trivial in C++), I still find it easier. Moreover, even if you didn’t know about this if you use clippy it’ll suggest construct replacements that are more idiomatic. So even if you didn’t know about lightweight clones, you’ll get suggestions to leverage them once they’re available for your codebase (and you can apply the vast majority trivially by asking clippy to do it automatically via --fix). This is distinctly not a superpower c++ has and why the complexity of c++ keeps piling up with either no one using the new features or using them in unnecessarily complicated ways.
> This is distinctly not a superpower c++ has and why the complexity
I guess you don't have that much experience with actual C++ development? Because there's a plethora of static analysis tools and any serious IDE come with refactoring tools on top of that, both assistive and automated, that will suggest fixes as you type. Rust didn't invent anything with clippy, however good the tool might be...
I don't think Rust is very complex. What you're doing is very complex. It's just that doing it in C/C++ lulls you into a false sense of security.
C++ is incredibly complicated. I mean there's a 278 page book just on initialization [1].
I have seen all sorts of bad multithreaded code that compilers have let someone write. It would've been much harder in Rust but Rust would've forced you to be correct. As an example, I've seen a pool of locks for message delivery where the locks are locked on one thread and unlocked on another. This would get deadlocked every now and again so every half second or so a separate process would just release all the locks.
> Looking at the rust rfc for the lightweight clones feature
while the Use trait (a better name is proposed [1]) is useful, but I don't see how the .use syntax adds any value over .clone()? If the compiler is able to perform those optimizations, it can also lint and ask the user to remove the unnecessary .clone()/change x.clone() to &x. IMO this is better than the compiler doing black magic.
In my opinion, it's not just about the complexity of C++ vs Rust. It's how often the complexity (or anything else) can unpleasantly surprise you, and how serious the consequences of that surprise are.
The problem with C++'s complexity is that you have to remember all of it yourself and if you forget some of it... boom undefined behaviour and elusive runtime bugs!
Rust is definitely on the same order of magnitude of complexity, but you don't have to remember it all. Usually if you forget some complex rule and make a mistake, the compiler will tell you.
That's not true for unsafe Rust, but you rarely need unsafe Rust. Apart from FFI I have yet to use it at all and I've been writing Rust for years.
Async Rust is probably the closest it gets to C++'s "you didn't explicitly co_return in the context of a promise with no return_void? ok carry on but I'm going to crash sometimes! maybe just in release mode, on another OS".
there is currently a lot of ongoing discussions about "easier light weight clones" not just in the context of the RFC but in general.
And from all the discussions I have seen this RFC is one of the less promising ones as it mixes up the concept of "implicitly doing an operation before moving something into a closure scope" and "light weight clones" in a confusing ambiguous way.
So I don't expect it to be accepted/implemented this way, but I expect something similar to happen.
Like for "light weight clones" use is a pretty bad name and new syntax isn't needed, if we start shortening a `.clone()` to `.use` because it saves 4 letters then we are doing something wrong. Similar if argue for it for niche optimization reasons instead of improving generic optimizations to have the same outcome we are doing something wrong IMHO.
And for the the scoping/closure aspect (i.e. a rust equivalent of C++ closures `[]` parts (e.g. [&x](){...}) then it also seems a bad solution. First it's a operation which relates to the closure scope not the call inside of it, so attaching it to the call inside of it isn't a grate idea. Especially given that you might have multiple places you pass a clone of x in and this leading to a lot of ambiguity not highlighted with any examples in the RFC. Secondly for this concept it isn't limited to "cheap clones" sometimes you have the same pattern for not-so-cheap clones (through it mainly matters for cheap clones). And lastly if we really add ways to define captures, why not allow defining captures.
Now sure if you have a good solution for more compact way to handle "not-copy but still cheap" sharing (cloning of handles/smart pointers) of values there it maybe could make sense to also allow it to happen implicitly outside of closure capture scope instead of the invocation scope. But I would argue it's an extension of an not yet existing handle/smart pointer ergonomic improvement and should be done after that improvement.
(yes, I'm aware they use `use` because it's already a keyword, but making a non-zero cost copy of a handle/smart pointer isn't exactly "use it" but more like "share it" :/)
Rust is more complex than C, yes, but as someone who has used both professionally, it is not even close to being as complex as C++. In fact it is closer in complexity to C than to C++.
Perhaps you can help guide a C expert but C++ avoider (and super-avoider of Rust, so far): If C is 1 in complexity, where does C++ and Rust fall. By 'complexity' here I mean: the ability to keep the Entire Language in your head at the same time. C, although it does have complex corners, is -- mostly -- not overly complicated. (As you can probably tell, I prefer assembly, because it is the least complicated. You can build your own abstractions up, which is the proper way to use assembly). Thank you for any insight; I'm not wedded to my views when shown a Better Way.
As someone who’s dipped their toes in it, I’d say Rust is complicated in theory but not as complicated in practice. I said on a different topic that LLMs help a bit with suggestions and you can start with suboptimal code, improving it as you get more confident.
Obviously I’m not building anything production ready in it but it’s been useful for a few apps that I’d previously been using Python for.
> Yet people seem to like making useful things in it so it must have gotten something right.
I'm not commenting on Rust, seriously! But I couldn't help to notice that this sentence is a non sequitur. Something right has been developed in PHP and Visual Basic, even in Javascript and Go; still, those developers who freely choose to use those abominations, they do deserve to be pointed at and made fun of.
> Since the talks described in this article, the work on field projection has received an update. Lossin wrote in to inform LWN that all fields of all structures are now considered structurally pinned, so projecting a Pin will now always produce a Pin<&mut Field> or similar value.
Huh, I missed that part. It's a pretty technical point, but I'm happy they made the decision, it held up a lot of discussions.
> The Rust for Linux project has been good for Rust
i just decided do a good ol' 'find -name "*.rs"' in the kernel tree to get a sense for what all this is about. from what i can tell, there's just an api compatibility layer (found in /rust) and then a smattering of proof of concept drivers in tree that appear to just be simple rewrites of existing drivers (with the exception of the incomplete nvidia thing) that aren't even really in use. from what i can tell even the android binder rust rewrite is vestigial.
the whole thing seems kinda cute but like, shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
redox is a pretty cool experimental piece of software that might be the os of the future, why not do it there?
The gpu driver for Apple silicon is Rust and the author stated it would have been much more difficult to implement in C. It isn't upstreamed yet.
"""
Normally, when you write a brand new kernel driver as complicated as this one, trying to go from simple demo apps to a full desktop with multiple apps using the GPU concurrently ends up triggering all sorts of race conditions, memory leaks, use-after-free issues, and all kinds of badness.
But all that just… didn’t happen! I only had to fix a few logic bugs and one issue in the core of the memory management code, and then everything else just worked stably! Rust is truly magical! Its safety features mean that the design of the driver is guaranteed to be thread-safe and memory-safe as long as there are no issues in the few unsafe sections. It really guides you towards not just safe but good design.
"""
> the whole thing seems kinda cute but like, shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
Rustlang doesn't aim to address race conditions. Sounds to me like overly "cautious" inefficient code you can write in any language. Think using `std::shared_ptr` for everything in C++, perchance…?
i don't really care for mindless appeals to authority. make your own arguments and defend them or don't bother.
this gpu driver looks pretty cool though. looks like there's much more to the rust compatibility layer in the asahi tree and it is pretty cool that they were able to ship so quickly. i'd be curious how kernel rust compares to user space rust with respect to bloat. (user rust is pretty bad in that regard, imo)
> from what i can tell even the android binder rust rewrite is vestigial.
Vestigal how? The commit message in the version in Linus's tree (from commit eafedbc7c050c44744fbdf80bdf3315e860b7513 "rust_binder: add Rust Binder driver") makes it seem rather more complete:
> Rust binder passes all tests that validate the correctness of Binder in
the Android Open Source Project. We can boot a device, and run a variety
of apps and functionality without issues. We have performed this both on
the Cuttlefish Android emulator device, and on a Pixel 6 Pro.
> As for feature parity, Rust binder currently implements all features
that C binder supports, with the exception of some debugging facilities.
The missing debugging facilities will be added before we submit the Rust
implementation upstream.
----
> shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
Rust for Linux did start as an out-of-tree project. The thing is that no matter how much work you do out of tree if you're serious about trying integration out you'll have to pull in experimental support at some point - which is more or less what is happening now.
Before you can have complex drivers you need the interface layer that the drivers are built on. The RfL project works on that, upstreaming more infrastructure work until there's enough to submit a complex driver. Redhat is working on nova, asahi on the apple GPU, collabora is working on one for ARM Mali.
If 3 GPU drivers don't count as complex, real drivers then what does?
"Experiment" is a misnomer. Rust has been around long enough and demonstrated more than enough real advantages in writing reliable code that we know it's what we want to be doing.
The point of the project is not meant to be an experiment in "programming language co-development", the point of the project is to use Rust in Linux kernel development. The project was started by Linux kernel developers who want to use Rust. It's been a slow start, but as you say, it's the world's most important piece of software so progress has been careful and trying to get the foundations right before going crazy with it.
The fact that Rust gets to benefit from the project too is just an added bonus.
It's hard to view the relatively small scope of existing Rust code in the kernel at the present time as an indictment of the utility of Rust being used in the kernel when there are major kernel maintainers who have publicly stated that they have been doing everything in their power to block any amount of Rust code from getting merged into any part of the codebase.
> redox is a pretty cool experimental piece of software that might be the os of the future, why not do it there?
Because people want to use Rust where they use C, right now? Whereas yours is a perfectly fine criticism, it ignores that people want the good stuff, everywhere, in the things they actually use every day. And since this is something the project lead wants to do, this doesn't seem to problem/live issue.
> shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
The language co-development isn't unique to Rust. There are plenty of features in GCC and Clang that exist specifically for Kernel usage too.
> there's just an api compatibility layer (found in /rust)
Even figuring out what exactly the Linux kernel API safety rules are is a huge task, much less encoding them in a computer-readable form.
The code there is not about C<->Rust FFI. It's about encoding Linux kernel API properties into a safe Rust API.
The uncertainty of the calling/ordering rules is exactly why kernel C has been hard to write. For VFS locking rules, you pretty much have to simulate Al Viro's brain and replay his whole life experience...
> The final design, taking inspiration from C++, would be a form of guaranteed optimization, where constructing a new value and then immediately moving it to the heap causes it to be constructed on the heap in the first place.
Note that there's some discussion about the name of that proposal, because "optimization" gives the wrong idea (that it's optional or could depend on the backend).
I'm probably misunderstanding the complexity of the problem, but wouldn't this be solvable by just defining the right calling convention?
"Any structures larger than x, or any structures marked with a marker type, are returned by the caller providing an outref to a buffer with correct size, and the callee directly writes the structure into that buffer."
Then you could just write normal code like
fn initialize() -> A {
// the initialization code
}
and it would just work? And it would reduce unnecessary copies in a lot of other situations too?
Given how much work has been put into this issue, and how much less convenient the proposed solutions are, I feel like I must be missing something.
The missing piece is that it would still force you to make even larger types in many cases, such as `Result<Large, Error>`.
Essentially the problem is composability. If you are building a large type from a sequence of other large types, and one or more step is fallible, the normal return ABI breaks down very quickly.
Because constructors are really weird. Usually in Rust, when a struct is constructed, it already upholds all its invariants because construction is the "last" step in the initialization function. But with a C++-like constructor, it starts with a struct where all fields are in an invalid state, and then the struct's invariants are slowly established field by field. This is kinda impossible to square with Rust's safety promise. Even in safe languages like Java, there are often bugs when one calls other function from the constructor, that now observes the instance under construction violating its usual invariants. And this is also something Rust wants to avoid.
Everytime features are mentioned it makes me go: "it's all fun and games until someone puts tokio into the kernel", better yet if rust becomes complete enough and someone makes a direct composition renderer we could have entire applications that run entirely in the kernel which could be... interesting.
I was about to take offence at the use of “trivial” in this context. But then I noticed your handle, lol. You have the license to say that, thanks for your contributions!
Won't that be an eager runtime though? Breaking Rust's assumption that futures do nothing until polled? Unless you don't submit it to the queue until the poll call, I guess
I'm not sure if you're joking, but if not this is a fundamental misunderstanding of how Rust (and C) are used in the kernel.
Much like how you don't have the C stdlib when writing kernel code, Rust is used with the no_std option. You do not use cargo and do not have access to crates.
You'd likely have to rewrite half of tokio to use kernel level abstractions for things like sockets and everything else that interacts with the OS.
These seem like the first features that Rust in Linux bring to the Rust language that are not almost exclusively useful to the kernel. In my perception the focus on bringing features for the kernel has held up development in other parts of the language and the standard library.
As I understand it systems programming is the priority application area for Rust, and there are plenty of projects working on OSs, embedded or other bare-metal cases, as well as interoperability with complex C codebases.
At first glance, these features look quite general to me and not particularly tied to the kernel, they are important utilities for doing this kind of programming in the real world.
I see Rust's place on low level systems programming, for everything else on userspace compiled managed languages are a much better option, systems following an architecture like Self, Inferno or Android, so I don't see a big deal with these efforts focusing on low level C like capabilities.
> for everything else on userspace compiled managed languages are a much better option
As someone who's written a number of userspace applications in many languages as well as embedded firmwares running on bare metal, Rust is a rare gem that excels at both.
> for everything else on userspace compiled managed languages are a much better option
That might be true if you're developing a pure application [1], but not if you're writing a library. Have fun integrating a C# library in a Java program, a Java library in a C# program, or either of those in a Python, Node, C, C++, or Rust program. There's something to be said for not requiring a runtime.
[1] Unless you care about easy parallelization with statically guaranteed thread-safety. But hey, who needs this in the age of multicore CPUs?
All these features sound really awesome and would also benefit many non-kernel cases (especially generalized projections). Very happy to see Linux driving the language forward.
LLMs seem generally unsuited for the task, because they're fundamentally approximators that won't always get things right, and as a result will introduce subtle bugs. Perhaps if you paired them with some sort of formal methods... I'm not aware of anyone doing that. Tests aren't sufficient - lots of subtle bugs will not be caught by existing test suites.
To me as someone who's not learned either it looks like all the concepts and features of 'true' modern C++ (as opposed to C + a few extra features) spliced with the features and concepts of Haskell.
Yet people seem to like making useful things in it so it must have gotten something right. So I'll probably get around to attempting to really use it again.
[1]: https://github.com/joshtriplett/rfcs/blob/use/text/3680-use....
Asking as someone whose life became much easier after opting not do anything of the above and just write C in C++ ;-)
They are trying to fix it in recent ~10 years, but they are also adding new clever expert features at the same time, so I kinda see it as a lost cause.
Rust isn't doesn't have "that" much less complexity if you take all the stable (or worse unstable experimental) things it has.
What makes Rust so nice is nearly always(1) if you don't use a feature you don't have to know about it (not so in C++) and if you stumble about a feature you don't know it's not just normally syntax visible but if you use it wrongly it won't segfault or even have a RCE due to out of bounds writes or similar.
So for C++ you have to learn a lot of the stuff upfront, but are not forced to by the compiler, and getting it wrong can have catastrophic consequences.
But for Rust you can learn it (mostly) bit by bit.
It's not perfect, when you go unsafe you are touching on a lot of "modern compiler" complexity which now also need to map to rust guarantees (but also have better save guards/visibility in Rust).
And async doesn't work so well with the bit by bit learning.
But in my personal experience if you don't have a team only consisting of senior C++ devs I would stay far away from C++. On the other hands with the right guidelines/limitations using rust with junior engineers is just fine (the guidelines matter to not get hangup on the wrong things or over-complicate things).
Complexity is not necessarily an automatic dealbreaker for a Rust language proposal—lots of Rust features are complicated because they solve problems that don't admit simple solutions—but the purpose of this particular feature is to make it easier to write code that uses reference-counted pointers and reduce how much stuff the programmer has to keep track of. It doesn't let you do anything you can't already do, it just makes it less clunky. So if people can't easily understand what it does, then that's bad.
Complexity is fine. Sometimes we're working on complex problems without simple, straightforward, correct solutions. I do try to avoid complications, though.
Case in point, my first read on lifetimes just left me confused. So I used Rc<> everywhere and made a perfectly functional program. Picking up lifetimes after mastering the basics made it a lot easier. Most people won't even need to care about lightweight clones.
Curious, did you run into lifetime issues or just started wrapping everything in Rc<> after reading about lifetimes? Wrapping everything in Rc<> isn't even a bad thing, that's what you have to when you do WASM in a browser.
I still find it confusing sometimes because you're not setting lifetime, you're just giving it a name so that the compiler can reason about it.
Like saying something 'static doesn't make it static, it supposed to mean "live until program closes", but you can totally create things with 'static and free them before program exits.
I guess you don't have that much experience with actual C++ development? Because there's a plethora of static analysis tools and any serious IDE come with refactoring tools on top of that, both assistive and automated, that will suggest fixes as you type. Rust didn't invent anything with clippy, however good the tool might be...
C++ is incredibly complicated. I mean there's a 278 page book just on initialization [1].
I have seen all sorts of bad multithreaded code that compilers have let someone write. It would've been much harder in Rust but Rust would've forced you to be correct. As an example, I've seen a pool of locks for message delivery where the locks are locked on one thread and unlocked on another. This would get deadlocked every now and again so every half second or so a separate process would just release all the locks.
[1]: https://leanpub.com/cppinitbook
while the Use trait (a better name is proposed [1]) is useful, but I don't see how the .use syntax adds any value over .clone()? If the compiler is able to perform those optimizations, it can also lint and ask the user to remove the unnecessary .clone()/change x.clone() to &x. IMO this is better than the compiler doing black magic.
[1]: https://smallcultfollowing.com/babysteps/blog/2025/10/07/the...
Rust is definitely on the same order of magnitude of complexity, but you don't have to remember it all. Usually if you forget some complex rule and make a mistake, the compiler will tell you.
That's not true for unsafe Rust, but you rarely need unsafe Rust. Apart from FFI I have yet to use it at all and I've been writing Rust for years.
Async Rust is probably the closest it gets to C++'s "you didn't explicitly co_return in the context of a promise with no return_void? ok carry on but I'm going to crash sometimes! maybe just in release mode, on another OS".
https://smallcultfollowing.com/babysteps/blog/2025/10/07/the...
And from all the discussions I have seen this RFC is one of the less promising ones as it mixes up the concept of "implicitly doing an operation before moving something into a closure scope" and "light weight clones" in a confusing ambiguous way.
So I don't expect it to be accepted/implemented this way, but I expect something similar to happen.
Like for "light weight clones" use is a pretty bad name and new syntax isn't needed, if we start shortening a `.clone()` to `.use` because it saves 4 letters then we are doing something wrong. Similar if argue for it for niche optimization reasons instead of improving generic optimizations to have the same outcome we are doing something wrong IMHO.
And for the the scoping/closure aspect (i.e. a rust equivalent of C++ closures `[]` parts (e.g. [&x](){...}) then it also seems a bad solution. First it's a operation which relates to the closure scope not the call inside of it, so attaching it to the call inside of it isn't a grate idea. Especially given that you might have multiple places you pass a clone of x in and this leading to a lot of ambiguity not highlighted with any examples in the RFC. Secondly for this concept it isn't limited to "cheap clones" sometimes you have the same pattern for not-so-cheap clones (through it mainly matters for cheap clones). And lastly if we really add ways to define captures, why not allow defining captures.
Now sure if you have a good solution for more compact way to handle "not-copy but still cheap" sharing (cloning of handles/smart pointers) of values there it maybe could make sense to also allow it to happen implicitly outside of closure capture scope instead of the invocation scope. But I would argue it's an extension of an not yet existing handle/smart pointer ergonomic improvement and should be done after that improvement.
(yes, I'm aware they use `use` because it's already a keyword, but making a non-zero cost copy of a handle/smart pointer isn't exactly "use it" but more like "share it" :/)
Obviously I’m not building anything production ready in it but it’s been useful for a few apps that I’d previously been using Python for.
I'm not commenting on Rust, seriously! But I couldn't help to notice that this sentence is a non sequitur. Something right has been developed in PHP and Visual Basic, even in Javascript and Go; still, those developers who freely choose to use those abominations, they do deserve to be pointed at and made fun of.
Huh, I missed that part. It's a pretty technical point, but I'm happy they made the decision, it held up a lot of discussions.
i just decided do a good ol' 'find -name "*.rs"' in the kernel tree to get a sense for what all this is about. from what i can tell, there's just an api compatibility layer (found in /rust) and then a smattering of proof of concept drivers in tree that appear to just be simple rewrites of existing drivers (with the exception of the incomplete nvidia thing) that aren't even really in use. from what i can tell even the android binder rust rewrite is vestigial.
the whole thing seems kinda cute but like, shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
redox is a pretty cool experimental piece of software that might be the os of the future, why not do it there?
""" Normally, when you write a brand new kernel driver as complicated as this one, trying to go from simple demo apps to a full desktop with multiple apps using the GPU concurrently ends up triggering all sorts of race conditions, memory leaks, use-after-free issues, and all kinds of badness.
But all that just… didn’t happen! I only had to fix a few logic bugs and one issue in the core of the memory management code, and then everything else just worked stably! Rust is truly magical! Its safety features mean that the design of the driver is guaranteed to be thread-safe and memory-safe as long as there are no issues in the few unsafe sections. It really guides you towards not just safe but good design. """
https://asahilinux.org/2022/11/tales-of-the-m1-gpu/
> the whole thing seems kinda cute but like, shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
Torvalds seems to disagree with you.
Speaking seriously, they surely meant data races, right? If so, what's preventing me from using C++ atomics to achieve the same thing?
i don't really care for mindless appeals to authority. make your own arguments and defend them or don't bother.
this gpu driver looks pretty cool though. looks like there's much more to the rust compatibility layer in the asahi tree and it is pretty cool that they were able to ship so quickly. i'd be curious how kernel rust compares to user space rust with respect to bloat. (user rust is pretty bad in that regard, imo)
This is incorrect. The android binder rust rewrite is planned to wholly replace the current C implementation.
https://www.phoronix.com/news/Rust-Binder-For-Linux-6.18
And most of the big drivers written for Apple M-series hardware are written in Rust, those are not simple rewrites or proof of concepts.
Vestigal how? The commit message in the version in Linus's tree (from commit eafedbc7c050c44744fbdf80bdf3315e860b7513 "rust_binder: add Rust Binder driver") makes it seem rather more complete:
> Rust binder passes all tests that validate the correctness of Binder in the Android Open Source Project. We can boot a device, and run a variety of apps and functionality without issues. We have performed this both on the Cuttlefish Android emulator device, and on a Pixel 6 Pro.
> As for feature parity, Rust binder currently implements all features that C binder supports, with the exception of some debugging facilities. The missing debugging facilities will be added before we submit the Rust implementation upstream.
----
> shouldn't this experiment in programming language co-development be taking place somewhere other than the source tree for the world's most important piece of software?
Rust for Linux did start as an out-of-tree project. The thing is that no matter how much work you do out of tree if you're serious about trying integration out you'll have to pull in experimental support at some point - which is more or less what is happening now.
The fact that Rust gets to benefit from the project too is just an added bonus.
Because people want to use Rust where they use C, right now? Whereas yours is a perfectly fine criticism, it ignores that people want the good stuff, everywhere, in the things they actually use every day. And since this is something the project lead wants to do, this doesn't seem to problem/live issue.
The language co-development isn't unique to Rust. There are plenty of features in GCC and Clang that exist specifically for Kernel usage too.
Even figuring out what exactly the Linux kernel API safety rules are is a huge task, much less encoding them in a computer-readable form.
The code there is not about C<->Rust FFI. It's about encoding Linux kernel API properties into a safe Rust API.
The uncertainty of the calling/ordering rules is exactly why kernel C has been hard to write. For VFS locking rules, you pretty much have to simulate Al Viro's brain and replay his whole life experience...
Since this is a Git repo, I'd go with `git ls-files '
.rs'`.That’s an interesting idea. You should let this guy know you disagree with his technical decision -> torvalds@linux-foundation.org
Note that there's some discussion about the name of that proposal, because "optimization" gives the wrong idea (that it's optional or could depend on the backend).
"Any structures larger than x, or any structures marked with a marker type, are returned by the caller providing an outref to a buffer with correct size, and the callee directly writes the structure into that buffer."
Then you could just write normal code like
and it would just work? And it would reduce unnecessary copies in a lot of other situations too? Given how much work has been put into this issue, and how much less convenient the proposed solutions are, I feel like I must be missing something.Essentially the problem is composability. If you are building a large type from a sequence of other large types, and one or more step is fallible, the normal return ABI breaks down very quickly.
Much like how you don't have the C stdlib when writing kernel code, Rust is used with the no_std option. You do not use cargo and do not have access to crates.
You'd likely have to rewrite half of tokio to use kernel level abstractions for things like sockets and everything else that interacts with the OS.
At first glance, these features look quite general to me and not particularly tied to the kernel, they are important utilities for doing this kind of programming in the real world.
Philopp has been a particular force for change in this area.
As someone who's written a number of userspace applications in many languages as well as embedded firmwares running on bare metal, Rust is a rare gem that excels at both.
Except for thread safety.
That might be true if you're developing a pure application [1], but not if you're writing a library. Have fun integrating a C# library in a Java program, a Java library in a C# program, or either of those in a Python, Node, C, C++, or Rust program. There's something to be said for not requiring a runtime.
[1] Unless you care about easy parallelization with statically guaranteed thread-safety. But hey, who needs this in the age of multicore CPUs?
Ask LLM to generate rust code from chat, usb, i2c, GPU drivers - build and test it automatically? Possible?
Or start with other "smaller" projects such as sqlite, apache, nginx, etc - possible?
LLMs seem generally unsuited for the task, because they're fundamentally approximators that won't always get things right, and as a result will introduce subtle bugs. Perhaps if you paired them with some sort of formal methods... I'm not aware of anyone doing that. Tests aren't sufficient - lots of subtle bugs will not be caught by existing test suites.
Your idea of "smaller" projects is not... smaller enough. See the actual success stories for example: https://github.com/immunant/c2rust?tab=readme-ov-file#uses-o...