Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c24a73d
test(config): demonstrate `--config-path` searching behavior
rami3l Sep 11, 2026
880d20e
refactor(config): extract `resolve_project_file()` and `config_from_u…
rami3l Sep 11, 2026
ec2bb9c
fix(config): search for config file recursively on `--config-path`
rami3l Sep 11, 2026
684d929
Rename `rust-toolchain` to `rust-toolchain.toml`
Kobzol Sep 22, 2026
4a50b96
Merge pull request #7132 from Kobzol/rust-toolchain
jieyouxu Sep 22, 2026
d91799d
`chain`: drop redundant check
matthewhughes934 Sep 2, 2026
e57d37f
Merge pull request #7095 from matthewhughes934/chain-refactor-2
ytmimi Sep 22, 2026
b850b35
Initial josh-sync configuration
Kobzol Sep 23, 2026
d8fb113
Prepare for merging from rust-lang/rust
Kobzol Sep 23, 2026
3df6d03
Merge ref '6bb1652a020e' (nightly-2026-09-23) from rust-lang/rust
Kobzol Sep 23, 2026
c2e5f11
Update sync docs
Kobzol Sep 23, 2026
55901bb
Merge pull request #7134 from Kobzol/clif-sync
jieyouxu Sep 23, 2026
a49d393
chore: drop unneeded `#![allow(unreachable_pub)]`
jieyouxu Sep 23, 2026
e37660b
Merge pull request #7135 from jieyouxu/jieyouxu/unreachable_pub
ytmimi Sep 23, 2026
dee003b
Merge pull request #7115 from rami3l/fix/config-path-dirwalk
ytmimi Sep 24, 2026
79d6180
fix panic on failure to format generics in enum
ding-young Nov 17, 2024
bc92c86
refactor visit_enum
ding-young Nov 29, 2024
da10331
add test case for issue#6571
ding-young Oct 5, 2025
6769474
Merge pull request #6396 from ding-young/fix-panic-on-enum
jieyouxu Sep 24, 2026
c224825
test(config): add regression test for `adjust_max_width` overflows
jieyouxu Sep 29, 2026
5e9724c
docs(config): `increase_max_width` actually increases max width
jieyouxu Sep 29, 2026
942efae
fix(config): use saturating arithmetics in `adjust_max_width`
jieyouxu Sep 29, 2026
cdb1e99
chore(triagebot): route rustfmt repo backport nominations to zulip
jieyouxu Sep 29, 2026
3128678
Merge pull request #7153 from jieyouxu/backport-nom
ytmimi Sep 29, 2026
c84441f
Merge pull request #7152 from jieyouxu/struct-variant-width
ytmimi Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 20 additions & 167 deletions src/tools/rustfmt/Subtree sync procedure.md
Original file line number Diff line number Diff line change
@@ -1,190 +1,43 @@
# `rustfmt` subtree sync procedure

