[HN Gopher] Upcoming Rust language features for kernel development
___________________________________________________________________
Upcoming Rust language features for kernel development
Author : pykello
Score : 302 points
Date : 2025-10-16 06:12 UTC (16 hours ago)
(HTM) web link (lwn.net)
(TXT) w3m dump (lwn.net)
| hannesfur wrote:
| 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.
| oersted wrote:
| 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.
| heavyset_go wrote:
| What's the story with C interop now with these and related
| changes? I'm out of the loop.
| muvlon wrote:
| C interop is excellent and has been for years. The one
| piece that still needs unstable is defining/exposing
| varargs functions (support for _calling_ them was
| stabilized many years ago). You can write almost anything
| you can write in C in (partly unsafe) Rust, in fact there
| are projects like c2rust that automate this translation.
|
| These new features are all about making things that the
| kernel devs need possible in _safe_ Rust. This often
| requires support for some quite fancy abstractions, some of
| which cannot be expressed in current stable Rust.
| Foxboron wrote:
| > C interop is excellent and has been for years.
|
| Only if you primarily work with `cargo` and want to
| interact with C from Rust. The other way around has far
| less support and `rustc` does not standardize the object
| generation. This is actively preventing projects like
| `systemd` to adopt Rust into their project as an example.
|
| https://github.com/systemd/systemd/pull/19598
| aw1621107 wrote:
| > Only if you primarily work with `cargo` and want to
| interact with C from Rust.
|
| In what way(s) does Rust's C interop depend on cargo?
|
| > The other way around has far less support and `rustc`
| does not standardize the object generation.
|
| I believe in this context the understanding is that
| you're going to be using `extern "C"` and/or `#[repr(C)]`
| in your Rust code, which gives you a plain C interface. I
| think attempting to use "raw" Rust code from other
| languages is a rare phenomenon, if it's even attempted at
| all.
|
| > This is actively preventing projects like `systemd` to
| adopt Rust into their project as an example.
|
| Could you point out specific instances from that thread?
| From a quick glance I didn't see any obvious instances of
| someone saying that using Rust from C is problematic.
| humanrebar wrote:
| > In what way(s) does Rust's C interop depend on cargo?
|
| Do rust and cargo allow for multiple interpretations of
| the same C header file across different objects in the
| same program? That's how C libraries are often
| implemented in practice due to preprocessor tricks,
| though I wish it wasn't normal to do this sort of thing.
| nicoburns wrote:
| I would expect so. Rust and Cargo don't consume C header
| files directly at all. They consume bindings generated by
| bindgen (or hand written if you prefer). So you could
| probably generate mulitple bindings if you needed
| multiple interpretations of a C header.
|
| If the header files are consumed by C code that is then
| consumed by Rust then you'll have full support for what C
| supports because it will be compiled by a C compiler.
| steveklabnik wrote:
| Rust and Cargo do not build C programs, so, the answer to
| that is "no", strictly speaking.
|
| However, some people use cargo's build scripts to build c
| programs, which then you can link into your Rust program.
| Support would then depend on whatever the person wrote
| with the script, which in my experience usually delegates
| to whatever build system that project uses. So it should
| work fine.
| DaanDeMeyer wrote:
| https://github.com/rust-lang/rust/issues/73632 needs to
| be addressed and then integrated into meson before
| systemd could consider adopting rust.
| namr2000 wrote:
| I have to disagree here a little bit. Calling C functions
| from Rust is a very pleasant experience, but the other
| way around is not so nice. You usually have to manually
| create types that will unpack rust collections into C
| compatible structures (think decomposing `Vec` into ptr,
| len, capacity) & then ensure that memory passed between
| the two sides is free'd with the appropriate allocator.
| Even with `cbindgen` taking care of the mindless
| conversions for you, you still have to put a lot of
| thought into the API between the two languages.
|
| I am currently working on a fairly involved C & Rust
| embedded systems project and getting the inter-language
| interface stable and memory-leak free took a good amount
| of effort. It probably didn't help that I don't have
| access to valgrind or gdb on this platform.
| aw1621107 wrote:
| I feel this might come down to the scope one has in mind
| when thinking of the word "interop". I think one can
| reasonably simultaneously claim that the interop
| "mechanics" are excellent in that it's generally possible
| to create a Rust library that quacks like a C library and
| that basically any C library is usable by Rust code, but
| the interop "ergonomics" are suboptimal in that (as you
| say) actually writing the glue code can be a bit of an
| adventure.
| namr2000 wrote:
| I think that's a fair assessment. To your point
| `cbindgen` makes the mechanics of the whole thing
| painless & linking was trivial. That's worth a lot
| especially when compared to other languages.
| 3836293648 wrote:
| It's C++ that is problematic, C has been easy for years
| cyphar wrote:
| Calling C code from Rust? Pretty nice.
|
| Writing Rust code to be called from C (but within the same
| application)? Doable but somewhat painful.
|
| Writing Rust code to act like a C shared library? Quite
| painful and some pretty important features are missing
| (proper symbol versioning support being the most obvious
| one). Theoretically doable if you're willing to compromise.
|
| There's also some aspects of FFI-safety that are very
| subtle and easy to mess up: * #[repr(C)]
| enums still have the same requirements as Rust enums and so
| C callers can easily trigger UB, so you need to use
| something like open_enum. Thankfully cbindgen is too dumb
| to know that #[open_enum] is a proc macro and produces a
| non-enum type. * Before io_safety in Rust 1.63,
| dealing with file descriptors from C without accidentally
| closing them was horrific (though this was a wider problem
| in Rust). BorrowedFd is quite nice -- though Rustix will
| panic if you use negative fds and so you need to add
| validation and your own type in practice. However,
| #[repr(transparent)] is very nice for this. * Lots of
| reading about unsafe Rust is necessary when doing most non-
| trivial things with C FFI. * You need to make use of
| a lot of compiler internals, build scripts, and other magic
| to get the output you want. * Tools like cargo-c and
| cbindgen are nice and probably work great for 80% of
| projects, but the 20% really suffer from no useful tooling.
| I haven't tried to use rustc directly to work around some
| of the remaining issues, but I suspect it'd be even more
| painful.
|
| I would say that the C interop with Rust is pretty good but
| it has lots of room for improvement and it feels like very
| few resources have been spent on it after they got the core
| stuff working.
|
| Source: I've been writing a Rust library intended to be
| used primarily via C FFI and run into a lot of issues...
| pjmlp wrote:
| 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.
| timschmidt wrote:
| > 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.
| pjmlp wrote:
| Only if those userspace applications are headless, Rust
| exceling at GUIs is a bit of a strech.
| timschmidt wrote:
| Well https://github.com/timschmidt/egui-rad-builder has
| come together rather well in the last week of hacking, if
| I say so myself. I think building a similar app with QT,
| for example, would have been significantly more
| challenging.
|
| I'm particularly fond of how easy it was to make all the
| controls live in the editor, and editable with changes
| appearing immediately. imgui would probably provide a
| similar experience, but I find C++ much more of a pain to
| work with than Rust.
| mdhb wrote:
| But that's no longer the choice you need to make. Ubuntu
| themselves have said for a couple of years now that every
| new GUI app they make natively for Linux is going to be
| Flutter and dedicated a bunch of engineers to the project
| to make sure it's a first class citizen.
|
| Beyond that, Dart / Futter are truly an absolute pleasure
| to use for that use case.
| timschmidt wrote:
| Sounds great for the Dart people. But unrelated to
| correcting misinformation about Rust. I'm not opposed to
| whatever language folks want to use. Just out here
| hacking in Rust because it suits my particular needs. And
| finding that it's enjoyable to hack GUIs as well as
| firmwares in.
| mdhb wrote:
| No I get all that, but to the parent comments point
| however, there's no way in hell I would ever pretend for
| a moment that one is as straightforward as the other and
| it's no longer a choice between Rust and C++ both of
| which add a lot of complexity to a scenario where it
| offers very little benefit.
| timschmidt wrote:
| Over the years, I've found that the complexity is there
| whether or not it's been papered over by a runtime. It's
| wonderful to forget about, until it's not. Some
| applications may never run into the limitations imposed
| by abstracting it away, but others run into them quickly.
|
| "There ain't no such thing as a free lunch" as the saying
| goes.
| mdhb wrote:
| To which the counter argument I guess would be.. there's
| no sense in trying to solve for some abstract future set
| of problems that the vast majority of people are never
| going to have ahead of time on the off chance you're one
| of them.
|
| That too requires a substantial investment of time and
| resources.
|
| I think in a more pragmatic sense too that you can form a
| very good understanding on if you're going to have weird
| special requirements just from looking at what others
| have done with the same tools in similar situations
| before you.
| timschmidt wrote:
| > there's no sense in trying to solve for some abstract
| future set of problems that the vast majority of people
| are never going to have
|
| > That too requires a substantial investment of time and
| resources.
|
| The discussion has gotten to be pretty abstract at this
| point. To get back to concrete examples, the egui RAD
| builder I've been hacking on worked on day 1, first
| commit. It's been a joy to put together, and no more
| difficult than building GUI apps with any other toolkit
| I've worked with. Which causes me to question your
| statements about additional complexity. You can dig deep
| and do dark magic with Rust if you want, but you can also
| treat it like any high level language and get things done
| quickly. That's part of what makes it a rare gem to me.
|
| Some folks don't like dealing with strict types, or with
| the borrow checker, but I find that the errors they
| illuminate for me would have been similarly serious in
| other languages which lacked the tooling to highlight
| them. Which adds to my appreciation of Rust.
| johnisgood wrote:
| Yeah, I do not know Dart / Flutter much, but if I had to
| choose, I would either pick that, or wxWidgets, or even
| Tcl/Tk, but not Rust.
| pjmlp wrote:
| How does it handle localization and assistive
| technologies, UI/UX tooling for designers, 3rd party
| component ecosystem?
| timschmidt wrote:
| egui works with AccessKit to provide accessibility
| support. I haven't added anything explicitly to the RAD
| builder for it yet. Great idea!
| ogoffart wrote:
| Regarding Rust GUI framework, there is also Slint
| https://slint.dev
|
| (Disclaimer: I'm one of the Slint developers.)
| timschmidt wrote:
| I looked at Slint a couple years ago when I was
| evaluating UI toolkits. Looks slick! The only thing that
| turned me off was needing an additional DSL to define
| UIs. Trying to learn fewer languages, more deeply, these
| days. Is it possible to use Slint without the DSL?
| ogoffart wrote:
| Slint does require using its DSL to define UIs, but I'd
| argue it's not really like learning a whole new language.
| It's not harder than learning the API surface of any
| other GUI framework.
|
| I actually wrote a blog post about this exact topic,
| since it's a common question:
| https://slint.dev/blog/domain-specific-language-vs-
| imperativ...
| timschmidt wrote:
| I appreciate the answer, and you taking time to write up
| your thoughts on it. Your point about the GUI builder
| working with the DSL is noted. In the egui RAD builder, I
| am manipulating structs which describe the UI (and which
| can be exported / imported as JSON) prior to code
| generation, which amounts to something similar. I still
| feel I have to context switch less, the back-and-forth is
| of more concern to me than learning an additional
| language.
|
| That said, great work! There's plenty of room in the
| language for more than one solution!
| onionisafruit wrote:
| That's a compelling post. You drew me in by calling SQL a
| DSL. You're right, but if you asked me to list the DSLs I
| use regularly I never would have thought of SQL until
| now. My thinking was too uptight because I didn't
| consider the "domain" in DSL could be something as big as
| querying structured data. That makes me wonder if Rust is
| a DSL for the domain of general computing (obviously not
| in the usual intended meaning of DSL).
|
| Like the person you're replying to, I am generally averse
| to DSLs where the domain is a single project because I
| associate them with previous bad experiences where I
| spent time learning only to find it totally misses the
| mark. There's also the issue of software where I'm the
| sole maintainer and look at it rarely. If it's the only
| place I use Slint, then I'm going to be worried that I
| need to relearn the DSL in three months when I want to
| tweak the UI. Although you can probably say the same
| about any non-trivial framework's API whether or not it
| uses a DSL.
|
| All that said, I'll be a bit more open to DSLs after
| reading your post, and if I ever need to write a GUI in
| Rust I'll give Slint a shot (although that seems unlikely
| since I don't typically write Rust or GUIs).
| codedokode wrote:
| I don't think the DSL is any good. It looks weird (like a
| mix of CSS and classes), and it has a side effect of
| locking the user to a specific product.
|
| In your article, you mention that an imperative code in
| Rust looks more complicated, but this can be fixed by
| adding an "object tree" syntax to Rust, that allows
| creating trees of objects and link them like this:
| VBox margin=10: Label text=label_text
| Button label="OK" onclick=on_ok_clicked
|
| This syntax could be used not only for UI, but for
| describing configuration, database tables and many other
| things. I think it would be better solution than a
| proprietary language.
|
| Also I think it would be better if GUI could be drawn in
| the editor, it would allow to use lower paid developers
| without expensive computer science education for making
| UI.
| izacus wrote:
| One week of hacking makes every library look good, but
| have you shipped actual product that other people widely
| use with Rust GUI yet? What was the experience there and
| - most importantly - what were the downsides?
| timschmidt wrote:
| I've been working with egui for a couple years. Written
| maybe a dozen applications with it doing various things
| from image manipulation to 3D graphics. As I've said
| elsewhere in the thread, I haven't run into anything I
| wasn't able to accomplish with it.
|
| Immediate mode has it's detractors, but in practice I've
| found it remarkably flexible, the resulting code
| relatively clean, and egui gets out of the way when I
| want to do something like blit fast graphics to a memory
| mapped area of the screen. Responses have been positive.
| cosmic_cheese wrote:
| Indeed. Last I knew all the Rust UI libraries were
| declarative and/or immediate mode, both of which have
| their place but I'm not convinced that they're suitable
| in all situations. Sometimes you need a boring "old
| style" imperative UI framework with deep toolbox of
| capable widgets (think AppKit, win32, etc), but that's
| notably absent in the Rust world.
| timschmidt wrote:
| https://www.gpui.rs/ is a relatively new entrant which is
| described as "hybrid immediate and retained mode". Maybe
| worth checking out for your use cases.
|
| Immediate mode was certainly a different paradigm to wrap
| my head around, but so far I haven't found anything I
| couldn't accomplish with egui, including some fairly
| complex applications like
| https://timschmidt.github.io/alumina-interface/
| timeon wrote:
| How far from "old style" is Slint?
| cosmic_cheese wrote:
| From a quick glance, about as far as the other Rust
| toolkits. Looks declarative with with a relatively small
| number of more basic widgets (a lot of custom widget code
| is necessary), as opposed to e.g. AppKit which is
| imperative and comes with a great number of rich widgets
| that are ready to use out of the box.
| IshKebab wrote:
| Sure, but that's true of basically every language except
| maybe C++, C#, Javascript/Typescript and Dart.
|
| GUIs are incredibly hard and most languages _never_ get
| high quality GUI libraries. Rust is still pretty young
| and a ton of people are working on the problem so that
| will definitely change.
| afishhh wrote:
| > Rust exceling at GUIs is a bit of a strech.
|
| I strongly agree with this. In particular the Rust GUI
| libraries I've looked at have text layout / rendering
| that is nowhere near what should be considered adequate
| today (imo).
|
| For example egui:
|
| - It doesn't do any bidi reordering.
|
| - It also doesn't do any font fallback so even if you
| didn't need bidi you can't render many languages without
| first acquiring an appropriate font somehow.
|
| - Complex shaping is nowhere to be seen either.
|
| - egui's italics look really terrible and I'm not sure
| why since I can't believe even synthesized ones have to
| look that bad.
|
| CSS has been doing this for years and it's been doing it
| very well. So I am kind of disappointed that we don't
| have equally powerful tools in the general Rust
| ecosystem. Even just considering text layout / rendering
| libraries, only `cosmic-text` has an API that is somewhat
| in the right direction[1], but even it fails simply
| because I don't see a way to insert a button (block
| element) in-between the text[2].
|
| Note that I'm not just hating on egui here, egui is
| amazing. Afaict it is the most complete GUI library for
| Rust and it's great to be able to make GUIs this easily.
| However I can't just not point out that it is, in fact,
| not perfect and doesn't truly "excel" at GUIs.
|
| Also I have no idea how inline layout looks in other
| established GUI libraries like GTK and Qt so maybe I'm
| complaining about something that is not available most
| places outside a browser. If anyone knows, it would be
| interesting to learn how well they compare here.
|
| [1] CSS inline layout is so complex that even this is a
| decent achievement, since it is not reasonable to expect
| most CSS features out of new Rust libraries with a
| significant time disadvantage.
|
| [2] This is non-trivial because bidi reordering should
| happen on the whole paragraph not only on both sides of
| the button, so the inline layout API must handle non-text
| blocks in text.
| timschmidt wrote:
| This is a detail oriented list of real issues, which is
| wonderful! ChatGPT found open issues in the egui Github
| for each of your problems, so they're known about and
| being worked on.
|
| However, it seems like most of the other UI toolkits
| discussed here, even in other languages, suffer similar
| issues. Which points to the difficulty of the problems.
| Consequently, I don't have any problem praising egui and
| Rust alongside. They're great! And even great can always
| get better! :)
| mamcx wrote:
| > Rust exceling at GUIs is a bit of a strech.
|
| BTW, this happens to almost all languages. Which ACTUAL
| good GUIs toolkits _exist_? And which ACTUAL languages
| HAVE good integration or implementation of them?
|
| A good GUI kit AND integration is a bigger task than do a
| Os or a RDBMS. (And neither are many _good_ languages for
| RDBMS)
| 0x457 wrote:
| Depends on your definition of good.
|
| I think Swift (and even ObjC) is perfect for AppKit &
| UIKit. I think those frameworks are pretty good and I
| like using them. Languages have great integration, Swift
| literally made around them. Those toolkits have great
| integrations with the macOS.
|
| I find C# a pretty nice language for GUI, I assume it has
| good (maybe not great) integration with at least one of
| MS GUI toolkits.
|
| I find Rust good for GUI, but right now story is meh.
| Wrapper style frameworks always suffer from Rust not
| being whatever it wraps. Pure Rust framework miss a lot
| of features compared to wrapper frameworks.
| anarki8 wrote:
| I wouldn't say it's bad at GUIs either. There are some
| nice libraries like Iced and Slint. Some even have good
| accessibility support like egui.
|
| There is a full-fledged DE written in Rust that uses
| Iced: https://en.wikipedia.org/wiki/COSMIC_(desktop_envir
| onment)
| WD-42 wrote:
| The GTK bindings are fine.
| discreteevent wrote:
| > Rust is a rare gem that excels at both.
|
| This can be true but it can still be the case that a
| managed language is even better at one of them.
| timeon wrote:
| > for everything else on userspace compiled managed languages
| are a much better option
|
| Except for thread safety.
| pjmlp wrote:
| Fearless concurrency, is only fearless for a very fine
| grained version of it.
|
| In memory resources shared among threads.
|
| Turns out threads also may share resources like out-of-
| process files, memory mapped regions, shared memory,
| databases, distributed transactions,.... where the Send and
| Sync traits is of no help.
|
| Also you happen to forget Haskell has a Software
| Transactional Memory, and Swift also has similar protocols
| since version 6, and effects are a thing in OCaml, Scala,
| Koka, while languages like Dafny, Koka and Idris also
| provide similar capabilities via proofs.
| okanat wrote:
| That's why everybody who cares about OS safety should
| invest into capability-based operating systems. They take
| the concept of Send and Sync and implement at the runtime
| of the entire computer.
| adwn wrote:
| > _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?
| pjmlp wrote:
| OS IPC exists for a reason, aren't microservices all the
| rage nowadays, and Plan 9 rules?
| adwn wrote:
| > _OS IPC exists for a reason_
|
| Message-passing IPC is much, much slower and less
| efficient than shared-memory communication, and inter-
| process IPC (both message-passing and shared-memory) is
| much less convenient than intra-process multi-threading.
| Rust is the only mainstream language, managed or
| otherwise, which enables safe _and_ efficient multi-
| threading.
| pjmlp wrote:
| Not at all, because as I explain on another sibiling
| answer, it is only safe if we cut down the use cases to a
| very specific one that helps to sell that narrative.
| adwn wrote:
| This one?
|
| > _Turns out threads also may share resources like out-
| of-process files, memory mapped regions, shared memory,
| databases, distributed transactions_
|
| For multi-threaded parallelization, -
| out-of-process files - databases -
| distributed transactions
|
| aren't really relevant, and Rust directly helps with the
| other two aspects: - memory mapped
| regions - shared memory
|
| In practice, your _" very specific"_ aspect is the most
| important one, and the hardest to get right without
| Rust's Send and Sync traits and their automatic
| enforcement.
| pjmlp wrote:
| Who gets to say what is relevant is the architect driving
| the project implementation.
|
| > aren't really relevant, and Rust directly helps with
| the other two aspects:
|
| Not at all, because Rust code has nothing to say about
| what other processes do to those resources, the only
| thing you can do is wrap accesses in a unsafe code block
| and hope for the best, that nothing was corrupted.
| adwn wrote:
| I think you're confusing _concurrency_ with
| _parallelism_. I 've been talking about _parallelization_
| since my first comment in this thread. There 's some
| overlap, yes, but the aspects you listed have typically
| very little to do with parallelization, which is why I
| called them "[not] really relevant". And where they _do_
| matter to multi-threading (the shared memory part), Rust
| _does_ help with correctness.
| pdimitar wrote:
| Eh, modern OS-es indeed have loads of problems still, of
| which non-transactional access to the filesystem is in my
| top three, but to put those problems on Rust is a bit
| uncharitable. It's not Rust's fault that zero kernel devs
| have the courage to finally start enforcing patterns that
| have proven themselves useful and safe for decades, in
| other areas outside of IT as well (i.e. in financial
| accounting).
|
| Rust plucks the fruit it can reach and it mostly stays in
| its lane and it's trying to expand it here and there
| (like Rust in Linux and embedded). I too want one
| ultimate language and one ultimate kernel but I don't
| think you and I will live to see it. Maybe our
| grandchildren will not as well.
| junon wrote:
| There are a lot of features being added for kernel/firmware
| development, they're just not on everyone's radar.
|
| Philopp has been a particular force for change in this area.
| PoignardAzur wrote:
| > _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.
| PoignardAzur wrote:
| > _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).
| dapperdrake wrote:
| How does "coalesced heap construction" or "coalesced heap
| allocation"?
| Tuna-Fish wrote:
| 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.
| simonask wrote:
| 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.
| sesm wrote:
| Why make this a behind-the-scene optimization instead of just
| introducing `new`? That would make things much more clear for
| everyone.
| jojomodding wrote:
| 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.
| zozbot234 wrote:
| > 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.
|
| AIUI, that's why MaybeUninit<T> exists. But even if you
| address the issue of it being unsafe to assert that a
| MaybeUninit has been initialized (which &out references
| could in principle solve) there are real problems with
| this; for example, MaybeUninit<T> has no niches or free-
| for-use padding even when T does, so you can't just
| "project" MaybeUninit to individual fields except in
| special cases. My understanding is that C++ partial
| initialization has the exact same issues in principle, they
| just don't come up as often because the standard for code
| correctness is a lot less rigorous.
| Maxatar wrote:
| C++ uses the term elision for these kinds of semantics.
| kachapopopow wrote:
| 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.
| aliceryhl wrote:
| It's trivial to implement an async runtime in the kernel. The
| kernel's workqueue is already essentially a runtime.
| jgilias wrote:
| 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!
| seabrookmx wrote:
| 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.
| Jweb_Guru wrote:
| 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.
| a-dub wrote:
| > 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?
| dmm wrote:
| 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. """
|
| 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.
| remix2000 wrote:
| 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...?
| tobz1000 wrote:
| The comment probably refers to data races over memory
| access, which are prevented by usage of `Send` and `Sync`
| traits, rather than more general race conditions.
| remix2000 wrote:
| I see, but that's not the point of my comment. I don't
| know rustlang, perhaps I could address that if someone
| translated the rust-specific parlance to more generally
| accepted terms.
| jdub wrote:
| a data race is specific kind of race condition; it's not
| rust parlance, but that specificity comes up a lot in
| rust discussions because that's part of the value
| remix2000 wrote:
| I meant the trait send sync things. I just thought it was
| obvious, since Rust is not the only language susceptible
| to data races.
| masklinn wrote:
| > since Rust is not the only language susceptible to data
| races.
|
| The point is rather that it's not. The "trait send sync
| things" specify whether a value of the type is allowed to
| be respectively move or borrowed across thread
| boundaries.
| Dr_Emann wrote:
| Thats kinda the problem, there are concepts in rust that
| don't have equivalents in other common languages. In this
| case, rust's type system models data-race-safety: it
| prevents data races at compile time in a way unlike what
| you can do in c or c++. It will prevent getting mutable
| access (with a compile time error) to a value across
| threads unless that access is syncronized (atomics,
| locks, etc)
| remix2000 wrote:
| And from what I can see, rustlang mutability is also a
| type system construct? I.e. it assumes that all other
| code is Rust for the purpose of those checks?
| gpm wrote:
| > rustlang mutability is also a type system construct?
|
| Yes
|
| > I.e. it assumes that all other code is Rust for the
| purpose of those checks?
|
| Not exactly, it merely assumes that you upheld the
| documented invariants when you wrote code to call/be-
| called-from other languages. For example that if I have a
| `extern "C" fn foo(x: &mut i32)` that
|
| - x points to a properly aligned properly allocated i32
| (not to null, not to the middle of un-unallocated page
| somewhere)
|
| - The only way that memory will be accessed for the
| duration of the call to `foo` is via `x`. Which is to say
| that other parts of the system won't be writing to `x` or
| making assumptions about what value is stored in its
| memory until the function call returns (rust is, in
| principle, permitted to store some temporary value in
| `x`s memory even if the code never touches x beyond being
| passed it. So long as when `foo` returns the memory
| contains what it is supposed to). Note that this implies
| that a pointer to the same memory isn't also being passed
| to rust some other way (e.g. through a static which
| doesn't have a locked lock around it)
|
| - foo will be called via the standard "C" calling
| convention (on x86_64 linux this for instance means that
| the stack pointer must be 2-byte aligned. Which is the
| type of constraint that is very easy to violate from
| assembly and next to impossible to violate from C code).
|
| That it's up to the programmer to verify the invariants
| is why FFI code is considered "unsafe" in rust -
| programmer error can result in unsoundness. But if you,
| the programmer, are confident you have upheld the
| invariants you still get the guarantees about the broader
| system.
|
| Rust is generally all about local reasoning. It doesn't
| actually care very much what the rest of the system is,
| so long as it called us following the agreed upon
| contract. It just has a much more explicit definition of
| what that contract is then C.
| tialaramex wrote:
| Also we can (in 2024 Edition) say we're vouching for an
| FFI function as safe to call, avoiding the need for a
| thin safe Rust wrapper which just passes through. We do
| still need the unsafe keyword to introduce the FFI
| function name, but by marking it safe all the actual
| callers don't care it wasn't written in Rust.
|
| This is fairly narrow, often C functions for example
| aren't actually safe, for example they take a pointer and
| it must be valid, that's not inherently safe, or they
| have requirements about the relative values of parameters
| or the state of the wider system which can't be checked
| by the Rust, again unsafe. But there are cases where this
| affordance is a nice improvement.
| jaggederest wrote:
| Also "safe" and "unsafe" have very specific meanings, not
| the more widely used meanings. It's not inherently
| dangerous to call unsafe code that is well written, it's
| really more a statement about who is taking
| responsibility for the behavior, the writer or the
| compiler.
|
| I like the term "checked" and "unchecked" better but not
| enough to actually lobby to change them, and as a term of
| art they're fine.
| mcherm wrote:
| Yes. Just like C++ "const" is a type system construct
| that assumes all other code is C++ (or at least
| cooperates with the C++ code by not going around changing
| random bytes).
|
| As far as I can tell, ANY guarantee provided by ANY
| language is "just a language construct" that fails if we
| assume there is other code executing which is ill-
| behaved.
| emn13 wrote:
| I mean, reliably tracking ownership and therefore knowing
| that e.g. an aliased write must complete before a read is
| surely helpful?
|
| It won't prevent all races, but it might help avoid
| mistakes in a few of em. And concurrency is such a pain;
| any such machine-checked guarantees are probably nice to
| have to those dealing with em - caveat being that I'm not
| such a person.
| gpm wrote:
| I'm not sure I understand the point of your comment at
| all.
|
| Rust does, successfully, guarantee the lack of data
| races. It also guarantees the lack of memory-unsafety
| resulting from race conditions in general (which to be
| fair largely just means "it guarantees a lack of data
| races", though it does also include things like "race
| conditions won't result in a use after free or an out of
| bounds memory access").
|
| If by address it you mean "show how C/C++ does this"...
| they don't and this is well known.
|
| If by address it you mean "prove that rust doesn't do
| what it says it does"... as that point you're inviting
| someone to teach you the details of how rust works down
| to the nitty gritty in an HN comment. You'd be much
| better off finding and reading the relevant materials on
| the internet than someones off hand attempt at recreating
| them on HN.
| uecker wrote:
| Safe Rust does. To the extend Rust interfaces that wrap
| kernel APIs will achieve safety for the drivers that make
| use of them remains to be seen. I think it will indeed do
| this to some degree, but I have some doubts whether the
| effort and overhead is worth it. IMHO all these resources
| would better be invested elsewhere.
| remix2000 wrote:
| The point of my comment is that in my experience,
| incompetently written, overly-cautious code tends to be
| more safe at the expense of maintainability and/or
| performance.
|
| Sadly, I don't know rustlang, so I can't tell if the
| inability to describe its features in more commonly used
| terms is due to incompetence or the features being
| irrelevant to this discussion (see the title of the
| thread).
| gpm wrote:
| The thing is you aren't really asking about a "feature"
| of rust (as the word is used in the title of the thread),
| unless that feature is "the absence of data races" or
| "memory safety" which I think are both well defined
| terms+ and which rust has. Rather you're asking how those
| features were implemented, and the answer is through a
| coherent design across all the different features of rust
| that maintains the properties.
|
| As near as I can tell to give you the answer you're
| looking for I'd have to explain the majority of rust to
| you. How traits work, and auto traits, and unsafe trait
| impls, and ownership, and the borrow checker, and for it
| to make sense as a practical thing interior mutability,
| and then I could point you at the standard library
| concepts of Send and Sync which someone mentioned above
| and they would actually make sense, and then I could give
| some examples of how everything comes together to enable
| memory safe, efficient, and ergonomic, threading
| primitives.
|
| But this would no longer be a discussion about a rust
| language feature, but a tutorial on rust in general.
| Because to properly understand how the primitives that
| allow rust to build safe abstractions work, you need to
| understand most of rust.
|
| Send and Sync (mentioned up thread) while being useful
| search terms, are some of the last things in a reasonable
| rust curriculum, not the first. I could quickly explain
| them to someone who already knew rust, and hadn't used
| them (or threads) at all, because they're simple once you
| have the foundation of "how the rest of rust works".
| Skipping the foundation doesn't make sense.
|
| + "Memory safety" was admittedly possibly popularized by
| rust, but is equivalent to "the absence of undefined
| behaviour" which should be understandable to any C
| programmer.
| umanwizard wrote:
| > The point of my comment is that in my experience,
| incompetently written, overly-cautious code tends to be
| more safe at the expense of maintainability and/or
| performance
|
| Well, yes, but that's the whole value of Rust: you don't
| need to use these overly-cautious defensive constructs,
| (at least not to prevent data races), because the
| language prevents them for you automatically.
| umanwizard wrote:
| There's no programming language called "rustlang". It's
| just rust.
| lowbloodsugar wrote:
| Heh. This is such a C++ thing to say: "I want to do the
| right thing, but then my code is slow." I know, I used to
| write video games in C++. So I feel your pain.
|
| I can only tell you: open your mind. Is Rust just a fad?
| The latest cool new shiny, espoused only by amateurs who
| don't have a real job? Or is it something radically
| different? Go dig into Rust. Compile it down to assembly
| and see what it generates. Get frustrated by the borrow
| checker rules until you have the epiphany. Write some
| unsafe code and learn what "unsafe" really means. Form your
| own opinion.
| giancarlostoro wrote:
| I was just going to say, I think its hard to argue against it
| since it is the only way to run the GPU on the M1 / M2 Macs.
| William_BB wrote:
| What does rust have to do with thread safety and race
| conditions? Is rust going to synchronize shared memory access
| for me?
|
| Speaking seriously, they surely meant data races, right? If
| so, what's preventing me from using C++ atomics to achieve
| the same thing?
| Aurornis wrote:
| > What does rust have to do with thread safety and race
| conditions? Is rust going to synchronize shared memory
| access for me?
|
| Rust's strict ownership model enforces more correct
| handling of data that is shared or sent across threads.
|
| > Speaking seriously, they surely meant data races, right?
| If so, what's preventing me from using C++ atomics to
| achieve the same thing?
|
| C++ is not used in the Linux kernel.
|
| You can write safe code in C++ or C if everything is
| attended to carefully and no mistakes are made by you or
| future maintainers who modify code. The benefit of Rust is
| that the compiler enforces it at a language level so you
| don't have to rely on everyone touching the code avoiding
| mistakes or the disallowed behavior.
| Lvl999Noob wrote:
| Rust's design eliminates data races completely. It also
| makes it much easier to write thread safe code from the
| start. Race conditions are possible but generally less of a
| thing compared to C++ (at least that's what I think).
|
| Nothing is preventing you from writing correct C++ code.
| Rust is strictly less powerful (in terms of possible
| programs) than C++. The problem with C++ is that the
| easiest way to do anything is often the wrong way to do it.
| You might not even realize you are sharing a variable
| across threads and that it needs to be atomic.
| tialaramex wrote:
| > What does rust have to do with thread safety [...] ?
|
| Rust inherently models this idea. Read about Rust's "Send"
| and "Sync" marker traits. e.g. https://doc.rust-
| lang.org/std/marker/trait.Send.html
|
| > Is rust going to synchronize shared memory access for me?
|
| Much better than that. (safe) Rust is going to complain
| that you can't write the unsynchronized nonsense you were
| probably going to write, shortcutting the step where in
| production everything gets corrupted and you spend six
| months trying to reproduce and debug your mistake...
| a-dub wrote:
| aren't they just annotations? proper use of mutexes and
| lock ordering aren't that hard, they just require a
| little bit of discipline and consistency.
|
| i can't remember the last time i faced a data race to be
| honest.
|
| i guess the real question is, how well does it all hold
| up when you have teamwork and everything isn't strictly
| adherent to one specific philosophy.
| aw1621107 wrote:
| > aren't they just annotations?
|
| "Just" annotations... that are automatically added (in
| the vast majority of cases) and enforced by the compiler.
|
| > proper use of mutexes and lock ordering aren't that
| hard, they just require a little bit of discipline and
| consistency.
|
| Yes, like how avoiding type confusion/OOB/use-after-
| free/etc. "just require[s] a little bit of discipline and
| consistency"?
|
| The point of offloading these kinds of things onto the
| compiler/language is precisely so that you have something
| watching your back if/when your discipline and
| consistency slips, especially when dealing with
| larger/more complex systems/teams. Most of us are only
| human, after all.
|
| > how well does it all hold up when you have teamwork and
| everything isn't strictly adherent to one specific
| philosophy.
|
| Again, part of the point is that Send/Sync are virtually
| always handled by the compiler, so teamwork and
| philosophy generally aren't in the picture in the first
| place. Consider it an extension of your "regular" strong
| static type system checks (e.g., can't pass object of
| type A to a function that expects an unrelated object of
| type B) to cross-thread concerns.
| jcranmer wrote:
| > aren't they just annotations? proper use of mutexes and
| lock ordering aren't that hard, they just require a
| little bit of discipline and consistency.
|
| Spatial memory safety is easy, just check the bounds
| before indexing an array. Temporal memory safety is easy,
| just free memory only after you've finished using it, and
| not too early or too late. As you say, thread safety is
| easy.
|
| Except we have loads of empirical evidence--from
| widespread failures of software--that it's _not_ easy in
| practice. Especially in large codebases, remembering the
| remote conditions you need to uphold to maintain memory
| safety and thread safety can be difficult. I 've written
| loads of code that created issues like "oops, I forgot to
| account for the possibility that someone might use this
| notification to immediately tell me to shut down."
|
| What these annotations provide is a way to have the
| compiler bop you in the head when you accidentally screw
| something up, in the same way the compiler bops you in
| the head if you fucked up a type or the name of
| something. And my experience is that many people do go
| through a phase with the borrow checker where they
| complain about it being incorrect, only to later discover
| that it was correct, and the pattern they thought was
| safe wasn't.
| AlotOfReading wrote:
| Proper use of lock ordering is reasonably difficult in a
| large, deeply connected codebase like a kernel.
|
| Rust has real improvements here, like this example from
| the fuschia team of enforcing lock ordering at compile
| time [0]. This is technically possible in C++ as well
| (see Alon Wolf's metaprogramming), but it's truly dark
| magic to do so.
|
| [0] https://lwn.net/Articles/995814/
| turtleyacht wrote:
| _Borrow Checker, Lifetimes, and Destructor Arguments in
| C++_ (2024)
|
| https://a10nw01f.github.io/post/advanced_compile_time_val
| ida...
| vlovich123 wrote:
| The lifetimes it implements is the now unused lexical
| lifetimes of early Rust. Modern rust uses non-lexical
| lifetimes which accepts a larger amount of valid programs
| and the work on Polonius will further allow more legal
| programs that lexical lifetimes and non lexical lifetimes
| can't allow. Additionally, the "borrow checker" they
| implement is RefCell which isn't the Rust borrow checker
| at all but an escape hatch to do limited single-threaded
| borrow checking at runtime (which the library won't
| notice if you use in multiple threads but Rust won't let
| you).
|
| Given how the committee works and the direction they
| insist on taking, C++ will never ever become a safe
| language.
| aw1621107 wrote:
| > Stateful Metaprogeamming
|
| Bit of a fun fact, but as one of the linked articles
| states the C++ committee doesn't seem to be a fan of
| stateful metaprogramming so its status is somewhat
| unclear. From Core Working Group issue 2118:
|
| > Defining a friend function in a template, then
| referencing that function later provides a means of
| capturing and retrieving metaprogramming state. This
| technique is arcane and should be made ill-formed.
|
| > Notes from the May, 2015 meeting:
|
| > CWG agreed that such techniques should be ill-formed,
| although the mechanism for prohibiting them is as yet
| undetermined.
|
| [0]: https://cplusplus.github.io/CWG/issues/2118.html
| j-krieger wrote:
| > aren't they just annotations? proper use of mutexes and
| lock ordering aren't that hard, they just require a
| little bit of discipline and consistency.
|
| No, they are not. You also don't need mutex ordering as
| much since Mutexes in Rust are a container type. You can
| only get ahold of the inside value as a reference when
| calling the lock method.
| loeg wrote:
| > You also don't need mutex ordering as much since
| Mutexes in Rust are a container type. You can only get
| ahold of the inside value as a reference when calling the
| lock method.
|
| Mutex as a container has no bearing on lock ordering
| problems (deadlock).
| umanwizard wrote:
| > proper use of mutexes and lock ordering aren't that
| hard, they just require a little bit of discipline and
| consistency.
|
| Wow, you must be really smart! I guess you don't need
| rust. For the rest of us who find concurrent programming
| difficult, it is useful.
| umanwizard wrote:
| > What does rust have to do with thread safety and race
| conditions? Is rust going to synchronize shared memory
| access for me?
|
| Well, pretty close to that, actually! Rust will statically
| prevent you from accessing the same data from different
| threads concurrently without using a lock or atomic.
|
| > what's preventing me from using C++ atomics to achieve
| the same thing
|
| You might forget?
| William_BB wrote:
| The first comment is the definition of a data race, not
| preventing race conditions. And data races are trivial
| (sure, no static prevention in C++)
| umanwizard wrote:
| > data races are trivial
|
| Imagine this C++ code: class Foo {
| // ... public: void frobFoo(); };
|
| Now, is it okay to call `frobFoo` from multiple threads
| at once? Maybe, maybe not -- if it's not documented (or
| if you don't trust the documentation), you will have to
| read the entire implementation to answer that.
|
| Now imagine this Rust code: struct Foo {
| // ... } impl Foo { fn
| frobFoo(&mut self) { // ... } }
|
| Now, is `frobFoo` okay to call from multiple threads at
| once? No, and the language will automatically make it
| impossible to do so.
|
| If we had `&self` instead of `&mut self`, then it might
| be okay, you can discover whether it's okay by pure local
| reasoning (looking at the traits implemented by Foo, not
| the implementation), and if it's _not_ then the language
| will again automatically prevent you from doing so (and
| also prevent the function from doing anything that would
| make it unsafe).
| 0x457 wrote:
| Rust will also prevent you from sharing the unsharable
| between threads.
| a-dub wrote:
| > Torvalds seems to disagree with you.
|
| 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)
| 15155 wrote:
| > i don't really care for mindless appeals to authority.
|
| This isn't an appeal to just any authority, but _the_
| authority that defines Linux and is its namesake.
| ynx wrote:
| To be fair, assigning the highly competent BDFL of Linux
| who has listened to a bunch of highly competent maintainers
| some credibility isn't mindless.
|
| Unless you have a specific falsifiable claim that is being
| challenged or defended, it's not at all a fallacy to assume
| expert opinions are implicitly correct. It's just wisdom
| and good sense, even if it's not useful to the debate you
| want to have.
| mekoka wrote:
| Mindless appeal to authority? I don't think that's how the
| fallacy really works. It's pretty much _the_ authority that
| seems to disagree with your sentiment, that is if we can
| agree that Torvalds still knows what he 's doing. Him not
| sharing your skepticism is a valid argument. The point
| being that instead of giving weight to our distant
| feelings, maybe we could just pause and be more curious as
| to why someone with much closer involvement would not share
| them. Why should we care more about the opinions of randos
| on hn?
| serious8aller wrote:
| Not every mention of an authority's opinion needs to be
| interpreted as an "appeal to authority". In this case I
| think they're just trying to give you perspective, not use
| Torvalds opinion as words from god.
| j-krieger wrote:
| > i don't really care for mindless appeals to authority.
| make your own arguments and defend them or don't bother.
|
| You previously appealed to Linux being the largest worlds
| most important source tree and then you choose to eschew
| the opinion of that project's lead.
| Anonbrit wrote:
| So rather than pointing to experts who're in the best
| position to know, you'd prefer bad rephrasing and airchair
| experts? Do you 'do your own research' too?
| koverstreet wrote:
| "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.
| izacus wrote:
| But WHERE is that code in the kernel? That, I think, it the
| OPs point. Where is that demonstration?
| corbet wrote:
| See, for example, the binder driver merged for 6.18. It's
| out there, and will land when it's ready.
| arnsholt wrote:
| In discussions like this, I sometimes feel that the
| importance of related work like the increasing use of
| Rust in Android and MS land is under-appreciated. Those
| who think C is fine often (it seems to me) make arguments
| along the lines that C just needs to have a less UB-prone
| variant along the lines of John Regehr and colleagues'
| "Friendly C" proposal,[0] which unfortunately Regehr
| about a year and a half later concluded couldn't really
| be landed by a consensus approach.[1] But he does suggest
| a way forwards: "an influential group such as the Android
| team could create a friendly C dialect and use it to
| build the C code (or at least the security-sensitive C
| code) in their project", which is what I would argue is
| happening; it's just that rather than nailing down a
| better C, several important efforts are all deciding that
| Rust is the way forward.
|
| The avalanche has already started. It is too late for the
| pebbles to vote.
|
| 0: https://blog.regehr.org/archives/1180 1:
| https://blog.regehr.org/archives/1287
| uecker wrote:
| Some parts of the industry with a lot of money and
| influence decided this is the way forward. IMHO Rust has
| the same issue as C++: it is too complex and a memory
| safe C would be far more useful. It is sad that not more
| resources are invested into this.
| gpm wrote:
| I'm entirely unconvinced that a low-level+ memory safe C
| that is meaningfully simpler than rust is even possible,
| let alone desirable. IMHO Basically all of rust's
| complexity comes from implementing the structure
| necessary to make it memory safe without making it too
| difficult to use++.
|
| Even if it is though, we don't have it. It seems like
| linux should go with the solution we have in hand and can
| see works, not a solution that hasn't been developed or
| proved possible and practical.
|
| Nor is memory safety the only thing rust brings to the
| table, it's also brings a more expressive type system
| that prevents other mistakes (just not as categorically)
| and lets you program faster. Supposing we got this memory
| safe C that somehow avoided this complexity... I don't
| think I'd even want to use it over the more expressive
| memory safe language that also brings other benefits.
|
| + A memory-safe managed C is possible of course (see
| https://fil-c.org/), but it seems unsuitable for a
| kernel.
|
| ++ There are some other alternatives to the choices rust
| made, but not meaningfully less complex. Separately you
| could ditch the complexity of async I guess, but you can
| also just use rust as if async didn't exist, it's a
| purely value added feature. There's likely one or two
| other similar examples though they don't immediately come
| to mind.
| uecker wrote:
| I don't think so. First, Rust did not come from nowhere,
| there were memory safe C variants before it that stayed
| closer to C. Second, I do not even believe that memory
| safety is that important that this trumps other
| considerations, e.g. the complexity of having two
| languages in the kernel (even if you ignore the
| complexity of Rust). Now, it is not my decision but
| Google's and other company's influence. But I still think
| it is a mistake and highlights more the influence of
| certain tech companies on open source than anything else.
| gpm wrote:
| > First, Rust did not come from nowhere, there were
| memory safe C variants before it that stayed closer to C.
|
| Can you give an example? One that remained a low level
| language, and remained ergonomic enough for practical
| use?
|
| > Second, I do not even believe that memory safety is
| that important that this trumps other considerations
|
| In your previous comment you stated "a memory safe C
| would be far more useful. It is sad that not more
| resources are invested into this". It seems to me that
| after suggesting that people should stop working on what
| they are working on and work on memory safe C instead you
| ought to be prepared to defend the concept of a memory
| safe C. Not to simply back away from memory safety being
| a useful concept in the first place.
|
| I'm not particularly interested in debating the merits of
| memory safety with you, I entered this discussion upon
| the assumption that you had conceded them.
| Jweb_Guru wrote:
| > Can you give an example? One that remained a low level
| language, and remained ergonomic enough for practical
| use?
|
| They can't, of course, because there was no such
| language. Some people for whatever reason struggle to
| acknowledge that (1) Rust was not just the synthesis of
| existing ideas (the borrow checker was novel, and aspects
| of its thread safety story like Send and Sync were also
| AFAIK not found in the literature), and (2) to the extent
| that it was the synthesis of existing ideas, a number of
| these were locked away in languages that were not even
| close to being ready for industry adoption. There was no
| other Rust alternative (that genuinely aimed to replace
| C++ for all use cases, not just supplement it) just on
| the horizon or something around the time of Rust 1.0's
| release. Pretty much _all_ the oxygen in the room for
| developing such a language has gone to Rust for well over
| a decade now, and that 's why it's in the Linux kernel
| and [insert your pet language here] is not.
|
| BTW, this is also why people being are incentivized to
| figure out ways to solve complex cases like Rcu-
| projection through extensible mechanisms (like the
| generic field projection proposal) rather than ditching
| Rust as a language because it can't currently handle
| these ergonomically. The lack of alternatives to Rust is
| a big driving factor for people to find these
| abstractions. Conversely, having the weight of the Linux
| kernel behind these feature requests (instead of e.g.
| some random hobbyist) makes it far more likely for them
| to actually get into the language.
| Pet_Ant wrote:
| Oof. That's a depressing read:
|
| > This post is a long-winded way of saying that I lost
| faith in my ability to push the work forward.
|
| The gem of despair:
|
| > Another example is what should be done when a 32-bit
| integer is shifted by 32 places (this is undefined
| behavior in C and C++). Stephen Canon pointed out on
| twitter that there are many programs typically compiled
| for ARM that would fail if this produced something
| besides 0, and there are also many programs typically
| compiled for x86 that would fail when this evaluates to
| something other than the original value.
| koverstreet wrote:
| It's been moving slowly at first because you need a lot of
| bindings done before you can do interesting work, and
| bindings/FFI tend to be fiddly, error prone things that you
| want to take your time on and get right - that's where you
| deal with the impedance mismatch between C and Rust and
| have to get all the implicit rules expressed in the type
| system (if you can).
|
| It'll go faster once all the bindings are in place and
| people have more experience with this stuff. I've been
| greatly looking forward to expanding bcachefs's use of
| rust, right now it's just in userspace but I've got some
| initial bindings for bcachefs's core btree API.
|
| Real iterators, closures, better data types, all that stuff
| is going to be so nice when it can replace pages and pages
| of macro madness.
| the8472 wrote:
| 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?
| aw1621107 wrote:
| > 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.
| saghm wrote:
| 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.
| dralley wrote:
| > from what i can tell even the android binder rust rewrite is
| vestigial.
|
| 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.
| testdelacc1 wrote:
| > shouldn't this be taking place somewhere else
|
| That's an interesting idea. You should let this guy know you
| disagree with his technical decision -> torvalds@linux-
| foundation.org
| penguin_booze wrote:
| > 'find -name " _.rs "'
|
| Since this is a Git repo, I'd go with `git ls-files '_.rs'`.
| nicoburns wrote:
| > 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.
| chippiewill wrote:
| 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.
| mustache_kimono wrote:
| > 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.
| shevy-java wrote:
| I am scared. More than excited.
| bobajeff wrote:
| 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.
|
| [1]:
| https://github.com/joshtriplett/rfcs/blob/use/text/3680-use....
| dralley wrote:
| It is definitely a complex language though I would argue
| probably much less so, on the whole, than C++.
| meisel wrote:
| 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.
| GrantMoyer wrote:
| Thanks for organizing for me my thoughts on why even a
| restricted modern subset of C++ is complicated.
| jstimpfle wrote:
| Why check this != other? I've seen this once before in a
| codebase and concluded it was unnecessary.
|
| Asking as someone whose life became much easier after opting
| not do anything of the above and just write C in C++ ;-)
| Maxatar wrote:
| Consider a move assign to a vector<int> from _src_ to
| _this_. The first step is for _this_ to free its resources,
| the second step is to assign _src_ resources to _this_ ,
| the third step is to set _src_ resources to null.
|
| If _src_ and _this_ are equal and you don 't check for it,
| then you end up destroying _src_ / _this_ resources and the
| end result would be an empty vector (since the last step is
| to clear everything out).
|
| The expected behavior is a no-op.
| jstimpfle wrote:
| Right you said move but I was thinking of swap for some
| reason.
|
| I probably still wouldn't care, unless it's clear that
| moving to self is even required. Trying to break
| everything in a thousand pieces and generalizing and
| perfecting them individually is a lot of busywork.
| pama wrote:
| I have been out of it for a while and dont miss it much, but
| I thought that the rule of zero, not five, was the modern
| goal.
| dathinab wrote:
| 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).
| RGBCube wrote:
| 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.
| umanwizard wrote:
| 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++.
| GeorgeTirebiter wrote:
| 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.
| umanwizard wrote:
| If C is 1 and C++ is 100 I would say Rust is like 25.
|
| If your favorite language is assembly and C is too high-
| level for you then you are probably going to dislike Rust
| (and Java, Python, and every other modern language).
| vlovich123 wrote:
| 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.
| tredre3 wrote:
| > 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...
| kstrauser wrote:
| I worked for Coverity and people paid us ludicrous amounts
| of money to get the kinds of suggestions that rustc and
| clippy give everyone for free. I'm a huge fan.
| afavour wrote:
| 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.
| 0x457 wrote:
| > 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.
| afavour wrote:
| It's been so long I can barely remember now but I'm pretty
| sure it was the lifetime propagation that got me... once
| one struct had it, every struct using that struct needed
| one, then there was more than one lifetime and combining
| them (and establishing the rules of how the lifetimes
| related to each other) bent my brain out of shape. Rc<> let
| me sidestep all of that.
| rcxdude wrote:
| Yeah, once you're putting lifetimes in structs you're
| liable to run into trouble. In general you only want to
| do that for structs which are not expected to have long
| or complicated lifetimes (i.e. if you're expecting it
| might be allocated on the heap, it's likely too
| complicated to be workable)
| 0x457 wrote:
| Yeah, lifetime in structs are PITA. However, IMO using
| them is "the right choice" only in certain situations
| where performance hit from not using it is too much. I
| get why serde uses it, but notice who those don't get
| exposed to end user that much.
| teaearlgraycold wrote:
| Any time I need to explicitly give a lifetime in a struct
| I use an Rc or some other container. I've been using rust
| casually for years and every time I try to appease the
| compiler with lifetimes I realize it's not worth my time.
| If someone has a very ELI5 resource that will make me
| understand when and why to do this I'd appreciate it.
|
| IMO this is something that should just be handled by
| extra runtime code or a magically smarter compiler.
| Lifetime management feels like something that matters in
| a microcontroller or hyper-optimized setting, but never
| when I'm executing code on Apple Silicon for a random
| application. And yet the language makes simple GC
| ergonomically painful. I love the language but don't
| really need all of that performance. I would gladly take
| a 1% hit to increment reference counts.
| zozbot234 wrote:
| You're on Apple Silicon, which is the preferred platform
| for Swift. That does exactly what you're asking for wrt.
| ARC, and is memory safe.
| dev_l1x_be wrote:
| We have production systems, with ~10k Rust without
| lifetimes. Sometimes you can get away not using it.
| dathinab wrote:
| I think lifetimes are best thought of as constraints.
|
| Like `x: Foo<'a>` means "x is constrained by lifetime 'a"
| as in "x is only guaranteed to be soundly usable if 'a is
| 'alive'".
|
| With the implicit context of "you are only allowed to use
| things which are guaranteed to be soundly usable".
|
| And that "moving" is distinct from lifetimes (i.e. if you
| move x out of scope you just don't have it anymore, while a
| 'a constraint on x limits where you _can_ "have" it).
|
| Then `'static` basically means "no
| constraint"/"unconstrained".
|
| So a `x: X + 'static` mean x has no constraints, as long as
| you have it you can use it.
|
| Where `x: X+'a` (or `X<'a>`) would mean you can _at most_
| have x until 'a stops being "alive". (This doesn't mean the
| data behind X doesn't life longer, just that in that
| specific place you can't "have" it at most while 'a is
| alive).
|
| So then if we look at `&'static A` we have a type which 1)
| is always copied instead of moved, so you always have it
| while you can have it and 2) you can always have it. As
| consequence it must life for the whole program execution.
| Not because `'static` says "until end of program" but
| because a unconstrained &reference can only be sound if it
| exist until the end of the program!!
| dev_l1x_be wrote:
| 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.
| ameliaquining wrote:
| Note that the community has somewhat soured on that particular
| proposal and it's probably not going to be enacted in its
| current form, _precisely because_ it 's so complicated.
| (https://rust-lang.github.io/rust-project-
| goals/2025h2/ergono...)
|
| 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.
| kstrauser wrote:
| 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.
| ameliaquining wrote:
| Yeah, I was slightly sloppy about that, but also the
| distinction doesn't entirely help at this level because
| people get into vicious fights about whether a particular
| bit of complexity is really "necessary". E.g., lots of
| people argue that async Rust is unnecessary complication,
| either because you can just write all the state machines by
| hand (which is terrible for expressiveness, but do you
| really _need_ expressiveness?), or because you can just
| spawn an OS thread for every task (which is terrible for
| performance, but do you really _need_ performance?).
| Whereas the pro-async perspective is, yes, it 's very
| complex, but nothing simpler would have done everything
| that it needs to do.
| kstrauser wrote:
| Oh, I hear ya. That makes perfect sense, and you're so
| right: my idea of a complex solution might be someone
| else's complication, and vice versa. I didn't mean to
| disagree with you, and surely not to correct you, because
| not everyone agrees on the distinction I make between the
| ideas.
|
| I meant that more in the spirit of "oh, while we're
| talking about this, here are my thoughts on a
| tangentially related idea".
| jstimpfle wrote:
| > Complexity is fine. Sometimes we're working on complex
| problems without simple, straightforward, correct
| solutions.
|
| Often the best way to proceed is to just solve a simpler
| problem :)
| inhumantsar wrote:
| > Simple is better than complex. > > Complex is better than
| complicated.
|
| https://peps.python.org/pep-0020/
| misnome wrote:
| I wonder if the block-level `clone(var_a, var_b)` was
| considered. It's a bit verbose but very explicit and much
| better than the current situation.
| ameliaquining wrote:
| Do you mean something like this? https://github.com/rust-
| lang/rfcs/issues/2407
| andrepd wrote:
| A very interesting post about this issue.
|
| https://smallcultfollowing.com/babysteps/blog/2025/10/07/the...
| foota wrote:
| Fwiw C++ has the exact same problem with moving/referencing
| into closures, see "Lambda capture" in
| https://en.cppreference.com/w/cpp/language/lambda.html.
| dapperdrake wrote:
| It seems like Rust is being thorough. This is the way.
| JoshTriplett wrote:
| 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.
| pif wrote:
| > 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.
| prisenco wrote:
| Go is a great language.
| jmyeet wrote:
| 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.
|
| [1]: https://leanpub.com/cppinitbook
| nialv7 wrote:
| > 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.
|
| [1]:
| https://smallcultfollowing.com/babysteps/blog/2025/10/07/the...
| scott_w wrote:
| 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.
| dathinab wrote:
| 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" :/)
| IshKebab wrote:
| 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".
| tonyplee wrote:
| Are there any researches/works/agents into use LLM to auto covert
| some/all C code to Rust?
|
| 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?
| gpm wrote:
| There's non-LLM research towards doing this which has a few
| success stories: https://github.com/immunant/c2rust
|
| 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...
| steveklabnik wrote:
| Darpa is interested in funding such an effort, but as far as I
| know that's the stage it's at, they haven't released any
| results.
| anon-3988 wrote:
| fn project_reference(r: &MyStruct) -> &Field {
| &r.field } unsafe fn project_pointer(r: *mut
| MyStruct) -> *mut Field { unsafe { &raw mut
| (*r).field } } // The equivalent C code
| would look like this: struct field *project(struct my *r)
| { return &(r->field); }
|
| I am a very heavy Rust user. I mostly program in safe Rust while
| occassionally dipping into unsafe Rust.
|
| IDK, I think Rust should stick with what it is good at and not
| try to expand into domain that it is clearly not nicely designed
| for. That is, what if the best way to implement linked list in
| RUST is via an array of indices and NOT through RefCell or
| whatever it is? What if Rust will never ever have a sane way to
| implement linked list. What is so wrong with that? I think there
| should be a very clean divide between C and Rust. Rust stays in
| the happy Rust world and C stays on the happy C world.
|
| I am not sure I am excited to see something like this
| unsafe fn project_pointer(r: *mut MyStruct) -> *mut Field {
| unsafe { &raw mut (*r).field } }
| drdo wrote:
| It's not that hard to implement a linked list in Rust in
| exactly the same way as in C or C++, using raw pointers, and
| putting a safe API around it.
| piperswe wrote:
| In fact, IIRC exactly that is available in the standard
| library.
| lowbloodsugar wrote:
| The best way to implement a linked list is with unsafe in a
| collection type. You write that type once, check that it's
| bullet proof, and then go onto the next thing. I've got a
| sorted map using doubly linked list and I don't think twice
| about it. Using an array for a linked list means the compiler
| can't tell if you are being unsafe. You still have all the same
| problems.
___________________________________________________________________
(page generated 2025-10-16 23:00 UTC)