Skip to content

Conversation

maxdexh
Copy link

@maxdexh maxdexh commented Sep 5, 2025

This PR implements formatting of most attributes that follow the general meta format from the reference, rather than just ast::MetaItem-style attributes (which are restricted to using literals in their expressions).

The code to implement this uses its own AST structs and enums inspired by rustc_ast. It uses speculative parsing in meta lists to distinguish nested meta items from expressions by parsing as the latter if the former fails. Rustfmt already parses macro arguments using an approach similar to this.

@maxdexh
Copy link
Author

maxdexh commented Sep 5, 2025

Also fixes #3781 and #6374.

Example from the former:

enum E {
    #[error(display = "invalid max keyframe interval {} (expected > 0, < {})", _0, i32::max_value())]
    InvalidMaxKeyFrameInterval(u64),
    #[error(display = "invalid max keyframe interval {} (expected > 0, < {})", _0, i32::max_value() as u64)]
    InvalidMaxKeyFrameInterval(u64),
}

becomes

enum E {
    #[error(
        display = "invalid max keyframe interval {} (expected > 0, < {})",
        _0,
        i32::max_value()
    )]
    InvalidMaxKeyFrameInterval(u64),
    #[error(
        display = "invalid max keyframe interval {} (expected > 0, < {})",
        _0,
        i32::max_value() as u64
    )]
    InvalidMaxKeyFrameInterval(u64),
}

The first variant's attr is already formated by rustfmt, since the last element in the meta list formats as another meta list with path i32::max_value. This is still how it parses with the new logic. The second variant's attr was skipped by rustfmt because i32::max_value() as u64 is not a meta item. It is now parsed as an expression, which allows the entire attr to be formatted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants