Closed
Description
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]
There are two errors here:
- RA is incorrect here, since the code compiles successfully
- The error is indicated at the wrong spot - should be on the
rtt_init_print
macro and notcortex_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 {}
}