public inbox for linux-kbuild@vger.kernel.org
 help / color / mirror / Atom feed
From: "Gary Guo" <gary@garyguo.net>
To: "Yury Norov" <ynorov@nvidia.com>,
	"Miguel Ojeda" <miguel.ojeda.sandonis@gmail.com>
Cc: "Gary Guo" <gary@garyguo.net>, "Benno Lossin" <lossin@kernel.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun@kernel.org>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Yury Norov" <yury.norov@gmail.com>,
	"Nathan Chancellor" <nathan@kernel.org>,
	"Nicolas Schier" <nsc@kernel.org>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	linux-kbuild@vger.kernel.org
Subject: Re: [PATCH 2/2] rust: add `const_assert!` macro
Date: Mon, 09 Feb 2026 05:16:11 +0000	[thread overview]
Message-ID: <DGA6C99D24FV.34J2JWKWY08LS@garyguo.net> (raw)
In-Reply-To: <aYj7J0yTJtYlxLt4@yury>

On Sun Feb 8, 2026 at 9:07 PM GMT, Yury Norov wrote:
> On Sun, Feb 08, 2026 at 11:35:51AM +0100, Miguel Ojeda wrote:
>> On Sun, Feb 8, 2026 at 6:58 AM Yury Norov <ynorov@nvidia.com> wrote:
>> >
>> > This is confusing. You begin with "const_assert!() is more powerful",
>> > and finally recommend to use a less powerful option.
>> 
>> The goal is that users use the least powerful one that applies, not
>> the other way around, because the least powerful ones fail earlier and
>> are generally more robust.
>> 
>> I think the first example is intended to show the different ones, but
>> I think the wording can be improved -- the one in the existing
>> `build_assert!` docs is a bit clearer.
>
> Can you please keep more context? It would be easier to refer to an
> example if I have it on hand.
>  
>> Gary: perhaps we could factor out the explanation/examples to the
>> module-level docs, and then link to it from all the three asserts.
>> 
>> > I don't think this compiler implementation details should sneak into
>> > the kernel. The compiler may get changed, or whatever else, and this
>> > all will become just non-relevant.
>> 
>> How do they sneak into the kernel? Gary is explaining why it is not
>> called "link time", precisely because that would expose more details,
>> not less.
>> 
>> Regardless, that "link-time" vs. "build-time" discussion is
>> independent of this patch, because those docs already exist in the
>> tree.
>
> Again, more context would help. So this is the original comment from
> Benno, and Gary's reply:
>
>   > I think having "Build-time check" here is a bit confusing, how about we
>   > change it to "Link-time check"? Since a "Compile-time check" also is
>   > done at "Build-time"
>   
>   This is the intentional phrasing that I used for `build_assert!` when I created
>   it, for the reason that `build_assert!` ensure that it will fire, at latest,
>   link time. However, if you actually use such methods with CTFE, it will error
>   earlier. So it is "at latest link-time check", so I decided to just use
>   "build-time".
>
> I agree with ""Build-time check" here is a bit confusing", and the
> following indeed looks like a compiler implementation discussion. So
> I concluded that the difference between build_assert and const_assert
> is not visible from programmer's POV. Please correct me if I'm wrong.
>
>> > On the C side we've got similar statically_true() and const_true()
>> > macros, but they seemingly have a different meaning:
>> 
>> > Is it possible to maintain consistency with C on rust side? If not,
>> > can you take those C comments as the reference for what level of
>> > detalization is desired? Maybe pick different names then?
>> 
>> Please explain what inconsistency you are seeing here.
>
> OK, maybe it's just me, but this is how I build a map between rust and C:
>
>  - Plain BUG_ON() matches plain assert!();
>  - BUILD_BUG_ON() is compiletime_assert() and matches build_assert!();

These two are correct.

Notably, `build_assert!` uses the same mechanism as `BUILD_BUG_ON`, i.e.
generating a undefined symbol reference is it failed to be optimized out.

>  - BUILD_BUG_ON_ZERO() - same as BUILD_BUG_ON(), but can be used in
>    initialization constructions, like GENMASK(), i.e. rvalue. No direct
>    analogue in Rust;
>  - BUILD_BUG_ON(statically_true()) - allows runtime conditions, like
>    "true || runtime_cond", and matches static_assert!() in rust;

`static_assert!(expr)` in Rust is equivalent to `static_assert(expr)` in C. This
means that the expression is evaluated by the compiler.

