How to make a const generic parameter dependent on a feature?

Hey, basically, I want to make this code syntactically valid:

impl<
        Ul,
        const ROW: usize,
        const COL: usize,
        #[cfg(feature = "chords")] const N: usize,
        #[cfg(feature = "chords")] const K: usize,
    > Layout<Ul, ROW, COL, #[cfg(feature = "chords")] N, #[cfg(feature = "chords")] K>
{
    // etc.
}

The compiler tells me:

error: invalid const generic expression
   --> src/layout.rs:169:55
    |
169 |     > Layout<Ul, ROW, COL, #[cfg(feature = "chords")] N, #[cfg(feature = "chords")] K>
    |                                                       ^
    |
help: expressions must be enclosed in braces to be used as const generic arguments
    |
169 |     > Layout<Ul, ROW, COL, #[cfg(feature = "chords")] { N }, #[cfg(feature = "chords")] K>
    |                                                       +   +

But if I try to add these braces, I get the exact same message again:

error: invalid const generic expression
   --> src/layout.rs:169:54
    |
169 |     > Layout<Ul, ROW, COL, #[cfg(feature = "chords")]{ N }, #[cfg(feature = "chords")] K>
    |                                                      ^^^^^
    |
help: expressions must be enclosed in braces to be used as const generic arguments
    |
169 |     > Layout<Ul, ROW, COL, #[cfg(feature = "chords")]{ { N } }, #[cfg(feature = "chords")] K>
    |                                                      +       +

How am I supposed to write that?

Edit: well, it appears that it does not work either with regular generic parameters: Rust Playground

1 Like

I could do it with a macro, but it's a bit crappy. I'd very much like a cleaner way to do that:

#[cfg(feature = "chords")]
macro_rules! layout_impl {
    ($ul:ident, $row:ident, $col:ident, $n:ident, $k:ident) => { Layout<$ul, $row, $col, $n, $k> }
}
#[cfg(not(feature = "chords"))]
macro_rules! layout_impl {
    ($ul:ident, $row:ident, $col:ident, $n:ident, $k:ident) => { Layout<$ul, $row, $col> }
}

impl<
        Ul,
        const ROW: usize,
        const COL: usize,
        #[cfg(feature = "chords")] const N: usize,
        #[cfg(feature = "chords")] const K: usize,
    > layout_impl!(Ul, ROW, COL, N, K)
{
    // etc.
}
1 Like

I am having the exact same problem. There is also a related post on StackOverflow: rust - Varying number of generic parameters based on a feature - Stack Overflow but the only solution seems to be to use macros.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.