Skip to content

Regression: spurious "error: expected ," in serde::Serialize on macro_rules-variable path enum discriminant #72608

Closed

Description

@SimonSapin

Somewhat minimized test case: (still involves serde_derive and syn)

[dependencies]
serde = {version = "1", features = ["derive"]}
syn = { version = "1", features = ["full"] }
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:

$ 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:

  • Removing use of serde::Serialize
  • Disabling the syn/full feature
  • Replacing $mod with a non-variable module name
  • Replacing the path expression with a { use $mod::DEPTH_COMPONENT; DEPTH_COMPONENT } block

Regression range: 8970e8b...46e85b4. Merges:

Excluding those that seem unrelated to me leaves:

Activity

  1. added
    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
    C-bugCategory: This is a bug.
    on May 26, 2020
  2. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on May 26, 2020
  3. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on May 26, 2020
  4. LeSeulArtichaut commented on May 26, 2020

    @LeSeulArtichaut
    Contributor

    Let’s see if we can minimize the example and bisect further to find the culprit PR?

  5. added
    E-needs-bisectionCall for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc
    E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
    on May 26, 2020
  6. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor

    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 8970e8b to 46e85b4
    regressed commit: 7726070

    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 #72388 and #72517 . The former looks more related. CC @Aaron1011

  7. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor

    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!()
    }
  8. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor
    #[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);
  9. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor

    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),
        },
    ]
  10. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor

    Replacing serde_derive with 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’t understand what’s 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

  11. removed
    E-needs-bisectionCall for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc
    on May 26, 2020
  12. LeSeulArtichaut commented on May 26, 2020

    @LeSeulArtichaut
    Contributor

    Could this be a duplicate of or a bug related to #72545? cc @dtolnay

  13. SimonSapin commented on May 26, 2020

    @SimonSapin
    ContributorAuthor

    It does look very similar. I suspect that a change in syn similar to the one discussed at #72545 (comment) 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

  14. dtolnay commented on May 26, 2020

    @dtolnay
    Member

    I released a fix to parse $mod::DEPTH_COMPONENT in syn 1.0.26.

  15. spastorino commented on May 27, 2020

    @spastorino
    Member

    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?

  16. added and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on May 27, 2020
  17. dtolnay commented on May 27, 2020

    @dtolnay
    Member

    Yeah I think we can close in favor of #72545, it's the same underlying change.

  18. added a commit that references this issue on Mar 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleP-criticalCritical priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions