Skip to content

Incorrect understanding of private member access for locally defined structs within blocks #14047

Closed
@tgross35

Description

@tgross35

rust-analyzer version: rust-analyzer version: 0.3.1377-standalone (daa0138 2023-01-21)

rustc version: rustc 1.69.0-nightly (5e37043d6 2023-01-22)

This is mostly copied from my issue here: probe-rs/rtt-target#30

RA seems to struggle with expanded private members within blocks. Example code, with dependencies cortex-m-runtime and rtt-target with the cortex-m feature:

#![no_std]
#![no_main]

#[cortex_m_rt::entry]
fn main() -> ! {
    rtt_target::rtt_init_print!();
    loop {}
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

RA claims that a private member cannot be accessed, and places the error squiggle over #[cortex_m_rt::entry]

image

There are two errors here:

  1. RA is incorrect here, since the code compiles successfully
  2. The error is indicated at the wrong spot - should be on the rtt_init_print macro and not cortex_m_rt::entry.

Relevant section of expansion:

    let channels = {
            ...
            pub struct Channels {
                up: (UpChannel,), // field defined here
            }
            Channels {
                up: (UpChannel::new(&mut cb.up_channels[0] as *mut _),),
            }
        }
    };
    ::rtt_target::set_print_channel(channels.up.0); // field accessed here
Full expansion
#![feature(prelude_import)]
#![no_std]
#![no_main]
#[prelude_import]
use core::prelude::rust_2021::*;
#[macro_use]
extern crate core;
#[macro_use]
extern crate compiler_builtins;
#[doc(hidden)]
#[export_name = "main"]
pub unsafe extern "C" fn __cortex_m_rt_main_trampoline() {
    __cortex_m_rt_main()
}
fn __cortex_m_rt_main() -> ! {
    let channels = {
        use core::mem::MaybeUninit;
        use core::ptr;
        use ::rtt_target::UpChannel;
        use ::rtt_target::DownChannel;
        use ::rtt_target::rtt::*;
        #[repr(C)]
        pub struct RttControlBlock {
            header: RttHeader,
            up_channels: [RttChannel; (1 + 0)],
            down_channels: [RttChannel; (0)],
        }
        #[used]
        #[no_mangle]
        #[export_name = "_SEGGER_RTT"]
        pub static mut CONTROL_BLOCK: MaybeUninit<RttControlBlock> = MaybeUninit::uninit();
        unsafe {
            ptr::write_bytes(CONTROL_BLOCK.as_mut_ptr(), 0, 1);
            let cb = &mut *CONTROL_BLOCK.as_mut_ptr();
            let mut name: *const u8 = core::ptr::null();
            name = "Terminal\u{0}".as_bytes().as_ptr();
            let mut mode = ::rtt_target::ChannelMode::NoBlockSkip;
            mode = ::rtt_target::ChannelMode::NoBlockSkip;
            cb.up_channels[0]
                .init(
                    name,
                    mode,
                    {
                        static mut _RTT_CHANNEL_BUFFER: MaybeUninit<[u8; 1024]> = MaybeUninit::uninit();
                        _RTT_CHANNEL_BUFFER.as_mut_ptr()
                    },
                );
            cb.header.init(cb.up_channels.len(), cb.down_channels.len());
            pub struct Channels {
                up: (UpChannel,),
            }
            Channels {
                up: (UpChannel::new(&mut cb.up_channels[0] as *mut _),),
            }
        }
    };
    ::rtt_target::set_print_channel(channels.up.0);
    loop {}
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-nameresname, path and module resolutionC-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions