Skip to content

Commit

Permalink
ci: Use some tricks to format macro bodies
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tgross35 committed Nov 19, 2024
1 parent a4a3e78 commit 9da7ceb
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
43 changes: 42 additions & 1 deletion ci/style.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,48 @@ 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

# Suffix all braced macros except `macro_rules!` with `_fmt_tmp()`. Also
# remove the bang.
perl -pi -e 's/(?!macro_rules)\b(\w+)!\s*\{/fn $1_fmt_tmp() {/g' "$file"

# Replace `#[cfg(...)]` within `cfg_if` with `cfg_tmp!([...])` which
# `rustfmt` will format. We put braces within the parens so it is easy to
# match (matching 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. 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"

# We need to invoke `rustfmt` directly since `cargo fmt` can't figure out
# the module tree with the hacks in place.
rustfmt --config-path rustfmt.toml "$file" ${check:+"$check"}

# Reset everything
perl -pi -e 's/fn (\w+)_fmt_tmp\(\)/$1!/g' "$file"
perl -pi -0777 -e 's/cfg_tmp!\(\[(.*?)\]\)/#[cfg($1)]/gms' "$file"

# Rustfmt sometimes puts our `/* FMT-CONST */` comment on the preceding line
# so we need to do a multiline match.
perl -pi -0777 -e 's/\/\* FMT-CONST \*\/(?:\n\s*)?(.*?)const/$1\{const\}/gms' "$file"
done < "$tmpfile"

rm "$tmpfile"

if shellcheck --version ; then
find . -name '*.sh' -print0 | xargs -0 shellcheck
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
error_on_line_overflow = true
edition = "2021"

0 comments on commit 9da7ceb

Please sign in to comment.