LWN: Comments on "A GPIO driver in Rust" https://lwn.net/Articles/863459/ This is a special feed containing comments posted to the individual LWN article titled "A GPIO driver in Rust". en-us Wed, 08 Oct 2025 09:23:08 +0000 Wed, 08 Oct 2025 09:23:08 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net type inference surely? https://lwn.net/Articles/872254/ https://lwn.net/Articles/872254/ zesterer <div class="FormattedComment"> <font class="QuotedText">&gt; The curse is that nobody knows WTF is going on any more.</font><br> <p> This is rarely the case.<br> <p> Rust&#x27;s type system is very rich and it&#x27;s common practice to wrap types to compose certain guarantees. For example, `Arc&lt;T&gt;` gives you a reference-counted, immutable `T` and `Mutex&lt;T&gt;` gives you a `T` for which every access is guarded by a mutex. You can compose these guarantees together like `Arc&lt;Mutex&lt;T&gt;&gt;` to make a reference-counted, thread-safe wrapper around a piece of data.<br> <p> It is not uncommon to transform values to and from these representations, unwrapping and wrapping them as and when invariants need to be maintained. It&#x27;s very common for the *semantics* of the underlying value to be more important than the actual type.<br> <p> Don&#x27;t fear: Rust will prevent you doing dumb stuff.<br> <p> <font class="QuotedText">&gt; Basically you are programming in python at this point</font><br> <p> This conveys a fundamental misunderstanding of how type inference vs dynamic typing works. Type inference is sound and requires principal types in all cases, it&#x27;s just able to be a little cleverer about deciding what type to give terms. It won&#x27;t, however, infer types that you have not specified *at some point* in the context. These types are still all checked for compatibility at compile-time and the compiler will still tell you about any typing problems.<br> <p> Python, on the other hand, has a dynamic type system that detects typing errors at runtime. This means that for any given variable, it&#x27;s incredibly difficult to talk about what invariants pertain to it, how to enforce them, or even what shape the value has.<br> <p> Python sacrifices compile-time guarantees for a more terse syntax.<br> <p> Rust does no such thing: it only allows you to omit this information *when you&#x27;ve already made clear to the compiler elsewhere* what&#x27;s going on.<br> <p> <font class="QuotedText">&gt; C project where everything is &quot;simple&quot;</font><br> <p> C is not simple. Its syntax appears simple, but this is only because it makes exceedingly few meaningful guarantees about how values can be used, what invariants need enforcing, or how to safely use values. It is &quot;simple&quot; only in that it shifts all of the complexity on to the human writing the code and, as we all know, humans are fallible fleshy creatures that regularly make catastrophic mistakes.<br> <p> Rust&#x27;s explicit purpose is to hoist as much of this complexity on to the compiler as possible. Invariants that previously needed remembering or forgetting-and-later-debugging-after-an-expensive-or-dangerous-failure are now managed by the compiler, meaning that the limited processing power of the human mind can be used to focus on architectural concerns, program logic, etc.<br> <p> <font class="QuotedText">&gt; Are people going to upgrade their editors to have inspection?</font><br> <p> No. I&#x27;ve been writing Rust for 6 years now with a run-of-the-miss text editor with syntax highlighting. Not an IDE in sight. It&#x27;s been fine!<br> <p> <font class="QuotedText">&gt; Will someone figure out tooling to replace grep?</font><br> <p> Check out ripgrep. It&#x27;s written in Rust, is shockingly quick (significantly faster than most existing grep impls), and is very user-friendly.<br> </div> Fri, 08 Oct 2021 13:45:42 +0000 I'm delighted to see this https://lwn.net/Articles/867073/ https://lwn.net/Articles/867073/ carORcdr <div class="FormattedComment"> It is difficult, if not impossible, for anyone to learn a subject purely by reading about it, without applying the information to specific problems and thereby forcing himself to think about what has been read. Furthermore, we all learn best the things we have discovered for ourselves.<br> <p> Donald E. Knuth, The Art of Computer Programming, Volume 1/Fundamental Algorithms (Second Edition, Addison-Wesley 1973); Ante, p. xvii.<br> <p> </div> Mon, 23 Aug 2021 04:23:58 +0000 type inference surely? https://lwn.net/Articles/864766/ https://lwn.net/Articles/864766/ dlazerka <div class="FormattedComment"> <font class="QuotedText">&gt; Stated from alot of experiance in C++ where auto does the same thing.. It is a curse and a blessing.</font><br> <p> I came from Java world and it&#x27;s long forgotten problem there. Your IDE knows it, so it either show it (small grey font) like it was typed there but really isn&#x27;t, or, if you don&#x27;t like it, IDE always shows in when your cursor is on the variable name, and hotkeys like Ctrl-B will show you the type, maybe even with its documentation, in a popup.<br> <p> I believe IntelliJ does that for Rust as well. But for C++ on large projects CLion couldn&#x27;t pick it up, probably because C++ world doesn&#x27;t have &quot;default&quot; builder and it&#x27;s hard to support all the tricky ways people build C++.<br> </div> Sat, 31 Jul 2021 14:18:50 +0000 type inference surely? https://lwn.net/Articles/864723/ https://lwn.net/Articles/864723/ tialaramex <div class="FormattedComment"> No doubt proc macros can cause utter mayhem. Mara&#x27;s <a href="https://crates.io/crates/nightly-crimes">https://crates.io/crates/nightly-crimes</a> is secretly running another compiler from the macro to re-compile your code with different environment variables, nobody&#x27;s syntax highlighter copes (or at least should cope) with that. The C-pre-processor can&#x27;t compete.<br> <p> Still, the proc macros that do this are on purpose. &quot;That&#x27;s scary, punt&quot; is a reasonable strategy for them - what went in was tokens, and what comes out would have been tokens (modulo somebody forking the compiler, Mara again) so if you get scared give up and pass the un-processed macro through to your next phase. I feel like things get out of hand in the C pre-processor in a more gradual frog-boiling way with no individual step seeming outrageous and yet you can&#x27;t understand your own code.<br> <p> As to fixing things in C++ with Epochs, my impression is that all the big interesting changes proposed for Epochs turn out to get into difficulties with templates, and specifically template meta-programming. It may be that introducing some extra places where you can write &quot;auto&quot; is allowed without that particular problem, but I don&#x27;t see it being more than a band-aid.<br> </div> Sat, 31 Jul 2021 02:00:40 +0000 type inference surely? https://lwn.net/Articles/864640/ https://lwn.net/Articles/864640/ farnz <p>Part of the difference between the two is that Rust permits partial declaration of an unclear type, while C++ does not. It would be easier to punt on the hard cases if C++ provided a way to express things like "it's definitely going to be a <tt>std::vector::iterator</tt>, but you can infer the type of the contents of the iterator". Something like <tt>std::vector&lt;T=auto&gt;::iterator</tt> would be currently free syntax that would make it easier for C++ to say "nope, can't infer that", and the change could be introduced in a epoch thingy (by saying that old epoch code has the old rules, but can use the new syntax, but the new epoch code gets a compile failure if the surprising rules are needed to find a type). <p>And while I'd agree that Rust's procmacros are better for syntax highlighting than CPP (especially if the procmacro author bothered with <a href="https://docs.rs/proc-macro2/1.0.28/proc_macro2/struct.Span.html">span information</a> in their error cases), they do have own their issues that CPP doesn't share - the <a href="https://github.com/raycar5/better-macro"><tt>better-macro</tt> crate</a> is designed to open a web page with a surprise in it when you use a "standard" macro, and because it's a procmacro, it'll run in your type-inferring tool. Fri, 30 Jul 2021 08:07:55 +0000 type inference surely? https://lwn.net/Articles/864619/ https://lwn.net/Articles/864619/ tialaramex <div class="FormattedComment"> I just watched a 2014 C++ talk by Scott Meyers about C++ type deduction, which includes auto but also the other places where C++ decided to have deduction. The talk gives several examples that are potentially surprising.<br> <p> As I see it, the main problem is that C++ chooses to deduce types when the programmer intent isn&#x27;t at all clear.<br> <p> Inference is used in Rust to let the programmer not state the obvious. Whenever what is meant isn&#x27;t obvious, Rust prefers to have the programmer spell out what they mean. The language owners have frequently been conservative here, identifying narrow cases that are obvious, inferring those cases only. If the covered inference is too narrow they can iterate. Code which makes explicit something that subsequently became obvious and could now be inferred still compiles, more inference does not break anything.<br> <p> But because C++ deduction is mandatory in some places, and can be invoked elsewhere with auto even when the type is not clear, C++ must have some rules to &quot;deduce&quot; a type even when it isn&#x27;t at all clear to the programmer, which is where the surprises leak in.<br> <p> I think a LOT of places where auto is surprising in C++ ought to be compile errors instead. &quot;Nope, I don&#x27;t know for sure what the intended type is, write it down so I can check we&#x27;re both on the same page&quot;.<br> <p> As to tooling, there already exist popular Rust tools that will tell you what types things are, e.g. if you hover over something, or in greyed &quot;ghost&quot; text in your editor next to the line with the inferred type, or by context clicking. If there isn&#x27;t already a way to say &quot;Find the places I use the type Vec&lt;Foo&lt;i32&gt;&gt;&quot; then I wouldn&#x27;t anticipate it being difficult to add. One of the things Rust dodged that C++ inherited from C is the tool-hostile macro system. Any non-trivial C++ codebase is riddled with macros which make it impossible for simple tools to understand the source code, but Rust&#x27;s ordinary (&quot;by example&quot; or declarative) macros are at worst opaque to such tools (ie the tool doesn&#x27;t understand some macro calls but can press on unphased), while its &quot;procedural&quot; macros - which are effectively code running inside your compiler - at least respect the idea that the program consists of tokens, not just arbitrary text they should mangle. So a tool could definitely mis-understand what&#x27;s going on in your source due to a proc macro in theory, but in practice that&#x27;s rare.<br> </div> Fri, 30 Jul 2021 01:22:13 +0000 A GPIO driver in Rust https://lwn.net/Articles/864469/ https://lwn.net/Articles/864469/ hkalbasi <div class="FormattedComment"> I suggested a lint for enforcing either a dedicated block or a drop for locks:<br> <a rel="nofollow" href="https://github.com/rust-lang/rust-clippy/issues/7500">https://github.com/rust-lang/rust-clippy/issues/7500</a><br> </div> Wed, 28 Jul 2021 13:11:29 +0000 A GPIO driver in Rust https://lwn.net/Articles/864384/ https://lwn.net/Articles/864384/ calumapplepie <div class="FormattedComment"> Error on line six: close smiley not paired with an open smiley. <br> <p> <font class="QuotedText">&gt; should be safe :-)</font><br> ...........................^^<br> </div> Tue, 27 Jul 2021 04:03:45 +0000 A GPIO driver in Rust https://lwn.net/Articles/864247/ https://lwn.net/Articles/864247/ intgr <div class="FormattedComment"> An explicit scope or `drop()` may indeed be a good idea. The rules for implicit drop can be surprising and cause bugs when dealing with MutexGuards: <a href="https://github.com/rust-lang/book/issues/1871">https://github.com/rust-lang/book/issues/1871</a><br> <p> </div> Sun, 25 Jul 2021 12:18:09 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/864213/ https://lwn.net/Articles/864213/ wtarreau <div class="FormattedComment"> Just tried and indeed, I never noticed before and gave up precisely because of this. However they&#x27;re tricky as they seem to reuse the same type of previous constant when used with automatic enumeration, and when it&#x27;s a pure int, it silently wraps to zero, so one has to be extremely cautious:<br> <p> enum {<br> LASTN1 = ~0,<br> LAST,<br> };<br> <p> unsigned long long last()<br> {<br> return LAST;<br> }<br> <p> 0000000000000000 &lt;last&gt;:<br> 0: 31 c0 xor %eax,%eax<br> 2: c3 retq <br> <p> With ~0U, the overflow is detected:<br> enum1.c:3:2: error: overflow in enumeration values<br> LAST,<br> ^<br> With 0xffffffffUL, it only builds on 64-bit (of course). With ~0ULL, the LAST value is always correct, even in 32-bit:<br> 0000000000000000 &lt;last&gt;:<br> 0: 48 b8 00 00 00 00 01 movabs $0x100000000,%rax<br> 7: 00 00 00 <br> a: c3 retq <br> <p> 00000000 &lt;last&gt;:<br> 0: 31 c0 xor %eax,%eax<br> 2: ba 01 00 00 00 mov $0x1,%edx<br> 7: c3 ret <br> <p> </div> Sat, 24 Jul 2021 10:37:25 +0000 A GPIO driver in Rust https://lwn.net/Articles/864100/ https://lwn.net/Articles/864100/ mathstuf <div class="FormattedComment"> I don&#x27;t know how feasible that is in Rust today. Supporting linear types with any kind of safety guarantees would mean that `panic=abort` is not a viable option. In fact, that Rust considers leaking memory safe is probably what allows `panic=abort` to even exist in the first place[1]. I suppose an attribute that a type cannot be passed to `mem::forget` (including when embedded into other types) would be fine, but that still doesn&#x27;t support `panic=abort` behaviors with such types in a scope if you&#x27;re relying upon that behavior for safety.<br> <p> As for the link error, I don&#x27;t think there&#x27;d be any mechanism to say that &quot;only `unlock_irq` can call `mem::forget` for type `IrqLockGuard`&quot; (since to make it a link error, you&#x27;d have to *avoid* the `Drop` call at the use site(s). I suspect ad-hoc tooling (akin to sparse or coccinelle) would be the best option here.<br> <p> [1] Obviously Rust cannot save you from SIGKILL or power failure; nor can any language for that matter. I see this as more of a system architecture level thing where some languages help more in obtaining such resiliency (say, Erlang) than others, but is possible in even C (see sqlite).<br> </div> Fri, 23 Jul 2021 13:51:09 +0000 A GPIO driver in Rust https://lwn.net/Articles/864098/ https://lwn.net/Articles/864098/ ojeda <div class="FormattedComment"> I was thinking of having a link error in the `Drop` or perhaps some ad-hoc tooling. Ideally, of course, the language would provide a way to do it.<br> </div> Fri, 23 Jul 2021 13:39:07 +0000 A GPIO driver in Rust https://lwn.net/Articles/864097/ https://lwn.net/Articles/864097/ mathstuf <div class="FormattedComment"> <font class="QuotedText">&gt; One more alternative is keeping unlocks explicit, but still preventing double unlocks and missing unlocks at compile-time.</font><br> <p> Double unlocks I know how to prevent (just consume the guard and make sure the guard type doesn&#x27;t `impl Clone`). However, without linear types, there&#x27;s no way to have the *compiler* enforce missing unlocks since `mem::forget` is a thing and the next best thing is a `Drop` impl that detects that you forgot to do something which is only runtime.<br> </div> Fri, 23 Jul 2021 13:09:24 +0000 A GPIO driver in Rust https://lwn.net/Articles/864087/ https://lwn.net/Articles/864087/ ojeda <div class="FormattedComment"> <font class="QuotedText">&gt; In such a case I&#x27;m fine without an explicit unlock if it ends at a block that leaves it possible to add anything at the end of the function, including a printk() that someone would need to better follow the code.</font><br> <p> This could definitely be a reasonable coding guideline for some of the RAII types.<br> <p> One more alternative is keeping unlocks explicit, but still preventing double unlocks and missing unlocks at compile-time.<br> </div> Fri, 23 Jul 2021 12:55:34 +0000 A GPIO driver in Rust https://lwn.net/Articles/864094/ https://lwn.net/Articles/864094/ wtarreau <div class="FormattedComment"> Yep that&#x27;s what I meant. Thanks for showing the variants. It would indeed add an extra indent but I don&#x27;t find this shocking if the purpose precisely is &quot;to be run under a lock&quot;.<br> <p> </div> Fri, 23 Jul 2021 12:53:34 +0000 A GPIO driver in Rust https://lwn.net/Articles/864093/ https://lwn.net/Articles/864093/ mathstuf It seems like you're arguing that any use of a lock guard type should match this pattern: <pre> { // IRQ locking let _guard = data.lock(); // code under the IRQ lock } // Code not under the IRQ lock </pre> Even if it is the first line in the function. This would add an extra level of indentation to any such function (which is non-trivial under normal kernel indentation rules), but makes it more visible than even C where different effect regions exist. I think this is reasonable for such low-level code where debugging may be useful, but not possible under every kind of lock. But unlike C++, one can also drop the lock manually if needed: <pre> let _guard = data.lock(); // Added debugging code drop(_guard); printk(…); </pre> But forgetting that `drop` call seems like it'd be quite impactful, so maybe the explicit block is indeed better. Fri, 23 Jul 2021 12:43:03 +0000 A GPIO driver in Rust https://lwn.net/Articles/864066/ https://lwn.net/Articles/864066/ wtarreau <div class="FormattedComment"> <font class="QuotedText">&gt; Here are the x86-64 instructions for a loop like the one above (compiler explorer link here): </font><br> <p> perfect, thanks for doing this, at least now the two drivers ought to be equivalent.<br> <p> I still find the rust one totally unreadable, but as long as there exist people on this planet with a strong enough parser for all the smileys, we should be safe :-)<br> <p> </div> Fri, 23 Jul 2021 03:04:43 +0000 A GPIO driver in Rust https://lwn.net/Articles/864065/ https://lwn.net/Articles/864065/ wtarreau <div class="FormattedComment"> <font class="QuotedText">&gt; &gt; By not placing the explicit unlock, it will hold till the end (if I understand right), which means that any extra code added to that function will be added under that lock even if not required at all.</font><br> <font class="QuotedText">&gt;</font><br> <font class="QuotedText">&gt; Not exactly: the unlock happens at the end of the scope, not at the end of the function.</font><br> <font class="QuotedText">&gt;</font><br> <font class="QuotedText">&gt; This is an important distinction, because it allows one to precisely control how long the lock is held. RAII would be unworkable otherwise!</font><br> <p> OK that&#x27;s better, but then I&#x27;d appreciate it if an explicit block was written in the function to show where the lock is expected to be held, because the way it&#x27;s done right now implies it&#x27;s held for the whole function. And my concern precisely is that any addition to that function will naturally be under the lock.<br> <p> <font class="QuotedText">&gt; In the case of RAII, I think being implicit is a good compromise because it avoids a good amount of mechanically-written code while still being easy enough to figure out where the calls happen when needed.</font><br> <p> I&#x27;m not fundamentally against this provided that critical sections are well delimited. There are thousands of contributors to the kernel, not everyone has the same ease to grasp the subtleties of certain locks, and making such areas explicit is better. In such a case I&#x27;m fine without an explicit unlock if it ends at a block that leaves it possible to add anything at the end of the function, including a printk() that someone would need to better follow the code.<br> <p> <font class="QuotedText">&gt; &gt; To be honest that still doesn&#x27;t reconciliate me with this language but I&#x27;m very happy that the effort was made to offer the comparison, and yes, I think that for those who can parse it it should be manageable.</font><br> <font class="QuotedText">&gt;</font><br> <font class="QuotedText">&gt; These words mean a lot to me since I know you dislike the language. Thanks for being open to discussion!</font><br> <p> That&#x27;s the difference between rejecting things by religion and rejecting them by taste :-) I still find a lot of this totally disgusting but I know we don&#x27;t all have the same taste. Flies also exist to remind this to us :-)<br> <p> </div> Fri, 23 Jul 2021 02:59:48 +0000 A GPIO driver in Rust https://lwn.net/Articles/864042/ https://lwn.net/Articles/864042/ wedsonaf Willy, I had to add a bunch of facilities to build this driver. Iterating over bits was one I didn't do because I didn't expect people to care about this when N=8 in a demonstration, but I should have known better. :) <br> For completeness, and to make it clear that there is no limitation to Rust that prevents it from doing simple loops like this, I added it to the repo, the commit is <a href="https://github.com/wedsonaf/linux/commit/f7bc92ee2a1c82662418937fe28b11e8d8108516">here</a>.<br><br> And here's what irq_route looks like now: <pre> fn irq_route(data: &amp;Ref&lt;DeviceData&gt;, router: &amp;gpio::IrqRouter) { if let Some(pl061) = data.resources() { let pending = pl061.base.readb(GPIOMIS); for offset in bits_iter(pending) { router.deliver(offset); } } } </pre> <br> Here are the x86-64 instructions for a loop like the one above (compiler explorer link <a href="https://godbolt.org/z/T1MY4KqWc">here</a>): <pre> .LBB0_2: bsfq %rbx, %rcx movq $-2, %r15 rolq %cl, %r15 movl %ecx, %edi callq *%r14 andq %r15, %rbx jne .LBB0_2 </pre> What I like about the Rust version is that it's type-checked and doesn't need special macros -- you iterate over the bits using the very same for-loop idiom you would to iterate over the nodes of a red-black tree. And yet, we get code that is as efficient as C. Thu, 22 Jul 2021 20:12:02 +0000 type inference surely? https://lwn.net/Articles/864043/ https://lwn.net/Articles/864043/ mathstuf <div class="FormattedComment"> I see it as a bit different. Rust does not have `auto`. In Rust, it is either:<br> <p> - the compiler will figure it out or it will error and I need to help it (not saying anything); or<br> - I will specify the type and the compiler will tell me if there&#x27;s a mistake (by specifying some or all of the type.<br> <p> In C++, `auto` can do quite a number of things including indicating a copy, move, lifetime extension, etc. depending on how one decorates the `auto`. There are lints from `clang-tidy` to at least decorate your `auto` with `const`, `&amp;`, and `*` as appropriate so you at least know the *syntax* of how to use the variable in question and whether it is modifiable. But in all the Rust I&#x27;ve done, the types in the signatures (no `auto` allowed there) have been sufficient. Really, the same as in Haskell most of the time when I did work there. This is largely because of the better ability of these languages to express type combinations and such.<br> <p> There are times you want to specify what *shape* your types are when you&#x27;re working with generic code (usually via the `collect()` mentioned elsewhere in the thread, but `.into()` is also handy to decorate at times), but even there I let the compiler just handle what type is inside of the container (e.g., via `.collect::&lt;Vec&lt;_&gt;&gt;()`). AFAIK, there&#x27;s no placeholder in C++ to say &quot;figure this part out&quot; like `std::vector&lt;auto&gt; v = some_vector_returning_api();` and instead you are left with either naming the whole thing or obsfuscating the whole thing.<br> </div> Thu, 22 Jul 2021 20:01:02 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/864021/ https://lwn.net/Articles/864021/ jgg <div class="FormattedComment"> They can be large constants, it is a gcc extension widely used in the kernel.<br> </div> Thu, 22 Jul 2021 18:46:48 +0000 type inference surely? https://lwn.net/Articles/864020/ https://lwn.net/Articles/864020/ jgg <div class="FormattedComment"> Stated from alot of experiance in C++ where auto does the same thing.. It is a curse and a blessing.<br> <p> The blessing times are when the type is so convoluted and complex that a human can barely manage it. This situation comes up with meta programming quite a bit - ie have a function take these types as input and generate some wild type as output.<br> <p> The curse is that nobody knows WTF is going on any more. &#x27;auto X&#x27; is that an int? A class? How can I use this thing? Basically you are programming in python at this point. At least in C++ auto didn&#x27;t make things worse as prior to auto the &quot;how can I use this thing&quot; would have typically already been obfuscated to death by the MPL environment.<br> <p> But here we are going trom a C project where everything is &quot;simple&quot; straight to &quot;read the code and you still have no idea WTF is going on&quot;. I wonder if people will accept that. Are people going to upgrade their editors to have inspection?<br> <p> Will someone figure out tooling to replace grep? (I would dearly love to have a fast semantic grep even in C)<br> </div> Thu, 22 Jul 2021 18:45:03 +0000 A GPIO driver in Rust https://lwn.net/Articles/864014/ https://lwn.net/Articles/864014/ ojeda <div class="FormattedComment"> <font class="QuotedText">&gt; Still I&#x27;m seeing that an O(log(N)) loop was routinely turned into O(N) in the interrupt handler</font><br> <p> If you are referring to the in-one-go `ffs`, yes, equivalent facilities should be provided by the Rust side too.<br> <p> <font class="QuotedText">&gt; By not placing the explicit unlock, it will hold till the end (if I understand right), which means that any extra code added to that function will be added under that lock even if not required at all.</font><br> <p> Not exactly: the unlock happens at the end of the scope, not at the end of the function.<br> <p> This is an important distinction, because it allows one to precisely control how long the lock is held. RAII would be unworkable otherwise!<br> <p> <font class="QuotedText">&gt; If the compiler is able to do that by itself, instead it should be configured to emit a loud warning for missing unlocks in the return paths.</font><br> <p> Yes, it could be done, and it would be probably a good idea (for cases where RAII is applicable). Another warning could be for double unlocks and unlocks in not-the-opposite-order etc. At that point, one would be doing &quot;explicit RAII&quot;.<br> <p> Being explicit is good in many cases, of course. In the case of RAII, I think being implicit is a good compromise because it avoids a good amount of mechanically-written code while still being easy enough to figure out where the calls happen when needed.<br> <p> A third, middle-ground option is going a bit meta: RAII as usual, but use tooling that renders the calls in your text editor without actually adding them to the code. This already exists for things like showing inferred types in rust-analyzer.<br> <p> <font class="QuotedText">&gt; To be honest that still doesn&#x27;t reconciliate me with this language but I&#x27;m very happy that the effort was made to offer the comparison, and yes, I think that for those who can parse it it should be manageable.</font><br> <p> These words mean a lot to me since I know you dislike the language. Thanks for being open to discussion!<br> </div> Thu, 22 Jul 2021 18:14:04 +0000 A GPIO driver in Rust https://lwn.net/Articles/864005/ https://lwn.net/Articles/864005/ wtarreau <div class="FormattedComment"> I find that it&#x27;s great that Wedson did this. There are quite some parts that I really cannot parse in the rust version (and even with the C in front of it I cannot match the probe function).<br> <p> Still I&#x27;m seeing that an O(log(N)) loop was routinely turned into O(N) in the interrupt handler, and such jokes can make a significant differences at larger scale if developers are not more careful.<br> <p> I absolutely hate the principle of lazy unlocking, letting the compiler handle it by itself. This is a horrible practice in my opinion, because the person who wrote the code had a good reason to put a lock and knows exactly where it ought to be unlocked. By not placing the explicit unlock, it will hold till the end (if I understand right), which means that any extra code added to that function will be added under that lock even if not required at all. And often it&#x27;s not the person who adds the extra code at the end who will take the decision to add an explicit unlock.<br> <p> If the compiler is able to do that by itself, instead it should be configured to emit a loud warning for missing unlocks in the return paths.<br> <p> To be honest that still doesn&#x27;t reconciliate me with this language but I&#x27;m very happy that the effort was made to offer the comparison, and yes, I think that for those who can parse it it should be manageable.<br> </div> Thu, 22 Jul 2021 15:57:30 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/864004/ https://lwn.net/Articles/864004/ wtarreau <div class="FormattedComment"> <font class="QuotedText">&gt; enums are integers and therefore cannot be used for larger constants.</font><br> <p> That&#x27;s exactly why I stopped using them to define bit values in masks! They were convenient for GDB at the beginning but not once they became too short :-)<br> </div> Thu, 22 Jul 2021 15:51:50 +0000 type inference surely? https://lwn.net/Articles/863939/ https://lwn.net/Articles/863939/ tialaramex <div class="FormattedComment"> I think the &quot;magic&quot; could reasonably attract complaints.<br> <p> Stroustrup claims that innovations in C+ are often obliged to be very loud because suspicious C++ programmers worry they won&#x27;t notice the new thing and will be surprised by its consequences. Such innovations can get through committee but if only when given some more verbosity they didn&#x27;t really need - to shake awake readers, so, that&#x27;s what happens. And you end up a few years later writing:<br> <p> annoying verbosity thing = more annoying verbosity { cool_thing.cool [ more verbosity is obligatory here too ] };<br> <p> ... and now that everybody agrees it&#x27;s awesome, they find the verbosity annoying, there&#x27;s pressure to do more standardisation effort so eventually years later it can be:<br> <p> annoy thing = more annoy { cool_thing.cool [ok ] };<br> <p> ... but Bjarne feels like if they just trusted that it&#x27;s going to be awesome it need only ever have been<br> <p> thing = { cool_thing.cool };<br> <p> To some extent Rust editions give them more options to get in or out of syntactic decisions like this, since an edition is almost completely free to change how Rust is spelled, so long as what it means is unaffected.<br> <p> But the concerns about quiet changes are real, and I expect the kernel folks to be more worried about them than the average Rust programmer, and thus, less happy to see magic. Requiring a turbofish for every collect() feels crazy to me, but it might not seem as crazy to kernel maintainers.<br> </div> Thu, 22 Jul 2021 10:38:41 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863915/ https://lwn.net/Articles/863915/ pbonzini <div class="FormattedComment"> It is undefined behavior if a const is changed.<br> </div> Thu, 22 Jul 2021 06:26:37 +0000 I'm delighted to see this https://lwn.net/Articles/863898/ https://lwn.net/Articles/863898/ david.a.wheeler <div class="FormattedComment"> I&#x27;m delighted to see this specific *worked* example. There&#x27;s been a lot of Rust work to provide APIs that could be used. Greg K-H complained (correctly in my view) that he needed to see an actual worked example (I don&#x27;t remember his exact words, but I think that was the gist).<br> <p> There&#x27;s now a lot of discussion about this example, and that&#x27;s as it should be. You learn a lot by trying to make things actually work.<br> </div> Wed, 21 Jul 2021 23:20:06 +0000 type inference surely? https://lwn.net/Articles/863884/ https://lwn.net/Articles/863884/ jezuch <div class="FormattedComment"> <font class="QuotedText">&gt; let sizes: Vec&lt;u32&gt; = something.collect(); // x is a Vec of u32s, so the collect must make one of those</font><br> <p> I only wanted to say that type inference in Rust feels like magic at times. This is not the best example of this, but yes, it&#x27;s usually when `collect()` is involved. I sometimes think it could plausibly be called `dwim()` ;)<br> </div> Wed, 21 Jul 2021 19:19:04 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863731/ https://lwn.net/Articles/863731/ pm215 <div class="FormattedComment"> Also, by the C standard a &#x27;const int&#x27; is not one of the fairly short list of things that the spec says you can use as a constant integer in places like the right-hand side of a &#x27;const int x = ...&#x27; initializer. So gcc 7 and earlier will not compile code like &#x27;const int x = 5; const int y = x + 2;&#x27;. (The spec permits compilers to allow an impdef extra set of things to be treated as compile-time constant expressions, and gcc 8 and up are more intelligent/friendly and will compile that.) We actually just ran into this wrinkle this month in QEMU, so it&#x27;s not purely an &quot;old compilers from a decade ago encouraged #define over const&quot; holdover...<br> <p> </div> Wed, 21 Jul 2021 13:34:24 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863719/ https://lwn.net/Articles/863719/ chris_se <div class="FormattedComment"> <font class="QuotedText">&gt; enums are integers and therefore cannot be used for larger constants.</font><br> <p> Interesting. I work mostly with C++ nowadays, so I haven&#x27;t followed newer C standards closely, but I would have expected that C11 or C17 would improve that. I just looked at the standard and you&#x27;re correct though, in C they are always int.<br> <p> In C++11 and newer you can create enums that have any integral type, even something like int64_t, as their backing type. I&#x27;ve been using these basically since C++11 compilers that supported them came out, so for roughly a decade; learning that C still restricts enums to int is completely counter to my current intuition about that language feature. And a good indication that C++ and C have diverged quite a bit nowadays.<br> </div> Wed, 21 Jul 2021 08:55:10 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863697/ https://lwn.net/Articles/863697/ creemj <div class="FormattedComment"> Futhermore const in C does not mean constant, that is, it is a guarantee that the variable will only be read, not written (except at declaration), in the compilation unit, but that is not a guarantee that it will not be written in any circumstance whatsoever.<br> </div> Wed, 21 Jul 2021 02:39:20 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863683/ https://lwn.net/Articles/863683/ aliguori <div class="FormattedComment"> enums are integers and therefore cannot be used for larger constants.<br> </div> Tue, 20 Jul 2021 22:39:17 +0000 Machine code https://lwn.net/Articles/863663/ https://lwn.net/Articles/863663/ atnot <div class="FormattedComment"> The thread mentions that the rust code is significantly larger due to having additional features around device handling and differences in LTO and inlining support<br> </div> Tue, 20 Jul 2021 20:15:26 +0000 A GPIO driver in Rust https://lwn.net/Articles/863639/ https://lwn.net/Articles/863639/ willy <div class="FormattedComment"> I&#x27;ve been mulling the difference between how we implement spin_lock_irq(), spin_lock_irqsave() and spin_lock_bh().<br> <p> We could, in principle, make spin_lock_irq() behave like spin_lock_bh(). That is, it automatically takes care of nesting, can be called in all contexts, and doesn&#x27;t need a flags argument passed to it (because it stores its state in current).<br> <p> Would it really have worse performance than the current spin_lock_irq() and spin_lock_irqsave() pair? I&#x27;m a little busy right now so I haven&#x27;t delved into it. But if anyone&#x27;s looking for a project ...<br> </div> Tue, 20 Jul 2021 17:02:43 +0000 A GPIO driver in Rust https://lwn.net/Articles/863587/ https://lwn.net/Articles/863587/ xav <div class="FormattedComment"> <font class="QuotedText">&gt; It would seem that the C code is &quot;hold it this way and you&#x27;ll be fine&quot;[2] whereas Rust is more &quot;you have a reference to me, so I must keep myself safe&quot;.</font><br> <p> That would match my experience with C and Rust very nicely.<br> </div> Tue, 20 Jul 2021 14:29:44 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863585/ https://lwn.net/Articles/863585/ epa <div class="FormattedComment"> I guess it&#x27;s surprising that an enum is not more widely used to create a group of compile-time constants.<br> </div> Tue, 20 Jul 2021 14:25:07 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863565/ https://lwn.net/Articles/863565/ Karellen <p>Old versions of C, and old C compilers, required that a named "const int" would only be defined in one file (e.g. "const int x = 3;"). This is the "One Definition Rule". All the other files would see a declaration (e.g. "extern const int x;"), typically from a header file, so they'd know the variable existed, but they wouldn't know what the value of that variable was. Compilers which worked a file at a time wouldn't be able to perform any optimisations based on the value of the variable. Using the value would require loading it, rather than just using an immediate value. <p>You could get around this by putting a static declaration in a header file (e.g. "static const int x = 3;") so that each file would get its own private declaration of the variable, which wouldn't clash with the same variable in other files. The value would typically get inlined everywhere, if the compiler did any optimisations at all. And maybe the variable itself would get optimised out if there were no other uses of it. <p>But you'd be guaranteed to get the actual value inlined everywhere and no left-over variables if you just used a #define (e.g. "#define x 3"). <p>So using "#define" over "const int" is the traditional idiomatic style in C, because compilers were dumb. And even though most compilers aren't dumb any more, some are. And so, that's how people who write C, write C. Which is why Linux and other C codebases use it. Tue, 20 Jul 2021 13:54:39 +0000 type inference surely? https://lwn.net/Articles/863561/ https://lwn.net/Articles/863561/ tialaramex <div class="FormattedComment"> I think &quot;type erasure&quot; is a term of art for specifically the way some languages consider types in one phase, then forget (erase) them e.g. to enable generics in Java the actual output bytecode does not mention the constraints it says Object everywhere, the real type was erased.<br> <p> So in this respect C and Rust are no different from each other, you get fancy high level &quot;structure&quot; types in the programming language but the machine code leaves no trace of those types, just whatever register sizes and arithmetic operations exist on that CPU.<br> <p> I think what you&#x27;re worried about might be Rust&#x27;s type inference? This is optional, and I guess the kernel could insist on some more (or even _far_ more, but Linus seems too pragmatic to go down that road) verbosity.<br> <p> That is, Rust doesn&#x27;t mind whether you write:<br> <p> let x: Foozle = something.getFoozle(); // x is a Foozle<br> <p> or let the compiler infer from its type signature that getFoozle() returns a Foozle, so obviously:<br> <p> let x = something.getFoozle(); // x is still a Foozle. Same type, just inferred by the compiler<br> <p> The latter is more idiomatic, but if kernel style says you need to spell out that getFoozle results in a Foozle, so be it.<br> <p> <p> The same inference can be (and is) used elsewhere, for example:<br> <p> let sizes: Vec&lt;u32&gt; = something.collect(); // x is a Vec of u32s, so the collect must make one of those<br> <p> gets the same code as if you spell out to the compiler what sort of collect to use instead of what type the result must be:<br> <p> let sizes = something.collect::&lt;Vec&lt;u32&gt;&gt;(); // Now we told the compiler which collect() to use, it can infer the type of x<br> <p> In this case the former is the idiomatic example, but the latter illustrates a &quot;turbofish&quot; ::&lt;&gt; operator that lets you explicitly tell the compiler the type parameters of a generic function. A future kernel Rust style guide could insist on the turbofish everywhere, or even demand both the turbofish and the type of sizes, but I expect many Rust programmers would wonder why, the compiler can do this for us, why tell it what you both already know?<br> <p> It&#x27;s certainly useful to stop sometimes and contemplate in Rust, what *is* the type of some.thing(in).this().chain() ? You can teach Vim or Emacs and presumably shiny GUI editors to tell you what the type is of things you&#x27;re looking at, since Rust is fairly well suited to this question, so it may be that quickly people writing more than one or two patches a year to Rust in the kernel have those tools and never experience concern. But it&#x27;s also possible Linus decides the style guide needs to force them to use more variables and always spell out types as they go. Choosing never to do type inference should have zero impact on output code, though I can&#x27;t say the same for the impact on source code readability.<br> </div> Tue, 20 Jul 2021 12:59:33 +0000 Defining constants rather than using preprocessor https://lwn.net/Articles/863563/ https://lwn.net/Articles/863563/ HelloWorld <div class="FormattedComment"> Defining them as const int would require memory at runtime, and you would be able to access it from other compilation units with an extern declaration. But declaring them static would fix that.<br> </div> Tue, 20 Jul 2021 12:45:18 +0000