There's no equivalent construct of `statically_true` and `const_true` in Rust.
Rust intentionally avoid providing the ability to observe different behaviour in
compile time and runtime. These macros simply return `false` if the
evaluatability is not met; Rust's `static_assert!()` (and C's `static_assert!`
and the `const_assert!()` will fail the compilation with a compiler error (not
an assertion failure) if the expression cannot be evaluated at compile time.

>  - BUILD_BUG_ON(const_true()) - doesn't allow runtime conditions.
>
> I expected that const_assert!() would be an analogue for
> BUILD_BUG_ON(const_true()), but it is seemingly a different thing. Or
> am I wrong?
>  

Let me give a summary of the three assertions in Rust:

`static_assert!(expr)` is equivalent to `static_assert` in C. It requires `expr`
to be a constant expression. This expression cannot refer to any generics.
When you write a `static_assert!(expr)` in a program, it is always evaluated,
regardless if the function it appears in is used or not.

`const_assert!()` has no equivalent in C, because C does not have generics.
However, you can treat it as a more powerful version of `static_assert!()`. We
need it because it has the ability to refer to generics. It also requires the
expression to be constant expression. *However*, because it can refer to
generics, it is inherently tied to a specific instance of a function. So if you
use it in a generic function and the function is not used, the assertion will
not be performed. `static_assert!` is recommend over `const_assert!` if possible
for this reason. It also has a limitation that it is only usable inside a
function (strictly speaking in Rust term, bodies).

`build_assert!()` is equivalent to our `BUILD_BUG_ON`. It is even more powerful
than `const_assert!()` because it is supposed to be able to check tautologies
that depend on runtime value (similar to C). However, as the assertion failure
mechanism is undefined symbol and linker error, it is not developer friendly so
it is recommend to avoid it and prefer other two assertions where possible.

In summary:
`static_assert!()`, `const_assert!()` and `build_assert!()` in that order has
increasing expressiveness, but decreasing robustness and the checks are
performed later in the pipeline. Hence, the suggestion to use the least powerful
one that still works.

Regarding the name:

`const_assert!()` has it's name because it is literally

    const { assert!() }

where `const {}` is a construct in Rust which says "this must be a constant
expression and evaluated at compile time". The names here refer to related Rust
constructs rather than `statically_true` and `const_true` in the C side.

Best,
Gary



>> Also, please note that two of the three names have been for years in
>> the kernel tree, and that standard C also uses `static_assert` as a
>> name. `const_assert` fits the pattern and it literally expands to what
>> it says.
>> 
>> Moreover, `const` in C is not the same as `const` in Rust. `constexpr`
>> in C is closer to `const` in Rust.
>> 
>> By the way, I am not sure why you suggested `const_true` for the name
>> of that C macro -- I think it should be `constexpr_true` instead,
>> which is closer to what it does, and it fits the pattern on the C side
>> better, too. So that would be more consistent.
>
> I suggested const_true() over the original underscored _statically_true(),
> and this is an obvious improvement. If you think that 'constexpr_true()'
> would add to explainability, please submit a patch. I have a weakly
> negative opinion on that.



>
> Thanks,
> Yury


  reply	other threads:[~2026-02-09  5:16 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260206171253.2704684-1-gary@kernel.org>
2026-02-06 17:12 ` [PATCH 2/2] rust: add `const_assert!` macro Gary Guo
2026-02-06 21:30   ` Benno Lossin
2026-02-06 21:48     ` Gary Guo
2026-02-08  5:58       ` Yury Norov
2026-02-08 10:35         ` Miguel Ojeda
2026-02-08 21:07           ` Yury Norov
2026-02-09  5:16             ` Gary Guo [this message]
2026-02-09 11:44             ` Miguel Ojeda
2026-02-12 20:16               ` Yury Norov
2026-02-06 22:21   ` John Hubbard
2026-02-06 22:28     ` Gary Guo
2026-02-06 23:37       ` John Hubbard
2026-02-13  1:16   ` Yury Norov
2026-02-13  9:06     ` Gary Guo
2026-02-13 10:26       ` Miguel Ojeda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DGA6C99D24FV.34J2JWKWY08LS@garyguo.net \
    --to=gary@garyguo.net \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=dakr@kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=miguel.ojeda.sandonis@gmail.com \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=ynorov@nvidia.com \
    --cc=yury.norov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox