Skip to content

eval_order_dependence shouldn't fire for struct initializers #4637

Open
@CAD97

Description

@CAD97

It's become idiomatic for syn-based parsers to parse members of each AST struct directly into the struct initializer, including e.g. bracketed! which initializes a place outside of the initializer. The bracketed! example:

use proc_macro2::TokenStream;
use syn::parse::{Parse, ParseStream};
use syn::{bracketed, token, Result, Token};

// Parse an outer attribute like:
//
//     #[repr(C, packed)]
struct OuterAttribute {
    pound_token: Token![#],
    bracket_token: token::Bracket,
    content: TokenStream,
}

impl Parse for OuterAttribute {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        Ok(OuterAttribute {
            pound_token: input.parse()?,
            bracket_token: bracketed!(content in input),
            content: content.parse()?,
        })
    }
}

clippy gives a eval_order_dependence warning here:

warning: unsequenced read of a variable
  --> src/lib.rs:20:22
   |
20 |             content: content.parse()?,
   |                      ^^^^^^^
   |
   = note: `#[warn(clippy::eval_order_dependence)]` on by default
note: whether read occurs before this write depends on evaluation order
  --> src/lib.rs:19:28
   |
19 |             bracket_token: bracketed!(content in input),
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence
   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

I believe that struct initializer syntax is in fact strongly specified to evaluate the member expressions in source order. And in this case, the order of the write and read can only be this, as the place assigned is both non-mut and not yet initialized before the write.

(Note that ParseStream is &'_ ParseBuffer<'_> which does include internal mutability but does so through &Cell, so the false negative on internal mutability ordering here is expected and likely unpreventable.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-mediumCall for participation: Medium difficulty level problem and requires some initial experience.T-async-awaitType: Issues related to async/awaitT-macrosType: Issues with macros and macro expansion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions