Re: [PATCH RFC 0/3] rust: kunit: #[should_panic] and same test name with different #[cfg(...)] support
From: Gary Guo
Date: Tue Sep 22 2026 - 11:44:50 EST
On Tue Sep 22, 2026 at 4:27 PM BST, David Gow wrote:
> Le 22/09/2026 à 21:35, Gary Guo a écrit :
>> On Tue Sep 22, 2026 at 8:56 AM BST, David Gow wrote:
>>> Le 16/09/2026 à 03:33, Nicolás Antinori a écrit :
>>>> - Is it ok to 'stringify' the configuration so it can be distinguished
>>>> in the report? Would you prefer something like `_case_1` `_case_2` ..
>>>> instead?
>>
>> I also don't like the stringifcation of cfgs.
>>
>>>
>>> I don't _like_ this: my preference would be for us to keep the same
>>> name, and just not emit a test_case for anything which should be
>>> compiled out with cfg. Unfortunately, implementing that is a bit harder
>>> than would be ideal: we need a way of evaluating the cfg() arguments in
>>> a proc macro, I think. (Ultimately, because otherwise there's no way of
>>> statically determining the length of the TEST_CASES array?)
>>
>> This is possible with a trick. In pin-init we have a similar need, so what I do
>> is for
>>
>> #[macro]
>> struct Foo {
>> #[cfg(a)]
>> bar: u32,
>> }
>>
>> to be expanded to
>>
>> #[cfg(a)]
>> #[macro]
>> struct Foo {
>> bar: u32
>> }
>>
>> #[cfg(not(a))]
>> #[macro]
>> struct Foo {
>> }
>>
>> However, for kunit I don't think that's needed. Deduplicating the names
>> should be sufficient?
>>
> The problem with (at least my naive implementation of) duplication is
> that -- while it works great for switching between implementations -- it
> doesn't handle the case where _no_ implementation is active.
>
> (The current implementation just compiles to a skipped test if the
> #[cfg(...)] isn't active, which sidesteps the problem until we have
> multiple implementations...)
>
> Even the expansion above could be problematic, as we really are trying
> to add entries to a static array, so I don't know what we could put in
> the not(a) case (particularly since there'd be potentially lots of them).
>
> Maybe the trick is to generate the array size by using a big series of
> something like:
> static mut TEST_CASES: [...,
> #[cfg(a)] 1
> #[cfg(not(a))]0
> +
> #[cfg(b)] 1
> #[cfg(not(b))]0
> +
> …] = {
> #[cfg(a)] case1,
> #[cfg(b)] case1,
> …
> }
> }
>
For array sizes, you have the option of building a slice first.
Some thing like:
const TEST_CASES_UNIT: &[()] = [
#[cfg(a)] (),
#[cfg(b)] (),
];
static mut TEST_CASES: [...; TEST_CASES_SLICE.len()] = [...];
You could also just build everything as a const slice of `&'static
[kunit_cases]`, if there is no need to make it `mut`. But I suppose it needs to
be `static mut` for some reason?
Best,
Gary
> Then, as long as there's only one or zero active configurations, the
> array size should match, and any duplicates will be caught by having
> multiple definitions of case1.
>
> I assume the compiler would be able to reduce that down to a
> compile-time integer, even if it is extremely ugly...
>
> -- David