-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Analysis confused by proc-macro expansion with input very similar to syntactically valid enum
?
#10463
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
Comments
Can you post the exact expansion of the macro invocation in your example? You can use |
Expansion#![feature(prelude_import)]
#![allow(non_camel_case_types, non_upper_case_globals)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
use glazing_macros::oxidize_enum;
mod swconst {
use winapi::ENUM;
pub type swDocumentTypes_e = u32;
pub const swDocNONE: swDocumentTypes_e = 0;
pub const swDocPART: swDocumentTypes_e = 1;
pub const swDocASSEMBLY: swDocumentTypes_e = 2;
pub const swDocDRAWING: swDocumentTypes_e = 3;
pub const swDocSDM: swDocumentTypes_e = 4;
pub const swDocLAYOUT: swDocumentTypes_e = 5;
pub const swDocIMPORTED_PART: swDocumentTypes_e = 6;
pub const swDocIMPORTED_ASSEMBLY: swDocumentTypes_e = 7;
}
extern crate test;
#[cfg(test)]
#[rustc_test_marker]
pub const qualified: test::TestDescAndFn = test::TestDescAndFn {
desc: test::TestDesc {
name: test::StaticTestName("qualified"),
ignore: false,
allow_fail: false,
compile_fail: false,
no_run: false,
should_panic: test::ShouldPanic::No,
test_type: test::TestType::IntegrationTest,
},
testfn: test::StaticTestFn(|| test::assert_test_result(qualified())),
};
fn qualified() {
enum DocumentKind {
swDocNONE,
swDocPART,
swDocASSEMBLY,
swDocDRAWING,
swDocSDM,
swDocLAYOUT,
swDocIMPORTED_PART,
swDocIMPORTED_ASSEMBLY,
}
match DocumentKind::swDocNONE {
DocumentKind::swDocNONE
| DocumentKind::swDocPART
| DocumentKind::swDocASSEMBLY
| DocumentKind::swDocDRAWING
| DocumentKind::swDocSDM
| DocumentKind::swDocLAYOUT
| DocumentKind::swDocIMPORTED_PART
| DocumentKind::swDocIMPORTED_ASSEMBLY => true,
};
}
extern crate test;
#[cfg(test)]
#[rustc_test_marker]
pub const local: test::TestDescAndFn = test::TestDescAndFn {
desc: test::TestDesc {
name: test::StaticTestName("local"),
ignore: false,
allow_fail: false,
compile_fail: false,
no_run: false,
should_panic: test::ShouldPanic::No,
test_type: test::TestType::IntegrationTest,
},
testfn: test::StaticTestFn(|| test::assert_test_result(local())),
};
fn local() {
use swconst::*;
enum DocumentKind {
swDocNONE,
swDocPART,
swDocASSEMBLY,
swDocDRAWING,
swDocSDM,
swDocLAYOUT,
swDocIMPORTED_PART,
swDocIMPORTED_ASSEMBLY,
}
match DocumentKind::swDocNONE {
DocumentKind::swDocNONE
| DocumentKind::swDocPART
| DocumentKind::swDocASSEMBLY
| DocumentKind::swDocDRAWING
| DocumentKind::swDocSDM
| DocumentKind::swDocLAYOUT
| DocumentKind::swDocIMPORTED_PART
| DocumentKind::swDocIMPORTED_ASSEMBLY => true,
};
}
#[rustc_main]
pub fn main() -> () {
extern crate test;
test::test_main_static(&[&qualified, &local])
} |
Yeah, good point. I have been using |
What does rust-analyzer's "Expand macro recursively" command show? What's the actual error message you're getting? (It's rather unlikely that the problem is actually the macro input looking like an enum. RA doesn't parse macro inputs like that. So it's probably more likely that there's some problem with how RA is expanding the macro.) Edit: Also, where does "Go to definition" on the |
That's what I thought initially. It seemed very unlikely that it would be set up that way. But, I couldn't think of any other way it could possibly be picking up |
Hmm... // Recursive expansion of oxidize_enum! macro
// ===========================================
enum DocumentKind {
swDocNONE,swDocPART,swDocASSEMBLY,swDocDRAWING,swDocSDM,swDocLAYOUT,swDocIMPORTED_PART,swDocIMPORTED_ASSEMBLY
} Odd, that looks correct... |
The initial "Fill match arms" did this: match DocumentKind::swDocNONE {
DocumentKind::swconst => todo!(),
DocumentKind::swDocNONE => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocPART => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocASSEMBLY => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocDRAWING => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocSDM => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocLAYOUT => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocIMPORTED_PART => todo!(),
DocumentKind::swconst => todo!(),
DocumentKind::swDocIMPORTED_ASSEMBLY => todo!(),
}; |
Umm, no idea why... but it's working now? I put the "enum" token-supporting bit back in to get the recursive expansion... and I just noticed that Aw, dang it, maybe it updated when I started VS Code back up this morning? I probably should have checked for that yesterday... |
I think it might not be detecting changes in proc macro source code properly, so it's not refreshing them? I'm having persistent issues where changing the
|
It seems possible that this problem might be related to my environment. Didn't seem relevant before, as I assumed a logic error, so here goes: Windows 10 |
Ah, seems likely. Ok, so this is already a known issue. Thanks! |
Apologies if this falls under purview of known proc-macro limitations. From my limited perspective, it doesn't seem to.
A proc macro that generates valid
enum
s from "enum-like" syntax seems to trip uprust-analyzer
Simply removing the "enum" token from both variations (and removing the associated proc macro parsing) works just fine. This seems to indicate that
rust-analyzer
is capable of expanding and analyzing an proc macro that generates an enum, just that -- for some reason -- it gets hung up if the macro input looks sufficiently like anenum
before expansion.I initially included the "enum" token as part of the macro input following the pattern established by
winapi::ENUM
macro. It doesn't generate anenum
(but only atype
alias from what would be theenum
's identifier and constants (not syntactically related, and thus not compile-time checkable) for each variant), so it doesn't confuserust-analyzer
. The whole point of my macro, though, is to generate a Rustenum
for better ergonomics in higher-level bindings to Microsoft COM components. It uses the outputs of thewinapi::ENUM
macro (manually collected), because bindgen'd enum values.It's a simple enough fix for my purposes simply to continue eliding the "enum" token from my macro input.
The behavior here, though, seems like it might mess other people's macros up, though. What if a macro is written that takes a valid
enum
as input but modifies it into another validenum
? It seems thatrust-analyzer
might also incorrectly base its analysis on the pre-expansion valid macro.Also, it seems to indicate a deficiency in
rust-analyzer
's syntax parsing:rustc
outright rejectsenum
s with invalid variant names whilerust-analyzer
seems to accept the deviant syntax just enough to confusedly generate phantom variants. Presumably,rustc
's compile error usually steps in first, sorust-analyzer
doesn't normally see the degenerateenum
. But here, whererustc
just passes it along to the proc macro expander, that sieve doesn't apply.The text was updated successfully, but these errors were encountered: