jamesmunns / postcard-rpc

An RPC layer for postcard based protocols
Apache License 2.0
48 stars 11 forks source link

`#[deny(unreachable_patterns)]` does not yield an error with duplicated endpoints #34

Closed glaeqen closed 2 weeks ago

glaeqen commented 2 weeks ago

To reproduce:

  1. Apply patch
    diff --git a/example/firmware/src/bin/comms-02.rs b/example/firmware/src/bin/comms-02.rs
    index ad1efff..b7b4106 100644
    --- a/example/firmware/src/bin/comms-02.rs
    +++ b/example/firmware/src/bin/comms-02.rs
    @@ -68,6 +68,7 @@ define_dispatch! {
         Context = Context,
     >;
     PingEndpoint => blocking ping_handler,
    +    PingEndpoint => blocking ping_handler,
     GetUniqueIdEndpoint => blocking unique_id_handler,
     SetSingleLedEndpoint => async set_led_handler,
     SetAllLedEndpoint => async set_all_led_handler,
  2. Try to build firmware crate
  3. Observe success

Expected behaviour

Compilation failure

jamesmunns commented 2 weeks ago

This seems to be down to the fact that lints in expanded code doesn't fire.

If I make one crate that has this:

pub trait Val {
    const VAL: [u8; 8];
}

impl Val for u8 {
    const VAL: [u8; 8] = [0u8; 8];
}

impl Val for u16 {
    const VAL: [u8; 8] = [1u8; 8];
}

#[macro_export]
macro_rules! example {
    ($val: ident, $($name:ty),*) => {
        // We want this macro to fire if there are dupes
        #[deny(unreachable_patterns)]
        match $val {
            $(
                <$name as Val>::VAL => println!("$name"),
            )*
            _ => println!("Other"),
        }
    };
}

And another crate that does this:

#![deny(unreachable_patterns)]

use macro_source::Val;

fn main() {
    let val = [2u8; 8];
    macro_source::example!(val, u8, u8, u16);
}

I don't get the lint to fire at all, even though the expanded code looks like this:

#![feature(prelude_import)]
#![deny(unreachable_patterns)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use macro_source::Val;
fn main() {
    let val = [2u8; 8];
    #[deny(unreachable_patterns)]
    match val {
        <u8 as Val>::VAL => {
            ::std::io::_print(format_args!("$name\n"));
        }
        <u8 as Val>::VAL => {
            ::std::io::_print(format_args!("$name\n"));
        }
        <u16 as Val>::VAL => {
            ::std::io::_print(format_args!("$name\n"));
        }
        _ => {
            ::std::io::_print(format_args!("Other\n"));
        }
    };
}
jamesmunns commented 2 weeks ago

Asked on T-Lang: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/deny.20lint.20behavior.20in.20macro.20expansion/near/444722399

jamesmunns commented 2 weeks ago

Addressed by #35, released in v0.5.1