diff --git a/src/tools/rustfmt/.editorconfig b/src/tools/rustfmt/.editorconfig
new file mode 100644
index 000000000000..5bb92df3e043
--- /dev/null
+++ b/src/tools/rustfmt/.editorconfig
@@ -0,0 +1,26 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.rs]
+indent_size = 4
+
+[tests/**/*.rs]
+charset = utf-8
+end_of_line = unset
+indent_size = unset
+indent_style = unset
+trim_trailing_whitespace = unset
+insert_final_newline = unset
+
+[appveyor.yml]
+end_of_line = unset
diff --git a/src/tools/rustfmt/.gitattributes b/src/tools/rustfmt/.gitattributes
new file mode 100644
index 000000000000..91df4f0eb18d
--- /dev/null
+++ b/src/tools/rustfmt/.gitattributes
@@ -0,0 +1,7 @@
+* text=auto eol=lf
+tests/source/issue-3494/crlf.rs -text
+tests/source/comment_crlf_newline.rs -text
+tests/source/configs/enum_discrim_align_threshold/40.rs -text
+tests/target/issue-3494/crlf.rs -text
+tests/target/comment_crlf_newline.rs -text
+tests/target/configs/enum_discrim_align_threshold/40.rs -text
diff --git a/src/tools/rustfmt/.github/workflows/integration.yml b/src/tools/rustfmt/.github/workflows/integration.yml
new file mode 100644
index 000000000000..b79221d05436
--- /dev/null
+++ b/src/tools/rustfmt/.github/workflows/integration.yml
@@ -0,0 +1,85 @@
+name: integration
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ integration-tests:
+ runs-on: ubuntu-latest
+ name: ${{ matrix.integration }}
+ strategy:
+ # https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions#usage-limits
+ # There's a limit of 60 concurrent jobs across all repos in the rust-lang organization.
+ # In order to prevent overusing too much of that 60 limit, we throttle the
+ # number of rustfmt jobs that will run concurrently.
+ max-parallel: 4
+ fail-fast: false
+ matrix:
+ integration: [
+ bitflags,
+ error-chain,
+ log,
+ mdbook,
+ packed_simd,
+ rust-semverver,
+ tempdir,
+ futures-rs,
+ rust-clippy,
+ failure,
+ ]
+ include:
+ # Allowed Failures
+ # Actions doesn't yet support explicitly marking matrix legs as allowed failures
+ # https://github.community/t5/GitHub-Actions/continue-on-error-allow-failure-UI-indication/td-p/37033
+ # https://github.community/t5/GitHub-Actions/Why-a-matrix-step-will-be-canceled-if-another-one-failed/td-p/30920
+ # Instead, leverage `continue-on-error`
+ # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
+ #
+ # Failing due to breaking changes in rustfmt 2.0 where empty
+ # match blocks have trailing commas removed
+ # https://github.com/rust-lang/rustfmt/pull/4226
+ - integration: chalk
+ allow-failure: true
+ - integration: crater
+ allow-failure: true
+ - integration: glob
+ allow-failure: true
+ - integration: stdsimd
+ allow-failure: true
+ # Using old rustfmt configuration option
+ - integration: rand
+ allow-failure: true
+ # Keep this as an allowed failure as it's fragile to breaking changes of rustc.
+ - integration: rust-clippy
+ allow-failure: true
+ # Using old rustfmt configuration option
+ - integration: packed_simd
+ allow-failure: true
+ # calebcartwright (2019-12-24)
+ # Keeping this as an allowed failure since it was flagged as such in the TravisCI config, even though
+ # it appears to have been passing for quite some time.
+ # Original comment was: temporal build failure due to breaking changes in the nightly compiler
+ - integration: rust-semverver
+ allow-failure: true
+ # Can be moved back to include section after https://github.com/rust-lang-nursery/failure/pull/298 is merged
+ - integration: failure
+ allow-failure: true
+
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+
+ # Run build
+ - name: install rustup
+ run: |
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
+ sh rustup-init.sh -y --default-toolchain none
+
+ - name: run integration tests
+ env:
+ INTEGRATION: ${{ matrix.integration }}
+ TARGET: x86_64-unknown-linux-gnu
+ run: ./ci/integration.sh
+ continue-on-error: ${{ matrix.allow-failure == true }}
diff --git a/src/tools/rustfmt/.github/workflows/linux.yml b/src/tools/rustfmt/.github/workflows/linux.yml
new file mode 100644
index 000000000000..6eaae69c7080
--- /dev/null
+++ b/src/tools/rustfmt/.github/workflows/linux.yml
@@ -0,0 +1,42 @@
+name: linux
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ name: (${{ matrix.target }}, nightly)
+ strategy:
+ # https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions#usage-limits
+ # There's a limit of 60 concurrent jobs across all repos in the rust-lang organization.
+ # In order to prevent overusing too much of that 60 limit, we throttle the
+ # number of rustfmt jobs that will run concurrently.
+ max-parallel: 1
+ fail-fast: false
+ matrix:
+ target: [
+ x86_64-unknown-linux-gnu,
+ ]
+
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+
+ # Run build
+ - name: install rustup
+ run: |
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
+ sh rustup-init.sh -y --default-toolchain none
+ rustup target add ${{ matrix.target }}
+
+ - name: build
+ run: |
+ rustc -Vv
+ cargo -V
+ cargo build
+
+ - name: test
+ run: cargo test
diff --git a/src/tools/rustfmt/.github/workflows/mac.yml b/src/tools/rustfmt/.github/workflows/mac.yml
new file mode 100644
index 000000000000..79e4f69163e0
--- /dev/null
+++ b/src/tools/rustfmt/.github/workflows/mac.yml
@@ -0,0 +1,39 @@
+name: mac
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ test:
+ # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources
+ # macOS Catalina 10.15
+ runs-on: macos-latest
+ name: (${{ matrix.target }}, nightly)
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [
+ x86_64-apple-darwin,
+ ]
+
+ steps:
+ - name: checkout
+ uses: actions/checkout@v2
+
+ # Run build
+ - name: install rustup
+ run: |
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
+ sh rustup-init.sh -y --default-toolchain none
+ rustup target add ${{ matrix.target }}
+
+ - name: build
+ run: |
+ rustc -Vv
+ cargo -V
+ cargo build
+
+ - name: test
+ run: cargo test
diff --git a/src/tools/rustfmt/.github/workflows/upload-assets.yml b/src/tools/rustfmt/.github/workflows/upload-assets.yml
new file mode 100644
index 000000000000..9a5fd0dd1d31
--- /dev/null
+++ b/src/tools/rustfmt/.github/workflows/upload-assets.yml
@@ -0,0 +1,80 @@
+name: upload
+
+on:
+ release:
+ types: [created]
+
+jobs:
+ build-release:
+ name: build-release
+ strategy:
+ matrix:
+ build: [linux-x86_64, macos-x86_64, windows-x86_64-gnu, windows-x86_64-msvc]
+ include:
+ - build: linux-x86_64
+ os: ubuntu-latest
+ rust: nightly
+ - build: macos-x86_64
+ os: macos-latest
+ rust: nightly
+ - build: windows-x86_64-gnu
+ os: windows-latest
+ rust: nightly-x86_64-gnu
+ - build: windows-x86_64-msvc
+ os: windows-latest
+ rust: nightly-x86_64-msvc
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: ${{ matrix.rust }}
+ override: true
+
+ - name: Add mingw64 to path for x86_64-gnu
+ run: echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH
+ if: matrix.rust == 'nightly-x86_64-gnu'
+ shell: bash
+
+ - name: Install cargo-make
+ uses: actions-rs/cargo@v1
+ with:
+ command: install
+ args: --force cargo-make
+
+ - name: Build release binaries
+ uses: actions-rs/cargo@v1
+ with:
+ command: make
+ args: release
+
+ - name: Build archive
+ shell: bash
+ run: |
+ staging="rustfmt_${{ matrix.build }}_${{ github.event.release.tag_name }}"
+ mkdir -p "$staging"
+
+ cp {README.md,Configurations.md,CHANGELOG.md,LICENSE-MIT,LICENSE-APACHE} "$staging/"
+
+ if [ "${{ matrix.os }}" = "windows-latest" ]; then
+ cp target/release/{rustfmt.exe,cargo-fmt.exe,rustfmt-format-diff.exe,git-rustfmt.exe} "$staging/"
+ 7z a "$staging.zip" "$staging"
+ echo "ASSET=$staging.zip" >> $GITHUB_ENV
+ else
+ cp target/release/{rustfmt,cargo-fmt,rustfmt-format-diff,git-rustfmt} "$staging/"
+ tar czf "$staging.tar.gz" "$staging"
+ echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV
+ fi
+
+ - name: Upload Release Asset
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ github.event.release.upload_url }}
+ asset_path: ${{ env.ASSET }}
+ asset_name: ${{ env.ASSET }}
+ asset_content_type: application/octet-stream
diff --git a/src/tools/rustfmt/.github/workflows/windows.yml b/src/tools/rustfmt/.github/workflows/windows.yml
new file mode 100644
index 000000000000..08cb52eedaea
--- /dev/null
+++ b/src/tools/rustfmt/.github/workflows/windows.yml
@@ -0,0 +1,69 @@
+name: windows
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ test:
+ runs-on: windows-latest
+ name: (${{ matrix.target }}, nightly)
+ strategy:
+ # https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions#usage-limits
+ # There's a limit of 60 concurrent jobs across all repos in the rust-lang organization.
+ # In order to prevent overusing too much of that 60 limit, we throttle the
+ # number of rustfmt jobs that will run concurrently.
+ max-parallel: 2
+ fail-fast: false
+ matrix:
+ target: [
+ i686-pc-windows-gnu,
+ i686-pc-windows-msvc,
+ x86_64-pc-windows-gnu,
+ x86_64-pc-windows-msvc,
+ ]
+
+ steps:
+ # The Windows runners have autocrlf enabled by default
+ # which causes failures for some of rustfmt's line-ending sensitive tests
+ - name: disable git eol translation
+ run: git config --global core.autocrlf false
+ - name: checkout
+ uses: actions/checkout@v2
+
+ # Run build
+ - name: Install Rustup using win.rustup.rs
+ run: |
+ # Disable the download progress bar which can cause perf issues
+ $ProgressPreference = "SilentlyContinue"
+ Invoke-WebRequest https://win.rustup.rs/ -OutFile rustup-init.exe
+ .\rustup-init.exe -y --default-host=x86_64-pc-windows-msvc --default-toolchain=none
+ del rustup-init.exe
+ rustup target add ${{ matrix.target }}
+ shell: powershell
+
+ - name: Add mingw32 to path for i686-gnu
+ run: |
+ echo "C:\msys64\mingw32\bin" >> $GITHUB_PATH
+ if: matrix.target == 'i686-pc-windows-gnu' && matrix.channel == 'nightly'
+ shell: bash
+
+ - name: Add mingw64 to path for x86_64-gnu
+ run: echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH
+ if: matrix.target == 'x86_64-pc-windows-gnu' && matrix.channel == 'nightly'
+ shell: bash
+
+ - name: cargo-make
+ run: cargo install --force cargo-make
+
+ - name: build
+ run: |
+ rustc -Vv
+ cargo -V
+ cargo build
+ shell: cmd
+
+ - name: test
+ run: cargo test
+ shell: cmd
diff --git a/src/tools/rustfmt/.gitignore b/src/tools/rustfmt/.gitignore
new file mode 100644
index 000000000000..37adf8751ca8
--- /dev/null
+++ b/src/tools/rustfmt/.gitignore
@@ -0,0 +1,24 @@
+
+# Created by https://www.gitignore.io/api/rust
+
+### Rust ###
+# Generated by Cargo
+# will have compiled files and executables
+/target
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
+# Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# End of https://www.gitignore.io/api/rust
+
+# Used by macOS' file system to track custom attributes of containing folder
+.DS_Store
+
+# Editors' specific files
+.idea/
+.vscode/
+*~
diff --git a/src/tools/rustfmt/.travis.yml b/src/tools/rustfmt/.travis.yml
new file mode 100644
index 000000000000..d699bd842eec
--- /dev/null
+++ b/src/tools/rustfmt/.travis.yml
@@ -0,0 +1,77 @@
+sudo: false
+language: rust
+rust: nightly
+os: linux
+cache:
+ directories:
+ - $HOME/.cargo
+
+addons:
+ apt:
+ packages:
+ - libcurl4-openssl-dev
+ - libelf-dev
+ - libdw-dev
+
+matrix:
+ include:
+ - env: DEPLOY=LINUX
+ - env: CFG_RELEASE_CHANNEL=beta
+ - os: osx
+ - env: INTEGRATION=bitflags
+ - env: INTEGRATION=chalk
+ - env: INTEGRATION=crater
+ - env: INTEGRATION=error-chain
+ - env: INTEGRATION=glob
+ - env: INTEGRATION=log
+ - env: INTEGRATION=mdbook
+ - env: INTEGRATION=packed_simd
+ - env: INTEGRATION=rust-semverver
+ - env: INTEGRATION=stdsimd TARGET=x86_64-unknown-linux-gnu
+ - env: INTEGRATION=tempdir
+ - env: INTEGRATION=futures-rs
+ allow_failures:
+ # Using old configuration option
+ - env: INTEGRATION=rand
+ # Doesn't build - keep this in allow_failures as it's fragile to breaking changes of rustc.
+ - env: INTEGRATION=rust-clippy
+ # Doesn't build - seems to be because of an option
+ - env: INTEGRATION=packed_simd
+ # Doesn't build - a temporal build failure due to breaking changes in the nightly compilre
+ - env: INTEGRATION=rust-semverver
+ # can be moved back to include section after https://github.com/rust-lang-nursery/failure/pull/298 is merged
+ - env: INTEGRATION=failure
+ # `cargo test` doesn't finish - disabling for now.
+ # - env: INTEGRATION=cargo
+
+script:
+ - |
+ if [ -z ${INTEGRATION} ]; then
+ export CFG_RELEASE_CHANNEL=nightly
+ export CFG_RELEASE=nightly
+ cargo build
+ cargo test
+ cargo test -- --ignored
+ else
+ ./ci/integration.sh
+ fi
+
+after_success:
+- if [ -z ${INTEGRATION} ]; then travis-cargo coveralls --no-sudo; fi
+
+before_deploy:
+ # TODO: cross build
+ - cargo build --release --target=x86_64-unknown-linux-gnu
+ - tar czf rustfmt-x86_64-unknown-linux-gnu.tar.gz Contributing.md Design.md README.md -C target/x86_64-unknown-linux-gnu/release/rustfmt rustfmt
+
+deploy:
+ provider: releases
+ api_key:
+ secure: "your own encrypted key"
+ file:
+ - rustfmt-x86_64-unknown-linux-gnu.tar.gz
+ on:
+ repo: nrc/rustfmt
+ tags: true
+ condition: "$DEPLOY = LINUX"
+ skip_cleanup: true
diff --git a/src/tools/rustfmt/CHANGELOG.md b/src/tools/rustfmt/CHANGELOG.md
new file mode 100644
index 000000000000..0f23663d6c2f
--- /dev/null
+++ b/src/tools/rustfmt/CHANGELOG.md
@@ -0,0 +1,1168 @@
+# Changelog
+
+## [Unreleased]
+
+## [1.4.37] 2021-04-03
+
+### Changed
+
+- `rustc-ap-*` crates updated to v712.0.0
+
+### Fixed
+- Resolve idempotence issue related to indentation of macro defs that contain or-patterns with inner comments ([#4603](https://github.com/rust-lang/rustfmt/issues/4603))
+- Addressed various clippy and rustc warnings
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - *pending*
+- **GitHub Release Binaries** - [Release v1.4.37](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.37)
+- **Build from source** - [Tag v1.4.37](https://github.com/rust-lang/rustfmt/tree/v1.4.37), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.36] 2021-02-07
+
+### Changed
+
+- `rustc-ap-*` crates updated to v705.0.0
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - *pending*
+- **GitHub Release Binaries** - [Release v1.4.36](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.36)
+- **Build from source** - [Tag v1.4.36](https://github.com/rust-lang/rustfmt/tree/v1.4.36), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.35] 2021-02-03
+
+### Changed
+
+- `rustc-ap-*` crates updated to v702.0.0
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - *n/a (superseded by [v1.4.36](#1436-2021-02-07))
+- **GitHub Release Binaries** - [Release v1.4.35](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.35)
+- **Build from source** - [Tag v1.4.35](https://github.com/rust-lang/rustfmt/tree/v1.4.35), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.34] 2021-01-28
+
+### Fixed
+- Don't insert trailing comma on (base-less) rest in struct literals within macros ([#4675](https://github.com/rust-lang/rustfmt/issues/4675))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2021-01-31`
+- **GitHub Release Binaries** - [Release v1.4.34](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.34)
+- **Build from source** - [Tag v1.4.34](https://github.com/rust-lang/rustfmt/tree/v1.4.34), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.33] 2021-01-27
+
+### Changed
+- `merge_imports` configuration has been deprecated in favor of the new `imports_granularity` option. Any existing usage of `merge_imports` will be automatically mapped to the corresponding value on `imports_granularity` with a warning message printed to encourage users to update their config files.
+
+### Added
+- New `imports_granularity` option has been added which succeeds `merge_imports`. This new option supports several additional variants which allow users to merge imports at different levels (crate or module), and even flatten imports to have a single use statement per item. ([PR #4634](https://github.com/rust-lang/rustfmt/pull/4634), [PR #4639](https://github.com/rust-lang/rustfmt/pull/4639))
+
+See the section on the configuration site for more information
+https://rust-lang.github.io/rustfmt/?version=v1.4.33&search=#imports_granularity
+
+### Fixed
+- Fix erroneous removal of `const` keyword on const trait impl ([#4084](https://github.com/rust-lang/rustfmt/issues/4084))
+- Fix incorrect span usage wit const generics in supertraits ([#4204](https://github.com/rust-lang/rustfmt/issues/4204))
+- Use correct span for const generic params ([#4263](https://github.com/rust-lang/rustfmt/issues/4263))
+- Correct span on const generics to include type bounds ([#4310](https://github.com/rust-lang/rustfmt/issues/4310))
+- Idempotence issue on blocks containing only empty statements ([#4627](https://github.com/rust-lang/rustfmt/issues/4627) and [#3868](https://github.com/rust-lang/rustfmt/issues/3868))
+- Fix issue with semicolon placement on required functions that have a trailing comment that ends in a line-style comment before the semicolon ([#4646](https://github.com/rust-lang/rustfmt/issues/4646))
+- Avoid shared interned cfg_if symbol since rustfmt can re-initialize the rustc_ast globals on multiple inputs ([#4656](https://github.com/rust-lang/rustfmt/issues/4656))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - n/a (superseded by [v1.4.34](#1434-2021-01-28))
+- **GitHub Release Binaries** - [Release v1.4.33](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.33)
+- **Build from source** - [Tag v1.4.33](https://github.com/rust-lang/rustfmt/tree/v1.4.33), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.32] 2021-01-16
+
+### Fixed
+- Indentation now correct on first bound in cases where the generic bounds are multiline formatted and the first bound itself is multiline formatted ([#4636](https://github.com/rust-lang/rustfmt/issues/4636))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2021-01-18`
+- **GitHub Release Binaries** - [Release v1.4.32](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.32)
+- **Build from source** - [Tag v1.4.32](https://github.com/rust-lang/rustfmt/tree/v1.4.32), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.31] 2021-01-09
+
+### Changed
+
+- `rustc-ap-*` crates updated to v697.0.0
+
+### Added
+- Support for 2021 Edition [#4618](https://github.com/rust-lang/rustfmt/pull/4618))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2021-01-16`
+- **GitHub Release Binaries** - [Release v1.4.31](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.31)
+- **Build from source** - [Tag v1.4.31](https://github.com/rust-lang/rustfmt/tree/v1.4.31), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.30] 2020-12-20
+
+### Fixed
+- Last character in derive no longer erroneously stripped when `indent_style` is overridden to `Visual`. ([#4584](https://github.com/rust-lang/rustfmt/issues/4584))
+- Brace wrapping of closure bodies maintained in cases where the closure has an explicit return type and the body consists of a single expression statement. ([#4577](https://github.com/rust-lang/rustfmt/issues/4577))
+- No more panics on invalid code with `err` and `typeof` types ([#4357](https://github.com/rust-lang/rustfmt/issues/4357), [#4586](https://github.com/rust-lang/rustfmt/issues/4586))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-12-25`
+- **GitHub Release Binaries** - [Release v1.4.30](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.30)
+- **Build from source** - [Tag v1.4.30](https://github.com/rust-lang/rustfmt/tree/v1.4.30), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.29] 2020-12-04
+
+### Fixed
+- Negative polarity on non-trait impl now preserved. ([#4566](https://github.com/rust-lang/rustfmt/issues/4566))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-12-07`
+- **GitHub Release Binaries** - [Release v1.4.29](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.29)
+- **Build from source** - [Tag v1.4.29](https://github.com/rust-lang/rustfmt/tree/v1.4.29), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.28] 2020-11-29
+
+### Changed
+
+- `rustc-ap-*` crates updated to v691.0.0
+- In the event of an invalid inner attribute on a `cfg_if` condition, rustfmt will now attempt to continue and format the imported modules. Previously rustfmt would emit the parser error about an inner attribute being invalid in this position, but for rustfmt's purposes the invalid attribute doesn't prevent nor impact module formatting.
+
+### Added
+
+- [`group_imports`][group-imports-config-docs] - a new configuration option that allows users to control the strategy used for grouping imports ([#4107](https://github.com/rust-lang/rustfmt/issues/4107))
+
+[group-imports-config-docs]: https://github.com/rust-lang/rustfmt/blob/v1.4.28/Configurations.md#group_imports
+
+### Fixed
+- Formatting of malformed derived attributes is no longer butchered. ([#3898](https://github.com/rust-lang/rustfmt/issues/3898), [#4029](https://github.com/rust-lang/rustfmt/issues/4029), [#4115](https://github.com/rust-lang/rustfmt/issues/4115), [#4545](https://github.com/rust-lang/rustfmt/issues/4545))
+- Correct indentation used in macro branches when `hard_tabs` is enabled. ([#4152](https://github.com/rust-lang/rustfmt/issues/4152))
+- Comments between the visibility modifier and item name are no longer dropped. ([#2781](https://github.com/rust-lang/rustfmt/issues/2781))
+- Comments preceding the assignment operator in type aliases are no longer dropped. ([#4244](https://github.com/rust-lang/rustfmt/issues/4244))
+- Comments between {`&` operator, lifetime, `mut` kw, type} are no longer dropped. ([#4245](https://github.com/rust-lang/rustfmt/issues/4245))
+- Comments between type bounds are no longer dropped. ([#4243](https://github.com/rust-lang/rustfmt/issues/4243))
+- Function headers are no longer dropped on foreign function items. ([#4288](https://github.com/rust-lang/rustfmt/issues/4288))
+- Foreign function blocks are no longer dropped. ([#4313](https://github.com/rust-lang/rustfmt/issues/4313))
+- `where_single_line` is no longer incorrectly applied to multiline function signatures that have no `where` clause. ([#4547](https://github.com/rust-lang/rustfmt/issues/4547))
+- `matches!` expressions with multiple patterns and a destructure pattern are now able to be formatted. ([#4512](https://github.com/rust-lang/rustfmt/issues/4512))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - n/a (superseded by [v1.4.29](#1429-2020-12-04))
+- **GitHub Release Binaries** - [Release v1.4.28](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.28)
+- **Build from source** - [Tag v1.4.28](https://github.com/rust-lang/rustfmt/tree/v1.4.28), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.27] 2020-11-16
+
+### Fixed
+
+- Leading comments in an extern block are no longer dropped (a bug that exists in v1.4.26). ([#4528](https://github.com/rust-lang/rustfmt/issues/4528))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-11-18`
+- **GitHub Release Binaries** - [Release v1.4.27](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.27)
+- **Build from source** - [Tag v1.4.27](https://github.com/rust-lang/rustfmt/tree/v1.4.27), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.26] 2020-11-14
+
+### Changed
+
+- Original comment indentation for trailing comments within an `if` is now taken into account when determining the indentation level to use for the trailing comment in formatted code. This does not modify any existing code formatted with rustfmt; it simply gives the programmer discretion to specify whether the comment is associated to the `else` block, or if the trailing comment is just a member of the `if` block. ([#1575](https://github.com/rust-lang/rustfmt/issues/1575), [#4120](https://github.com/rust-lang/rustfmt/issues/4120), [#4506](https://github.com/rust-lang/rustfmt/issues/4506))
+
+In this example the `// else comment` refers to the `else`:
+```rust
+// if comment
+if cond {
+ "if"
+// else comment
+} else {
+ "else"
+}
+```
+
+Whereas in this case the `// continue` comments are members of their respective blocks and do not refer to the `else` below.
+```rust
+if toks.eat_token(Token::Word("modify"))? && toks.eat_token(Token::Word("labels"))? {
+ if toks.eat_token(Token::Colon)? {
+ // ate the token
+ } else if toks.eat_token(Token::Word("to"))? {
+ // optionally eat the colon after to, e.g.:
+ // @rustbot modify labels to: -S-waiting-on-author, +S-waiting-on-review
+ toks.eat_token(Token::Colon)?;
+ } else {
+ // It's okay if there's no to or colon, we can just eat labels
+ // afterwards.
+ }
+ 1 + 2;
+ // continue
+} else if toks.eat_token(Token::Word("label"))? {
+ // continue
+} else {
+ return Ok(None);
+}
+```
+
+### Fixed
+- Formatting of empty blocks with attributes which only contained comments is no longer butchered.([#4475](https://github.com/rust-lang/rustfmt/issues/4475), [#4467](https://github.com/rust-lang/rustfmt/issues/4467), [#4452](https://github.com/rust-lang/rustfmt/issues/4452#issuecomment-705886282), [#4522](https://github.com/rust-lang/rustfmt/issues/4522))
+- Indentation of trailing comments in non-empty extern blocks is now correct. ([#4120](https://github.com/rust-lang/rustfmt/issues/4120#issuecomment-696491872))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-11-16`
+- **GitHub Release Binaries** - [Release v1.4.26](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.26)
+- **Build from source** - [Tag v1.4.26](https://github.com/rust-lang/rustfmt/tree/v1.4.26), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.25] 2020-11-10
+
+### Changed
+
+- Semicolons are no longer automatically inserted on trailing expressions in macro definition arms ([#4507](https://github.com/rust-lang/rustfmt/pull/4507)). This gives the programmer control and discretion over whether there should be semicolons in these scenarios so that potential expansion issues can be avoided.
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-11-14`
+- **GitHub Release Binaries** - [Release v1.4.25](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.25)
+- **Build from source** - [Tag v1.4.25](https://github.com/rust-lang/rustfmt/tree/v1.4.25), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.24] 2020-11-05
+
+### Changed
+
+- Block wrapped match arm bodies containing a single macro call expression are no longer flattened ([#4496](https://github.com/rust-lang/rustfmt/pull/4496)). This allows programmer discretion so that the block wrapping can be preserved in cases where needed to prevent issues in expansion, such as with trailing semicolons, and aligns with updated [Style Guide guidance](https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/expressions.md#macro-call-expressions) for such scenarios.
+
+### Fixed
+- Remove useless `deprecated` attribute on a trait impl block in the rustfmt lib, as these now trigger errors ([rust-lang/rust/#78626](https://github.com/rust-lang/rust/pull/78626))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - Starting in `2020-11-09`
+- **GitHub Release Binaries** - [Release v1.4.24](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.24)
+- **Build from source** - [Tag v1.4.24](https://github.com/rust-lang/rustfmt/tree/v1.4.24), see instructions for how to [install rustfmt from source][install-from-source]
+
+## [1.4.23] 2020-10-30
+
+### Changed
+
+- Update `rustc-ap-*` crates to v686.0.0
+
+### Added
+- Initial support for formatting new ConstBlock syntax ([#4478](https://github.com/rust-lang/rustfmt/pull/4478))
+
+### Fixed
+- Handling of unclosed delimiter-only parsing errors in input files ([#4466](https://github.com/rust-lang/rustfmt/issues/4466))
+- Misc. minor parser bugs ([#4418](https://github.com/rust-lang/rustfmt/issues/4418) and [#4431](https://github.com/rust-lang/rustfmt/issues/4431))
+- Panic on nested tuple access ([#4355](https://github.com/rust-lang/rustfmt/issues/4355))
+- Unable to disable license template path via cli override ([#4487](https://github.com/rust-lang/rustfmt/issues/4487))
+- Preserve comments in empty statements [#4018](https://github.com/rust-lang/rustfmt/issues/4018))
+- Indentation on skipped code [#4398](https://github.com/rust-lang/rustfmt/issues/4398))
+
+### Install/Download Options
+- **crates.io package** - *pending*
+- **rustup (nightly)** - n/a (superseded by [v1.4.24](#1424-2020-11-05))
+- **GitHub Release Binaries** - [Release v1.4.23](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.23)
+- **Build from source** - [Tag v1.4.23](https://github.com/rust-lang/rustfmt/tree/v1.4.23), see instructions for how to [install rustfmt from source][install-from-source]
+
+
+
+## [1.4.22] 2020-10-04
+
+### Changed
+
+- Update `rustc-ap-*` crates to v679.0.0
+- Add config option to allow control of leading match arm pipes
+- Support `RUSTFMT` environment variable in `cargo fmt` to run specified `rustfmt` instance
+
+### Fixed
+
+- Fix preservation of type aliases within extern blocks
+
+
+## [1.4.9] 2019-10-07
+
+### Changed
+
+- Update `rustc-ap-*` crates to 606.0.0.
+
+### Fixed
+
+- Fix aligning comments of different group
+- Fix flattening imports with a single `self`.
+- Fix removing attributes on function parameters.
+- Fix removing `impl` keyword from opaque type.
+
+## [1.4.8] 2019-09-08
+
+### Changed
+
+- Update `rustc-ap-*` crates to 583.0.0.
+
+## [1.4.7] 2019-09-06
+
+### Added
+
+- Add `--config` command line option.
+
+### Changed
+
+- Update `rustc-ap-*` crates to 581.0.0.
+- rustfmt now do not warn against trailing whitespaces inside macro calls.
+
+### Fixed
+
+- Fix `merge_imports` generating invalid code.
+- Fix removing discriminant values on enum variants.
+- Fix modules defined inside `cfg_if!` not being formatted.
+- Fix minor formatting issues.
+
+## [1.4.6] 2019-08-28
+
+### Added
+
+- Add `--message-format` command line option to `cargo-fmt`.
+- Add `-l,--files-with-diff` command line option to `rustfmt`.
+- Add `json` emit mode.
+
+### Fixed
+
+- Fix removing attributes on struct pattern's fields.
+- Fix non-idempotent formatting of match arm.
+- Fix `merge_imports` generating invalid code.
+- Fix imports with `#![macro_use]` getting reordered with `reorder_imports`.
+- Fix calculation of line numbers in checkstyle output.
+- Fix poor formatting of complex fn type.
+
+## [1.4.5] 2019-08-13
+
+### Fixed
+
+- Fix generating invalid code when formatting an impl block with const generics inside a where clause.
+- Fix adding a trailing space after a `dyn` keyword which is used as a macro argument by itself.
+
+## [1.4.4] 2019-08-06
+
+### Fixed
+
+- Fix `cargo fmt` incorrectly formatting crates that is not part of the workspace or the path dependencies.
+- Fix removing a trailing comma from a tuple pattern.
+
+## [1.4.3] 2019-08-02
+
+### Changed
+
+- Update `rustc-ap-*` crates to 546.0.0.
+
+### Fixed
+
+- Fix an underscore pattern getting removed.
+
+## [1.4.2] 2019-07-31
+
+### Changed
+
+- Explicitly require the version of `rustfmt-config_proc_macro` to be 0.1.2 or later.
+
+## [1.4.1] 2019-07-30
+
+### Changed
+
+- Update `rustc-ap-*` crates to 542.0.0.
+
+## [1.4.0] 2019-07-29
+
+### Added
+
+- Add new attribute `rustfmt::skip::attributes` to prevent rustfmt
+from formatting an attribute #3665
+
+### Changed
+
+- Update `rustc-ap-*` crates to 541.0.0.
+- Remove multiple semicolons.
+
+## [1.3.3] 2019-07-15
+
+### Added
+
+- Add `--manifest-path` support to `cargo fmt` (#3683).
+
+### Fixed
+
+- Fix `cargo fmt -- --help` printing nothing (#3620).
+- Fix inserting an extra comma (#3677).
+- Fix incorrect handling of CRLF with `file-lines` (#3684).
+- Fix `print-config=minimal` option (#3687).
+
+## [1.3.2] 2019-07-06
+
+### Fixed
+
+- Fix rustfmt crashing when `await!` macro call is used in a method chain.
+- Fix rustfmt not recognizing a package whose name differs from its directory's name.
+
+## [1.3.1] 2019-06-30
+
+### Added
+
+- Implement the `Display` trait on the types of `Config`.
+
+### Changed
+
+- `ignore` configuration option now only supports paths separated by `/`. Windows-style paths are not supported.
+- Running `cargo fmt` in a sub-directory of a project is now supported.
+
+### Fixed
+
+- Fix bugs that may cause rustfmt to crash.
+
+## [1.3.0] 2019-06-09
+
+### Added
+
+- Format modules defined inside `cfg_if` macro calls #3600
+
+### Changed
+
+- Change option `format_doc_comment` to `format_code_in_doc_comment`.
+- `use_small_heuristics` changed to be an enum and stabilised. Configuration
+ options are now ready for 1.0.
+- Stabilise `fn_args_density` configuration option and rename it to `fn_args_layout` #3581
+- Update `rustc-ap-*` crates to 486.0.0
+- Ignore sub-modules when skip-children is used #3607
+- Removed bitrig support #3608
+
+### Fixed
+
+- `wrap_comments` should not imply `format_doc_comments` #3535
+- Incorrect handling of const generics #3555
+- Add the handling for `vec!` with paren inside macro #3576
+- Format trait aliases with where clauses #3586
+- Catch panics from the parser while rewriting macro calls #3589
+- Fix erasing inner attributes in struct #3593
+- Inline the attribute with its item even with the `macro_use` attribute or when `reorder_imports` is disabled #3598
+- Fix the bug add unwanted code to impl #3602
+
+## [1.2.2] 2019-04-24
+
+### Fixed
+
+- Fix processing of `ignore` paths #3522
+- Attempt to format attributes if only they exist #3523
+
+## [1.2.1] 2019-04-18
+
+### Added
+
+- Add `--print-config current` CLI option b473e65
+- Create GitHub [page](https://rust-lang.github.io/rustfmt/) for Configuration.md #3485
+
+### Fixed
+
+- Keep comment appearing between parameter's name and its type #3491
+- Do not delete semicolon after macro call with square brackets #3500
+- Fix `--version` CLI option #3506
+- Fix duplication of attributes on a match arm's body #3510
+- Avoid overflowing item with attributes #3511
+
+## [1.2.0] 2019-03-27
+
+### Added
+
+- Add new attribute `rustfmt::skip::macros` to prevent rustfmt from formatting a macro #3454
+
+### Changed
+
+- Discard error report in silent_emitter #3466
+
+### Fixed
+
+- Fix bad performance on deeply nested binary expressions #3467
+- Use BTreeMap to guarantee consistent ordering b4d4b57
+
+## [1.1.1] 2019-03-21
+
+### Fixed
+
+- Avoid panic on macro inside deeply nested block c9479de
+- Fix line numbering in missed spans and handle file_lines in edge cases cdd08da
+- Fix formatting of async blocks 1fa06ec
+- Avoid duplication on the presence of spaces between macro name and `!` #3464
+
+## [1.1.0] 2019-03-17
+
+### Added
+
+- Add `inline_attribute_width` configuration option to write an item and its attribute on the same line if their combined width is below a threshold #3409
+- Support `const` generics f0c861b
+- Support path clarity module #3448
+
+### Changed
+
+- Align loop and while formatting 7d9a2ef
+- Support `EmitMode::ModifiedLines` with stdin input #3424
+- Update `rustc-ap-*` crates to 407.0.0
+- Remove trailing whitespaces in missing spans 2d5bc69
+
+### Fixed
+
+- Do not remove comment in the case of no arg 8e3ef3e
+- Fix `Ident of macro+ident gets duplicated` error 40ff078
+- Format the if expression at the end of the block in a single line 5f3dfe6
+
+## [1.0.3] 2019-02-14
+
+### Added
+
+- Point unstable options to tracking issues 412dcc7
+
+### Changed
+
+- Update `rustc-ap-*` crates to 373.0.0
+
+## [1.0.2] 2019-02-12
+
+### Added
+
+- Add a [section](https://github.com/rust-lang/rustfmt/blob/ae331be/Contributing.md#version-gate-formatting-changes) to the Contributing.md file about version-gating formatting changes 36e2cb0
+- Allow specifying package with `-p` CLI option a8d2591
+- Support `rustfmt::skip` on imports #3289
+- Support global `rustfmt.toml` to be written in user config directory #3280
+- Format visibility on trait alias 96a3df3
+
+### Changed
+
+- Do not modify original source code inside macro call #3260
+- Recognize strings inside comments in order to avoid indenting them baa62c6
+- Use Unicode-standard char width to wrap comments or strings a01990c
+- Change new line point in the case of no args #3294
+- Use the same formatting rule between functions and macros #3298
+- Update rustc-ap-rustc_target to 366.0.0, rustc-ap-syntax to 366.0.0, and rustc-ap-syntax_pos to 366.0.0
+
+### Fixed
+
+- rewrite_comment: fix block fallback when failing to rewrite an itemized block ab7f4e1
+- Catch possible tokenizer panics #3240
+- Fix macro indentation on Windows #3266
+- Fix shape when formatting return or break expr on statement position #3259
+- rewrite_comment: fix block fallback when failing to rewrite an itemized block
+- Keep leading double-colon to respect the 2018 edition of rust's paths a2bfc02
+- Fix glob and nested global imports 2125ad2
+- Do not force trailing comma when using mixed layout #3306
+- Prioritize `single_line_fn` and `empty_item_single_line` over `brace_style` #3308
+- Fix `internal error: left behind trailing whitespace` with long lines c2534f5
+- Fix attribute duplication #3325
+- Fix formatting of strings within a macro 813aa79
+- Handle a macro argument with a single keyword 9a7ea6a
+
+## [1.0.1] 2018-12-09
+
+### Added
+
+- Add a `version` option 378994b
+
+### Changed
+
+- End expressions like return/continue/break with a semicolon #3223
+- Update rustc-ap-rustc_target to 306.0.0, rustc-ap-syntax to 306.0.0, and rustc-ap-syntax_pos to 306.0.0
+
+### Fixed
+
+- Allow to run a rustfmt command from cargo-fmt even when there is no target a2da636
+- Fix `un-closed delimiter` errors when formatting break labels 40174e9
+
+## [1.0.0] 2018-11-19
+
+### Changed
+
+- Preserve possibly one whitespace for brace macros 1a3bc79
+- Prefer to break arguments over putting output type on the next line 1dd54e6
+
+## [0.99.9] 2018-11-15
+
+### Changed
+
+- Update rustc-ap-rustc_target to 297.0.0, rustc-ap-syntax to 297.0.0, to rustc-ap-syntax_pos to 297.0.0
+- Don't align comments on `extern crate`s dd7add7
+
+## [0.99.8] 2018-11-14
+
+### Added
+
+- Add `overflow_delimited_expr` config option to more aggressively allow overflow #3175
+
+### Fixed
+
+- Fix the logic for retaining a comment before the arrow in a match #3181
+- Do not wrap comments in doctest to avoid failing doctest runs #3183
+- Fix comment rewriting that was wrapping code into a line comment #3188
+- Fix formatting of unit-struct with `where`-clause #3200
+
+## [0.99.7] 2018-11-07
+
+### Changed
+
+- Force a newline after the `if` condition if there is a different indentation level #3109
+- Use correct width when formatting type on local statement #3126
+- Treat crates non-alphabetically when ordering 799005f
+- Fix formatting of code that is annotated with rustfmt::skip #3113
+- Stabilize `edition` configuration option 9c3ae2d
+- cargo-fmt: detect Rust edition in use #3129
+- Trim the indentation on macros which heuristically appear to use block-style indentation #3178
+
+### Fixed
+
+- Do not remove path disambiugator inside macro #3142
+- Improve handling of Windows newlines #3141
+- Fix alignment of a struct's fields (`struct_field_align_threshold` option) with the Visual `indent_style` #3165
+- Fix a bug in formatting markdown lists within comments #3172
+
+## [0.99.6] 2018-10-18
+
+### Added
+
+- Add `enum_discrim_align_threshold` option to vertically align enum discriminants cc22869
+- Add `println!`-like heuristic to the `fail` attribute #3067
+- Handle itemized items inside comments #3083
+- Add `format_doc_comments` configuration option to control the formatting of code snippets inside comments #3089
+
+### Changed
+
+- Makes brace behavior consistent with empty bodies for traits and impls 2727d41
+- Consider a multi-lined array as a block-like expression #3969
+- Improve formatting of strings #3073
+- Get rid of extra commas in Visual struct literal formatting #3077
+- Update rustc-ap-rustc_target to 274.0.0, rustc-ap-syntax to 274.0.0, and rustc-ap-syntax_pos to 274.0.0
+- Format macro calls with item-like arguments #3080
+- Avoid control flow expressions conditions to go multi line ef59b34
+- Simplify multi-lining binop expressions #3101
+
+### Fixed
+
+- Do not format a code block in documentation if it is annotated with ignore or text 2bcc3a9
+- Fix inconsistent overflow behavior in Visual style #3078
+- Fix corner cases of the string formatting implementation #3083
+- Do not add parens around lifetimes 0ac68c9
+- Catch parser panic in format_snippet 8c4e92a
+
+## [0.99.5] 2018-09-25
+
+### Added
+
+- Handle leading module separator for 2018 Edition #2952
+- Add configuration option `normalize_doc_attributes`: convert doc attributes to comments #3002
+
+### Changed
+
+- Accept 2015 and 2018 instead of Edition2015 and Edition2018 for edition option eec7436
+- Support platforms without a timer 46e2a2e
+- Update rustc-ap-rustc_target to 263.0.0, rustc-ap-syntax to 263.0.0, and rustc-ap-syntax_pos to 263.0.0
+
+### Fixed
+
+- Format of attributes with commas #2971
+- Fix optional arg condensing #2972
+- Improve formatting of long function parameters #2981
+- Fix formatting of raw string literals #2983
+- Handle chain with try operators with spaces #2986
+- Use correct shape in Visual tuple rewriting #2987
+- Impove formatting of arguments with `visual_style = "Visual"` option #2988
+- Change `print_diff` to output the correct line number 992b179
+- Propagate errors about failing to rewrite a macro 6f318e3
+- Handle formatting of long function signature #3010
+- Fix indent computation of a macro with braces c3edf6d
+- Format generics on associated types #3035
+- Incorrect indentation of multiline block match expression #3042
+- Fix bug in import where two consecutive module separators were possible 98a0ef2
+- Prevent right-shifting of block comments with bare lines 5fdb6db
+
+## [0.99.4] 2018-08-27
+
+### Added
+
+- Handle formatting of underscore imports #2951
+- Handle formatting of try blocks #2965
+
+### Changed
+
+- Update rustc-ap-rustc_target to 237.0.0, rustc-ap-syntax to 237.0.0, and rustc-ap-syntax_pos to 237.0.0 ca19c9a
+- Consider `dev` channel as nightly for unstable features #2948
+
+### Fixed
+
+- Fix formatting of patterns with ellipsis # 2942
+
+## [0.99.3] 2018-08-23
+
+### Added
+
+- Use path attribute when searching for modules #2901
+- Expose FileLines JSON representation to allow external libraries to use the file_lines option #2915
+
+### Changed
+
+- Replace '--conifig-help' with '--config=help' cb10e06
+- Improve formatting of slice patterns #2912
+
+### Fixed
+
+- Format chains with comment #2899
+- Fix indentation of formatted macro body #2920
+- Fix indentation of block comments f23e6aa
+
+## [0.99.2] 2018-08-07
+
+### Changed
+
+- Update rustc-ap-rustc_target to 218.0.0, rustc-ap-syntax to 218.0.0, and rustc-ap-syntax_pos to 218.0.0 5c9a2b6
+- Combine function-like attributes #2900
+
+### Fixed
+
+- Explicitly handle semicolon after the item in statement position d96e3ca
+- Fix parsing '#'-hiding of rustdoc 2eca09e
+
+## [0.99.1] 2018-08-04
+
+### Fixed
+
+- fix use statements ordering when a number is present 1928ae7
+
+## [0.99.0] 2018-08-03
+
+- 1.0 RC release
+
+### Changed
+
+- Clarification in README.md 30fe66b
+
+## [0.9.0] 2018-08-01
+
+### Added
+
+- Handle raw identifiers 3027c21
+- Format async closure 60ce411
+- Add max_width option for all heuristics c2ae39e
+- Add config option `format_macro_matchers` to format the metavariable matching patterns in macros 79c5ee8
+- Add config option `format_macro_bodies` to format the bodies of macros 79c5ee8
+- Format exitential type fc307ff
+- Support raw identifiers in struct expressions f121b1a
+- Format Async block and async function 0b25f60
+
+### Changed
+
+- Update rustc-ap-rustc_target to 211.0.0, rustc-ap-syntax to 211.0.0, and rustc-ap-syntax_pos to 211.0.0
+- Put each nested import on its own line while putting non-nested imports on the same line as much as possible 42ab258
+- Respect `empty_item_single_line` config option when formatting empty impls. Put the `where` on its own line to improve readability #2771
+- Strip leading `|` in match arm patterns 1d4b988
+- Apply short function call heuristic to attributes 3abebf9
+- Indent a match guard if the pattern is multiline be4d37d
+- Change default newline style to `Native` 9d8f381
+- Improve formatting of series of binop expressions a4cdb68
+- Trigger an internal error if we skip formatting due to a lost comment b085113
+- Refactor chain formatting #2838
+
+### Fixed
+
+- Do not insert spaces around braces with empty body or multiple lines 2f65852
+- Allow using mixed layout with comments #2766
+- Handle break labels #2726
+- fix rewrite_string when a line feed is present 472a2ed
+- Fix an anomaly with comments and array literals b28a0cd
+- Check for comments after the `=>` in a match arm 6899471
+
+## [0.8.0,0.8.1,0.8.2] 2018-05-28
+
+### Added
+
+- Use scoped attributes for skip attribute https://github.com/rust-lang/rustfmt/pull/2703
+
+### Changed
+
+- Comment options `wrap_comments` and `normalize_comments` are reverted back to unstable 416bc4c
+- Stabilise `reorder_imports` and `reorder_modules` options 7b6d2b4
+- Remove `spaces_within_parens_and_brackets` option d726492
+- Stabilise shorthand options: `use_try_shorthand`, `use_field_init_shorthand`, and `force_explicit_abi` 8afe367
+- Stabilise `remove_nested_parens` and set default to true a70f716
+- Unstabilise `unstable_features` dd9c15a
+- Remove `remove_blank_lines_at_start_or_end_of_block` option 2ee8b0e
+- Update rustc-ap-syntax to 146.0.0 and rustc-ap-rustc_target to 146.0.0 2c275a2
+- Audit the public API #2639
+
+### Fixed
+
+- Handle code block in doc comment without rust prefix f1974e2
+
+## [0.7.0] 2018-05-14
+
+### Added
+
+- Add integration tests against crates in the rust-lang-nursery c79f39a
+
+### Changed
+
+- Update rustc-ap-syntax to 128.0.0 and ustc-ap-rustc_target to 128.0.0 195395f
+- Put operands on its own line when each fits in a single line f8439ce
+- Improve CLI options 55ac062 1869888 798bffb 4d9de48 eca7796 8396da1 5d9f5aa
+
+### Fixed
+
+- Use correct line width for list attribute 61a401a
+- Avoid flip-flopping impl items when reordering them 37c216c
+- Formatting breaks short lines when max_width is less than 100 9b36156
+- Fix variant "Mixed" of imports_layout option 8c8676c
+- Improve handling of long lines f885039
+- Fix up lines exceeding max width 51c07f4
+- Fix handling of modules in non_modrs_mods style cf573e8
+- Do not duplicate attributes on use items e59ceaf
+- Do not insert an extra brace in macros with native newlines 4c9ef93
+
+## [0.6.1] 2018-05-01
+
+### Changed
+
+- Change the default value of imports_indent to IndentStyle::Block https://github.com/rust-lang/rustfmt/pull/2662
+
+### Fixed
+
+- Handle formatting of auto traits 5b5a72c
+- Use consistent formatting for empty enum and struct https://github.com/rust-lang/rustfmt/pull/2656
+
+## [0.6.0] 2018-04-20
+
+### Changed
+
+- Improve public API 8669004
+
+## [0.5.0] 2018-04-20
+
+### Added
+
+- Add `verbose-diff` CLI option 5194984
+
+### Changed
+
+- Update rustc-ap-syntax to 103.0.0 dd807e2
+- Refactor to make a sensible public API ca610d3
+
+### Fixed
+
+- Add spaces between consecutive `..` `..=` 61d29eb
+
+## [0.4.2] 2018-04-12
+
+### Added
+
+- Handle binary operators and lifetimes 0fd174d
+- Add reorder_impl_items config option 94f5a05
+- Add `--unstable-features` CLI option to list unstable options from the `--help` output 8208f8a
+- Add merge_imports config option 5dd203e
+
+### Changed
+
+- Format macro arguments with vertical layout ec71459
+- Reorder imports by default 164cf7d
+- Do not collapse block around expr with condition on match arm 5b9b7d5
+- Use vertical layout for complex attributes c77708f
+- Format array using heuristics for function calls 98c6f7b
+- Implement stable ordering for impl items with the the following item priority: type, const, macro, then method fa80ddf
+- Reorder imports by default 164cf7d
+- Group `extern crate` by default 3a138a2
+- Make `error_on_line_overflow` false by default f146711
+- Merge imports with the same prefix into a single nested import 1954513
+- Squash the various 'reorder imports' option into one 911395a
+
+### Fixed
+
+- Print version is missing the channel ca6fc67
+- Do not add the beginning vert to the match arm 1e1d9d4
+- Follow indent style config when formatting attributes efd295a
+- Do not insert newline when item is empty a8022f3
+- Do not indent or unindent inside string literal ec1907b
+
+## [0.4.1] 2018-03-16
+
+### Added
+
+- Add `ignore` configuration option.
+- Add `license_template_path` configuration option.
+- Format `lazy_static!`.
+
+### Fixed
+
+- Fix formatting bugs.
+- Fix setting `reorder_modules` removing inline modules.
+- Format attributes on block expressions.
+- Support `dyn trait` syntax.
+- Support multiple patterns in `if let` and `while let`.
+- Support a pattern with parentheses.
+
+## [0.4.0] 2018-03-02
+
+### Changed
+
+- Do not print verbose outputs when formatting with stdin.
+- Preserve trailing whitespaces in doc comments.
+- Scale the values of width heuristics by `max_width`.
+
+### Fixed
+
+- Do not reorder items with `#[macro_use]`.
+- Fix formatting bugs.
+- Support the beginning `|` on a match arm.
+
+## [0.3.8] 2018-02-04
+
+### Added
+
+- Format (or at least try to format) `macro_rules!`.
+
+## [0.3.7] 2018-02-01
+
+### Added
+
+- Add `use_field_init_shorthand` config option.
+- Add `reorder_modules` configuration option.
+
+## [0.3.6] 2018-01-18
+
+### Fixed
+
+- Fix panicking on formatting certain macros (#2371).
+
+## [0.3.5] 2018-01-15
+
+### Changed
+
+- Format code block in comments when `wrap_comments` is set to `true`.
+- Remove `same_line_attributes` configuration option.
+- Rename `git-fmt` to `git-rustfmt`.
+
+### Fixed
+
+- Rustup to `rustc 1.25.0-nightly (e6072a7b3 2018-01-13)`.
+- Fix formatting bugs.
+
+## [0.3.4] 2017-12-23
+
+### Added
+
+- Add `--version` flag to `cargo-fmt`, allow `cargo fmt --version`.
+
+### Fixed
+
+- Rustup to `rustc 1.24.0-nightly (5165ee9e2 2017-12-22)`.
+
+## [0.3.3] 2017-12-22
+
+### Added
+
+- Format trait aliases.
+
+### Changed
+
+- `cargo fmt` will format every workspace member.
+
+### Fixed
+
+- Rustup to `rustc 1.24.0-nightly (250b49205 2017-12-21)`
+- Fix formatting bugs.
+
+## [0.3.2] 2017-12-15
+
+### Changed
+
+- Warn when unknown configuration option is used.
+
+### Fixed
+
+- Rustup to `rustc 1.24.0-nightly (0077d128d 2017-12-14)`.
+
+## [0.3.1] 2017-12-11
+
+### Added
+
+- Add `error_on_unformatted` configuration option.
+- Add `--error-on-unformatted` command line option.
+
+### Changed
+
+- Do not report formatting errors on comments or strings by default.
+- Rename `error_on_line_overflow_comments` to `error_on_unformatted`.
+
+### Fixed
+
+- Fix formatting bugs.
+- Fix adding a trailing whitespace inside code block when `wrap_comments = true`.
+
+## [0.3.0] 2017-12-11
+
+### Added
+
+- Support nested imports.
+
+### Changed
+
+- Do not report errors on skipped items.
+- Do not format code block inside comments when `wrap_comments = true`.
+- Keep vertical spaces between items within range.
+- Format `format!` and its variants using compressed style.
+- Format `write!` and its variants using compressed style.
+- Format **simple** array using compressed style.
+
+### Fixed
+
+- Fix `rustfmt --package package_name` not working properly.
+- Fix formatting bugs.
+
+## [0.2.17] 2017-12-03
+
+### Added
+
+- Add `blank_lines_lower_bound` and `blank_lines_upper_bound` configuration options.
+
+### Changed
+
+- Combine configuration options related to width heuristic into `width_heuristic`.
+- If the match arm's body is `if` expression, force to use block.
+
+### Fixed
+
+- Fix `cargo fmt --all` being trapped in an infinite loop.
+- Fix many formatting bugs.
+
+### Removed
+
+- Remove legacy configuration options.
+
+## [0.2.16] 2017-11-21
+
+### Added
+
+- Remove empty lines at the beginning of the file.
+- Soft wrapping on doc comments.
+
+### Changed
+
+- Break before `|` when using multiple lines for match arm patterns.
+- Combine `control_style`, `where_style` and `*_indent` config options into `indent_style`.
+- Combine `item_brace_style` and `fn_brace_style` config options into `brace_style`.
+- Combine config options related spacing around colons into `space_before_colon` and `space_after_colon`.
+
+### Fixed
+
+- Fix many bugs.
+
+## [0.2.15] 2017-11-08
+
+### Added
+
+- Add git-fmt tool
+- `where_single_line` configuration option.
+
+### Changed
+
+- Rename `chain_one_line_max` to `chain_width`.
+- Change the suffix of indent-related configuration options to `_indent`.
+
+## [0.2.14] 2017-11-06
+
+### Fixed
+
+- Rustup to the latest nightly.
+
+## [0.2.13] 2017-10-30
+
+### Fixed
+
+- Rustup to the latest nightly.
+
+## [0.2.12] 2017-10-29
+
+### Fixed
+
+- Fix a bug that `cargo fmt` hangs forever.
+
+## [0.2.11] 2017-10-29
+
+### Fixed
+
+- Fix a bug that `cargo fmt` crashes.
+
+## [0.2.10] 2017-10-28
+
+## [0.2.9] 2017-10-16
+
+## [0.2.8] 2017-09-28
+
+## [0.2.7] 2017-09-21
+
+### Added
+
+- `binop_separator` configuration option (#1964).
+
+### Changed
+
+- Use horizontal layout for function call with a single argument.
+
+### Fixed
+
+- Fix panicking when calling `cargo fmt --all` (#1963).
+- Refactorings & faster rustfmt.
+
+## [0.2.6] 2017-09-14
+
+### Fixed
+
+- Fix a performance issue with nested block (#1940).
+- Refactorings & faster rustfmt.
+
+## [0.2.5] 2017-08-31
+
+### Added
+
+- Format and preserve attributes on statements (#1933).
+
+### Fixed
+
+- Use getters to access `Span` fields (#1899).
+
+## [0.2.4] 2017-08-30
+
+### Added
+
+- Add support for `Yield` (#1928).
+
+## [0.2.3] 2017-08-30
+
+### Added
+
+- `multiline_closure_forces_block` configuration option (#1898).
+- `multiline_match_arm_forces_block` configuration option (#1898).
+- `merge_derives` configuration option (#1910).
+- `struct_remove_empty_braces` configuration option (#1930).
+- Various refactorings.
+
+### Changed
+
+- Put single-lined block comments on the same line with list-like structure's item (#1923).
+- Preserve blank line between doc comment and attribute (#1925).
+- Put the opening and the closing braces of enum and struct on the same line, even when `item_brace_style = "AlwaysNextLine"` (#1930).
+
+### Fixed
+
+- Format attributes on `ast::ForeignItem` and take max width into account (#1916).
+- Ignore empty lines when calculating the shortest indent width inside macro with braces (#1918).
+- Handle tabs properly inside macro with braces (#1918).
+- Fix a typo in `compute_budgets_for_args()` (#1924).
+- Recover comment between keyword (`impl` and `trait`) and `{` which used to get removed (#1925).
+
+
+[install-from-source]: https://github.com/rust-lang/rustfmt#installing-from-source
diff --git a/src/tools/rustfmt/CODE_OF_CONDUCT.md b/src/tools/rustfmt/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000000..d70b2b52aca1
--- /dev/null
+++ b/src/tools/rustfmt/CODE_OF_CONDUCT.md
@@ -0,0 +1,40 @@
+# The Rust Code of Conduct
+
+A version of this document [can be found online](https://www.rust-lang.org/conduct.html).
+
+## Conduct
+
+**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org)
+
+* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
+* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
+* Please be kind and courteous. There's no need to be mean or rude.
+* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
+* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
+* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
+* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
+* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
+
+## Moderation
+
+
+These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team].
+
+1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
+2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
+3. Moderators will first respond to such remarks with a warning.
+4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
+5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
+6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.
+7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.
+8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.
+
+In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.
+
+And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
+
+The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
+
+*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
+
+[mod_team]: https://www.rust-lang.org/team.html#Moderation-team
diff --git a/src/tools/rustfmt/Cargo.lock b/src/tools/rustfmt/Cargo.lock
new file mode 100644
index 000000000000..0e12e81904c9
--- /dev/null
+++ b/src/tools/rustfmt/Cargo.lock
@@ -0,0 +1,915 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "annotate-snippets"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5"
+dependencies = [
+ "yansi-term",
+]
+
+[[package]]
+name = "ansi_term"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
+
+[[package]]
+name = "arrayref"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
+
+[[package]]
+name = "arrayvec"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
+dependencies = [
+ "nodrop",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
+[[package]]
+name = "backtrace"
+version = "0.3.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
+dependencies = [
+ "backtrace-sys",
+ "cfg-if",
+ "libc",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "base64"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
+name = "blake2b_simd"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "constant_time_eq",
+]
+
+[[package]]
+name = "bstr"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "bytecount"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e"
+dependencies = [
+ "packed_simd",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
+
+[[package]]
+name = "cargo_metadata"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426"
+dependencies = [
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "clap"
+version = "2.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "bitflags",
+ "strsim",
+ "textwrap",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "constant_time_eq"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
+dependencies = [
+ "crossbeam-utils 0.7.0",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "derive-new"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "diff"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
+
+[[package]]
+name = "dirs"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
+dependencies = [
+ "cfg-if",
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "either"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+
+[[package]]
+name = "env_logger"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "failure"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
+dependencies = [
+ "backtrace",
+ "failure_derive",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
+
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+
+[[package]]
+name = "getopts"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "globset"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "fnv",
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "heck"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "humantime"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+dependencies = [
+ "quick-error",
+]
+
+[[package]]
+name = "ignore"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "522daefc3b69036f80c7d2990b28ff9e0471c683bad05ca258e0a01dd22c5a1e"
+dependencies = [
+ "crossbeam-channel",
+ "globset",
+ "lazy_static",
+ "log",
+ "memchr",
+ "regex",
+ "same-file",
+ "thread_local 1.0.1",
+ "walkdir",
+ "winapi-util",
+]
+
+[[package]]
+name = "itertools"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
+
+[[package]]
+name = "log"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
+
+[[package]]
+name = "nodrop"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
+
+[[package]]
+name = "packed_simd"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "syn-mid",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
+
+[[package]]
+name = "quote"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+dependencies = [
+ "rand_core 0.4.2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+dependencies = [
+ "cloudabi",
+ "fuchsia-cprng",
+ "libc",
+ "rand_core 0.4.2",
+ "rdrand",
+ "winapi",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
+
+[[package]]
+name = "redox_users"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d"
+dependencies = [
+ "failure",
+ "rand_os",
+ "redox_syscall",
+ "rust-argon2",
+]
+
+[[package]]
+name = "regex"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local 0.3.6",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
+
+[[package]]
+name = "rust-argon2"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
+dependencies = [
+ "base64",
+ "blake2b_simd",
+ "crossbeam-utils 0.6.6",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+
+[[package]]
+name = "rustc-workspace-hack"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
+
+[[package]]
+name = "rustfmt-config_proc_macro"
+version = "0.2.0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "rustfmt-nightly"
+version = "1.4.37"
+dependencies = [
+ "annotate-snippets",
+ "anyhow",
+ "bytecount",
+ "cargo_metadata",
+ "derive-new",
+ "diff",
+ "dirs",
+ "env_logger",
+ "getopts",
+ "ignore",
+ "itertools",
+ "lazy_static",
+ "log",
+ "regex",
+ "rustc-workspace-hack",
+ "rustfmt-config_proc_macro",
+ "serde",
+ "serde_json",
+ "structopt",
+ "term",
+ "thiserror",
+ "toml",
+ "unicode-segmentation",
+ "unicode-width",
+ "unicode_categories",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
+
+[[package]]
+name = "same-file"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+ "serde",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "serde"
+version = "1.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+
+[[package]]
+name = "structopt"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073"
+dependencies = [
+ "clap",
+ "lazy_static",
+ "structopt-derive",
+]
+
+[[package]]
+name = "structopt-derive"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "syn-mid"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
+name = "term"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5"
+dependencies = [
+ "dirs",
+ "winapi",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
+dependencies = [
+ "wincolor",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6b305ec0e323c7b6cfff6098a22516e0063d0bb7c3d88660a890217dca099a"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45ba8d810d9c48fc456b7ad54574e8bfb7c7918a57ad7a6e6a0985d7959e8597"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thread_local"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+
+[[package]]
+name = "unicode_categories"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+
+[[package]]
+name = "vec_map"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+
+[[package]]
+name = "version_check"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
+
+[[package]]
+name = "walkdir"
+version = "2.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "wincolor"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
+dependencies = [
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "yansi-term"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
+dependencies = [
+ "winapi",
+]
diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml
new file mode 100644
index 000000000000..24b3b79343b0
--- /dev/null
+++ b/src/tools/rustfmt/Cargo.toml
@@ -0,0 +1,67 @@
+[package]
+
+name = "rustfmt-nightly"
+version = "1.4.37"
+authors = ["Nicholas Cameron ", "The Rustfmt developers"]
+description = "Tool to find and fix Rust formatting issues"
+repository = "https://github.com/rust-lang/rustfmt"
+readme = "README.md"
+license = "Apache-2.0/MIT"
+build = "build.rs"
+categories = ["development-tools"]
+edition = "2018"
+
+[[bin]]
+name = "rustfmt"
+path = "src/bin/main.rs"
+
+[[bin]]
+name = "cargo-fmt"
+path = "src/cargo-fmt/main.rs"
+
+[[bin]]
+name = "rustfmt-format-diff"
+path = "src/format-diff/main.rs"
+
+[[bin]]
+name = "git-rustfmt"
+path = "src/git-rustfmt/main.rs"
+
+[features]
+default = ["cargo-fmt", "rustfmt-format-diff"]
+cargo-fmt = []
+rustfmt-format-diff = []
+generic-simd = ["bytecount/generic-simd"]
+
+[dependencies]
+itertools = "0.8"
+toml = "0.5"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+unicode-segmentation = "1.0.0"
+regex = "1.0"
+term = "0.6"
+diff = "0.1"
+log = "0.4"
+env_logger = "0.6"
+getopts = "0.2"
+derive-new = "0.5"
+cargo_metadata = "0.8"
+bytecount = "0.6"
+unicode-width = "0.1.5"
+unicode_categories = "0.1.1"
+dirs = "2.0.1"
+ignore = "0.4.11"
+annotate-snippets = { version = "0.8", features = ["color"] }
+structopt = "0.3"
+rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" }
+lazy_static = "1.0.0"
+anyhow = "1.0"
+thiserror = "1.0"
+
+# A noop dependency that changes in the Rust repository, it's a bit of a hack.
+# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
+# for more information.
+rustc-workspace-hack = "1.0.0"
+
+# Rustc dependencies are loaded from the sysroot, Cargo doesn't know about them.
diff --git a/src/tools/rustfmt/Configurations.md b/src/tools/rustfmt/Configurations.md
new file mode 100644
index 000000000000..37cb7474130c
--- /dev/null
+++ b/src/tools/rustfmt/Configurations.md
@@ -0,0 +1,2773 @@
+# Configuring Rustfmt
+
+Rustfmt is designed to be very configurable. You can create a TOML file called `rustfmt.toml` or `.rustfmt.toml`, place it in the project or any other parent directory and it will apply the options in that file. If none of these directories contain such a file, both your home directory and a directory called `rustfmt` in your [global config directory](https://docs.rs/dirs/1.0.4/dirs/fn.config_dir.html) (e.g. `.config/rustfmt/`) are checked as well.
+
+A possible content of `rustfmt.toml` or `.rustfmt.toml` might look like this:
+
+```toml
+indent_style = "Block"
+reorder_imports = false
+```
+
+Each configuration option is either stable or unstable.
+Stable options can be used directly, while unstable options are opt-in.
+To enable unstable options, set `unstable_features = true` in `rustfmt.toml` or pass `--unstable-features` to rustfmt.
+
+# Configuration Options
+
+Below you find a detailed visual guide on all the supported configuration options of rustfmt:
+
+## `array_width`
+
+Maximum width of an array literal before falling back to vertical formatting.
+
+- **Default value**: `60`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `array_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `attr_fn_like_width`
+
+Maximum width of the args of a function-like attributes before falling back to vertical formatting.
+
+- **Default value**: `70`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `attr_fn_like_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `binop_separator`
+
+Where to put a binary operator when a binary expression goes multiline.
+
+- **Default value**: `"Front"`
+- **Possible values**: `"Front"`, `"Back"`
+- **Stable**: No (tracking issue: #3368)
+
+#### `"Front"` (default):
+
+```rust
+fn main() {
+ let or = foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo
+ || barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar;
+
+ let sum = 123456789012345678901234567890
+ + 123456789012345678901234567890
+ + 123456789012345678901234567890;
+
+ let range = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ ..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;
+}
+```
+
+#### `"Back"`:
+
+```rust
+fn main() {
+ let or = foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo ||
+ barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar;
+
+ let sum = 123456789012345678901234567890 +
+ 123456789012345678901234567890 +
+ 123456789012345678901234567890;
+
+ let range = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;
+}
+```
+
+## `blank_lines_lower_bound`
+
+Minimum number of blank lines which must be put between items. If two items have fewer blank lines between
+them, additional blank lines are inserted.
+
+- **Default value**: `0`
+- **Possible values**: *unsigned integer*
+- **Stable**: No (tracking issue: #3382)
+
+### Example
+Original Code (rustfmt will not change it with the default value of `0`):
+
+```rust
+#![rustfmt::skip]
+
+fn foo() {
+ println!("a");
+}
+fn bar() {
+ println!("b");
+ println!("c");
+}
+```
+
+#### `1`
+```rust
+fn foo() {
+
+ println!("a");
+}
+
+fn bar() {
+
+ println!("b");
+
+ println!("c");
+}
+```
+
+
+## `blank_lines_upper_bound`
+
+Maximum number of blank lines which can be put between items. If more than this number of consecutive empty
+lines are found, they are trimmed down to match this integer.
+
+- **Default value**: `1`
+- **Possible values**: any non-negative integer
+- **Stable**: No (tracking issue: #3381)
+
+### Example
+Original Code:
+
+```rust
+#![rustfmt::skip]
+
+fn foo() {
+ println!("a");
+}
+
+
+
+fn bar() {
+ println!("b");
+
+
+ println!("c");
+}
+```
+
+#### `1` (default):
+```rust
+fn foo() {
+ println!("a");
+}
+
+fn bar() {
+ println!("b");
+
+ println!("c");
+}
+```
+
+#### `2`:
+```rust
+fn foo() {
+ println!("a");
+}
+
+
+fn bar() {
+ println!("b");
+
+
+ println!("c");
+}
+```
+
+See also: [`blank_lines_lower_bound`](#blank_lines_lower_bound)
+
+## `brace_style`
+
+Brace style for items
+
+- **Default value**: `"SameLineWhere"`
+- **Possible values**: `"AlwaysNextLine"`, `"PreferSameLine"`, `"SameLineWhere"`
+- **Stable**: No (tracking issue: #3376)
+
+### Functions
+
+#### `"SameLineWhere"` (default):
+
+```rust
+fn lorem() {
+ // body
+}
+
+fn lorem(ipsum: usize) {
+ // body
+}
+
+fn lorem(ipsum: T)
+where
+ T: Add + Sub + Mul + Div,
+{
+ // body
+}
+```
+
+#### `"AlwaysNextLine"`:
+
+```rust
+fn lorem()
+{
+ // body
+}
+
+fn lorem(ipsum: usize)
+{
+ // body
+}
+
+fn lorem(ipsum: T)
+where
+ T: Add + Sub + Mul + Div,
+{
+ // body
+}
+```
+
+#### `"PreferSameLine"`:
+
+```rust
+fn lorem() {
+ // body
+}
+
+fn lorem(ipsum: usize) {
+ // body
+}
+
+fn lorem(ipsum: T)
+where
+ T: Add + Sub + Mul + Div, {
+ // body
+}
+```
+
+### Structs and enums
+
+#### `"SameLineWhere"` (default):
+
+```rust
+struct Lorem {
+ ipsum: bool,
+}
+
+struct Dolor
+where
+ T: Eq,
+{
+ sit: T,
+}
+```
+
+#### `"AlwaysNextLine"`:
+
+```rust
+struct Lorem
+{
+ ipsum: bool,
+}
+
+struct Dolor
+where
+ T: Eq,
+{
+ sit: T,
+}
+```
+
+#### `"PreferSameLine"`:
+
+```rust
+struct Lorem {
+ ipsum: bool,
+}
+
+struct Dolor
+where
+ T: Eq, {
+ sit: T,
+}
+```
+
+## `chain_width`
+
+Maximum width of a chain to fit on one line.
+
+- **Default value**: `60`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `chain_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `color`
+
+Whether to use colored output or not.
+
+- **Default value**: `"Auto"`
+- **Possible values**: "Auto", "Always", "Never"
+- **Stable**: No (tracking issue: #3385)
+
+## `combine_control_expr`
+
+Combine control expressions with function calls.
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3369)
+
+#### `true` (default):
+
+```rust
+fn example() {
+ // If
+ foo!(if x {
+ foo();
+ } else {
+ bar();
+ });
+
+ // IfLet
+ foo!(if let Some(..) = x {
+ foo();
+ } else {
+ bar();
+ });
+
+ // While
+ foo!(while x {
+ foo();
+ bar();
+ });
+
+ // WhileLet
+ foo!(while let Some(..) = x {
+ foo();
+ bar();
+ });
+
+ // ForLoop
+ foo!(for x in y {
+ foo();
+ bar();
+ });
+
+ // Loop
+ foo!(loop {
+ foo();
+ bar();
+ });
+}
+```
+
+#### `false`:
+
+```rust
+fn example() {
+ // If
+ foo!(
+ if x {
+ foo();
+ } else {
+ bar();
+ }
+ );
+
+ // IfLet
+ foo!(
+ if let Some(..) = x {
+ foo();
+ } else {
+ bar();
+ }
+ );
+
+ // While
+ foo!(
+ while x {
+ foo();
+ bar();
+ }
+ );
+
+ // WhileLet
+ foo!(
+ while let Some(..) = x {
+ foo();
+ bar();
+ }
+ );
+
+ // ForLoop
+ foo!(
+ for x in y {
+ foo();
+ bar();
+ }
+ );
+
+ // Loop
+ foo!(
+ loop {
+ foo();
+ bar();
+ }
+ );
+}
+```
+
+## `comment_width`
+
+Maximum length of comments. No effect unless`wrap_comments = true`.
+
+- **Default value**: `80`
+- **Possible values**: any positive integer
+- **Stable**: No (tracking issue: #3349)
+
+**Note:** A value of `0` results in [`wrap_comments`](#wrap_comments) being applied regardless of a line's width.
+
+#### `80` (default; comments shorter than `comment_width`):
+```rust
+// Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+```
+
+#### `60` (comments longer than `comment_width`):
+```rust
+// Lorem ipsum dolor sit amet,
+// consectetur adipiscing elit.
+```
+
+See also [`wrap_comments`](#wrap_comments).
+
+## `condense_wildcard_suffixes`
+
+Replace strings of _ wildcards by a single .. in tuple patterns
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3384)
+
+#### `false` (default):
+
+```rust
+fn main() {
+ let (lorem, ipsum, _, _) = (1, 2, 3, 4);
+ let (lorem, ipsum, ..) = (1, 2, 3, 4);
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ let (lorem, ipsum, ..) = (1, 2, 3, 4);
+}
+```
+
+## `control_brace_style`
+
+Brace style for control flow constructs
+
+- **Default value**: `"AlwaysSameLine"`
+- **Possible values**: `"AlwaysNextLine"`, `"AlwaysSameLine"`, `"ClosingNextLine"`
+- **Stable**: No (tracking issue: #3377)
+
+#### `"AlwaysSameLine"` (default):
+
+```rust
+fn main() {
+ if lorem {
+ println!("ipsum!");
+ } else {
+ println!("dolor!");
+ }
+}
+```
+
+#### `"AlwaysNextLine"`:
+
+```rust
+fn main() {
+ if lorem
+ {
+ println!("ipsum!");
+ }
+ else
+ {
+ println!("dolor!");
+ }
+}
+```
+
+#### `"ClosingNextLine"`:
+
+```rust
+fn main() {
+ if lorem {
+ println!("ipsum!");
+ }
+ else {
+ println!("dolor!");
+ }
+}
+```
+
+## `disable_all_formatting`
+
+Don't reformat anything
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3388)
+
+## `edition`
+
+Specifies which edition is used by the parser.
+
+- **Default value**: `"2015"`
+- **Possible values**: `"2015"`, `"2018"`, `"2021"`
+- **Stable**: Yes
+
+Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if executed
+through the Cargo's formatting tool `cargo fmt`. Otherwise, the edition needs to be specified
+in your config file:
+
+```toml
+edition = "2018"
+```
+
+## `empty_item_single_line`
+
+Put empty-body functions and impls on a single line
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3356)
+
+#### `true` (default):
+
+```rust
+fn lorem() {}
+
+impl Lorem {}
+```
+
+#### `false`:
+
+```rust
+fn lorem() {
+}
+
+impl Lorem {
+}
+```
+
+See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_style).
+
+
+## `enum_discrim_align_threshold`
+
+The maximum length of enum variant having discriminant, that gets vertically aligned with others.
+Variants without discriminants would be ignored for the purpose of alignment.
+
+Note that this is not how much whitespace is inserted, but instead the longest variant name that
+doesn't get ignored when aligning.
+
+- **Default value** : 0
+- **Possible values**: any positive integer
+- **Stable**: No (tracking issue: #3372)
+
+#### `0` (default):
+
+```rust
+enum Bar {
+ A = 0,
+ Bb = 1,
+ RandomLongVariantGoesHere = 10,
+ Ccc = 71,
+}
+
+enum Bar {
+ VeryLongVariantNameHereA = 0,
+ VeryLongVariantNameHereBb = 1,
+ VeryLongVariantNameHereCcc = 2,
+}
+```
+
+#### `20`:
+
+```rust
+enum Foo {
+ A = 0,
+ Bb = 1,
+ RandomLongVariantGoesHere = 10,
+ Ccc = 2,
+}
+
+enum Bar {
+ VeryLongVariantNameHereA = 0,
+ VeryLongVariantNameHereBb = 1,
+ VeryLongVariantNameHereCcc = 2,
+}
+```
+
+
+## `error_on_line_overflow`
+
+Error if Rustfmt is unable to get all lines within `max_width`, except for comments and string
+literals. If this happens, then it is a bug in Rustfmt. You might be able to work around the bug by
+refactoring your code to avoid long/complex expressions, usually by extracting a local variable or
+using a shorter name.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3391)
+
+See also [`max_width`](#max_width).
+
+## `error_on_unformatted`
+
+Error if unable to get comments or string literals within `max_width`, or they are left with
+trailing whitespaces.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3392)
+
+## `fn_args_layout`
+
+Control the layout of arguments in a function
+
+- **Default value**: `"Tall"`
+- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
+- **Stable**: Yes
+
+#### `"Tall"` (default):
+
+```rust
+trait Lorem {
+ fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet);
+
+ fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) {
+ // body
+ }
+
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ consectetur: Consectetur,
+ adipiscing: Adipiscing,
+ elit: Elit,
+ );
+
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ consectetur: Consectetur,
+ adipiscing: Adipiscing,
+ elit: Elit,
+ ) {
+ // body
+ }
+}
+```
+
+#### `"Compressed"`:
+
+```rust
+trait Lorem {
+ fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet);
+
+ fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) {
+ // body
+ }
+
+ fn lorem(
+ ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur,
+ adipiscing: Adipiscing, elit: Elit,
+ );
+
+ fn lorem(
+ ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur,
+ adipiscing: Adipiscing, elit: Elit,
+ ) {
+ // body
+ }
+}
+```
+
+#### `"Vertical"`:
+
+```rust
+trait Lorem {
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ );
+
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ ) {
+ // body
+ }
+
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ consectetur: Consectetur,
+ adipiscing: Adipiscing,
+ elit: Elit,
+ );
+
+ fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ consectetur: Consectetur,
+ adipiscing: Adipiscing,
+ elit: Elit,
+ ) {
+ // body
+ }
+}
+```
+
+## `fn_call_width`
+
+Maximum width of the args of a function call before falling back to vertical formatting.
+
+- **Default value**: `60`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `fn_call_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `fn_single_line`
+
+Put single-expression functions on a single line
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3358)
+
+#### `false` (default):
+
+```rust
+fn lorem() -> usize {
+ 42
+}
+
+fn lorem() -> usize {
+ let ipsum = 42;
+ ipsum
+}
+```
+
+#### `true`:
+
+```rust
+fn lorem() -> usize { 42 }
+
+fn lorem() -> usize {
+ let ipsum = 42;
+ ipsum
+}
+```
+
+See also [`control_brace_style`](#control_brace_style).
+
+
+## `force_explicit_abi`
+
+Always print the abi for extern items
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+**Note:** Non-"C" ABIs are always printed. If `false` then "C" is removed.
+
+#### `true` (default):
+
+```rust
+extern "C" {
+ pub static lorem: c_int;
+}
+```
+
+#### `false`:
+
+```rust
+extern {
+ pub static lorem: c_int;
+}
+```
+
+## `force_multiline_blocks`
+
+Force multiline closure and match arm bodies to be wrapped in a block
+
+- **Default value**: `false`
+- **Possible values**: `false`, `true`
+- **Stable**: No (tracking issue: #3374)
+
+#### `false` (default):
+
+```rust
+fn main() {
+ result.and_then(|maybe_value| match maybe_value {
+ None => foo(),
+ Some(value) => bar(),
+ });
+
+ match lorem {
+ None => |ipsum| {
+ println!("Hello World");
+ },
+ Some(dolor) => foo(),
+ }
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ result.and_then(|maybe_value| {
+ match maybe_value {
+ None => foo(),
+ Some(value) => bar(),
+ }
+ });
+
+ match lorem {
+ None => {
+ |ipsum| {
+ println!("Hello World");
+ }
+ }
+ Some(dolor) => foo(),
+ }
+}
+```
+
+
+## `format_code_in_doc_comments`
+
+Format code snippet included in doc comments.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3348)
+
+#### `false` (default):
+
+```rust
+/// Adds one to the number given.
+///
+/// # Examples
+///
+/// ```rust
+/// let five=5;
+///
+/// assert_eq!(
+/// 6,
+/// add_one(5)
+/// );
+/// # fn add_one(x: i32) -> i32 {
+/// # x + 1
+/// # }
+/// ```
+fn add_one(x: i32) -> i32 {
+ x + 1
+}
+```
+
+#### `true`
+
+```rust
+/// Adds one to the number given.
+///
+/// # Examples
+///
+/// ```rust
+/// let five = 5;
+///
+/// assert_eq!(6, add_one(5));
+/// # fn add_one(x: i32) -> i32 {
+/// # x + 1
+/// # }
+/// ```
+fn add_one(x: i32) -> i32 {
+ x + 1
+}
+```
+
+## `format_macro_matchers`
+
+Format the metavariable matching patterns in macros.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3354)
+
+#### `false` (default):
+
+```rust
+macro_rules! foo {
+ ($a: ident : $b: ty) => {
+ $a(42): $b;
+ };
+ ($a: ident $b: ident $c: ident) => {
+ $a = $b + $c;
+ };
+}
+```
+
+#### `true`:
+
+```rust
+macro_rules! foo {
+ ($a:ident : $b:ty) => {
+ $a(42): $b;
+ };
+ ($a:ident $b:ident $c:ident) => {
+ $a = $b + $c;
+ };
+}
+```
+
+See also [`format_macro_bodies`](#format_macro_bodies).
+
+
+## `format_macro_bodies`
+
+Format the bodies of macros.
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3355)
+
+#### `true` (default):
+
+```rust
+macro_rules! foo {
+ ($a: ident : $b: ty) => {
+ $a(42): $b;
+ };
+ ($a: ident $b: ident $c: ident) => {
+ $a = $b + $c;
+ };
+}
+```
+
+#### `false`:
+
+```rust
+macro_rules! foo {
+ ($a: ident : $b: ty) => { $a(42): $b; };
+ ($a: ident $b: ident $c: ident) => { $a=$b+$c; };
+}
+```
+
+See also [`format_macro_matchers`](#format_macro_matchers).
+
+
+## `format_strings`
+
+Format string literals where necessary
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3353)
+
+#### `false` (default):
+
+```rust
+fn main() {
+ let lorem = "ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit amet consectetur adipiscing";
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ let lorem = "ipsum dolor sit amet consectetur adipiscing elit lorem ipsum dolor sit amet \
+ consectetur adipiscing";
+}
+```
+
+See also [`max_width`](#max_width).
+
+## `hard_tabs`
+
+Use tab characters for indentation, spaces for alignment
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `false` (default):
+
+```rust
+fn lorem() -> usize {
+ 42 // spaces before 42
+}
+```
+
+#### `true`:
+
+```rust
+fn lorem() -> usize {
+ 42 // tabs before 42
+}
+```
+
+See also: [`tab_spaces`](#tab_spaces).
+
+
+## `hide_parse_errors`
+
+Do not show parse errors if the parser failed to parse files.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3390)
+
+## `ignore`
+
+Skip formatting files and directories that match the specified pattern.
+The pattern format is the same as [.gitignore](https://git-scm.com/docs/gitignore#_pattern_format). Be sure to use Unix/forwardslash `/` style paths. This path style will work on all platforms. Windows style paths with backslashes `\` are not supported.
+
+- **Default value**: format every file
+- **Possible values**: See an example below
+- **Stable**: No (tracking issue: #3395)
+
+### Example
+
+If you want to ignore specific files, put the following to your config file:
+
+```toml
+ignore = [
+ "src/types.rs",
+ "src/foo/bar.rs",
+]
+```
+
+If you want to ignore every file under `examples/`, put the following to your config file:
+
+```toml
+ignore = [
+ "examples",
+]
+```
+
+If you want to ignore every file under the directory where you put your rustfmt.toml:
+
+```toml
+ignore = ["/"]
+```
+
+## `imports_indent`
+
+Indent style of imports
+
+- **Default Value**: `"Block"`
+- **Possible values**: `"Block"`, `"Visual"`
+- **Stable**: No (tracking issue: #3360)
+
+#### `"Block"` (default):
+
+```rust
+use foo::{
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,
+};
+```
+
+#### `"Visual"`:
+
+```rust
+use foo::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
+ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz};
+```
+
+See also: [`imports_layout`](#imports_layout).
+
+## `imports_layout`
+
+Item layout inside a imports block
+
+- **Default value**: "Mixed"
+- **Possible values**: "Horizontal", "HorizontalVertical", "Mixed", "Vertical"
+- **Stable**: No (tracking issue: #3361)
+
+#### `"Mixed"` (default):
+
+```rust
+use foo::{xxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzz};
+
+use foo::{
+ aaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbb, cccccccccccccccccc, dddddddddddddddddd,
+ eeeeeeeeeeeeeeeeee, ffffffffffffffffff,
+};
+```
+
+#### `"Horizontal"`:
+
+**Note**: This option forces all imports onto one line and may exceed `max_width`.
+
+```rust
+use foo::{xxx, yyy, zzz};
+
+use foo::{aaa, bbb, ccc, ddd, eee, fff};
+```
+
+#### `"HorizontalVertical"`:
+
+```rust
+use foo::{xxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzz};
+
+use foo::{
+ aaaaaaaaaaaaaaaaaa,
+ bbbbbbbbbbbbbbbbbb,
+ cccccccccccccccccc,
+ dddddddddddddddddd,
+ eeeeeeeeeeeeeeeeee,
+ ffffffffffffffffff,
+};
+```
+
+#### `"Vertical"`:
+
+```rust
+use foo::{
+ xxx,
+ yyy,
+ zzz,
+};
+
+use foo::{
+ aaa,
+ bbb,
+ ccc,
+ ddd,
+ eee,
+ fff,
+};
+```
+
+## `indent_style`
+
+Indent on expressions or items.
+
+- **Default value**: `"Block"`
+- **Possible values**: `"Block"`, `"Visual"`
+- **Stable**: No (tracking issue: #3346)
+
+### Array
+
+#### `"Block"` (default):
+
+```rust
+fn main() {
+ let lorem = vec![
+ "ipsum",
+ "dolor",
+ "sit",
+ "amet",
+ "consectetur",
+ "adipiscing",
+ "elit",
+ ];
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn main() {
+ let lorem = vec!["ipsum",
+ "dolor",
+ "sit",
+ "amet",
+ "consectetur",
+ "adipiscing",
+ "elit"];
+}
+```
+
+### Control flow
+
+#### `"Block"` (default):
+
+```rust
+fn main() {
+ if lorem_ipsum
+ && dolor_sit
+ && amet_consectetur
+ && lorem_sit
+ && dolor_consectetur
+ && amet_ipsum
+ && lorem_consectetur
+ {
+ // ...
+ }
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn main() {
+ if lorem_ipsum
+ && dolor_sit
+ && amet_consectetur
+ && lorem_sit
+ && dolor_consectetur
+ && amet_ipsum
+ && lorem_consectetur
+ {
+ // ...
+ }
+}
+```
+
+See also: [`control_brace_style`](#control_brace_style).
+
+### Function arguments
+
+#### `"Block"` (default):
+
+```rust
+fn lorem() {}
+
+fn lorem(ipsum: usize) {}
+
+fn lorem(
+ ipsum: usize,
+ dolor: usize,
+ sit: usize,
+ amet: usize,
+ consectetur: usize,
+ adipiscing: usize,
+ elit: usize,
+) {
+ // body
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn lorem() {}
+
+fn lorem(ipsum: usize) {}
+
+fn lorem(ipsum: usize,
+ dolor: usize,
+ sit: usize,
+ amet: usize,
+ consectetur: usize,
+ adipiscing: usize,
+ elit: usize) {
+ // body
+}
+```
+
+### Function calls
+
+#### `"Block"` (default):
+
+```rust
+fn main() {
+ lorem(
+ "lorem",
+ "ipsum",
+ "dolor",
+ "sit",
+ "amet",
+ "consectetur",
+ "adipiscing",
+ "elit",
+ );
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn main() {
+ lorem("lorem",
+ "ipsum",
+ "dolor",
+ "sit",
+ "amet",
+ "consectetur",
+ "adipiscing",
+ "elit");
+}
+```
+
+### Generics
+
+#### `"Block"` (default):
+
+```rust
+fn lorem<
+ Ipsum: Eq = usize,
+ Dolor: Eq = usize,
+ Sit: Eq = usize,
+ Amet: Eq = usize,
+ Adipiscing: Eq = usize,
+ Consectetur: Eq = usize,
+ Elit: Eq = usize,
+>(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ adipiscing: Adipiscing,
+ consectetur: Consectetur,
+ elit: Elit,
+) -> T {
+ // body
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn lorem(
+ ipsum: Ipsum,
+ dolor: Dolor,
+ sit: Sit,
+ amet: Amet,
+ adipiscing: Adipiscing,
+ consectetur: Consectetur,
+ elit: Elit)
+ -> T {
+ // body
+}
+```
+
+#### Struct
+
+#### `"Block"` (default):
+
+```rust
+fn main() {
+ let lorem = Lorem {
+ ipsum: dolor,
+ sit: amet,
+ };
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn main() {
+ let lorem = Lorem { ipsum: dolor,
+ sit: amet };
+}
+```
+
+See also: [`struct_lit_single_line`](#struct_lit_single_line), [`indent_style`](#indent_style).
+
+### Where predicates
+
+#### `"Block"` (default):
+
+```rust
+fn lorem() -> T
+where
+ Ipsum: Eq,
+ Dolor: Eq,
+ Sit: Eq,
+ Amet: Eq,
+{
+ // body
+}
+```
+
+#### `"Visual"`:
+
+```rust
+fn lorem() -> T
+ where Ipsum: Eq,
+ Dolor: Eq,
+ Sit: Eq,
+ Amet: Eq
+{
+ // body
+}
+```
+
+## `inline_attribute_width`
+
+Write an item and its attribute on the same line if their combined width is below a threshold
+
+- **Default value**: 0
+- **Possible values**: any positive integer
+- **Stable**: No (tracking issue: #3343)
+
+### Example
+
+#### `0` (default):
+```rust
+#[cfg(feature = "alloc")]
+use core::slice;
+```
+
+#### `50`:
+```rust
+#[cfg(feature = "alloc")] use core::slice;
+```
+
+## `license_template_path`
+
+Check whether beginnings of files match a license template.
+
+- **Default value**: `""`
+- **Possible values**: path to a license template file
+- **Stable**: No (tracking issue: #3352)
+
+A license template is a plain text file which is matched literally against the
+beginning of each source file, except for `{}`-delimited blocks, which are
+matched as regular expressions. The following license template therefore
+matches strings like `// Copyright 2017 The Rust Project Developers.`, `//
+Copyright 2018 The Rust Project Developers.`, etc.:
+
+```
+// Copyright {\d+} The Rust Project Developers.
+```
+
+`\{`, `\}` and `\\` match literal braces / backslashes.
+
+## `match_arm_blocks`
+
+Wrap the body of arms in blocks when it does not fit on the same line with the pattern of arms
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3373)
+
+#### `true` (default):
+
+```rust
+fn main() {
+ match lorem {
+ true => {
+ foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x)
+ }
+ false => println!("{}", sit),
+ }
+}
+```
+
+#### `false`:
+
+```rust
+fn main() {
+ match lorem {
+ true =>
+ foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x),
+ false => println!("{}", sit),
+ }
+}
+```
+
+See also: [`match_block_trailing_comma`](#match_block_trailing_comma).
+
+## `match_arm_leading_pipes`
+
+Controls whether to include a leading pipe on match arms
+
+- **Default value**: `Never`
+- **Possible values**: `Always`, `Never`, `Preserve`
+- **Stable**: Yes
+
+#### `Never` (default):
+```rust
+// Leading pipes are removed from this:
+// fn foo() {
+// match foo {
+// | "foo" | "bar" => {}
+// | "baz"
+// | "something relatively long"
+// | "something really really really realllllllllllllly long" => println!("x"),
+// | "qux" => println!("y"),
+// _ => {}
+// }
+// }
+
+// Becomes
+fn foo() {
+ match foo {
+ "foo" | "bar" => {}
+ "baz"
+ | "something relatively long"
+ | "something really really really realllllllllllllly long" => println!("x"),
+ "qux" => println!("y"),
+ _ => {}
+ }
+}
+```
+
+#### `Always`:
+```rust
+// Leading pipes are emitted on all arms of this:
+// fn foo() {
+// match foo {
+// "foo" | "bar" => {}
+// "baz"
+// | "something relatively long"
+// | "something really really really realllllllllllllly long" => println!("x"),
+// "qux" => println!("y"),
+// _ => {}
+// }
+// }
+
+// Becomes:
+fn foo() {
+ match foo {
+ | "foo" | "bar" => {}
+ | "baz"
+ | "something relatively long"
+ | "something really really really realllllllllllllly long" => println!("x"),
+ | "qux" => println!("y"),
+ | _ => {}
+ }
+}
+```
+
+#### `Preserve`:
+```rust
+fn foo() {
+ match foo {
+ | "foo" | "bar" => {}
+ | "baz"
+ | "something relatively long"
+ | "something really really really realllllllllllllly long" => println!("x"),
+ | "qux" => println!("y"),
+ _ => {}
+ }
+
+ match baz {
+ "qux" => {}
+ "foo" | "bar" => {}
+ _ => {}
+ }
+}
+```
+
+## `match_block_trailing_comma`
+
+Put a trailing comma after a block based match arm (non-block arms are not affected)
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3380)
+
+#### `false` (default):
+
+```rust
+fn main() {
+ match lorem {
+ Lorem::Ipsum => {
+ println!("ipsum");
+ }
+ Lorem::Dolor => println!("dolor"),
+ }
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ match lorem {
+ Lorem::Ipsum => {
+ println!("ipsum");
+ },
+ Lorem::Dolor => println!("dolor"),
+ }
+}
+```
+
+See also: [`trailing_comma`](#trailing_comma), [`match_arm_blocks`](#match_arm_blocks).
+
+## `max_width`
+
+Maximum width of each line
+
+- **Default value**: `100`
+- **Possible values**: any positive integer
+- **Stable**: Yes
+
+See also [`error_on_line_overflow`](#error_on_line_overflow).
+
+## `merge_derives`
+
+Merge multiple derives into a single one.
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `true` (default):
+
+```rust
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+pub enum Foo {}
+```
+
+#### `false`:
+
+```rust
+#[derive(Eq, PartialEq)]
+#[derive(Debug)]
+#[derive(Copy, Clone)]
+pub enum Foo {}
+```
+
+## `imports_granularity`
+
+How imports should be grouped into `use` statements. Imports will be merged or split to the configured level of granularity.
+
+- **Default value**: `Preserve`
+- **Possible values**: `Preserve`, `Crate`, `Module`, `Item`
+- **Stable**: No
+
+#### `Preserve` (default):
+
+Do not change the granularity of any imports and preserve the original structure written by the developer.
+
+```rust
+use foo::b;
+use foo::b::{f, g};
+use foo::{a, c, d::e};
+use qux::{h, i};
+```
+
+#### `Crate`:
+
+Merge imports from the same crate into a single `use` statement. Conversely, imports from different crates are split into separate statements.
+
+```rust
+use foo::{
+ a, b,
+ b::{f, g},
+ c,
+ d::e,
+};
+use qux::{h, i};
+```
+
+#### `Module`:
+
+Merge imports from the same module into a single `use` statement. Conversely, imports from different modules are split into separate statements.
+
+```rust
+use foo::b::{f, g};
+use foo::d::e;
+use foo::{a, b, c};
+use qux::{h, i};
+```
+
+#### `Item`:
+
+Flatten imports so that each has its own `use` statement.
+
+```rust
+use foo::a;
+use foo::b;
+use foo::b::f;
+use foo::b::g;
+use foo::c;
+use foo::d::e;
+use qux::h;
+use qux::i;
+```
+
+## `merge_imports`
+
+This option is deprecated. Use `imports_granularity = "Crate"` instead.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+
+#### `false` (default):
+
+```rust
+use foo::{a, c, d};
+use foo::{b, g};
+use foo::{e, f};
+```
+
+#### `true`:
+
+```rust
+use foo::{a, b, c, d, e, f, g};
+```
+
+
+## `newline_style`
+
+Unix or Windows line endings
+
+- **Default value**: `"Auto"`
+- **Possible values**: `"Auto"`, `"Native"`, `"Unix"`, `"Windows"`
+- **Stable**: Yes
+
+#### `Auto` (default):
+
+The newline style is detected automatically on a per-file basis. Files
+with mixed line endings will be converted to the first detected line
+ending style.
+
+#### `Native`
+
+Line endings will be converted to `\r\n` on Windows and `\n` on all
+other platforms.
+
+#### `Unix`
+
+Line endings will be converted to `\n`.
+
+#### `Windows`
+
+Line endings will be converted to `\r\n`.
+
+## `normalize_comments`
+
+Convert /* */ comments to // comments where possible
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3350)
+
+#### `false` (default):
+
+```rust
+// Lorem ipsum:
+fn dolor() -> usize {}
+
+/* sit amet: */
+fn adipiscing() -> usize {}
+```
+
+#### `true`:
+
+```rust
+// Lorem ipsum:
+fn dolor() -> usize {}
+
+// sit amet:
+fn adipiscing() -> usize {}
+```
+
+## `normalize_doc_attributes`
+
+Convert `#![doc]` and `#[doc]` attributes to `//!` and `///` doc comments.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3351)
+
+#### `false` (default):
+
+```rust
+#![doc = "Example documentation"]
+
+#[doc = "Example item documentation"]
+pub enum Foo {}
+```
+
+#### `true`:
+
+```rust
+//! Example documentation
+
+/// Example item documentation
+pub enum Foo {}
+```
+
+## `overflow_delimited_expr`
+
+When structs, slices, arrays, and block/array-like macros are used as the last
+argument in an expression list, allow them to overflow (like blocks/closures)
+instead of being indented on a new line.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3370)
+
+#### `false` (default):
+
+```rust
+fn example() {
+ foo(ctx, |param| {
+ action();
+ foo(param)
+ });
+
+ foo(
+ ctx,
+ Bar {
+ x: value,
+ y: value2,
+ },
+ );
+
+ foo(
+ ctx,
+ &[
+ MAROON_TOMATOES,
+ PURPLE_POTATOES,
+ ORGANE_ORANGES,
+ GREEN_PEARS,
+ RED_APPLES,
+ ],
+ );
+
+ foo(
+ ctx,
+ vec![
+ MAROON_TOMATOES,
+ PURPLE_POTATOES,
+ ORGANE_ORANGES,
+ GREEN_PEARS,
+ RED_APPLES,
+ ],
+ );
+}
+```
+
+#### `true`:
+
+```rust
+fn example() {
+ foo(ctx, |param| {
+ action();
+ foo(param)
+ });
+
+ foo(ctx, Bar {
+ x: value,
+ y: value2,
+ });
+
+ foo(ctx, &[
+ MAROON_TOMATOES,
+ PURPLE_POTATOES,
+ ORGANE_ORANGES,
+ GREEN_PEARS,
+ RED_APPLES,
+ ]);
+
+ foo(ctx, vec![
+ MAROON_TOMATOES,
+ PURPLE_POTATOES,
+ ORGANE_ORANGES,
+ GREEN_PEARS,
+ RED_APPLES,
+ ]);
+}
+```
+
+## `remove_nested_parens`
+
+Remove nested parens.
+
+- **Default value**: `true`,
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+
+#### `true` (default):
+```rust
+fn main() {
+ (foo());
+}
+```
+
+#### `false`:
+```rust
+fn main() {
+ ((((foo()))));
+}
+```
+
+
+## `reorder_impl_items`
+
+Reorder impl items. `type` and `const` are put first, then macros and methods.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3363)
+
+#### `false` (default)
+
+```rust
+struct Dummy;
+
+impl Iterator for Dummy {
+ fn next(&mut self) -> Option {
+ None
+ }
+
+ type Item = i32;
+}
+```
+
+#### `true`
+
+```rust
+struct Dummy;
+
+impl Iterator for Dummy {
+ type Item = i32;
+
+ fn next(&mut self) -> Option {
+ None
+ }
+}
+```
+
+## `reorder_imports`
+
+Reorder import and extern crate statements alphabetically in groups (a group is
+separated by a newline).
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `true` (default):
+
+```rust
+use dolor;
+use ipsum;
+use lorem;
+use sit;
+```
+
+#### `false`:
+
+```rust
+use lorem;
+use ipsum;
+use dolor;
+use sit;
+```
+
+## `group_imports`
+
+Controls the strategy for how imports are grouped together.
+
+- **Default value**: `Preserve`
+- **Possible values**: `Preserve`, `StdExternalCrate`
+- **Stable**: No
+
+#### `Preserve` (default):
+
+Preserve the source file's import groups.
+
+```rust
+use super::update::convert_publish_payload;
+use chrono::Utc;
+
+use alloc::alloc::Layout;
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+
+use std::sync::Arc;
+
+use broker::database::PooledConnection;
+
+use super::schema::{Context, Payload};
+use crate::models::Event;
+use core::f32;
+```
+
+#### `StdExternalCrate`:
+
+Discard existing import groups, and create three groups for:
+1. `std`, `core` and `alloc`,
+2. external crates,
+3. `self`, `super` and `crate` imports.
+
+```rust
+use alloc::alloc::Layout;
+use core::f32;
+use std::sync::Arc;
+
+use broker::database::PooledConnection;
+use chrono::Utc;
+use juniper::{FieldError, FieldResult};
+use uuid::Uuid;
+
+use super::schema::{Context, Payload};
+use super::update::convert_publish_payload;
+use crate::models::Event;
+```
+
+## `reorder_modules`
+
+Reorder `mod` declarations alphabetically in group.
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `true` (default)
+
+```rust
+mod a;
+mod b;
+
+mod dolor;
+mod ipsum;
+mod lorem;
+mod sit;
+```
+
+#### `false`
+
+```rust
+mod b;
+mod a;
+
+mod lorem;
+mod ipsum;
+mod dolor;
+mod sit;
+```
+
+**Note** `mod` with `#[macro_export]` will not be reordered since that could change the semantics
+of the original source code.
+
+## `report_fixme`
+
+Report `FIXME` items in comments.
+
+- **Default value**: `"Never"`
+- **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"`
+- **Stable**: No (tracking issue: #3394)
+
+Warns about any comments containing `FIXME` in them when set to `"Always"`. If
+it contains a `#X` (with `X` being a number) in parentheses following the
+`FIXME`, `"Unnumbered"` will ignore it.
+
+See also [`report_todo`](#report_todo).
+
+
+## `report_todo`
+
+Report `TODO` items in comments.
+
+- **Default value**: `"Never"`
+- **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"`
+- **Stable**: No (tracking issue: #3393)
+
+Warns about any comments containing `TODO` in them when set to `"Always"`. If
+it contains a `#X` (with `X` being a number) in parentheses following the
+`TODO`, `"Unnumbered"` will ignore it.
+
+See also [`report_fixme`](#report_fixme).
+
+## `required_version`
+
+Require a specific version of rustfmt. If you want to make sure that the
+specific version of rustfmt is used in your CI, use this option.
+
+- **Default value**: `CARGO_PKG_VERSION`
+- **Possible values**: any published version (e.g. `"0.3.8"`)
+- **Stable**: No (tracking issue: #3386)
+
+## `skip_children`
+
+Don't reformat out of line modules
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3389)
+
+## `single_line_if_else_max_width`
+
+Maximum line length for single line if-else expressions. A value of `0` (zero) results in if-else expressions always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
+
+- **Default value**: `50`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `single_line_if_else_max_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `space_after_colon`
+
+Leave a space after the colon.
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3366)
+
+#### `true` (default):
+
+```rust
+fn lorem(t: T) {
+ let lorem: Dolor = Lorem {
+ ipsum: dolor,
+ sit: amet,
+ };
+}
+```
+
+#### `false`:
+
+```rust
+fn lorem(t:T) {
+ let lorem:Dolor = Lorem {
+ ipsum:dolor,
+ sit:amet,
+ };
+}
+```
+
+See also: [`space_before_colon`](#space_before_colon).
+
+## `space_before_colon`
+
+Leave a space before the colon.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3365)
+
+#### `false` (default):
+
+```rust
+fn lorem(t: T) {
+ let lorem: Dolor = Lorem {
+ ipsum: dolor,
+ sit: amet,
+ };
+}
+```
+
+#### `true`:
+
+```rust
+fn lorem(t : T) {
+ let lorem : Dolor = Lorem {
+ ipsum : dolor,
+ sit : amet,
+ };
+}
+```
+
+See also: [`space_after_colon`](#space_after_colon).
+
+## `spaces_around_ranges`
+
+Put spaces around the .., ..=, and ... range operators
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3367)
+
+#### `false` (default):
+
+```rust
+fn main() {
+ let lorem = 0..10;
+ let ipsum = 0..=10;
+
+ match lorem {
+ 1..5 => foo(),
+ _ => bar,
+ }
+
+ match lorem {
+ 1..=5 => foo(),
+ _ => bar,
+ }
+
+ match lorem {
+ 1...5 => foo(),
+ _ => bar,
+ }
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ let lorem = 0 .. 10;
+ let ipsum = 0 ..= 10;
+
+ match lorem {
+ 1 .. 5 => foo(),
+ _ => bar,
+ }
+
+ match lorem {
+ 1 ..= 5 => foo(),
+ _ => bar,
+ }
+
+ match lorem {
+ 1 ... 5 => foo(),
+ _ => bar,
+ }
+}
+```
+
+## `struct_field_align_threshold`
+
+The maximum diff of width between struct fields to be aligned with each other.
+
+- **Default value** : 0
+- **Possible values**: any non-negative integer
+- **Stable**: No (tracking issue: #3371)
+
+#### `0` (default):
+
+```rust
+struct Foo {
+ x: u32,
+ yy: u32,
+ zzz: u32,
+}
+```
+
+#### `20`:
+
+```rust
+struct Foo {
+ x: u32,
+ yy: u32,
+ zzz: u32,
+}
+```
+
+## `struct_lit_single_line`
+
+Put small struct literals on a single line
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3357)
+
+#### `true` (default):
+
+```rust
+fn main() {
+ let lorem = Lorem { foo: bar, baz: ofo };
+}
+```
+
+#### `false`:
+
+```rust
+fn main() {
+ let lorem = Lorem {
+ foo: bar,
+ baz: ofo,
+ };
+}
+```
+
+See also: [`indent_style`](#indent_style).
+
+## `struct_lit_width`
+
+Maximum width in the body of a struct literal before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
+
+- **Default value**: `18`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_lit_width` will take precedence.
+
+See also [`max_width`](#max_width), [`use_small_heuristics`](#use_small_heuristics), and [`struct_lit_single_line`](#struct_lit_single_line)
+
+## `struct_variant_width`
+
+Maximum width in the body of a struct variant before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
+
+- **Default value**: `35`
+- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
+- **Stable**: Yes
+
+By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_variant_width` will take precedence.
+
+See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
+
+## `tab_spaces`
+
+Number of spaces per tab
+
+- **Default value**: `4`
+- **Possible values**: any positive integer
+- **Stable**: Yes
+
+#### `4` (default):
+
+```rust
+fn lorem() {
+ let ipsum = dolor();
+ let sit = vec![
+ "amet consectetur adipiscing elit amet",
+ "consectetur adipiscing elit amet consectetur.",
+ ];
+}
+```
+
+#### `2`:
+
+```rust
+fn lorem() {
+ let ipsum = dolor();
+ let sit = vec![
+ "amet consectetur adipiscing elit amet",
+ "consectetur adipiscing elit amet consectetur.",
+ ];
+}
+```
+
+See also: [`hard_tabs`](#hard_tabs).
+
+
+## `trailing_comma`
+
+How to handle trailing commas for lists
+
+- **Default value**: `"Vertical"`
+- **Possible values**: `"Always"`, `"Never"`, `"Vertical"`
+- **Stable**: No (tracking issue: #3379)
+
+#### `"Vertical"` (default):
+
+```rust
+fn main() {
+ let Lorem { ipsum, dolor, sit } = amet;
+ let Lorem {
+ ipsum,
+ dolor,
+ sit,
+ amet,
+ consectetur,
+ adipiscing,
+ } = elit;
+}
+```
+
+#### `"Always"`:
+
+```rust
+fn main() {
+ let Lorem { ipsum, dolor, sit, } = amet;
+ let Lorem {
+ ipsum,
+ dolor,
+ sit,
+ amet,
+ consectetur,
+ adipiscing,
+ } = elit;
+}
+```
+
+#### `"Never"`:
+
+```rust
+fn main() {
+ let Lorem { ipsum, dolor, sit } = amet;
+ let Lorem {
+ ipsum,
+ dolor,
+ sit,
+ amet,
+ consectetur,
+ adipiscing
+ } = elit;
+}
+```
+
+See also: [`match_block_trailing_comma`](#match_block_trailing_comma).
+
+## `trailing_semicolon`
+
+Add trailing semicolon after break, continue and return
+
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3378)
+
+#### `true` (default):
+```rust
+fn foo() -> usize {
+ return 0;
+}
+```
+
+#### `false`:
+```rust
+fn foo() -> usize {
+ return 0
+}
+```
+
+## `type_punctuation_density`
+
+Determines if `+` or `=` are wrapped in spaces in the punctuation of types
+
+- **Default value**: `"Wide"`
+- **Possible values**: `"Compressed"`, `"Wide"`
+- **Stable**: No (tracking issue: #3364)
+
+#### `"Wide"` (default):
+
+```rust
+fn lorem() {
+ // body
+}
+```
+
+#### `"Compressed"`:
+
+```rust
+fn lorem() {
+ // body
+}
+```
+
+## `unstable_features`
+
+Enable unstable features on the unstable channel.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3387)
+
+## `use_field_init_shorthand`
+
+Use field initialize shorthand if possible.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `false` (default):
+
+```rust
+struct Foo {
+ x: u32,
+ y: u32,
+ z: u32,
+}
+
+fn main() {
+ let x = 1;
+ let y = 2;
+ let z = 3;
+ let a = Foo { x: x, y: y, z: z };
+}
+```
+
+#### `true`:
+
+```rust
+struct Foo {
+ x: u32,
+ y: u32,
+ z: u32,
+}
+
+fn main() {
+ let x = 1;
+ let y = 2;
+ let z = 3;
+ let a = Foo { x, y, z };
+}
+```
+
+## `use_small_heuristics`
+
+This option can be used to simplify the management and bulk updates of the granular width configuration settings ([`fn_call_width`](#fn_call_width), [`attr_fn_like_width`](#attr_fn_like_width), [`struct_lit_width`](#struct_lit_width), [`struct_variant_width`](#struct_variant_width), [`array_width`](#array_width), [`chain_width`](#chain_width), [`single_line_if_else_max_width`](#single_line_if_else_max_width)), that respectively control when formatted constructs are multi-lined/vertical based on width.
+
+Note that explicitly provided values for the width configuration settings take precedence and override the calculated values determined by `use_small_heuristics`.
+
+- **Default value**: `"Default"`
+- **Possible values**: `"Default"`, `"Off"`, `"Max"`
+- **Stable**: Yes
+
+#### `Default` (default):
+When `use_small_heuristics` is set to `Default`, the values for the granular width settings are calculated as a ratio of the value for `max_width`.
+
+The ratios are:
+* [`fn_call_width`](#fn_call_width) - `60%`
+* [`attr_fn_like_width`](#attr_fn_like_width) - `70%`
+* [`struct_lit_width`](#struct_lit_width) - `18%`
+* [`struct_variant_width`](#struct_variant_width) - `35%`
+* [`array_width`](#array_width) - `60%`
+* [`chain_width`](#chain_width) - `60%`
+* [`single_line_if_else_max_width`](#single_line_if_else_max_width) - `50%`
+
+For example when `max_width` is set to `100`, the width settings are:
+* `fn_call_width=60`
+* `attr_fn_like_width=70`
+* `struct_lit_width=18`
+* `struct_variant_width=35`
+* `array_width=60`
+* `chain_width=60`
+* `single_line_if_else_max_width=50`
+
+and when `max_width` is set to `200`:
+* `fn_call_width=120`
+* `attr_fn_like_width=140`
+* `struct_lit_width=36`
+* `struct_variant_width=70`
+* `array_width=120`
+* `chain_width=120`
+* `single_line_if_else_max_width=100`
+
+```rust
+enum Lorem {
+ Ipsum,
+ Dolor(bool),
+ Sit { amet: Consectetur, adipiscing: Elit },
+}
+
+fn main() {
+ lorem(
+ "lorem",
+ "ipsum",
+ "dolor",
+ "sit",
+ "amet",
+ "consectetur",
+ "adipiscing",
+ );
+
+ let lorem = Lorem {
+ ipsum: dolor,
+ sit: amet,
+ };
+ let lorem = Lorem { ipsum: dolor };
+
+ let lorem = if ipsum { dolor } else { sit };
+}
+```
+
+#### `Off`:
+When `use_small_heuristics` is set to `Off`, the granular width settings are functionally disabled and ignored. See the documentation for the respective width config options for specifics.
+
+```rust
+enum Lorem {
+ Ipsum,
+ Dolor(bool),
+ Sit {
+ amet: Consectetur,
+ adipiscing: Elit,
+ },
+}
+
+fn main() {
+ lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing");
+
+ let lorem = Lorem {
+ ipsum: dolor,
+ sit: amet,
+ };
+
+ let lorem = if ipsum {
+ dolor
+ } else {
+ sit
+ };
+}
+```
+
+#### `Max`:
+When `use_small_heuristics` is set to `Max`, then each granular width setting is set to the same value as `max_width`.
+
+So if `max_width` is set to `200`, then all the width settings are also set to `200`.
+* `fn_call_width=200`
+* `attr_fn_like_width=200`
+* `struct_lit_width=200`
+* `struct_variant_width=200`
+* `array_width=200`
+* `chain_width=200`
+* `single_line_if_else_max_width=200`
+
+```rust
+enum Lorem {
+ Ipsum,
+ Dolor(bool),
+ Sit { amet: Consectetur, adipiscing: Elit },
+}
+
+fn main() {
+ lorem("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing");
+
+ let lorem = Lorem { ipsum: dolor, sit: amet };
+
+ let lorem = if ipsum { dolor } else { sit };
+}
+```
+
+
+See also:
+* [`max_width`](#max_width)
+* [`fn_call_width`](#fn_call_width)
+* [`attr_fn_like_width`](#attr_fn_like_width)
+* [`struct_lit_width`](#struct_lit_width)
+* [`struct_variant_width`](#struct_variant_width)
+* [`array_width`](#array_width)
+* [`chain_width`](#chain_width)
+* [`single_line_if_else_max_width`](#single_line_if_else_max_width)
+
+## `use_try_shorthand`
+
+Replace uses of the try! macro by the ? shorthand
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: Yes
+
+#### `false` (default):
+
+```rust
+fn main() {
+ let lorem = try!(ipsum.map(|dolor| dolor.sit()));
+}
+```
+
+#### `true`:
+
+```rust
+fn main() {
+ let lorem = ipsum.map(|dolor| dolor.sit())?;
+}
+```
+
+## `version`
+
+Which version of the formatting rules to use. `Version::One` is backwards-compatible
+with Rustfmt 1.0. Other versions are only backwards compatible within a major
+version number.
+
+- **Default value**: `One`
+- **Possible values**: `One`, `Two`
+- **Stable**: No (tracking issue: #3383)
+
+### Example
+
+```toml
+version = "Two"
+```
+
+## `where_single_line`
+
+Forces the `where` clause to be laid out on a single line.
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3359)
+
+#### `false` (default):
+
+```rust
+impl Lorem for T
+where
+ Option: Ipsum,
+{
+ // body
+}
+```
+
+#### `true`:
+
+```rust
+impl Lorem for T
+where Option: Ipsum
+{
+ // body
+}
+```
+
+See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_style).
+
+
+## `wrap_comments`
+
+Break comments to fit on the line
+
+- **Default value**: `false`
+- **Possible values**: `true`, `false`
+- **Stable**: No (tracking issue: #3347)
+
+#### `false` (default):
+
+```rust
+// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+```
+
+#### `true`:
+
+```rust
+// Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+// sed do eiusmod tempor incididunt ut labore et dolore
+// magna aliqua. Ut enim ad minim veniam, quis nostrud
+// exercitation ullamco laboris nisi ut aliquip ex ea
+// commodo consequat.
+```
+
+# Internal Options
+
+## `emit_mode`
+
+Internal option
+
+## `make_backup`
+
+Internal option, use `--backup`
+
+## `print_misformatted_file_names`
+
+Internal option, use `-l` or `--files-with-diff`
diff --git a/src/tools/rustfmt/Contributing.md b/src/tools/rustfmt/Contributing.md
new file mode 100644
index 000000000000..131f38dd06a2
--- /dev/null
+++ b/src/tools/rustfmt/Contributing.md
@@ -0,0 +1,251 @@
+# Contributing
+
+There are many ways to contribute to Rustfmt. This document lays out what they
+are and has information on how to get started. If you have any questions about
+contributing or need help with anything, please ask in the WG-Rustfmt channel
+on [Discord](https://discordapp.com/invite/rust-lang). Feel free to also ask questions
+on issues, or file new issues specifically to get help.
+
+All contributors are expected to follow our [Code of
+Conduct](CODE_OF_CONDUCT.md).
+
+## Test and file issues
+
+It would be really useful to have people use rustfmt on their projects and file
+issues where it does something you don't expect.
+
+
+## Create test cases
+
+Having a strong test suite for a tool like this is essential. It is very easy
+to create regressions. Any tests you can add are very much appreciated.
+
+The tests can be run with `cargo test`. This does a number of things:
+* runs the unit tests for a number of internal functions;
+* makes sure that rustfmt run on every file in `./tests/source/` is equal to its
+ associated file in `./tests/target/`;
+* runs idempotence tests on the files in `./tests/target/`. These files should
+ not be changed by rustfmt;
+* checks that rustfmt's code is not changed by running on itself. This ensures
+ that the project bootstraps.
+
+Creating a test is as easy as creating a new file in `./tests/source/` and an
+equally named one in `./tests/target/`. If it is only required that rustfmt
+leaves a piece of code unformatted, it may suffice to only create a target file.
+
+Whenever there's a discrepancy between the expected output when running tests, a
+colourised diff will be printed so that the offending line(s) can quickly be
+identified.
+
+Without explicit settings, the tests will be run using rustfmt's default
+configuration. It is possible to run a test using non-default settings in several
+ways. Firstly, you can include configuration parameters in comments at the top
+of the file. For example: to use 3 spaces per tab, start your test with
+`// rustfmt-tab_spaces: 3`. Just remember that the comment is part of the input,
+so include in both the source and target files! It is also possible to
+explicitly specify the name of the expected output file in the target directory.
+Use `// rustfmt-target: filename.rs` for this. You can also specify a custom
+configuration by using the `rustfmt-config` directive. Rustfmt will then use
+that toml file located in `./tests/config/` for its configuration. Including
+`// rustfmt-config: small_tabs.toml` will run your test with the configuration
+file found at `./tests/config/small_tabs.toml`. The final option is used when the
+test source file contains no configuration parameter comments. In this case, the
+test harness looks for a configuration file with the same filename as the test
+file in the `./tests/config/` directory, so a test source file named `test-indent.rs`
+would need a configuration file named `test-indent.toml` in that directory. As an
+example, the `issue-1111.rs` test file is configured by the file
+`./tests/config/issue-1111.toml`.
+
+## Debugging
+
+Some `rewrite_*` methods use the `debug!` macro for printing useful information.
+These messages can be printed by using the environment variable `RUST_LOG=rustfmt=DEBUG`.
+These traces can be helpful in understanding which part of the code was used
+and get a better grasp on the execution flow.
+
+## Hack!
+
+Here are some [good starting issues](https://github.com/rust-lang/rustfmt/issues?q=is%3Aopen+is%3Aissue+label%3Agood-first-issue).
+
+If you've found areas which need polish and don't have issues, please submit a
+PR, don't feel there needs to be an issue.
+
+
+### Guidelines
+
+Rustfmt bootstraps, that is part of its test suite is running itself on its
+source code. So, basically, the only style guideline is that you must pass the
+tests. That ensures that the Rustfmt source code adheres to our own conventions.
+
+Talking of tests, if you add a new feature or fix a bug, please also add a test.
+It's really easy, see above for details. Please run `cargo test` before
+submitting a PR to ensure your patch passes all tests, it's pretty quick.
+
+Rustfmt is post-1.0 and within major version releases we strive for backwards
+compatibility (at least when using the default options). That means any code
+which changes Rustfmt's output must be guarded by either an option or a version
+check. The latter is implemented as an option called `option`. See the section on
+[configuration](#Configuration) below.
+
+Please try to avoid leaving `TODO`s in the code. There are a few around, but I
+wish there weren't. You can leave `FIXME`s, preferably with an issue number.
+
+
+### Version-gate formatting changes
+
+A change that introduces a different code-formatting should be gated on the
+`version` configuration. This is to ensure the formatting of the current major
+release is preserved, while allowing fixes to be implemented for the next
+release.
+
+This is done by conditionally guarding the change like so:
+
+```rust
+if config.version() == Version::One { // if the current major release is 1.x
+ // current formatting
+} else {
+ // new formatting
+}
+```
+
+This allows the user to apply the next formatting explicitly via the
+configuration, while being stable by default.
+
+When the next major release is done, the code block of the previous formatting
+can be deleted, e.g., the first block in the example above when going from `1.x`
+to `2.x`.
+
+| Note: Only formatting changes with default options need to be gated. |
+| --- |
+
+### A quick tour of Rustfmt
+
+Rustfmt is basically a pretty printer - that is, its mode of operation is to
+take an AST (abstract syntax tree) and print it in a nice way (including staying
+under the maximum permitted width for a line). In order to get that AST, we
+first have to parse the source text, we use the Rust compiler's parser to do
+that (see [src/lib.rs](src/lib.rs)). We shy away from doing anything too fancy, such as
+algebraic approaches to pretty printing, instead relying on an heuristic
+approach, 'manually' crafting a string for each AST node. This results in quite
+a lot of code, but it is relatively simple.
+
+The AST is a tree view of source code. It carries all the semantic information
+about the code, but not all of the syntax. In particular, we lose white space
+and comments (although doc comments are preserved). Rustfmt uses a view of the
+AST before macros are expanded, so there are still macro uses in the code. The
+arguments to macros are not an AST, but raw tokens - this makes them harder to
+format.
+
+There are different nodes for every kind of item and expression in Rust. For
+more details see the source code in the compiler -
+[ast.rs](https://dxr.mozilla.org/rust/source/src/libsyntax/ast.rs) - and/or the
+[docs](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/index.html).
+
+Many nodes in the AST (but not all, annoyingly) have a `Span`. A `Span` is a
+range in the source code, it can easily be converted to a snippet of source
+text. When the AST does not contain enough information for us, we rely heavily
+on `Span`s. For example, we can look between spans to try and find comments, or
+parse a snippet to see how the user wrote their source code.
+
+The downside of using the AST is that we miss some information - primarily white
+space and comments. White space is sometimes significant, although mostly we
+want to ignore it and make our own. We strive to reproduce all comments, but
+this is sometimes difficult. The crufty corners of Rustfmt are where we hack
+around the absence of comments in the AST and try to recreate them as best we
+can.
+
+Our primary tool here is to look between spans for text we've missed. For
+example, in a function call `foo(a, b)`, we have spans for `a` and `b`, in this
+case, there is only a comma and a single space between the end of `a` and the
+start of `b`, so there is nothing much to do. But if we look at
+`foo(a /* a comment */, b)`, then between `a` and `b` we find the comment.
+
+At a higher level, Rustfmt has machinery so that we account for text between
+'top level' items. Then we can reproduce that text pretty much verbatim. We only
+count spans we actually reformat, so if we can't format a span it is not missed
+completely but is reproduced in the output without being formatted. This is
+mostly handled in [src/missed_spans.rs](src/missed_spans.rs). See also `FmtVisitor::last_pos` in
+[src/visitor.rs](src/visitor.rs).
+
+
+#### Some important elements
+
+At the highest level, Rustfmt uses a `Visitor` implementation called `FmtVisitor`
+to walk the AST. This is in [src/visitor.rs](src/visitor.rs). This is really just used to walk
+items, rather than the bodies of functions. We also cover macros and attributes
+here. Most methods of the visitor call out to `Rewrite` implementations that
+then walk their own children.
+
+The `Rewrite` trait is defined in [src/rewrite.rs](src/rewrite.rs). It is implemented for many
+things that can be rewritten, mostly AST nodes. It has a single function,
+`rewrite`, which is called to rewrite `self` into an `Option`. The
+arguments are `width` which is the horizontal space we write into and `offset`
+which is how much we are currently indented from the lhs of the page. We also
+take a context which contains information used for parsing, the current block
+indent, and a configuration (see below).
+
+##### Rewrite and Indent
+
+To understand the indents, consider
+
+```
+impl Foo {
+ fn foo(...) {
+ bar(argument_one,
+ baz());
+ }
+}
+```
+
+When formatting the `bar` call we will format the arguments in order, after the
+first one we know we are working on multiple lines (imagine it is longer than
+written). So, when we come to the second argument, the indent we pass to
+`rewrite` is 12, which puts us under the first argument. The current block
+indent (stored in the context) is 8. The former is used for visual indenting
+(when objects are vertically aligned with some marker), the latter is used for
+block indenting (when objects are tabbed in from the lhs). The width available
+for `baz()` will be the maximum width, minus the space used for indenting, minus
+the space used for the `);`. (Note that actual argument formatting does not
+quite work like this, but it's close enough).
+
+The `rewrite` function returns an `Option` - either we successfully rewrite and
+return the rewritten string for the caller to use, or we fail to rewrite and
+return `None`. This could be because Rustfmt encounters something it doesn't
+know how to reformat, but more often it is because Rustfmt can't fit the item
+into the required width. How to handle this is up to the caller. Often the
+caller just gives up, ultimately relying on the missed spans system to paste in
+the un-formatted source. A better solution (although not performed in many
+places) is for the caller to shuffle around some of its other items to make
+more width, then call the function again with more space.
+
+Since it is common for callers to bail out when a callee fails, we often use a
+`?` operator to make this pattern more succinct.
+
+One way we might find out that we don't have enough space is when computing how much
+space we have. Something like `available_space = budget - overhead`. Since
+widths are unsized integers, this would cause underflow. Therefore we use
+checked subtraction: `available_space = budget.checked_sub(overhead)?`.
+`checked_sub` returns an `Option`, and if we would underflow `?` returns
+`None`, otherwise, we proceed with the computed space.
+
+##### Rewrite of list-like expressions
+
+Much of the syntax in Rust is lists: lists of arguments, lists of fields, lists of
+array elements, etc. We have some generic code to handle lists, including how to
+space them in horizontal and vertical space, indentation, comments between
+items, trailing separators, etc. However, since there are so many options, the
+code is a bit complex. Look in [src/lists.rs](src/lists.rs). `write_list` is the key function,
+and `ListFormatting` the key structure for configuration. You'll need to make a
+`ListItems` for input, this is usually done using `itemize_list`.
+
+##### Configuration
+
+Rustfmt strives to be highly configurable. Often the first part of a patch is
+creating a configuration option for the feature you are implementing. All
+handling of configuration options is done in [src/config/mod.rs](src/config/mod.rs). Look for the
+`create_config!` macro at the end of the file for all the options. The rest of
+the file defines a bunch of enums used for options, and the machinery to produce
+the config struct and parse a config file, etc. Checking an option is done by
+accessing the correct field on the config struct, e.g., `config.max_width()`. Most
+functions have a `Config`, or one can be accessed via a visitor or context of
+some kind.
diff --git a/src/tools/rustfmt/Design.md b/src/tools/rustfmt/Design.md
new file mode 100644
index 000000000000..00a7652aee0d
--- /dev/null
+++ b/src/tools/rustfmt/Design.md
@@ -0,0 +1,184 @@
+# Some thoughts on the design of rustfmt
+
+## Use cases
+
+A formatting tool can be used in different ways and the different use cases can
+affect the design of the tool. The use cases I'm particularly concerned with are:
+
+* running on a whole repo before check-in
+ - in particular, to replace the `make tidy` pass on the Rust distro
+* running on code from another project that you are adding to your own
+* using for mass changes in code style over a project
+
+Some valid use cases for a formatting tool which I am explicitly not trying to
+address (although it would be nice, if possible):
+
+* running 'as you type' in an IDE
+* running on arbitrary snippets of code
+* running on Rust-like code, specifically code which doesn't parse
+* use as a pretty printer inside the compiler
+* refactoring
+* formatting totally unformatted source code
+
+
+## Scope and vision
+
+I do not subscribe to the notion that a formatting tool should only change
+whitespace. I believe that we should semantics preserving, but not necessarily
+syntax preserving, i.e., we can change the AST of a program.
+
+I.e., we might change glob imports to list or single imports, re-order imports,
+move bounds to where clauses, combine multiple impls into a single impl, etc.
+
+However, we will not change the names of variables or make any changes which
+*could* change the semantics. To be ever so slightly formal, we might imagine
+a compilers high level intermediate representation, we should strive to only
+make changes which do not change the HIR, even if they do change the AST.
+
+I would like to be able to output refactoring scripts for making deeper changes
+though. (E.g., renaming variables to satisfy our style guidelines).
+
+My long term goal is that all style lints can be moved from the compiler to
+rustfmt and, as well as warning, can either fix problems or emit refactoring
+scripts to do so.
+
+### Configurability
+
+I believe reformatting should be configurable to some extent. We should read in
+options from a configuration file and reformat accordingly. We should supply at
+least a config file which matches the Rust style guidelines.
+
+There should be multiple modes for running the tool. As well as simply replacing
+each file, we should be able to show the user a list of the changes we would
+make, or show a list of violations without corrections (the difference being
+that there are multiple ways to satisfy a given set of style guidelines, and we
+should distinguish violations from deviations from our own model).
+
+
+## Implementation philosophy
+
+Some details of the philosophy behind the implementation.
+
+
+### Operate on the AST
+
+A reformatting tool can be based on either the AST or a token stream (in Rust
+this is actually a stream of token trees, but it's not a fundamental difference).
+There are pros and cons to the two approaches. I have chosen to use the AST
+approach. The primary reasons are that it allows us to do more sophisticated
+manipulations, rather than just change whitespace, and it gives us more context
+when making those changes.
+
+The advantage of the tokens approach is that you can operate on non-parsable
+code. I don't care too much about that, it would be nice, but I think being able
+to perform sophisticated transformations is more important. In the future, I hope to
+(optionally) be able to use type information for informing reformatting too. One
+specific case of unparsable code is macros. Using tokens is certainly easier
+here, but I believe it is perfectly solvable with the AST approach. At the limit,
+we can operate on just tokens in the macro case.
+
+I believe that there is not in fact that much difference between the two
+approaches. Due to imperfect span information, under the AST approach, we
+sometimes are reduced to examining tokens or do some re-lexing of our own. Under
+the tokens approach, you need to implement your own (much simpler) parser. I
+believe that as the tool gets more sophisticated, you end up doing more at the
+token-level, or having an increasingly sophisticated parser, until at the limit
+you have the same tool.
+
+However, I believe starting from the AST gets you more quickly to a usable and
+useful tool.
+
+
+### Heuristic rather than algorithmic
+
+Many formatting tools use a very general algorithmic or even algebraic tool for
+pretty printing. This results in very elegant code, but I believe does not give
+the best results. I prefer a more ad hoc approach where each expression/item is
+formatted using custom rules. We hopefully don't end up with too much code due
+to good old fashioned abstraction and code sharing. This will give a bigger code
+base, but hopefully a better result.
+
+It also means that there will be some cases we can't format and we have to give
+up. I think that is OK. Hopefully, they are rare enough that manually fixing them
+is not painful. Better to have a tool that gives great code in 99% of cases and
+fails in 1% than a tool which gives 50% great code and 50% ugly code, but never
+fails.
+
+
+### Incremental development
+
+I want rustfmt to be useful as soon as possible and to always be useful. I
+specifically don't want to have to wait for a feature (or worse, the whole tool)
+to be perfect before it is useful. The main ways this is achieved is to output
+the source code where we can't yet reformat, be able to turn off new features
+until they are ready, and the 'do no harm' principle (see next section).
+
+
+### First, do no harm
+
+Until rustfmt is perfect, there will always be a trade-off between doing more and
+doing existing things well. I want to err on the side of the latter.
+Specifically, rustfmt should never take OK code and make it look worse. If we
+can't make it better, we should leave it as is. That might mean being less
+aggressive than we like or using configurability.
+
+
+### Use the source code as guidance
+
+There are often multiple ways to format code and satisfy standards. Where this
+is the case, we should use the source code as a hint for reformatting.
+Furthermore, where the code has been formatted in a particular way that satisfies
+the coding standard, it should not be changed (this is sometimes not possible or
+not worthwhile due to uniformity being desirable, but it is a useful goal).
+
+
+### Architecture details
+
+We use the AST from [syntex_syntax], an export of rustc's libsyntax. We use
+syntex_syntax's visit module to walk the AST to find starting points for
+reformatting. Eventually, we should reformat everything and we shouldn't need
+the visit module. We keep track of the last formatted position in the code, and
+when we reformat the next piece of code we make sure to output the span for all
+the code in between (handled by missed_spans.rs).
+
+[syntex_syntax]: https://crates.io/crates/syntex_syntax
+
+We read in formatting configuration from a `rustfmt.toml` file if there is one.
+The options and their defaults are defined in `config.rs`. A `Config` object is
+passed throughout the formatting code, and each formatting routine looks there
+for its configuration.
+
+Our visitor keeps track of the desired current indent due to blocks (
+`block_indent`). Each `visit_*` method reformats code according to this indent,
+`config.comment_width()` and `config.max_width()`. Most reformatting that is done
+in the `visit_*` methods is a bit hacky and is meant to be temporary until it can
+be done properly.
+
+There are a bunch of methods called `rewrite_*`. They do the bulk of the
+reformatting. These take the AST node to be reformatted (this may not literally
+be an AST node from syntex_syntax: there might be multiple parameters
+describing a logical node), the current indent, and the current width budget.
+They return a `String` (or sometimes an `Option`) which formats the
+code in the box given by the indent and width budget. If the method fails, it
+returns `None` and the calling method then has to fallback in some way to give
+the callee more space.
+
+So, in summary, to format a node, we calculate the width budget and then walk down
+the tree from the node. At a leaf, we generate an actual string and then unwind,
+combining these strings as we go back up the tree.
+
+For example, consider a method definition:
+
+```
+ fn foo(a: A, b: B) {
+ ...
+ }
+```
+
+We start at indent 4, the rewrite function for the whole function knows it must
+write `fn foo(` before the arguments and `) {` after them, assuming the max width
+is 100, it thus asks the rewrite argument list function to rewrite with an indent
+of 11 and in a width of 86. Assuming that is possible (obviously in this case),
+it returns a string for the arguments and it can make a string for the function
+header. If the arguments couldn't be fitted in that space, we might try to
+fallback to a hanging indent, so we try again with indent 8 and width 89.
diff --git a/src/tools/rustfmt/LICENSE-APACHE b/src/tools/rustfmt/LICENSE-APACHE
new file mode 100644
index 000000000000..212ba1f31848
--- /dev/null
+++ b/src/tools/rustfmt/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2016-2021 The Rust Project Developers
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/src/tools/rustfmt/LICENSE-MIT b/src/tools/rustfmt/LICENSE-MIT
new file mode 100644
index 000000000000..1baa137f605b
--- /dev/null
+++ b/src/tools/rustfmt/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016-2021 The Rust Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/tools/rustfmt/Makefile.toml b/src/tools/rustfmt/Makefile.toml
new file mode 100644
index 000000000000..597dd1205643
--- /dev/null
+++ b/src/tools/rustfmt/Makefile.toml
@@ -0,0 +1,71 @@
+[env]
+CFG_RELEASE = { value = "${CARGO_MAKE_RUST_VERSION}", condition = { env_not_set = ["CFG_RELEASE"] } }
+CFG_RELEASE_CHANNEL = { value = "${CARGO_MAKE_RUST_CHANNEL}", condition = { env_not_set = ["CFG_RELEASE_CHANNEL"] } }
+
+[tasks.build-bin]
+command = "cargo"
+args = [
+ "build",
+ "--bin",
+ "rustfmt",
+ "--bin",
+ "cargo-fmt",
+]
+
+[tasks.build-bins]
+command = "cargo"
+args = [
+ "build",
+ "--bins",
+]
+
+[tasks.install]
+command = "cargo"
+args = [
+ "install",
+ "--path",
+ ".",
+ "--force",
+ "--locked", # Respect Cargo.lock
+]
+
+[tasks.release]
+command = "cargo"
+args = [
+ "build",
+ "--release",
+]
+
+[tasks.test]
+command = "cargo"
+args = [
+ "test",
+]
+
+[tasks.test-all]
+dependencies = ["build-bin"]
+run_task = { name = ["test", "test-ignored"] }
+
+[tasks.test-ignored]
+command = "cargo"
+args = [
+ "test",
+ "--",
+ "--ignored",
+]
+
+[tasks.b]
+alias = "build"
+
+[tasks.bb]
+alias = "build-bin"
+
+[tasks.bins]
+alias = "build-bins"
+
+[tasks.c]
+alias = "check"
+
+[tasks.t]
+alias = "test"
+
diff --git a/src/tools/rustfmt/Processes.md b/src/tools/rustfmt/Processes.md
new file mode 100644
index 000000000000..9d86d52b122d
--- /dev/null
+++ b/src/tools/rustfmt/Processes.md
@@ -0,0 +1,57 @@
+This document outlines processes regarding management of rustfmt.
+
+# Stabilising an Option
+
+In this Section, we describe how to stabilise an option of the rustfmt's configration.
+
+## Conditions
+
+- Is the default value correct ?
+- The design and implementation of the option are sound and clean.
+- The option is well tested, both in unit tests and, optimally, in real usage.
+- There is no open bug about the option that prevents its use.
+
+## Steps
+
+Open a pull request that closes the tracking issue. The tracking issue is listed beside the option in `Configurations.md`.
+
+- Update the `Config` enum marking the option as stable.
+- Update the the `Configuration.md` file marking the option as stable.
+- Update `CHANGELOG.md` marking the option as stable.
+
+## After the stabilisation
+
+The option should remain backward-compatible with previous parameters of the option. For instance, if the option is an enum `enum Foo { Alice, Bob }` and the variant `Foo::Bob` is removed/renamed, existing use of the `Foo::Bob` variant should map to the new logic. Breaking changes can be applied under the condition they are version-gated.
+
+# Make a Release
+
+## 0. Update CHANGELOG.md
+
+## 1. Update Cargo.toml and Cargo.lock
+
+For example, 1.0.0 -> 1.0.1:
+
+```diff
+-version = "1.0.0"
++version = "1.0.1"
+```
+
+## 2. Push the commit to the master branch
+
+E.g., https://github.com/rust-lang/rustfmt/commit/5274b49caa1a7db6ac10c76bf1a3d5710ccef569
+
+## 3. Create a release tag
+
+```sh
+git tag -s v1.2.3 -m "Release 1.2.3"
+```
+
+## 4. Publish to crates.io
+
+`cargo publish`
+
+## 5. Create a PR to rust-lang/rust to update the rustfmt submodule
+
+Note that if you are updating `rustc-ap-*` crates, then you need to update **every** submodules in the rust-lang/rust repository that depend on the crates to use the same version of those.
+
+As of 2019/05, there are two such crates: `rls` and `racer` (`racer` depends on `rustc-ap-syntax` and `rls` depends on `racer`, and `rls` is one of submodules of the rust-lang/rust repository).
diff --git a/src/tools/rustfmt/README.md b/src/tools/rustfmt/README.md
new file mode 100644
index 000000000000..7a97d31bab9c
--- /dev/null
+++ b/src/tools/rustfmt/README.md
@@ -0,0 +1,234 @@
+# rustfmt [](https://travis-ci.com/rust-lang/rustfmt) [](https://ci.appveyor.com/project/rust-lang-libs/rustfmt) [](https://crates.io/crates/rustfmt-nightly) [](https://travis-ci.org/davidalber/rustfmt-travis)
+
+A tool for formatting Rust code according to style guidelines.
+
+If you'd like to help out (and you should, it's a fun project!), see
+[Contributing.md](Contributing.md) and our [Code of
+Conduct](CODE_OF_CONDUCT.md).
+
+You can use rustfmt in Travis CI builds. We provide a minimal Travis CI
+configuration (see [here](#checking-style-on-a-ci-server)) and verify its status
+using another repository. The status of that repository's build is reported by
+the "travis example" badge above.
+
+## Quick start
+
+You can run `rustfmt` with Rust 1.24 and above.
+
+### On the Stable toolchain
+
+To install:
+
+```sh
+rustup component add rustfmt
+```
+
+To run on a cargo project in the current working directory:
+
+```sh
+cargo fmt
+```
+
+### On the Nightly toolchain
+
+For the latest and greatest `rustfmt`, nightly is required.
+
+To install:
+
+```sh
+rustup component add rustfmt --toolchain nightly
+```
+
+To run on a cargo project in the current working directory:
+
+```sh
+cargo +nightly fmt
+```
+
+## Limitations
+
+Rustfmt tries to work on as much Rust code as possible, sometimes, the code
+doesn't even need to compile! As we approach a 1.0 release we are also looking
+to limit areas of instability; in particular, post-1.0, the formatting of most
+code should not change as Rustfmt improves. However, there are some things that
+Rustfmt can't do or can't do well (and thus where formatting might change
+significantly, even post-1.0). We would like to reduce the list of limitations
+over time.
+
+The following list enumerates areas where Rustfmt does not work or where the
+stability guarantees do not apply (we don't make a distinction between the two
+because in the future Rustfmt might work on code where it currently does not):
+
+* a program where any part of the program does not parse (parsing is an early
+ stage of compilation and in Rust includes macro expansion).
+* Macro declarations and uses (current status: some macro declarations and uses
+ are formatted).
+* Comments, including any AST node with a comment 'inside' (Rustfmt does not
+ currently attempt to format comments, it does format code with comments inside, but that formatting may change in the future).
+* Rust code in code blocks in comments.
+* Any fragment of a program (i.e., stability guarantees only apply to whole
+ programs, even where fragments of a program can be formatted today).
+* Code containing non-ascii unicode characters (we believe Rustfmt mostly works
+ here, but do not have the test coverage or experience to be 100% sure).
+* Bugs in Rustfmt (like any software, Rustfmt has bugs, we do not consider bug
+ fixes to break our stability guarantees).
+
+
+## Installation
+
+```sh
+rustup component add rustfmt
+```
+
+## Installing from source
+
+To install from source (nightly required), first checkout to the tag or branch you want to install, then issue
+
+```sh
+cargo install --path .
+```
+
+This will install `rustfmt` in your `~/.cargo/bin`. Make sure to add `~/.cargo/bin` directory to
+your PATH variable.
+
+
+## Running
+
+You can run Rustfmt by just typing `rustfmt filename` if you used `cargo
+install`. This runs rustfmt on the given file, if the file includes out of line
+modules, then we reformat those too. So to run on a whole module or crate, you
+just need to run on the root file (usually mod.rs or lib.rs). Rustfmt can also
+read data from stdin. Alternatively, you can use `cargo fmt` to format all
+binary and library targets of your crate.
+
+You can run `rustfmt --help` for information about available arguments.
+
+When running with `--check`, Rustfmt will exit with `0` if Rustfmt would not
+make any formatting changes to the input, and `1` if Rustfmt would make changes.
+In other modes, Rustfmt will exit with `1` if there was some error during
+formatting (for example a parsing or internal error) and `0` if formatting
+completed without error (whether or not changes were made).
+
+
+
+## Running Rustfmt from your editor
+
+* [Vim](https://github.com/rust-lang/rust.vim#formatting-with-rustfmt)
+* [Emacs](https://github.com/rust-lang/rust-mode)
+* [Sublime Text 3](https://packagecontrol.io/packages/RustFmt)
+* [Atom](atom.md)
+* Visual Studio Code using [vscode-rust](https://github.com/editor-rs/vscode-rust), [vsc-rustfmt](https://github.com/Connorcpu/vsc-rustfmt) or [rls_vscode](https://github.com/jonathandturner/rls_vscode) through RLS.
+* [IntelliJ or CLion](intellij.md)
+
+
+## Checking style on a CI server
+
+To keep your code base consistently formatted, it can be helpful to fail the CI build
+when a pull request contains unformatted code. Using `--check` instructs
+rustfmt to exit with an error code if the input is not formatted correctly.
+It will also print any found differences. (Older versions of Rustfmt don't
+support `--check`, use `--write-mode diff`).
+
+A minimal Travis setup could look like this (requires Rust 1.24.0 or greater):
+
+```yaml
+language: rust
+before_script:
+- rustup component add rustfmt
+script:
+- cargo build
+- cargo test
+- cargo fmt --all -- --check
+```
+
+See [this blog post](https://medium.com/@ag_dubs/enforcing-style-in-ci-for-rust-projects-18f6b09ec69d)
+for more info.
+
+## How to build and test
+
+`cargo build` to build.
+
+`cargo test` to run all tests.
+
+To run rustfmt after this, use `cargo run --bin rustfmt -- filename`. See the
+notes above on running rustfmt.
+
+
+## Configuring Rustfmt
+
+Rustfmt is designed to be very configurable. You can create a TOML file called
+`rustfmt.toml` or `.rustfmt.toml`, place it in the project or any other parent
+directory and it will apply the options in that file. See `rustfmt
+--help=config` for the options which are available, or if you prefer to see
+visual style previews, [GitHub page](https://rust-lang.github.io/rustfmt/).
+
+By default, Rustfmt uses a style which conforms to the [Rust style guide][style
+guide] that has been formalized through the [style RFC
+process][fmt rfcs].
+
+Configuration options are either stable or unstable. Stable options can always
+be used, while unstable ones are only available on a nightly toolchain, and opt-in.
+See [GitHub page](https://rust-lang.github.io/rustfmt/) for details.
+
+### Rust's Editions
+
+Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if
+executed through the Cargo's formatting tool `cargo fmt`. Otherwise, the edition
+needs to be specified in `rustfmt.toml`, e.g., with `edition = "2018"`.
+
+## Tips
+
+* For things you do not want rustfmt to mangle, use `#[rustfmt::skip]`
+* To prevent rustfmt from formatting a macro or an attribute,
+ use `#[rustfmt::skip::macros(target_macro_name)]` or
+ `#[rustfmt::skip::attributes(target_attribute_name)]`
+
+ Example:
+
+ ```rust
+ #![rustfmt::skip::attributes(custom_attribute)]
+
+ #[custom_attribute(formatting , here , should , be , Skipped)]
+ #[rustfmt::skip::macros(html)]
+ fn main() {
+ let macro_result1 = html! {
+ Hello
+ }.to_string();
+ ```
+* When you run rustfmt, place a file named `rustfmt.toml` or `.rustfmt.toml` in
+ target file directory or its parents to override the default settings of
+ rustfmt. You can generate a file containing the default configuration with
+ `rustfmt --print-config default rustfmt.toml` and customize as needed.
+* After successful compilation, a `rustfmt` executable can be found in the
+ target directory.
+* If you're having issues compiling Rustfmt (or compile errors when trying to
+ install), make sure you have the most recent version of Rust installed.
+
+* You can change the way rustfmt emits the changes with the --emit flag:
+
+ Example:
+
+ ```sh
+ cargo fmt -- --emit files
+ ```
+
+ Options:
+
+ | Flag |Description| Nightly Only |
+ |:---:|:---:|:---:|
+ | files | overwrites output to files | No |
+ | stdout | writes output to stdout | No |
+ | coverage | displays how much of the input file was processed | Yes |
+ | checkstyle | emits in a checkstyle format | Yes |
+ | json | emits diffs in a json format | Yes |
+
+## License
+
+Rustfmt is distributed under the terms of both the MIT license and the
+Apache License (Version 2.0).
+
+See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.
+
+[rust]: https://github.com/rust-lang/rust
+[fmt rfcs]: https://github.com/rust-lang-nursery/fmt-rfcs
+[style guide]: https://github.com/rust-lang-nursery/fmt-rfcs/blob/master/guide/guide.md
diff --git a/src/tools/rustfmt/appveyor.yml b/src/tools/rustfmt/appveyor.yml
new file mode 100644
index 000000000000..7bfe696009fa
--- /dev/null
+++ b/src/tools/rustfmt/appveyor.yml
@@ -0,0 +1,55 @@
+# This is based on https://github.com/japaric/rust-everywhere/blob/master/appveyor.yml
+# and modified (mainly removal of deployment) to suit rustfmt.
+
+environment:
+ global:
+ PROJECT_NAME: rustfmt
+ matrix:
+ # Stable channel
+ # - TARGET: i686-pc-windows-gnu
+ # CHANNEL: stable
+ # - TARGET: i686-pc-windows-msvc
+ # CHANNEL: stable
+ # - TARGET: x86_64-pc-windows-gnu
+ # CHANNEL: stable
+ # - TARGET: x86_64-pc-windows-msvc
+ # CHANNEL: stable
+ # Beta channel
+ # - TARGET: i686-pc-windows-gnu
+ # CHANNEL: beta
+ # - TARGET: i686-pc-windows-msvc
+ # CHANNEL: beta
+ # - TARGET: x86_64-pc-windows-gnu
+ # CHANNEL: beta
+ # - TARGET: x86_64-pc-windows-msvc
+ # CHANNEL: beta
+ # Nightly channel
+ - TARGET: i686-pc-windows-gnu
+ CHANNEL: nightly
+ - TARGET: i686-pc-windows-msvc
+ CHANNEL: nightly
+ - TARGET: x86_64-pc-windows-gnu
+ CHANNEL: nightly
+ - TARGET: x86_64-pc-windows-msvc
+ CHANNEL: nightly
+
+# Install Rust and Cargo
+# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
+install:
+ - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
+ - if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin
+ - if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin
+ - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
+ - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y
+ - rustc -Vv
+ - cargo -V
+
+# ???
+build: false
+
+test_script:
+ - set CFG_RELEASE_CHANNEL=nightly
+ - set CFG_RELEASE=nightly
+ - cargo build --verbose
+ - cargo test
+ - cargo test -- --ignored
diff --git a/src/tools/rustfmt/atom.md b/src/tools/rustfmt/atom.md
new file mode 100644
index 000000000000..f77ac1490721
--- /dev/null
+++ b/src/tools/rustfmt/atom.md
@@ -0,0 +1,31 @@
+# Running Rustfmt from Atom
+
+## RLS
+
+Rustfmt is included with the Rust Language Server, itself provided by [ide-rust](https://atom.io/packages/ide-rust).
+
+`apm install ide-rust`
+
+Once installed a file is formatted with `ctrl-shift-c` or `cmd-shift-c`, also available in context menu.
+
+## atom-beautify
+
+Another way is to install [Beautify](https://atom.io/packages/atom-beautify), you
+can do this by running `apm install atom-beautify`.
+
+There are 2 settings that need to be configured in the atom beautifier configuration.
+
+- Install rustfmt as per the [readme](README.md).
+- Open the atom beautifier settings
+
+ Go to Edit->Preferences. Click the packages on the left side and click on setting for atom-beautifier
+
+- Set rustfmt as the beautifier
+
+ Find the setting labeled *Language Config - Rust - Default Beautifier* and make sure it is set to rustfmt as shown below. You can also set the beautifier to auto format on save here.
+
+
+- Set the path to your rustfmt location
+
+ Find the setting labeled *Rust - Rustfmt Path*. This setting is towards the bottom and you will need to scroll a bit. Set it to the path for your rustfmt executable.
+
diff --git a/src/tools/rustfmt/bootstrap.sh b/src/tools/rustfmt/bootstrap.sh
new file mode 100755
index 000000000000..05ac0ce2f306
--- /dev/null
+++ b/src/tools/rustfmt/bootstrap.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Make sure you double check the diffs after running this script - with great
+# power comes great responsibility.
+# We deliberately avoid reformatting files with rustfmt comment directives.
+
+cargo build --release
+
+target/release/rustfmt src/lib.rs
+target/release/rustfmt src/bin/main.rs
+target/release/rustfmt src/cargo-fmt/main.rs
+
+for filename in tests/target/*.rs; do
+ if ! grep -q "rustfmt-" "$filename"; then
+ target/release/rustfmt $filename
+ fi
+done
diff --git a/src/tools/rustfmt/build.rs b/src/tools/rustfmt/build.rs
new file mode 100644
index 000000000000..e7b1e1b854c0
--- /dev/null
+++ b/src/tools/rustfmt/build.rs
@@ -0,0 +1,55 @@
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+fn main() {
+ // Only check .git/HEAD dirty status if it exists - doing so when
+ // building dependent crates may lead to false positives and rebuilds
+ if Path::new(".git/HEAD").exists() {
+ println!("cargo:rerun-if-changed=.git/HEAD");
+ }
+
+ println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");
+
+ let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+ File::create(out_dir.join("commit-info.txt"))
+ .unwrap()
+ .write_all(commit_info().as_bytes())
+ .unwrap();
+}
+
+// Try to get hash and date of the last commit on a best effort basis. If anything goes wrong
+// (git not installed or if this is not a git repository) just return an empty string.
+fn commit_info() -> String {
+ match (channel(), commit_hash(), commit_date()) {
+ (channel, Some(hash), Some(date)) => format!("{} ({} {})", channel, hash.trim_end(), date),
+ _ => String::new(),
+ }
+}
+
+fn channel() -> String {
+ if let Ok(channel) = env::var("CFG_RELEASE_CHANNEL") {
+ channel
+ } else {
+ "nightly".to_owned()
+ }
+}
+
+fn commit_hash() -> Option {
+ Command::new("git")
+ .args(&["rev-parse", "--short", "HEAD"])
+ .output()
+ .ok()
+ .and_then(|r| String::from_utf8(r.stdout).ok())
+}
+
+fn commit_date() -> Option {
+ Command::new("git")
+ .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
+ .output()
+ .ok()
+ .and_then(|r| String::from_utf8(r.stdout).ok())
+}
diff --git a/src/tools/rustfmt/ci/integration.sh b/src/tools/rustfmt/ci/integration.sh
new file mode 100755
index 000000000000..13a3ecaa1961
--- /dev/null
+++ b/src/tools/rustfmt/ci/integration.sh
@@ -0,0 +1,107 @@
+#!/usr/bin/env bash
+
+set -ex
+
+: ${INTEGRATION?"The INTEGRATION environment variable must be set."}
+
+# FIXME: this means we can get a stale cargo-fmt from a previous run.
+#
+# `which rustfmt` fails if rustfmt is not found. Since we don't install
+# `rustfmt` via `rustup`, this is the case unless we manually install it. Once
+# that happens, `cargo install --force` will be called, which installs
+# `rustfmt`, `cargo-fmt`, etc to `~/.cargo/bin`. This directory is cached by
+# travis (see `.travis.yml`'s "cache" key), such that build-bots that arrive
+# here after the first installation will find `rustfmt` and won't need to build
+# it again.
+#
+#which cargo-fmt || cargo install --force
+CFG_RELEASE=nightly CFG_RELEASE_CHANNEL=nightly cargo install --path . --force
+
+echo "Integration tests for: ${INTEGRATION}"
+cargo fmt -- --version
+
+# Checks that:
+#
+# * `cargo fmt --all` succeeds without any warnings or errors
+# * `cargo fmt --all -- --check` after formatting returns success
+# * `cargo test --all` still passes (formatting did not break the build)
+function check_fmt_with_all_tests {
+ check_fmt_base "--all"
+ return $?
+}
+
+# Checks that:
+#
+# * `cargo fmt --all` succeeds without any warnings or errors
+# * `cargo fmt --all -- --check` after formatting returns success
+# * `cargo test --lib` still passes (formatting did not break the build)
+function check_fmt_with_lib_tests {
+ check_fmt_base "--lib"
+ return $?
+}
+
+function check_fmt_base {
+ local test_args="$1"
+ local build=$(cargo test $test_args 2>&1)
+ if [[ "$build" =~ "build failed" ]] || [[ "$build" =~ "test result: FAILED." ]]; then
+ return 0
+ fi
+ touch rustfmt.toml
+ cargo fmt --all -v |& tee rustfmt_output
+ if [[ ${PIPESTATUS[0]} != 0 ]]; then
+ cat rustfmt_output
+ return 1
+ fi
+ cat rustfmt_output
+ ! cat rustfmt_output | grep -q "internal error"
+ if [[ $? != 0 ]]; then
+ return 1
+ fi
+ ! cat rustfmt_output | grep -q "warning"
+ if [[ $? != 0 ]]; then
+ return 1
+ fi
+ ! cat rustfmt_output | grep -q "Warning"
+ if [[ $? != 0 ]]; then
+ return 1
+ fi
+ cargo fmt --all -- --check |& tee rustfmt_check_output
+ if [[ ${PIPESTATUS[0]} != 0 ]]; then
+ cat rustfmt_check_output
+ return 1
+ fi
+ cargo test $test_args
+ if [[ $? != 0 ]]; then
+ return $?
+ fi
+}
+
+function show_head {
+ local head=$(git rev-parse HEAD)
+ echo "Head commit of ${INTEGRATION}: $head"
+}
+
+case ${INTEGRATION} in
+ cargo)
+ git clone --depth=1 https://github.com/rust-lang/${INTEGRATION}.git
+ cd ${INTEGRATION}
+ show_head
+ export CFG_DISABLE_CROSS_TESTS=1
+ check_fmt_with_all_tests
+ cd -
+ ;;
+ crater)
+ git clone --depth=1 https://github.com/rust-lang-nursery/${INTEGRATION}.git
+ cd ${INTEGRATION}
+ show_head
+ check_fmt_with_lib_tests
+ cd -
+ ;;
+ *)
+ git clone --depth=1 https://github.com/rust-lang-nursery/${INTEGRATION}.git
+ cd ${INTEGRATION}
+ show_head
+ check_fmt_with_all_tests
+ cd -
+ ;;
+esac
diff --git a/src/tools/rustfmt/config_proc_macro/.gitignore b/src/tools/rustfmt/config_proc_macro/.gitignore
new file mode 100644
index 000000000000..9f970225adb6
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/.gitignore
@@ -0,0 +1 @@
+target/
\ No newline at end of file
diff --git a/src/tools/rustfmt/config_proc_macro/Cargo.lock b/src/tools/rustfmt/config_proc_macro/Cargo.lock
new file mode 100644
index 000000000000..abcf9654e5d7
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/Cargo.lock
@@ -0,0 +1,68 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "proc-macro2"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustfmt-config_proc_macro"
+version = "0.1.2"
+dependencies = [
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
+"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
+"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
+"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
+"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
+"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
diff --git a/src/tools/rustfmt/config_proc_macro/Cargo.toml b/src/tools/rustfmt/config_proc_macro/Cargo.toml
new file mode 100644
index 000000000000..cc995571602b
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+name = "rustfmt-config_proc_macro"
+version = "0.2.0"
+authors = ["topecongiro "]
+edition = "2018"
+description = "A collection of procedural macros for rustfmt"
+license = "Apache-2.0/MIT"
+categories = ["development-tools::procedural-macro-helpers"]
+repository = "https://github.com/rust-lang/rustfmt"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+proc-macro2 = "1.0"
+quote = "1.0"
+syn = { version = "1.0", features = ["full", "visit"] }
+
+[dev-dependencies]
+serde = { version = "1.0", features = ["derive"] }
+
+[features]
+default = []
+debug-with-rustfmt = []
diff --git a/src/tools/rustfmt/config_proc_macro/src/attrs.rs b/src/tools/rustfmt/config_proc_macro/src/attrs.rs
new file mode 100644
index 000000000000..0baba046f9e9
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/attrs.rs
@@ -0,0 +1,57 @@
+//! This module provides utilities for handling attributes on variants
+//! of `config_type` enum. Currently there are two types of attributes
+//! that could appear on the variants of `config_type` enum: `doc_hint`
+//! and `value`. Both comes in the form of name-value pair whose value
+//! is string literal.
+
+/// Returns the value of the first `doc_hint` attribute in the given slice or
+/// `None` if `doc_hint` attribute is not available.
+pub fn find_doc_hint(attrs: &[syn::Attribute]) -> Option {
+ attrs.iter().filter_map(doc_hint).next()
+}
+
+/// Returns `true` if the given attribute is a `doc_hint` attribute.
+pub fn is_doc_hint(attr: &syn::Attribute) -> bool {
+ is_attr_name_value(attr, "doc_hint")
+}
+
+/// Returns a string literal value if the given attribute is `doc_hint`
+/// attribute or `None` otherwise.
+pub fn doc_hint(attr: &syn::Attribute) -> Option {
+ get_name_value_str_lit(attr, "doc_hint")
+}
+
+/// Returns the value of the first `value` attribute in the given slice or
+/// `None` if `value` attribute is not available.
+pub fn find_config_value(attrs: &[syn::Attribute]) -> Option {
+ attrs.iter().filter_map(config_value).next()
+}
+
+/// Returns a string literal value if the given attribute is `value`
+/// attribute or `None` otherwise.
+pub fn config_value(attr: &syn::Attribute) -> Option {
+ get_name_value_str_lit(attr, "value")
+}
+
+/// Returns `true` if the given attribute is a `value` attribute.
+pub fn is_config_value(attr: &syn::Attribute) -> bool {
+ is_attr_name_value(attr, "value")
+}
+
+fn is_attr_name_value(attr: &syn::Attribute, name: &str) -> bool {
+ attr.parse_meta().ok().map_or(false, |meta| match meta {
+ syn::Meta::NameValue(syn::MetaNameValue { ref path, .. }) if path.is_ident(name) => true,
+ _ => false,
+ })
+}
+
+fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option {
+ attr.parse_meta().ok().and_then(|meta| match meta {
+ syn::Meta::NameValue(syn::MetaNameValue {
+ ref path,
+ lit: syn::Lit::Str(ref lit_str),
+ ..
+ }) if path.is_ident(name) => Some(lit_str.value()),
+ _ => None,
+ })
+}
diff --git a/src/tools/rustfmt/config_proc_macro/src/config_type.rs b/src/tools/rustfmt/config_proc_macro/src/config_type.rs
new file mode 100644
index 000000000000..93a78b8463ec
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/config_type.rs
@@ -0,0 +1,15 @@
+use proc_macro2::TokenStream;
+
+use crate::item_enum::define_config_type_on_enum;
+use crate::item_struct::define_config_type_on_struct;
+
+/// Defines `config_type` on enum or struct.
+// FIXME: Implement this on struct.
+pub fn define_config_type(input: &syn::Item) -> TokenStream {
+ match input {
+ syn::Item::Struct(st) => define_config_type_on_struct(st),
+ syn::Item::Enum(en) => define_config_type_on_enum(en),
+ _ => panic!("Expected enum or struct"),
+ }
+ .unwrap()
+}
diff --git a/src/tools/rustfmt/config_proc_macro/src/item_enum.rs b/src/tools/rustfmt/config_proc_macro/src/item_enum.rs
new file mode 100644
index 000000000000..dcee77a8549c
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/item_enum.rs
@@ -0,0 +1,208 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+
+use crate::attrs::*;
+use crate::utils::*;
+
+type Variants = syn::punctuated::Punctuated;
+
+/// Defines and implements `config_type` enum.
+pub fn define_config_type_on_enum(em: &syn::ItemEnum) -> syn::Result {
+ let syn::ItemEnum {
+ vis,
+ enum_token,
+ ident,
+ generics,
+ variants,
+ ..
+ } = em;
+
+ let mod_name_str = format!("__define_config_type_on_enum_{}", ident);
+ let mod_name = syn::Ident::new(&mod_name_str, ident.span());
+ let variants = fold_quote(variants.iter().map(process_variant), |meta| quote!(#meta,));
+
+ let impl_doc_hint = impl_doc_hint(&em.ident, &em.variants);
+ let impl_from_str = impl_from_str(&em.ident, &em.variants);
+ let impl_display = impl_display(&em.ident, &em.variants);
+ let impl_serde = impl_serde(&em.ident, &em.variants);
+ let impl_deserialize = impl_deserialize(&em.ident, &em.variants);
+
+ Ok(quote! {
+ #[allow(non_snake_case)]
+ mod #mod_name {
+ #[derive(Debug, Copy, Clone, Eq, PartialEq)]
+ pub #enum_token #ident #generics { #variants }
+ #impl_display
+ #impl_doc_hint
+ #impl_from_str
+ #impl_serde
+ #impl_deserialize
+ }
+ #vis use #mod_name::#ident;
+ })
+}
+
+/// Remove attributes specific to `config_proc_macro` from enum variant fields.
+fn process_variant(variant: &syn::Variant) -> TokenStream {
+ let metas = variant
+ .attrs
+ .iter()
+ .filter(|attr| !is_doc_hint(attr) && !is_config_value(attr));
+ let attrs = fold_quote(metas, |meta| quote!(#meta));
+ let syn::Variant { ident, fields, .. } = variant;
+ quote!(#attrs #ident #fields)
+}
+
+fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream {
+ let doc_hint = variants
+ .iter()
+ .map(doc_hint_of_variant)
+ .collect::>()
+ .join("|");
+ let doc_hint = format!("[{}]", doc_hint);
+ quote! {
+ use crate::config::ConfigType;
+ impl ConfigType for #ident {
+ fn doc_hint() -> String {
+ #doc_hint.to_owned()
+ }
+ }
+ }
+}
+
+fn impl_display(ident: &syn::Ident, variants: &Variants) -> TokenStream {
+ let vs = variants
+ .iter()
+ .filter(|v| is_unit(v))
+ .map(|v| (config_value_of_variant(v), &v.ident));
+ let match_patterns = fold_quote(vs, |(s, v)| {
+ quote! {
+ #ident::#v => write!(f, "{}", #s),
+ }
+ });
+ quote! {
+ use std::fmt;
+ impl fmt::Display for #ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ #match_patterns
+ _ => unimplemented!(),
+ }
+ }
+ }
+ }
+}
+
+fn impl_from_str(ident: &syn::Ident, variants: &Variants) -> TokenStream {
+ let vs = variants
+ .iter()
+ .filter(|v| is_unit(v))
+ .map(|v| (config_value_of_variant(v), &v.ident));
+ let if_patterns = fold_quote(vs, |(s, v)| {
+ quote! {
+ if #s.eq_ignore_ascii_case(s) {
+ return Ok(#ident::#v);
+ }
+ }
+ });
+ let mut err_msg = String::from("Bad variant, expected one of:");
+ for v in variants.iter().filter(|v| is_unit(v)) {
+ err_msg.push_str(&format!(" `{}`", v.ident));
+ }
+
+ quote! {
+ impl ::std::str::FromStr for #ident {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result {
+ #if_patterns
+ return Err(#err_msg);
+ }
+ }
+ }
+}
+
+fn doc_hint_of_variant(variant: &syn::Variant) -> String {
+ find_doc_hint(&variant.attrs).unwrap_or(variant.ident.to_string())
+}
+
+fn config_value_of_variant(variant: &syn::Variant) -> String {
+ find_config_value(&variant.attrs).unwrap_or(variant.ident.to_string())
+}
+
+fn impl_serde(ident: &syn::Ident, variants: &Variants) -> TokenStream {
+ let arms = fold_quote(variants.iter(), |v| {
+ let v_ident = &v.ident;
+ let pattern = match v.fields {
+ syn::Fields::Named(..) => quote!(#ident::v_ident{..}),
+ syn::Fields::Unnamed(..) => quote!(#ident::#v_ident(..)),
+ syn::Fields::Unit => quote!(#ident::#v_ident),
+ };
+ let option_value = config_value_of_variant(v);
+ quote! {
+ #pattern => serializer.serialize_str(option_value),
+ }
+ });
+
+ quote! {
+ impl ::serde::ser::Serialize for #ident {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: ::serde::ser::Serializer,
+ {
+ use serde::ser::Error;
+ match self {
+ #arms
+ _ => Err(S::Error::custom(format!("Cannot serialize {:?}", self))),
+ }
+ }
+ }
+ }
+}
+
+// Currently only unit variants are supported.
+fn impl_deserialize(ident: &syn::Ident, variants: &Variants) -> TokenStream {
+ let supported_vs = variants.iter().filter(|v| is_unit(v));
+ let if_patterns = fold_quote(supported_vs, |v| {
+ let config_value = config_value_of_variant(v);
+ let variant_ident = &v.ident;
+ quote! {
+ if #config_value.eq_ignore_ascii_case(s) {
+ return Ok(#ident::#variant_ident);
+ }
+ }
+ });
+
+ let supported_vs = variants.iter().filter(|v| is_unit(v));
+ let allowed = fold_quote(supported_vs.map(config_value_of_variant), |s| quote!(#s,));
+
+ quote! {
+ impl<'de> serde::de::Deserialize<'de> for #ident {
+ fn deserialize(d: D) -> Result
+ where
+ D: serde::Deserializer<'de>,
+ {
+ use serde::de::{Error, Visitor};
+ use std::marker::PhantomData;
+ use std::fmt;
+ struct StringOnly(PhantomData);
+ impl<'de, T> Visitor<'de> for StringOnly
+ where T: serde::Deserializer<'de> {
+ type Value = String;
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("string")
+ }
+ fn visit_str(self, value: &str) -> Result {
+ Ok(String::from(value))
+ }
+ }
+ let s = &d.deserialize_string(StringOnly::(PhantomData))?;
+
+ #if_patterns
+
+ static ALLOWED: &'static[&str] = &[#allowed];
+ Err(D::Error::unknown_variant(&s, ALLOWED))
+ }
+ }
+ }
+}
diff --git a/src/tools/rustfmt/config_proc_macro/src/item_struct.rs b/src/tools/rustfmt/config_proc_macro/src/item_struct.rs
new file mode 100644
index 000000000000..f03ff7e30d82
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/item_struct.rs
@@ -0,0 +1,5 @@
+use proc_macro2::TokenStream;
+
+pub fn define_config_type_on_struct(_st: &syn::ItemStruct) -> syn::Result {
+ unimplemented!()
+}
diff --git a/src/tools/rustfmt/config_proc_macro/src/lib.rs b/src/tools/rustfmt/config_proc_macro/src/lib.rs
new file mode 100644
index 000000000000..78e7e098ed9e
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/lib.rs
@@ -0,0 +1,25 @@
+//! This crate provides a derive macro for `ConfigType`.
+
+#![recursion_limit = "256"]
+
+mod attrs;
+mod config_type;
+mod item_enum;
+mod item_struct;
+mod utils;
+
+use proc_macro::TokenStream;
+use syn::parse_macro_input;
+
+#[proc_macro_attribute]
+pub fn config_type(_args: TokenStream, input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as syn::Item);
+ let output = config_type::define_config_type(&input);
+
+ #[cfg(feature = "debug-with-rustfmt")]
+ {
+ utils::debug_with_rustfmt(&output);
+ }
+
+ TokenStream::from(output)
+}
diff --git a/src/tools/rustfmt/config_proc_macro/src/utils.rs b/src/tools/rustfmt/config_proc_macro/src/utils.rs
new file mode 100644
index 000000000000..5b68d2748490
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/src/utils.rs
@@ -0,0 +1,52 @@
+use proc_macro2::TokenStream;
+use quote::{quote, ToTokens};
+
+pub fn fold_quote(input: impl Iterator, f: F) -> TokenStream
+where
+ F: Fn(I) -> T,
+ T: ToTokens,
+{
+ input.fold(quote! {}, |acc, x| {
+ let y = f(x);
+ quote! { #acc #y }
+ })
+}
+
+pub fn is_unit(v: &syn::Variant) -> bool {
+ match v.fields {
+ syn::Fields::Unit => true,
+ _ => false,
+ }
+}
+
+#[cfg(feature = "debug-with-rustfmt")]
+/// Pretty-print the output of proc macro using rustfmt.
+pub fn debug_with_rustfmt(input: &TokenStream) {
+ use std::io::Write;
+ use std::process::{Command, Stdio};
+ use std::env;
+ use std::ffi::OsStr;
+
+ let rustfmt_var = env::var_os("RUSTFMT");
+ let rustfmt = match &rustfmt_var {
+ Some(rustfmt) => rustfmt,
+ None => OsStr::new("rustfmt"),
+ };
+ let mut child = Command::new(rustfmt)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn()
+ .expect("Failed to spawn rustfmt in stdio mode");
+ {
+ let stdin = child.stdin.as_mut().expect("Failed to get stdin");
+ stdin
+ .write_all(format!("{}", input).as_bytes())
+ .expect("Failed to write to stdin");
+ }
+ let rustfmt_output = child.wait_with_output().expect("rustfmt has failed");
+
+ eprintln!(
+ "{}",
+ String::from_utf8(rustfmt_output.stdout).expect("rustfmt returned non-UTF8 string")
+ );
+}
diff --git a/src/tools/rustfmt/config_proc_macro/tests/smoke.rs b/src/tools/rustfmt/config_proc_macro/tests/smoke.rs
new file mode 100644
index 000000000000..940a8a0c251e
--- /dev/null
+++ b/src/tools/rustfmt/config_proc_macro/tests/smoke.rs
@@ -0,0 +1,20 @@
+pub mod config {
+ pub trait ConfigType: Sized {
+ fn doc_hint() -> String;
+ }
+}
+
+#[allow(dead_code)]
+#[allow(unused_imports)]
+mod tests {
+ use rustfmt_config_proc_macro::config_type;
+
+ #[config_type]
+ enum Bar {
+ Foo,
+ Bar,
+ #[doc_hint = "foo_bar"]
+ FooBar,
+ FooFoo(i32),
+ }
+}
diff --git a/src/tools/rustfmt/docs/index.html b/src/tools/rustfmt/docs/index.html
new file mode 100644
index 000000000000..2a12da3881f0
--- /dev/null
+++ b/src/tools/rustfmt/docs/index.html
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/rustfmt/intellij.md b/src/tools/rustfmt/intellij.md
new file mode 100644
index 000000000000..7aea6222b8bc
--- /dev/null
+++ b/src/tools/rustfmt/intellij.md
@@ -0,0 +1,26 @@
+# Running Rustfmt from IntelliJ or CLion
+
+## Installation
+
+- Install [CLion](https://www.jetbrains.com/clion/), [IntelliJ Ultimate or CE](https://www.jetbrains.com/idea/) through the direct download link or using the [JetBrains Toolbox](https://www.jetbrains.com/toolbox/).
+ CLion provides a built-in debugger interface but its not free like IntelliJ CE - which does not provide the debugger interface. (IntelliJ seems to lack the toolchain for that, see this discussion [intellij-rust/issues/535](https://github.com/intellij-rust/intellij-rust/issues/535))
+
+- Install the [Rust Plugin](https://intellij-rust.github.io/) by navigating to File -> Settings -> Plugins and press "Install JetBrains Plugin"
+ 
+
+- Press "Install" on the rust plugin
+ 
+
+- Restart CLion/IntelliJ
+
+## Configuration
+
+- Open the settings window (File -> Settings) and search for "reformat"
+ 
+- Right-click on "Reformat File with Rustfmt" and assign a keyboard shortcut
+
+ 
+- Press "OK"
+ 
+
+- Done. You can now use rustfmt in an opened *.rs file with your previously specified shortcut
diff --git a/src/tools/rustfmt/legacy-rustfmt.toml b/src/tools/rustfmt/legacy-rustfmt.toml
new file mode 100644
index 000000000000..f976fa68e4c7
--- /dev/null
+++ b/src/tools/rustfmt/legacy-rustfmt.toml
@@ -0,0 +1,2 @@
+indent_style = "Visual"
+combine_control_expr = false
diff --git a/src/tools/rustfmt/rust-toolchain b/src/tools/rustfmt/rust-toolchain
new file mode 100644
index 000000000000..7c9d02d933d0
--- /dev/null
+++ b/src/tools/rustfmt/rust-toolchain
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "nightly-2021-05-13"
+components = ["rustc-dev"]
diff --git a/src/tools/rustfmt/rustfmt.toml b/src/tools/rustfmt/rustfmt.toml
new file mode 100644
index 000000000000..eccd5f9bd19e
--- /dev/null
+++ b/src/tools/rustfmt/rustfmt.toml
@@ -0,0 +1,3 @@
+error_on_line_overflow = true
+error_on_unformatted = true
+version = "Two"
diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs
new file mode 100644
index 000000000000..c5ffb074ba55
--- /dev/null
+++ b/src/tools/rustfmt/src/attr.rs
@@ -0,0 +1,534 @@
+//! Format attributes and meta items.
+
+use rustc_ast::ast;
+use rustc_ast::AstLike;
+use rustc_span::{symbol::sym, Span, Symbol};
+
+use self::doc_comment::DocCommentFormatter;
+use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
+use crate::config::lists::*;
+use crate::config::IndentStyle;
+use crate::expr::rewrite_literal;
+use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
+use crate::overflow;
+use crate::rewrite::{Rewrite, RewriteContext};
+use crate::shape::Shape;
+use crate::types::{rewrite_path, PathContext};
+use crate::utils::{count_newlines, mk_sp};
+
+mod doc_comment;
+
+pub(crate) fn contains_name(attrs: &[ast::Attribute], name: Symbol) -> bool {
+ attrs.iter().any(|attr| attr.has_name(name))
+}
+
+pub(crate) fn first_attr_value_str_by_name(
+ attrs: &[ast::Attribute],
+ name: Symbol,
+) -> Option {
+ attrs
+ .iter()
+ .find(|attr| attr.has_name(name))
+ .and_then(|attr| attr.value_str())
+}
+
+/// Returns attributes on the given statement.
+pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
+ stmt.attrs()
+}
+
+pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span {
+ match stmt.kind {
+ ast::StmtKind::Local(ref local) => local.span,
+ ast::StmtKind::Item(ref item) => item.span,
+ ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span,
+ ast::StmtKind::MacCall(ref mac_stmt) => mac_stmt.mac.span(),
+ ast::StmtKind::Empty => stmt.span,
+ }
+}
+
+/// Returns attributes that are within `outer_span`.
+pub(crate) fn filter_inline_attrs(
+ attrs: &[ast::Attribute],
+ outer_span: Span,
+) -> Vec {
+ attrs
+ .iter()
+ .filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi())
+ .cloned()
+ .collect()
+}
+
+fn is_derive(attr: &ast::Attribute) -> bool {
+ attr.has_name(sym::derive)
+}
+
+// The shape of the arguments to a function-like attribute.
+fn argument_shape(
+ left: usize,
+ right: usize,
+ combine: bool,
+ shape: Shape,
+ context: &RewriteContext<'_>,
+) -> Option {
+ match context.config.indent_style() {
+ IndentStyle::Block => {
+ if combine {
+ shape.offset_left(left)
+ } else {
+ Some(
+ shape
+ .block_indent(context.config.tab_spaces())
+ .with_max_width(context.config),
+ )
+ }
+ }
+ IndentStyle::Visual => shape
+ .visual_indent(0)
+ .shrink_left(left)
+ .and_then(|s| s.sub_width(right)),
+ }
+}
+
+fn format_derive(
+ derives: &[ast::Attribute],
+ shape: Shape,
+ context: &RewriteContext<'_>,
+) -> Option {
+ // Collect all items from all attributes
+ let all_items = derives
+ .iter()
+ .map(|attr| {
+ // Parse the derive items and extract the span for each item; if any
+ // attribute is not parseable, none of the attributes will be
+ // reformatted.
+ let item_spans = attr.meta_item_list().map(|meta_item_list| {
+ meta_item_list
+ .into_iter()
+ .map(|nested_meta_item| nested_meta_item.span())
+ })?;
+
+ let items = itemize_list(
+ context.snippet_provider,
+ item_spans,
+ ")",
+ ",",
+ |span| span.lo(),
+ |span| span.hi(),
+ |span| Some(context.snippet(*span).to_owned()),
+ attr.span.lo(),
+ attr.span.hi(),
+ false,
+ );
+
+ Some(items)
+ })
+ // Fail if any attribute failed.
+ .collect::