BitMap is Picky about Size

I'm learning a lot playing with software for a Keybow. Discontinued HW that has keypad with 12-keys, each with an RGB LED under the key, and a Raspberry Pi Zero W attached underneath.

In trying to make my code cleaner I see my keydown_mask: Bitmap<12> and that 12 hurts my eyes somehow, but Bitmap is being ornery when I try to fix it.

So I am trying to refactor things to move hardware specific stuff to a single file. (I'm pobably doing it in a silly way, but that's not my question.)

[…]
use super::hw_specific;
use super::hw_specific::NUM_KEYS;
[…]
keydown_mask: Bitmap<12>, // Works.
[…]
keydown_mask: Bitmap<NUM_KEYS>, // Works.
[…]
keydown_mask: Bitmap<hw_specific::NUM_KEYS> // Fails.
[…]

The error is:

error[E0747]: unresolved item provided when a constant was expected
   --> src/keybow/keys.rs:424:30
    |
424 |         keydown_mask: Bitmap<hw_specific::NUM_KEYS>,
    |                              ^^^^^^^^^^^^^^^^^^^^^
    |
help: if this generic argument was intended as a const parameter, surround it with braces
    |
424 |         keydown_mask: Bitmap<{ hw_specific::NUM_KEYS }>,
    |                              +                       +

error[E0747]: unresolved item provided when a constant was expected
   --> src/keybow/keys.rs:425:28

My definition in hw_specific.rs is pub const NUM_KEYS: usize = 12;.

I don't get the error when defining an array:

[rgb::RGB<u8>; hw_specific::NUM_LEDS]

Nor when creating a Vec:

Vec::<bool>::with_capacity(hw_specific::NUM_LEDS);

This isn't a serious practical problem, but as I am still learning Rust, it is a puzzlement.

What is going on?

Thanks,

-kb

UPDATE: Doing as the compiler suggests (Bitmap<{hw_specific::NUM_KEYS}>)) does work, but I don't yet understand why.

The thing that is unique about this situation that doesn't apply to arrays is that each generic parameter in a <...> can be a type, a lifetime, or a const value, and some::path can be either a type or a named constant. I'm not clear on exactly why the current rule has to be the way it is, but if you write a path (that is, a name with a :: in it) then you have to use {} if the path is to a constant (and leave it off if the path is to a type).

So, you can follow the advice the compiler gave you to avoid this issue:

help: if this generic argument was intended as a const parameter, surround it with braces
    |
424 |         keydown_mask: Bitmap<{ hw_specific::NUM_KEYS }>,

Or you can use hw_specific::NUM_KEYS; and then write Bitmap<NUM_KEYS>, and the compiler will be happy.

In my odd little educational project, it seems every time I think I'm about to move faster I have to slow down to learn something I didn't know. Which I guess is the point of what I am doing!

Thanks a bunch for your help,

-kb

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.