From d8ccae537e7a51d99856422209ea17828138668b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 18 Nov 2024 15:28:04 -0500 Subject: [PATCH] ci: Use some tricks to format macro bodies We have a lot of syntax contained within macro bodies, which `rustfmt` doesn't touch. Add a hack that replaces relevant macro invocations with functions, formats, then resets. (backport ) (cherry picked from commit 6ab46bb97c1fbba3babaa9b460eb992cf21f3ae4) --- ci/style.sh | 48 +++++++++++++++++++++++++++++++++++++++++++++++- rustfmt.toml | 1 + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/ci/style.sh b/ci/style.sh index 74b26379b3a7d..53efb82280c87 100755 --- a/ci/style.sh +++ b/ci/style.sh @@ -13,7 +13,53 @@ rustc ci/style.rs && ./style src command -v rustfmt rustfmt -V -cargo fmt --all -- ${check:+"$check"} + +# Save a list of all source files +tmpfile="file-list~" # trailing tilde for gitignore +find src -name '*.rs' > "$tmpfile" + +# Before formatting, replace all macro identifiers with a function signature. +# This allows `rustfmt` to format it. +while IFS= read -r file; do + if [ "$file" = "src/macros.rs" ]; then + # Too much special syntax in `macros.rs` that we don't want to format + continue + fi + + # Turn all braced macro `foo! { /* ... */ }` invocations into + # `fn foo_fmt_tmp() { /* ... */ }`. + perl -pi -e 's/(?!macro_rules)\b(\w+)!\s*\{/fn $1_fmt_tmp() {/g' "$file" + + # Replace `if #[cfg(...)]` within `cfg_if` with `if cfg_tmp!([...])` which + # `rustfmt` will format. We put brackets within the parens so it is easy to + # match (trying to match parentheses would catch the first closing `)` which + # wouldn't be correct for something like `all(any(...), ...)`). + perl -pi -0777 -e 's/if #\[cfg\((.*?)\)\]/if cfg_tmp!([$1])/gms' "$file" + + # We have some instances of `{const}` that make macros happy but aren't + # valid syntax. Replace this with just the keyword, plus an indicator + # comment on the preceding line (which is where rustfmt puts it. Also + # rust-lang/rustfmt#5464). + perl -pi -e 's/^(\s*)(.*)\{const\}/$1\/\* FMT-CONST \*\/\n$1$2const/g' "$file" + + # Format the file. We need to invoke `rustfmt` directly since `cargo fmt` + # can't figure out the module tree with the hacks in place. + failed=false + rustfmt --config-path rustfmt.toml "$file" ${check:+"$check"} || failed=true + + # Restore all changes to the files. + perl -pi -e 's/fn (\w+)_fmt_tmp\(\)/$1!/g' "$file" + perl -pi -0777 -e 's/cfg_tmp!\(\[(.*?)\]\)/#[cfg($1)]/gms' "$file" + perl -pi -0777 -e 's/\/\* FMT-CONST \*\/(?:\n\s*)?(.*?)const/$1\{const\}/gms' "$file" + + # Defer emitting the failure until after the files get reset + if [ "$failed" != "false" ]; then + echo "Formatting failed" + exit 1 + fi +done < "$tmpfile" + +rm "$tmpfile" if shellcheck --version ; then find . -name '*.sh' -print0 | xargs -0 shellcheck diff --git a/rustfmt.toml b/rustfmt.toml index dc85c99467fcc..018747d94867a 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,2 @@ error_on_line_overflow = true +edition = "2021"