I need help to understand this error

Hi all

In my bevy game, I have multiple menus, which work correctly using the mouse. I would like to use keyboard also. For this, I created a trait to manage keyboard navigation :

pub trait ButtonNav<T> {
    fn up(&self, current: T) -> Option<T>;
    fn down(&self, current: T) -> Option<T>;
}

// As most of the menu are simple one (a 2 vertical buttons for example), 
// I impl this trait for slices :
impl<T> ButtonNav<T> for [T]
where
    T: PartialEq + Clone,
{
    fn up(&self, current: T) -> Option<T> {
        let i = self.iter().position(|v| *v == current)?;
        self.get(i.saturating_sub(1)).cloned()
    }

    fn down(&self, current: T) -> Option<T> {
        let i = self.iter().position(|v| *v == current)?;
        self.get(i + 1).cloned()
    }
}

// In bevy, resources must be stored in specific type, so I will do someting like
// struct MyMenu([MyButton])
// I would like MyMenu to impl the ButtonNav trait, 
// For this, I give the contract that the MyMenu deref to ButtonNav trait
impl<S, T, N> ButtonNav<T> for S
where
    S: std::ops::Deref<Target = N>,
    N: ButtonNav<T>,
{
    fn up(&self, current: T) -> Option<T> {
        (**self).up(current)
    }

    fn down(&self, current: T) -> Option<T> {
        (**self).down(current)
    }
}

OK, Let's try

#[derive(Clone, Copy, PartialEq)]
enum MenuButtonAction {
    PlayGame,
    ExitApplication,
}

struct MainMenuButtonNav([MenuButtonAction; 2]);

impl Default for MainMenuButtonNav {
    fn default() -> Self {
        MainMenuButtonNav([
            MenuButtonAction::PlayGame,
            MenuButtonAction::ExitApplication,
        ])
    }
}

impl std::ops::Deref for MainMenuButtonNav {
    type Target = [MenuButtonAction];
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

fn main() {
    let nav = MainMenuButtonNav::default();

    button_keyboard_nav(nav, MenuButtonAction::PlayGame);
    // let container = MyStructContainer(MyStruct { i: 5 });
    // do_func(container, 8);
    // println!("Hello, world!");
}

fn button_keyboard_nav<T, N>(nav: N, current: T)
where
    T: PartialEq + Clone,
    N: ButtonNav<T>,
{
    let _new = nav.down(current);
}

I get the followinf error :

error[E0277]: the size for values of type `[MenuButtonAction]` cannot be known at compilation time
  --> src/main.rs:31:25
   |
31 |     button_keyboard_nav(nav, MenuButtonAction::PlayGame);
   |     ------------------- ^^^ doesn't have a size known at compile-time
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `std::marker::Sized` is not implemented for `[MenuButtonAction]`, which is required by `MainMenuButtonNav: nav::ButtonNav<_>`
   = help: the trait `nav::ButtonNav<T>` is implemented for `[T]`
note: required for `MainMenuButtonNav` to implement `nav::ButtonNav<MenuButtonAction>`
  --> src\nav.rs:21:15
   |
21 | impl<S, T, N> ButtonNav<T> for S
   |            -  ^^^^^^^^^^^^     ^
   |            |
   |            unsatisfied trait bound introduced here
note: required by a bound in `button_keyboard_nav`
  --> src/main.rs:40:8
   |
37 | fn button_keyboard_nav<T, N>(nav: N, current: T)
   |    ------------------- required by a bound in this function
...
40 |     N: ButtonNav<T>,
   |        ^^^^^^^^^^^^ required by this bound in `button_keyboard_nav`

I don't understand what does that mean...
Any help ?

Maybe try changing

impl<S, T, N> ButtonNav<T> for S

to

impl<S, T, N: ?Sized> ButtonNav<T> for S
1 Like

This is indeed the solution. Why do I need it ?

You can find some basic information here:

Feel free to ask if that leaves further questions :wink:

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.