embassy-rs / nrf-softdevice

Apache License 2.0
269 stars 80 forks source link

Strange compiler error when using type parameters #138

Closed ctron closed 2 years ago

ctron commented 2 years ago

Having a GATT service like:

#[nrf_softdevice::gatt_service(uuid = "444ad9b2-4627-41a6-91a8-da66f8f70e28")]
pub struct ButtonsService<const N: usize> {
    #[characteristic(uuid = "24d1783f-5dd5-40a8-9baf-d0643f9b3076", read, notify)]
    pub presses: [u8; N],
    #[characteristic(uuid = "bc7186b1-577c-4239-ab05-0a546d50d508", read, write)]
    pub period: u16,
}

I would expect this to work. However I do get a weird compiler error:

error[E0107]: missing generics for struct `ButtonsService`
 --> /home/jreimann/git/drogue-device/device/src/drivers/ble/gatt/buttons.rs:2:12
  |
2 | pub struct ButtonsService<const N: usize> {
  |            ^^^^^^^^^^^^^^ expected 1 generic argument
  |
note: struct defined here, with 1 generic parameter: `N`
 --> /home/jreimann/git/drogue-device/device/src/drivers/ble/gatt/buttons.rs:2:12
  |
2 | pub struct ButtonsService<const N: usize> {
  |            ^^^^^^^^^^^^^^ --------------
help: add missing generic argument
  |
2 | pub struct ButtonsService<N><const N: usize> {
  |            ~~~~~~~~~~~~~~~~~

I assume the code generation in the macro doesn't handle this properly.

alexmoon commented 2 years ago

The macro pre-dates const generics so I'm not surprised it has problems parsing them. I'm actually not sure if it handles generics at all.

My recommendation is to use the ServiceBuilder API instead of the macro for anything at all complex. You can look at the ble_dis_bas_peripheral_builder.rs example or use rust-analyzer's expand macro function to get a starting point.

If you'd like to look at fixing the macro for these cases, PRs are welcome.