Note that `rustfmt` has not migrated to `josh` yet, so the git subtree sync is somewhat involved.
This procedure is mostly adapted from the `clippy` subtree sync process at
<https://doc.rust-lang.org/stable/clippy/development/infrastructure/sync.html>, but adapted for
`rustfmt`. We are keeping a separate copy of the instructions for `rustfmt` in case `clippy` moves
off of `git subtree` in the mean time (and also slightly adjusted to be `rustfmt`-specific.
`rustfmt` is using [Josh] to perform subtree synces with the `rust-lang/rust` repository.

> [!NOTE]
>
> Note that AFAIK, eventually both `clippy` and `rustfmt` would like to move to the `josh`-sync
> workflow, just that `rustfmt` is blocked on actually doing a bidirectional sync first, while
> `clippy` is sorting out some issues related to tags and git history (due to usage of `git
> subtree`).
[Josh]: https://josh-project.dev/docs/intro.html

## Tooling

The `git-subtree` tooling still has a bug that prevents it from working properly with the
`rust-lang/rust` repository. This means that you need to build and use a patched version of
`git-subtree`.
The [`josh-sync`][josh-sync] tool is used as a wrapper on top of Josh to help automate the subtree
sync process (both pulls and pushes). You can install it with `cargo install --git https://github.com/rust-lang/josh-sync`.

> [!NOTE]
>
> The patched version of `git-subtree` is the sources corresponding to the stale PR
> <https://github.com/gitgitgadget/git/pull/493>.
[josh-sync]: https://github.com/rust-lang/josh-sync

On Linux, place `git-subtree` under `/usr/lib/git-core` (make sure to keep a backup copy of the
'standard' `git-subtree`), and make sure it has proper permissions:
## Subtree pull direction: syncing changes from `rust-lang/rust` to `rustfmt`

```sh
$ sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
$ sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
$ sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
```
1. Be in a `rustfmt` checkout
2. Checkout the latest `main` branch from upstream
3. Create a new branch that will be used for the sync
4. Run `rustc-josh-sync pull`
5. Confirm the creation of a PR directly by `rustc-josh-sync`, or create a PR to `rust-lang/rustfmt` repository

> [!NOTE]
>
> Running `git subtree push` for the first time requires building a cache, which involves going
> through the entire history of `rustfmt` once. You likely will need to increase the stack limit via
>
> ```sh
> $ ulimit -s 60000
> ```

> [!NOTE]
>
> The following steps assume that you have configured the `rustfmt` remote as `upstream`, i.e.
>
> ```sh
> $ git remote add upstream git@github.com:rust-lang/rustfmt
> ```

## Subtree push direction: syncing changes from `rust-lang/rust` to `rustfmt`

> [!WARNING]
>
> **For this subtree-push direction, all commands described must be run within the `rust-lang/rust`
> checkout.**

### 1. Acquire a checkout of `rust-lang/rust`

Either acquire a clone of `rust-lang/rust`, or if you already have a checkout, make sure the
checkout is up-to-date via `git fetch`.

### 2. Checkout the commit from the latest available nightly

You can fetch the commit hash of the latest available nightly by inspecting `rustup check` output.

### 3. Sync changes from the `rust`-copy of `rustfmt` to your `rustfmt` fork

> [!WARNING]
>
> **Make sure to either use a fresh branch, e.g. `subtree-push`, or delete the branch beforehand**.
> Changes cannot be fast forwarded and you have to run this command again.

```sh
$ git subtree push -P src/tools/rustfmt /path/to/rustfmt/checkout subtree-push
```

Most of the time, you will need to create a **merge commit** in the `rustfmt` repository. Note that
this must be done in the subtree repo (i.e. `rustfmt` repo) and not in the `rust`-copy of `rustfmt`.

Assuming the `upstream` remote is the `rust-lang/rust` remote:

```sh
$ git fetch upstream
$ git switch subtree-push
$ git merge upstream/main --no-ff
```

> [!WARNING]
>
> You may have to manually resolve certain merge conflicts. Pay extra attention when resolving them,
> since it's easy to accidentally resolve the conflict in incorrect ways.

> [!TIP]
>
> Subtree syncs are one of the rare occasions where a merge commit is allowed in a PR.

### 4. Bump the nightly toolchain version in the `rustfmt` repository

Using the same latest nightly date (that you can obtain by inspecting `rustup check` output),
manually edit `rust-toolchain`:

```diff
[toolchain]
-channel = "nightly-2025-04-02"
+channel = "nightly-$LATEST_NIGHTLY_DATE"
components = ["llvm-tools", "rustc-dev"]
```

Substituting `$LATEST_NIGHTLY_DATE` with the latest nightly date.

Create a separate commit dedicated to making the `rust-toolchain` change. You can use [the following
commit message template](#rust-toolchain-bump-commit-message-template).

#### `rust-toolchain` bump commit message template

````text
chore: bump rustfmt toolchain to nightly-$LATEST_NIGHTLY_DATE

Bumping the toolchain version as part of a git subtree push.

Before:

```
$CURRENT_NIGHTLY_VERSION-nightly ($CURRENT_NIGHTLY_HASH $CURRENT_NIGHTLY_DATE)
```

After:

```
$LATEST_NIGHTLY_VERSION-nightly ($LATEST_NIGHTLY_HASH $LATEST_NIGHTLY_DATE)
```
````

Substituting the placeholders with the right information.

### 5. Open a PR against `rustfmt`

And wait for the sync PR to be merged. The `rustfmt` maintainers will run Diff Check against the PR
to catch any unexpected formatting changes.
The `rustfmt` maintainers will run Diff Check against the PR to catch any unexpected formatting changes.

- Maintainers should trigger Diff-Check for the combinations of Edition {2021, 2024} x Style
Edition {2021, 2024}.

Once Diff Check failures are investigated and are resolved, the PR can then be merged.

For the PR:

- Use the title `subtree-push nightly-$LATEST_NIGHTLY_DATE` for consistency with previous
subtree-pushes.
- Include a copy of the bump commit message in the PR description for quick reference. Feel free to
include additional notes that might be helpful for the maintainers when reviewing.

**Make sure to minimize the time between the subtree-push direction and the subtree-pull direction
to avoid unnecessary complications.**

### 5. (Where applicable) Update changelog and bump rustfmt version number
### (Where applicable) Update changelog and bump rustfmt version number

Where applicable, we may need to update the CHANGELOG entries with merged PRs (both in `rustfmt`
repository and also in the `rust-lang/rust` `rustfmt` subtree that was included in the subtree-push
merge), and then bump rustfmt version number.

## Subtree pull direction: syncing from `rustfmt` to `rust-lang/rust`

> [!WARNING]
>
> For this **subtree-pull** direction, all commands must also be performed within the
> `rust-lang/rust` checkout.

### 1. Make sure latest `main` of `rust-lang/rust` is checked out

### 2. Sync `rustfmt` `main` to the `rust`-copy of `rustfmt`

```sh
$ git switch -c rustfmt-subtree-update
$ git subtree pull -P src/tools/rustfmt /path/to/rustfmt/checkout main
```

### 3. Open a PR against `rust-lang/rust`

Use the PR title

> `rustfmt` subtree update
## Subtree push direction: syncing changes from `rustfmt` to rust-lang/rust`

so that `triagebot` will not warn against the PR containing a merge commit, and makes it easy for
`rustfmt` maintainers to discover.
1. Be in a `rustfmt` checkout
2. Checkout the latest `main` branch from upstream
3. Run `rustc-josh-sync push <branch-name> <github-username>`
- Josh will push the changes to a branch with the given name in your `<github-username>/rust` fork of `rust-lang/rust`.
4. Follow the prompt of `rustc-josh-sync` to open a PR to `rust-lang/rust`, or create the PR manually.

Back link to the `rustfmt` subtree-push PR as helpful context.
**Make sure to minimize the time between a pull and a subsequent push to avoid unnecessary complications.**
4 changes: 4 additions & 0 deletions src/tools/rustfmt/josh-sync.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
repo = "rustfmt"
filter = ":~(history=\"keep-trivial-merges,no-splice\")[:rev(<=e47f161c8476418e8b55b61db3bbf0338e0ab827:prefix=src/tools/rustfmt,<=e5b95097d9a14bdec7cd9101dde67ee3aad2578a:SQUASH)]:/src/tools/rustfmt"
filter-version = 2
pull-mode = "Nightly"
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2026-09-21"
channel = "nightly-2026-09-23"
components = ["llvm-tools", "rustc-dev"]
4 changes: 1 addition & 3 deletions src/tools/rustfmt/src/chains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,7 @@ impl Chain {
}
while let Some(chain_item) = iter.next() {
let comment_snippet = context.snippet(chain_item.span);
// FIXME: Figure out the way to get a correct span when converting `try!` to `?`.
let handle_comment =
!(context.config.use_try_shorthand() || is_tries(comment_snippet.trim()));
let handle_comment = !is_tries(comment_snippet.trim());

// Pre-comment
if handle_comment {
Expand Down
10 changes: 6 additions & 4 deletions src/tools/rustfmt/src/config/config_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,22 +435,22 @@ macro_rules! create_config {
/// arms within a declarative macro.
#[allow(unreachable_pub)]
pub fn reduce_max_width(&mut self, delta: usize) {
self.adjust_max_width(-(delta as isize));
self.adjust_max_width(-(delta.min(isize::MAX as usize) as isize));
}

/// Increases the maximum width of the configuration.
///
/// This method is intended to be used when creating a forked
/// configuration for a particular formatting context in which the
/// total available width needs to be reduced. This increases the
/// total available width needs to be increased. This increases the
/// size of max_width, and all other properties affected by small
/// heuristics, without treating those adjustments as overrides.
///
/// As an example use case, this method is used when formatting
/// arms within a declarative macro.
#[allow(unreachable_pub)]
pub fn increase_max_width(&mut self, delta: usize) {
self.adjust_max_width(delta as isize);
self.adjust_max_width(delta.min(isize::MAX as usize) as isize);
}

/// Adjusts the maximum width of the configuration.
Expand All @@ -464,7 +464,9 @@ macro_rules! create_config {
/// As an example use case, this method is used when formatting
/// arms within a declarative macro.
fn adjust_max_width(&mut self, delta: isize) {
let adjust = |value: usize| (value as isize + delta) as usize;
// NB: we need to either saturate or report an error (or some kind of testable
// warning). I picked to saturate here.
let adjust = |value: usize| value.saturating_add_signed(delta);

self.array_width.2 = adjust(self.array_width.2);
self.attr_fn_like_width.2 = adjust(self.attr_fn_like_width.2);
Expand Down
Loading
Loading