Somewhat minimized test case: (still involves serde_derive and syn)
[dependencies]
serde = {version = "1", features = ["derive"]}
syn = { version = "1", features = ["full"] }
```rust
mod gl {
pub const DEPTH_COMPONENT: isize = 0;
}
macro_rules! gl_enums {
($mod:ident) => {
#[derive(serde::Serialize)]
pub enum TexFormat {
DepthComponent = $mod::DEPTH_COMPONENT
}
}
}
gl_enums!(gl);
Compiles in `nightly-2020-05-24`, errors in `nightly-2020-05-25`:
```rust
$ cargo +nightly-2020-05-25 rustc -- -Z macro-backtrace
Compiling proc-macro2 v1.0.17
Compiling unicode-xid v0.2.0
Compiling syn v1.0.25
Compiling serde v1.0.110
Compiling quote v1.0.6
Compiling serde_derive v1.0.110
Compiling aa v0.1.0 (/tmp/aa)
error: expected `,`
--> src/lib.rs:9:34
|
5 | / macro_rules! gl_enums {
6 | | ($mod:ident) => {
7 | | #[derive(serde::Serialize)]
8 | | pub enum TexFormat {
9 | | DepthComponent = $mod::DEPTH_COMPONENT
| | ^^
10 | | }
11 | | }
12 | | }
| |_- in this expansion of `gl_enums!`
13 |
14 | gl_enums!(gl);
| -------------- in this macro invocation
error: aborting due to previous error
Any of these changes makes compilation succeed:
serde::Serializesyn/full feature$mod with a non-variable module name{ use $mod::DEPTH_COMPONENT; DEPTH_COMPONENT } blockRegression range: 8970e8bcf...46e85b432. Merges:
Excluding those that seem unrelated to me leaves:
Let鈥檚 see if we can minimize the example and bisect further to find the culprit PR?
https://blog.rust-lang.org/inside-rust/2019/12/18/bisecting-rust-compiler.html worked pretty well:
searched nightlies: from nightly-2020-05-24 to nightly-2020-05-26
regressed nightly: nightly-2020-05-25
searched commits: from https://github.com/rust-lang/rust/commit/8970e8bcf6153d1ead2283f1a0ed7b192230eca6 to https://github.com/rust-lang/rust/commit/46e85b4328fe18492894093c1092dfe509df4370
regressed commit: https://github.com/rust-lang/rust/commit/7726070fa755f660b5da3f82f46e07d9c6866f69
bisected with cargo-bisect-rustc v0.5.1
Host triple: x86_64-unknown-linux-gnu
Reproduce with:
cargo bisect-rustc
The regression commit is a rollup merge of https://github.com/rust-lang/rust/pull/72388 and https://github.com/rust-lang/rust/pull/72517 .聽The former looks more related. CC @Aaron1011
Replacing serde_derive with this proc macro still reproduces the same error:
use proc_macro::TokenStream;
use syn::{DeriveInput, parse_macro_input};
#[proc_macro_derive(Serialize)]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
unimplemented!()
}
#[proc_macro]
pub fn foo(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
syn::parse_macro_input!(input as syn::Expr);
unimplemented!()
}
macro_rules! gl_enums {
($mod:ident) => {
not_serde::foo! {
$mod::DEPTH_COMPONENT
}
}
}
gl_enums!(gl);
Output of dbg!(&input):
TokenStream [
Group {
delimiter: None,
stream: TokenStream [
Ident {
ident: "gl",
span: #0 bytes(136..138),
},
],
span: #3 bytes(84..88),
},
Punct {
ch: ':',
spacing: Joint,
span: #3 bytes(88..90),
},
Punct {
ch: ':',
spacing: Alone,
span: #3 bytes(88..90),
},
Ident {
ident: "DEPTH_COMPONENT",
span: #3 bytes(90..105),
},
]
And with $mod replaced by a hard-coded gl path:
TokenStream [
Ident {
ident: "gl",
span: #3 bytes(84..86),
},
Punct {
ch: ':',
spacing: Joint,
span: #3 bytes(86..88),
},
Punct {
ch: ':',
spacing: Alone,
span: #3 bytes(86..88),
},
Ident {
ident: "DEPTH_COMPONENT",
span: #3 bytes(88..103),
},
]
Replacing
serde_derivewith this proc macro still reproduces the same error:
This might be a false lead? The error is identical but it also happen with older rustc where serde succeeds. So I don鈥檛 understand what鈥檚 going on here. syn::parse_macro_input!(input as syn::DeriveInput) is the first thing that serde::Serialize does: https://github.com/serde-rs/serde/blob/v1.0.110/serde_derive/src/lib.rs#L78
Could this be a duplicate of or a bug related to #72545? cc @dtolnay
It does look very similar. I suspect that a change in syn similar to the one discussed at https://github.com/rust-lang/rust/issues/72545#issuecomment-633312939 in proc-macro-hack could solve this. I tried to find the relevant source code in syn but https://github.com/dtolnay/syn/blob/6d5c90ddf790342947cad5737051f34e715c58af/src/path.rs#L35 only has a definition that a PathSegment contains an Ident. Is the parsing code macro-generated? CC @dtolnay
I released a fix to parse $mod::DEPTH_COMPONENT in syn 1.0.26.
Assigning P-critical as discussed as part of the Prioritization Working Group process and removing I-prioritize.
This seems to be the same issue as #72545 ?. And the culprit being #72388 or am I wrong?
Yeah I think we can close in favor of #72545, it's the same underlying change.
Most helpful comment
I released a fix to parse
$mod::DEPTH_COMPONENTin syn 1.0.26.