Skip to content

Build error 'identifier appears more than once in list' after update to rust 1.50 #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrey-shigantsov opened this issue Mar 25, 2021 · 25 comments

Comments

@andrey-shigantsov
Copy link

andrey-shigantsov commented Mar 25, 2021

Hi.

I get this error when I use my macro to generate the rtic::app structure.

If I expand the code of my macro only with cargo expand and compile it, it works on rust v 1.50 too.

Rolling back to rust v 1.46 has solved this problem for me.

But I want use latest rust.

@korken89
Copy link
Collaborator

Hi,

What version of RTIC are you using?
I am using 0.5 and 0.6 alpha on latest Rust without issues.

Could you provide a minimal reproducible example as well?

@andrey-shigantsov
Copy link
Author

I an using 0.5.6.

I will try to reproduce this error with a minimal example.

@korken89
Copy link
Collaborator

Thanks!
Have you tried to do a cargo clean so its not something as simple as weird artifacts hanging around?

@andrey-shigantsov
Copy link
Author

rtic-platform.tar.gz

rasaro rtic-platform $ cargo +stable build --example "usart-drv"
   Compiling qemu-board-example v0.1.0 (/home/rasaro/Development/sandbox/tmp/rtic-platform/example-board/qemu-board)
   Compiling cortex-m-rtic-platform v0.1.0 (/home/rasaro/Development/sandbox/tmp/rtic-platform)
error: identifier appears more than once in list
  --> examples/usart-drv.rs:25:1
   |
