Smithay/wayland-rs

event_created_child macro can cause downcast error if constants are not imported

i509VCB opened this issue · 0 comments

The example for the macro is the following:

event_created_child!(MyState, WlFoo, [
    EVT_CREATE_BAR => (WlBar, BarUserData::new()),
]);

And expands to the following:

fn event_created_child(
    opcode: u16,
    qhandle: &QueueHandle<$selftype>
) -> std::sync::Arc<dyn ObjectData> {
    match opcode {
        EVT_CREATE_BAR => {
            qhandle.make_data::<WlBar, _>(BarUserData::new())
        },
        _ => {
            panic!("Missing event_created_child specialization for event opcode {} of {}", opcode, <$iface as $crate::Proxy>::interface().name);
        },
    }
}

However if the EVT_CREATE_BAR constant is not imported, rustc will treat the EVT_CREATE_BAR identifier as the name of the variable to pass through to the default branch.

Typically you would do that in Rust for something like this:

match value {
    0 => println!("Zero"),
    1 => println!("One"),
    x => println!("Something else: {}"),
}

This is able to be detected if the unused_variable lints (in my own code):

warning: unused variable: `EVT_TOPLEVEL_OPCODE`
  --> wm/src/foreign_toplevel.rs:65:9
   |
65 |         EVT_TOPLEVEL_OPCODE => (ExtForeignToplevelHandleV1,
   |         ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_EVT_TOPLEVEL_OPCODE`
   |
   = note: `#[warn(unused_variables)]` on by default

With a single match this is a very small problem, but with multiple match statements you will get a downcast error later in wayland-backend.

I think we should try to change the macro to make this error impossible or find an alternative to event_created_child.