Skip to content
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

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

Closed
tgross35 opened this issue Jan 29, 2023 · 10 comments · Fixed by #14349
Closed
Labels
A-nameres name, path and module resolution C-bug Category: bug

Comments

@tgross35
Copy link
Contributor

tgross35 commented Jan 29, 2023

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 {}
}
@tgross35
Copy link
Contributor Author

Removing the #[cortex_m_rt::entry] macro makes the error display at the correct location

image

@Veykril Veykril added A-nameres name, path and module resolution C-bug Category: bug labels Jan 29, 2023
@Sculas
Copy link
Contributor

Sculas commented Mar 11, 2023

I'm having this issue as well when using sqlx::query!.

@MilanLoveless
Copy link

I'm also observing this behavior when using sqlx::query!

@Veykril
Copy link
Member

Veykril commented Mar 14, 2023

To the sqlx people, do you have a private-field error or an unresolved-field error? Asking as the original issue reproduction seems fixed now.

@tgross35
Copy link
Contributor Author

tgross35 commented Mar 14, 2023

@Veykril was there a fix in RA that resolved the original issue? That PR I submitted to the rtt-target repo fixes the issue from that side in newer versions, but I think it would still reproduce with an older pinned version (though I have not verified)

@Sculas
Copy link
Contributor

Sculas commented Mar 14, 2023

To the sqlx people, do you have a private-field error or an unresolved-field error? Asking as the original issue reproduction seems fixed now.

I got the private-field error, "field 'exists' is private".

@Veykril
Copy link
Member

Veykril commented Mar 14, 2023

Sorry I didn't realize this was "fixed" in a new rtt-target version, I'll try it out on an earlier version then.

@Veykril
Copy link
Member

Veykril commented Mar 14, 2023

Okay, minimal repro:

fn main() {
    let strukt = {
        use crate as ForceParentBlockDefMap;
        {
            pub struct Struct {
                field: (),
            }
            Struct { field: () }
        }
    };
    strukt.field;
}

@tgross35
Copy link
Contributor Author

Thank you!

@MilanLoveless
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-nameres name, path and module resolution C-bug Category: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants