rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
13.62k stars 1.49k forks source link

Proc macro is panicking in `rust-analyzer` when it does not in a `rustc` compilation [Nightly Rust] #17193

Closed d3rpp closed 1 week ago

d3rpp commented 1 week ago

rust-analyzer version: 0.4.1948-standalone

rustc version:

editor or extension: VSCode

relevant settings:

repository link (if public, optional): d3rpp/proc_macros_path_panicking_incorrectly

code snippet to reproduce:

The repository link is a reproduced example, it is able to replicate the issue exactly as it is occurring in the main project (which is unfortunately closed source)

// look above

Note: This is using unstable features in order to provide the information that enables this bug to be triggered.

#![feature(proc_macro_span)]
Veykril commented 1 week ago

The unstable proc-macro apis are currently unimplemented in r-a https://github.com/rust-lang/rust-analyzer/issues/15950

d3rpp commented 1 week ago

For those that come across this and want their squiggly lines to go away, I've got 2 work arounds for you:

[!NOTE] I'm yet to test either of these, and they've been written from memory.

Detect when rust-analyzer is running the macro and act accordingly

in my reproducible example there's a line showing that the path simply shows up as being empty, since you'll either get a path or a compiler error in regular rust, we can use this to detect if the macro is being analyzed and just make it return an empty token stream.

use proc_macro::Span;
use proc_macro2::TokenStream;

#[proc_macro]
pub fn proc_macro(_input: TokenStream) -> TokenStream {
    let is_rust_analyzer = Span::call_site()
        .source_file()
        .path()
        .into_os_string()
        .is_empty();

    if is_rust_analyzer {
        TokenStream::default()
    } else {
        // ...
    }
}

Just, ignore the macro.

this is more useful to macros that are reside in, and are only used by, one project (like in my use case), they rust-analyzer devs are cool enough to allow you to add a config that just gets it to completely ignore specific macros.

Set the option

rust-analyzer.procMacro.ignored

to an object shaped like something below (below taken from VSCode)

"rust-analyzer.procMacro.ignored": {
    "crate_name": [
        "macro_name"
    ]
}

I'd recommend applying this to workspace settings as opposed to global settings, that way other users of the repo have the setting.