25 | / rtic_app! {
26 | |     [resources]
27 | |     {
28 | |         usart_drv_counter: i8 = 0,
...  |
87 | |     task_irqs(TIMER_0A, TIMER_0B);
88 | | }
   | |_^
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

error: could not compile `cortex-m-rtic-platform`
rasaro rtic-platform $ cargo +1.46 build --example "usart-drv"
   Compiling qemu-board-example v0.1.0 (/home/rasaro/Development/sandbox/tmp/rtic-platform/example-board/qemu-board)
   Compiling cortex-m-rtic-platform v0.1.0 (/home/rasaro/Development/sandbox/tmp/rtic-platform)
    Finished dev [unoptimized + debuginfo] target(s) in 0.63s

@andrey-shigantsov
Copy link
Author

cargo clean does not help

@korken89
Copy link
Collaborator

korken89 commented Mar 26, 2021

Hi, from what I can see this is not an error from RTIC, but the macro.
Could you try doing this without the rtic_app macro?

I have no idea how this framework of yours works unfortunately.

The error originates from src/macros.rs:604.

@andrey-shigantsov
Copy link
Author

I have not found an error in the macro.

src/macros.rs:604 I know that. I use RUSTFLAGS="-Z macro-backtrace" cargo +nightly build for debug my macros.

cargo expand code works: I expand this code, paste it instead of rtic_app and then builds successfully.

@andrey-shigantsov
Copy link
Author

At rust 1.46 this works well. What could have changed in rust >1.46?

@AfoHT
Copy link
Contributor

AfoHT commented Mar 30, 2021

Just to clarify, with

  • Rust 1.46: Works
  • Rust 1.47: ?
  • Rust 1.48: ?
  • Rust 1.49: ?
  • Rust 1.50: Broken
    Did I understand you correctly?

Tried the versions with a question mark?, could be helpful for narrowing down which version introduce a change causing breakage for you.

Just speculation, could it be the two stage macro execution somehow having changed? First your macro and then RTIC-macro would be the expected order.

@andrey-shigantsov
Copy link
Author

Rust 1.46: Works
Rust 1.47: Broken
Rust 1.48: Broken
Rust 1.49: Broken
Rust 1.50: Broken

@AfoHT
Copy link
Contributor

AfoHT commented Apr 4, 2021

The error message originates from here or here.

Looking at the code it is unhappy about having multiple identical identifiers, however it is unclear if it is resources or "ident" (line 158 or line 140) since the error message is identical.

Unfamiliar with your framework, do you think there's some name collision or such?

This is what I get when running it with macro-backtrace:

~/downloads/rtic-platform-error is 📦 v0.1.0 via R v1.53.0-nightly
❯ env RUSTFLAGS="-Z macro-backtrace" cargo build --example "usart-drv"
   Compiling cortex-m-rtic-platform v0.1.0 (/home/henrik/downloads/rtic-platform-error)
error: identifier appears more than once in list
   --> /home/henrik/downloads/rtic-platform-error/src/macros.rs:604:25
    |
75  |         macro_rules! rtic_app_item {
    |  _______-
    | |_______|
    | |_______|
    | |_______|
    | |_______|
    | |
76  | |
77  | |           (// FINISH
78  | |               $hw_rs_cb:ident,
...   |
394 | /               rtic_app_item!($hw_rs_cb,
395 |                     ($($ztt)*),
396 |                     (
397 |                         $($tt)*
...
421 |                     $($end_tt)*
422 | |               );
    | |________________- in this macro invocation (#4)
...
449 | /               rtic_app_item! (
450 |                     platform_hw_ph_cb,
451 |                     ($($ztt)*),
452 |                     (
...
465 |                     $($end_tt)*
466 | |               );
    | |________________- in this macro invocation (#3)
...
494 | /               rtic_app_item!($hw_rs_cb,
495 |                     ($($ztt)*),
496 |                     ($($tt)*),
497 |                     ($($zrs_tt)*),
...
513 |                     $($end_tt)*
514 | |               );
    | |________________- in this macro invocation (#5)
...
526 | /               $hw_rs_cb!($rs_src_hw: rtic_app_item ($hw_rs_cb,
527 |                     ($($ztt)*),
528 |                     (
529 |                         [$src_name($($src_meta_tt)*)]
...
532 |                     $($end_tt)*
533 | |               ));
    | |_________________- in this macro invocation (#6)
...
604 | |                               $rs_task_name,
    | |                               ^^^^^^^^^^^^^
...   |
752 | |           };
753 | |       }
    | |       -
    | |_______|
    | |_______in this expansion of `rtic_app_item!` (#2)
    | |_______in this expansion of `rtic_app_item!` (#3)
    | |_______in this expansion of `rtic_app_item!` (#4)
    | |_______in this expansion of `rtic_app_item!` (#5)
    |         in this expansion of `rtic_app_item!` (#7)
...
765 | /       macro_rules! rtic_app {
766 |             ( $($tt:tt)* ) => {
767 |                 rtic_app_item!(
    |  _______________-
768 | |                   ( ), ($($tt)*), ( ), ([ ]| |( )){ ( ),( ),( ) }, ([ ]|_cx|( )){(|_byte, _force|{ }),(),()}
769 | |               );
    | |________________- in this macro invocation (#2)
770 |             };
771 | |       }
    | |_______- in this expansion of `rtic_app!` (#1)
    |
   ::: /home/henrik/downloads/rtic-platform-error/example-board/qemu-board/src/lib.rs:27:1
    |
27  | /       macro_rules! ph_cb /* peripheral callback */ {
28  | |           (host_usart: $cb:ident ($($cb_args:tt)*)) => {
29  | |               $cb!(hw_rs: (host_usart, UART0, HOST_USART), {$($cb_args)*});
    | |               ------------------------------------------------------------- in this macro invocation (#7)
30  | |           };
31  | |       }
    | |_______- in this expansion of `platform_hw_ph_cb!` (#6)
    |
   ::: examples/usart-drv.rs:25:1
    |
25  |       / rtic_app! {
26  |       |     [resources]
27  |       |     {
28  |       |         //usart_drv_counter: i8 = 0,
...         |
87  |       |     //task_irqs(TIMER_0A, TIMER_0B);
88  |       | }
    |       |_- in this macro invocation (#1)

error: aborting due to previous error

error: could not compile `cortex-m-rtic-platform`

To learn more, run the command again with --verbose.

@andrey-shigantsov
Copy link
Author

I think this is not a resource name collision. Because cargo expand gives a working code.

To expand the code without rtic::app I rename it in rtic_app_raw macro (src/macros.rs:4):

4c4
<         #[rtic::app(
---
>         #[xrtic::app(

This is what I get when running it with cargo expand:

rasaro rtic-platform $ cargo +nightly expand --example "usart-drv"
    Checking cortex-m-rtic-platform v0.1.0 (/home/rasaro/Development/sandbox/tmp/rtic-platform)

... some build errors ...

... some prelude ...
pub mod uart0_drv {
    use crate::board::hal;
    use crate::board::device;
    use ::cortex_m_rtic_platform::driver::usart as usart_drv;
    pub type Device = device::UART0;
    pub type HwResource = hal::usart::Usart<Device>;
    pub use usart_drv::rtic_task_handler;
    pub use usart_drv::rtic_irq_handler;
    pub type TaskResources = usart_drv::TaskResources;
    pub type IrqResources = usart_drv::IrqResources;
}
# [ xrtic :: app ( device = crate :: board :: device , peripherals = true , monotonic = :: cortex_m_rtic_platform :: rtic_time :: MonotonicTimer ) ]
const APP: () = {
    struct Resources {
        usart_drv_counter: i8,
        uart0_drv_rsx: uart0_drv::IrqResources,
        uart0_drv_rst: uart0_drv::TaskResources,
    }
    # [ init ( spawn = [ usart_test_task , uart0_drv_task ] ) ]
    fn rtic_init(cx: rtic_init::Context) -> rtic_init::LateResources {
        #[allow(unused_variables)]
        let hw_resources = hw_init(cx.core, cx.device);
        if 15 != 2_u8.pow(crate::board::device::NVIC_PRIO_BITS.into()) - 1 {
            ::core::panicking::panic("SYSTEM TIMER: priority is not max");
        }
        #[allow(unused_mut)]
        let (uart0_drv_rsx, uart0_drv_rst) = {
            let uart0_drv_rst = uart0_drv::TaskResources {};
            (uart0_drv::IrqResources {}, uart0_drv_rst)
        };
        cx.spawn.usart_test_task().unwrap();
        cx.spawn.uart0_drv_task().unwrap();
        rtic_init::LateResources {
            usart_drv_counter: 0,
            uart0_drv_rsx,
            uart0_drv_rst,
        }
    }
    # [ task ( resources = [ uart0_drv_rst , usart_drv_counter , ] , priority = 2 , capacity = 16 , spawn = [ uart0_drv_task ] , ) ]
    #[allow(unused_mut)]
    fn uart0_drv_task(mut cx: uart0_drv_task::Context) {
        let rs = cx.resources.uart0_drv_rst;
        match cx.resources.usart_drv_counter.checked_add(1) {
            Some(count) => {
                *cx.resources.usart_drv_counter = count;
            }
            None => {
                *cx.resources.usart_drv_counter = -1;
            }
        }
        uart0_drv::rtic_task_handler(rs);
    }
    # [ task ( binds = UART0 , resources = [ uart0_drv_rsx ] , spawn = [ uart0_drv_task ] , priority = 4 , ) ]
    #[allow(unused_mut)]
    fn uart0_irq(cx: uart0_irq::Context) {
        let spawn = cx.spawn;
        spawn.uart0_drv_task().unwrap();
    }
    # [ task ( priority = 1 , spawn = [ uart0_drv_task ] , schedule = [ usart_test_task ] , resources = [ usart_drv_counter ] , ) ]
    #[allow(unused_mut)]
    fn usart_test_task(mut cx: usart_test_task::Context) {
        cx.spawn.uart0_drv_task().unwrap();
        if cx.resources.usart_drv_counter.lock(|x| *x != -1) {}
    }
    extern "C" {
        fn TIMER_0A();
        fn TIMER_0B();
    }
};

If you insert this code instead of rtiс_app! {...}, then it will work with routine improvements

@AfoHT
Copy link
Contributor

AfoHT commented Nov 10, 2021

Any difference when testing with latest Rust and RTIC RC?

@andrey-shigantsov
Copy link
Author

andrey-shigantsov commented Nov 16, 2021

@AfoHT Trying use latest Rust and RTIC 0.6-rc.2 but got errors

   Compiling cortex-m-rtic-macros v0.6.0-rc.2 (https://github.com/rtic-rs/cortex-m-rtic.git?tag=v0.6.0-rc.2#ca9088a7)
error[E0609]: no field `shared_resource_locations` on type `&analyze::Analysis`
  --> /home/rasaro/.cargo/git/checkouts/cortex-m-rtic-da08f71f062e5e7b/ca9088a/macros/src/codegen/post_init.rs:17:21
   |
17 |         if analysis.shared_resource_locations.get(name).is_some() {
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field
   |
   = note: available fields are: `interrupts`

error[E0609]: no field `local_resource_locations` on type `&analyze::Analysis`
  --> /home/rasaro/.cargo/git/checkouts/cortex-m-rtic-da08f71f062e5e7b/ca9088a/macros/src/codegen/post_init.rs:35:21
   |
35 |         if analysis.local_resource_locations.get(name).is_some() {
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ unknown field
   |
   = note: available fields are: `interrupts`

@AfoHT
Copy link
Contributor

AfoHT commented Nov 24, 2021

The field local_resource_locations has changed to local_resources, but -rc.2 is not aware of this change in rtic-syntax, which is fixed by updating to at least -rc.3 or latest -rc.4 should solve that issue.

https://github.com/rtic-rs/rtic-syntax/pull/61/files#diff-089eb76a42ce093644312806f6da0e9a39ea5ad30ceb3b04fe08e2677bdcdfb9R285

@andrey-shigantsov
Copy link
Author

@AfoHT Thanks!

https://github.com/rtic-rs/cortex-m-rtic/tags
There are no matching tags. Сan you add?.. Or I can use master?

@AfoHT
Copy link
Contributor

AfoHT commented Nov 24, 2021

Nice catch! We've forgotten to push tags, will fix that ASAP.

Other alternatives would be to use the releases via cargo, or latest master like you said.

@andrey-shigantsov
Copy link
Author

andrey-shigantsov commented Nov 24, 2021

via cargo

Even better than a tag! I didn't even think that the RC might be in the cargo version.

@AfoHT
Copy link
Contributor

AfoHT commented Dec 20, 2021

@andrey-shigantsov Any luck with the latest release? :)

@andrey-shigantsov
Copy link
Author

I've been very busy at work lately and can't find time to finish...

@andrey-shigantsov
Copy link
Author

I get a similar error with RTIC RC.

error: interrupt must be an identifier
...
1861 | |               ($($task_irq),+)
     | |                  ^^^^^^^^^

@AfoHT
Copy link
Contributor

AfoHT commented Dec 25, 2021

Hello,

I recall from the previous discussion it works flawlessly with 1.46 but anything later than that is broken.

With that in mind I think the way to solve this is to modify your macro-transformation code to adopt or handle the underlying change by the compiler.

Did you attempt this approach?

@andrey-shigantsov
Copy link
Author

Hi)
I tried to adapt my macro but didn’t succeed...

I realized that the approach I had chosen was not the right one here. My macro is too difficult to maintain, and the resulting code cannot be debugged with a debugger. In the future, I plan to switch to code generation, so this issue can be closed.

@AfoHT
Copy link
Contributor

AfoHT commented Dec 25, 2021

It is not easy, debugging macros running on output generated by macros... not for the feint of heart 😅

I will close this issue then, hopefully code generation will be an easier approach 😃

@AfoHT AfoHT closed this as completed Dec 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants