Merge commit '1d8491b120223272b13451fc81265aa64f7f4d5b' into sync-from-rustfmt
This commit is contained in:
commit
8e1e67dbaa
108 changed files with 2591 additions and 187 deletions
33
src/tools/rustfmt/.github/workflows/check_diff.yml
vendored
Normal file
33
src/tools/rustfmt/.github/workflows/check_diff.yml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
name: Diff Check
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
clone_url:
|
||||
description: 'Git url of a rustfmt fork to compare against the latest master rustfmt'
|
||||
required: true
|
||||
branch_name:
|
||||
description: 'Name of the feature branch on the forked repo'
|
||||
required: true
|
||||
commit_hash:
|
||||
description: 'Optional commit hash from the feature branch'
|
||||
required: false
|
||||
rustfmt_configs:
|
||||
description: 'Optional comma separated list of rustfmt config options to pass when running the feature branch'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
diff_check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- 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 x86_64-unknown-linux-gnu
|
||||
|
||||
- name: check diff
|
||||
run: bash ${GITHUB_WORKSPACE}/ci/check_diff.sh ${{ github.event.inputs.clone_url }} ${{ github.event.inputs.branch_name }} ${{ github.event.inputs.commit_hash }} ${{ github.event.inputs.rustfmt_configs }}
|
|
@ -27,7 +27,6 @@ jobs:
|
|||
tempdir,
|
||||
futures-rs,
|
||||
rust-clippy,
|
||||
failure,
|
||||
]
|
||||
include:
|
||||
# Allowed Failures
|
||||
|
@ -63,9 +62,6 @@ jobs:
|
|||
# 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
|
||||
|
|
|
@ -2,6 +2,32 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.5.2] 2023-01-24
|
||||
|
||||
### Fixed
|
||||
|
||||
- Resolve issue when comments are found within const generic defaults in unit structs [#5668](https://github.com/rust-lang/rustfmt/issues/5668)
|
||||
- Resolve issue when block comments are found within trait generics [#5358](https://github.com/rust-lang/rustfmt/issues/5358)
|
||||
- Correctly handle alignment of comments containing unicode characters [#5504](https://github.com/rust-lang/rustfmt/issues/5504)
|
||||
- Properly indent a single generic bound that requires being written across multiple lines [#4689](https://github.com/rust-lang/rustfmt/issues/4689) (n.b. this change is version gated and will only appear when the `version` configuration option is set to `Two`)
|
||||
|
||||
### Changed
|
||||
|
||||
- Renamed `fn_args_layout` configuration option to `fn_params_layout` [#4149](https://github.com/rust-lang/rustfmt/issues/4149). Note that `fn_args_layout` has only been soft deprecated: `fn_args_layout` will continue to work without issue, but rustfmt will display a warning to encourage users to switch to the new name
|
||||
|
||||
### Added
|
||||
|
||||
- New configuration option (`skip_macro_invocations`)[https://rust-lang.github.io/rustfmt/?version=master&search=#skip_macro_invocations] [#5347](https://github.com/rust-lang/rustfmt/pull/5347) that can be used to globally define a single enumerated list of macro calls that rustfmt should skip formatting. rustfmt [currently also supports this via a custom tool attribute](https://github.com/rust-lang/rustfmt#tips), however, these cannot be used in all contexts because [custom inner attributes are unstable](https://github.com/rust-lang/rust/issues/54726)
|
||||
|
||||
### Misc
|
||||
|
||||
- rustfmt now internally supports the ability to have both stable and unstable variants of a configuration option [#5378](https://github.com/rust-lang/rustfmt/issues/5378). This ability will allow the rustfmt team to make certain configuration options available on stable toolchains more quickly because we no longer have to wait for _every_ variant to be stable-ready before stabilizing _any_ variant.
|
||||
|
||||
### Install/Download Options
|
||||
- **rustup (nightly)** - nightly-2023-01-24
|
||||
- **GitHub Release Binaries** - [Release v1.5.2](https://github.com/rust-lang/rustfmt/releases/tag/v1.5.2)
|
||||
- **Build from source** - [Tag v1.5.2](https://github.com/rust-lang/rustfmt/tree/v1.5.2), see instructions for how to [install rustfmt from source][install-from-source]
|
||||
|
||||
## [1.5.1] 2022-06-24
|
||||
|
||||
**N.B** A bug was introduced in v1.5.0/nightly-2022-06-15 which modified formatting. If you happened to run rustfmt over your code with one of those ~10 nightlies it's possible you may have seen formatting changes, and you may see additional changes after this fix since that bug has now been reverted.
|
||||
|
@ -840,7 +866,7 @@ from formatting an attribute #3665
|
|||
- 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
|
||||
- Improve 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
|
||||
|
|
|
@ -476,7 +476,7 @@ checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
|
|||
|
||||
[[package]]
|
||||
name = "rustfmt-config_proc_macro"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -485,7 +485,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustfmt-nightly"
|
||||
version = "1.5.1"
|
||||
version = "1.5.2"
|
||||
dependencies = [
|
||||
"annotate-snippets",
|
||||
"anyhow",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
|
||||
name = "rustfmt-nightly"
|
||||
version = "1.5.1"
|
||||
version = "1.5.2"
|
||||
description = "Tool to find and fix Rust formatting issues"
|
||||
repository = "https://github.com/rust-lang/rustfmt"
|
||||
readme = "README.md"
|
||||
|
@ -57,7 +57,7 @@ unicode-segmentation = "1.9"
|
|||
unicode-width = "0.1"
|
||||
unicode_categories = "0.1"
|
||||
|
||||
rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" }
|
||||
rustfmt-config_proc_macro = { version = "0.3", path = "config_proc_macro" }
|
||||
|
||||
# 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`
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 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.
|
||||
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/4.0.0/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:
|
||||
|
||||
|
@ -425,7 +425,7 @@ fn example() {
|
|||
|
||||
## `comment_width`
|
||||
|
||||
Maximum length of comments. No effect unless`wrap_comments = true`.
|
||||
Maximum length of comments. No effect unless `wrap_comments = true`.
|
||||
|
||||
- **Default value**: `80`
|
||||
- **Possible values**: any positive integer
|
||||
|
@ -589,7 +589,7 @@ doesn't get ignored when aligning.
|
|||
#### `0` (default):
|
||||
|
||||
```rust
|
||||
enum Bar {
|
||||
enum Foo {
|
||||
A = 0,
|
||||
Bb = 1,
|
||||
RandomLongVariantGoesHere = 10,
|
||||
|
@ -645,7 +645,8 @@ trailing whitespaces.
|
|||
|
||||
## `fn_args_layout`
|
||||
|
||||
Control the layout of arguments in a function
|
||||
This option is deprecated and has been renamed to `fn_params_layout` to better communicate that
|
||||
it affects the layout of parameters in function signatures.
|
||||
|
||||
- **Default value**: `"Tall"`
|
||||
- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
|
||||
|
@ -753,6 +754,8 @@ trait Lorem {
|
|||
}
|
||||
```
|
||||
|
||||
See also [`fn_params_layout`](#fn_params_layout)
|
||||
|
||||
## `fn_call_width`
|
||||
|
||||
Maximum width of the args of a function call before falling back to vertical formatting.
|
||||
|
@ -765,6 +768,117 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi
|
|||
|
||||
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
|
||||
|
||||
## `fn_params_layout`
|
||||
|
||||
Control the layout of parameters in function signatures.
|
||||
|
||||
- **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_single_line`
|
||||
|
||||
Put single-expression functions on a single line
|
||||
|
@ -1014,6 +1128,62 @@ macro_rules! foo {
|
|||
|
||||
See also [`format_macro_matchers`](#format_macro_matchers).
|
||||
|
||||
## `skip_macro_invocations`
|
||||
|
||||
Skip formatting the bodies of macro invocations with the following names.
|
||||
|
||||
rustfmt will not format any macro invocation for macros with names set in this list.
|
||||
Including the special value "*" will prevent any macro invocations from being formatted.
|
||||
|
||||
Note: This option does not have any impact on how rustfmt formats macro definitions.
|
||||
|
||||
- **Default value**: `[]`
|
||||
- **Possible values**: a list of macro name idents, `["name_0", "name_1", ..., "*"]`
|
||||
- **Stable**: No (tracking issue: [#5346](https://github.com/rust-lang/rustfmt/issues/5346))
|
||||
|
||||
#### `[]` (default):
|
||||
|
||||
rustfmt will follow its standard approach to formatting macro invocations.
|
||||
|
||||
No macro invocations will be skipped based on their name. More information about rustfmt's standard macro invocation formatting behavior can be found in [#5437](https://github.com/rust-lang/rustfmt/discussions/5437).
|
||||
|
||||
```rust
|
||||
lorem!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
ipsum!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
```
|
||||
|
||||
#### `["lorem"]`:
|
||||
|
||||
The named macro invocations will be skipped.
|
||||
|
||||
```rust
|
||||
lorem!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
ipsum!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
```
|
||||
|
||||
#### `["*"]`:
|
||||
|
||||
The special selector `*` will skip all macro invocations.
|
||||
|
||||
```rust
|
||||
lorem!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
ipsum!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
```
|
||||
|
||||
## `format_strings`
|
||||
|
||||
|
@ -1687,13 +1857,16 @@ 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.
|
||||
Controls how imports are structured in `use` statements. Imports will be merged or split to the configured level of granularity.
|
||||
|
||||
Similar to other `import` related configuration options, this option operates within the bounds of user-defined groups of imports. See [`group_imports`](#group_imports) for more information on import groups.
|
||||
|
||||
Note that rustfmt will not modify the granularity of imports containing comments if doing so could potentially lose or misplace said comments.
|
||||
|
||||
- **Default value**: `Preserve`
|
||||
- **Possible values**: `Preserve`, `Crate`, `Module`, `Item`, `One`
|
||||
- **Stable**: No (tracking issue: [#4991](https://github.com/rust-lang/rustfmt/issues/4991))
|
||||
|
||||
Note that rustfmt will not modify the granularity of imports containing comments if doing so could potentially lose or misplace said comments.
|
||||
|
||||
#### `Preserve` (default):
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ 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.
|
||||
In this Section, we describe how to stabilise an option of the rustfmt's configuration.
|
||||
|
||||
## Conditions
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
set "RUSTFLAGS=-D warnings"
|
||||
set "RUSTFMT_CI=1"
|
||||
|
||||
:: Print version information
|
||||
rustc -Vv || exit /b 1
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
set -euo pipefail
|
||||
|
||||
export RUSTFLAGS="-D warnings"
|
||||
export RUSTFMT_CI=1
|
||||
|
||||
# Print version information
|
||||
rustc -Vv
|
||||
|
|
199
src/tools/rustfmt/ci/check_diff.sh
Executable file
199
src/tools/rustfmt/ci/check_diff.sh
Executable file
|
@ -0,0 +1,199 @@
|
|||
#!/bin/bash
|
||||
|
||||
function print_usage() {
|
||||
echo "usage check_diff REMOTE_REPO FEATURE_BRANCH [COMMIT_HASH] [OPTIONAL_RUSTFMT_CONFIGS]"
|
||||
}
|
||||
|
||||
if [ $# -le 1 ]; then
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REMOTE_REPO=$1
|
||||
FEATURE_BRANCH=$2
|
||||
OPTIONAL_COMMIT_HASH=$3
|
||||
OPTIONAL_RUSTFMT_CONFIGS=$4
|
||||
|
||||
# OUTPUT array used to collect all the status of running diffs on various repos
|
||||
STATUSES=()
|
||||
|
||||
# Clone a git repository and cd into it.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: git clone url
|
||||
# $2: directory where the repo should be cloned
|
||||
function clone_repo() {
|
||||
GIT_TERMINAL_PROMPT=0 git clone --quiet $1 --depth 1 $2 && cd $2
|
||||
}
|
||||
|
||||
# Initialize Git submoduels for the repo.
|
||||
#
|
||||
# Parameters
|
||||
# $1: list of directories to initialize
|
||||
function init_submodules() {
|
||||
git submodule update --init $1
|
||||
}
|
||||
|
||||
# Run rusfmt with the --check flag to see if a diff is produced.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Path to a rustfmt binary
|
||||
# $2: Output file path for the diff
|
||||
# $3: Any additional configuration options to pass to rustfmt
|
||||
#
|
||||
# Globlas:
|
||||
# $OPTIONAL_RUSTFMT_CONFIGS: Optional configs passed to the script from $4
|
||||
function create_diff() {
|
||||
local config;
|
||||
if [ -z "$3" ]; then
|
||||
config="--config=error_on_line_overflow=false,error_on_unformatted=false"
|
||||
else
|
||||
config="--config=error_on_line_overflow=false,error_on_unformatted=false,$OPTIONAL_RUSTFMT_CONFIGS"
|
||||
fi
|
||||
|
||||
for i in `find . | grep "\.rs$"`
|
||||
do
|
||||
$1 --unstable-features --skip-children --check --color=always $config $i >> $2 2>/dev/null
|
||||
done
|
||||
}
|
||||
|
||||
# Run the master rustfmt binary and the feature branch binary in the current directory and compare the diffs
|
||||
#
|
||||
# Parameters
|
||||
# $1: Name of the repository (used for logging)
|
||||
#
|
||||
# Globlas:
|
||||
# $RUSFMT_BIN: Path to the rustfmt master binary. Created when running `compile_rustfmt`
|
||||
# $FEATURE_BIN: Path to the rustfmt feature binary. Created when running `compile_rustfmt`
|
||||
# $OPTIONAL_RUSTFMT_CONFIGS: Optional configs passed to the script from $4
|
||||
function check_diff() {
|
||||
echo "running rustfmt (master) on $1"
|
||||
create_diff $RUSFMT_BIN rustfmt_diff.txt
|
||||
|
||||
echo "running rustfmt (feature) on $1"
|
||||
create_diff $FEATURE_BIN feature_diff.txt $OPTIONAL_RUSTFMT_CONFIGS
|
||||
|
||||
echo "checking diff"
|
||||
local diff;
|
||||
# we don't add color to the diff since we added color when running rustfmt --check.
|
||||
# tail -n + 6 removes the git diff header info
|
||||
# cut -c 2- removes the leading diff characters("+","-"," ") from running git diff.
|
||||
# Again, the diff output we care about was already added when we ran rustfmt --check
|
||||
diff=$(
|
||||
git --no-pager diff --color=never \
|
||||
--unified=0 --no-index rustfmt_diff.txt feature_diff.txt 2>&1 | tail -n +6 | cut -c 2-
|
||||
)
|
||||
|
||||
if [ -z "$diff" ]; then
|
||||
echo "no diff detected between rustfmt and the feture branch"
|
||||
return 0
|
||||
else
|
||||
echo "$diff"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Compiles and produces two rustfmt binaries.
|
||||
# One for the current master, and another for the feature branch
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Directory where rustfmt will be cloned
|
||||
#
|
||||
# Globlas:
|
||||
# $REMOTE_REPO: Clone URL to the rustfmt fork that we want to test
|
||||
# $FEATURE_BRANCH: Name of the feature branch
|
||||
# $OPTIONAL_COMMIT_HASH: Optional commit hash that will be checked out if provided
|
||||
function compile_rustfmt() {
|
||||
RUSTFMT_REPO="https://github.com/rust-lang/rustfmt.git"
|
||||
clone_repo $RUSTFMT_REPO $1
|
||||
git remote add feature $REMOTE_REPO
|
||||
git fetch feature $FEATURE_BRANCH
|
||||
|
||||
cargo build --release --bin rustfmt && cp target/release/rustfmt $1/rustfmt
|
||||
if [ -z "$OPTIONAL_COMMIT_HASH" ]; then
|
||||
git switch $FEATURE_BRANCH
|
||||
else
|
||||
git switch $OPTIONAL_COMMIT_HASH --detach
|
||||
fi
|
||||
cargo build --release --bin rustfmt && cp target/release/rustfmt $1/feature_rustfmt
|
||||
RUSFMT_BIN=$1/rustfmt
|
||||
FEATURE_BIN=$1/feature_rustfmt
|
||||
}
|
||||
|
||||
# Check the diff for running rustfmt and the feature branch on all the .rs files in the repo.
|
||||
#
|
||||
# Parameters
|
||||
# $1: Clone URL for the repo
|
||||
# $2: Name of the repo (mostly used for logging)
|
||||
# $3: Path to any submodules that should be initialized
|
||||
function check_repo() {
|
||||
WORKDIR=$(pwd)
|
||||
REPO_URL=$1
|
||||
REPO_NAME=$2
|
||||
SUBMODULES=$3
|
||||
|
||||
local tmp_dir;
|
||||
tmp_dir=$(mktemp -d -t $REPO_NAME-XXXXXXXX)
|
||||
clone_repo $REPO_URL $tmp_dir
|
||||
|
||||
if [ ! -z "$SUBMODULES" ]; then
|
||||
init_submodules $SUBMODULES
|
||||
fi
|
||||
|
||||
check_diff $REPO_NAME
|
||||
# append the status of running `check_diff` to the STATUSES array
|
||||
STATUSES+=($?)
|
||||
|
||||
echo "removing tmp_dir $tmp_dir"
|
||||
rm -rf $tmp_dir
|
||||
cd $WORKDIR
|
||||
}
|
||||
|
||||
function main() {
|
||||
tmp_dir=$(mktemp -d -t rustfmt-XXXXXXXX)
|
||||
echo Created tmp_dir $tmp_dir
|
||||
|
||||
compile_rustfmt $tmp_dir
|
||||
|
||||
# run checks
|
||||
check_repo "https://github.com/rust-lang/rust.git" rust-lang-rust
|
||||
check_repo "https://github.com/rust-lang/cargo.git" cargo
|
||||
check_repo "https://github.com/rust-lang/miri.git" miri
|
||||
check_repo "https://github.com/rust-lang/rust-analyzer.git" rust-analyzer
|
||||
check_repo "https://github.com/bitflags/bitflags.git" bitflags
|
||||
check_repo "https://github.com/rust-lang/log.git" log
|
||||
check_repo "https://github.com/rust-lang/mdBook.git" mdBook
|
||||
check_repo "https://github.com/rust-lang/packed_simd.git" packed_simd
|
||||
check_repo "https://github.com/rust-lang/rust-semverver.git" check_repo
|
||||
check_repo "https://github.com/Stebalien/tempfile.git" tempfile
|
||||
check_repo "https://github.com/rust-lang/futures-rs.git" futures-rs
|
||||
check_repo "https://github.com/dtolnay/anyhow.git" anyhow
|
||||
check_repo "https://github.com/dtolnay/thiserror.git" thiserror
|
||||
check_repo "https://github.com/dtolnay/syn.git" syn
|
||||
check_repo "https://github.com/serde-rs/serde.git" serde
|
||||
check_repo "https://github.com/rust-lang/rustlings.git" rustlings
|
||||
check_repo "https://github.com/rust-lang/rustup.git" rustup
|
||||
check_repo "https://github.com/SergioBenitez/Rocket.git" Rocket
|
||||
check_repo "https://github.com/rustls/rustls.git" rustls
|
||||
check_repo "https://github.com/rust-lang/rust-bindgen.git" rust-bindgen
|
||||
check_repo "https://github.com/hyperium/hyper.git" hyper
|
||||
check_repo "https://github.com/actix/actix.git" actix
|
||||
check_repo "https://github.com/denoland/deno.git" denoland_deno
|
||||
|
||||
# cleanup temp dir
|
||||
echo removing tmp_dir $tmp_dir
|
||||
rm -rf $tmp_dir
|
||||
|
||||
# figure out the exit code
|
||||
for status in ${STATUSES[@]}
|
||||
do
|
||||
if [ $status -eq 1 ]; then
|
||||
echo "formatting diff found 💔"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "no diff found 😊"
|
||||
}
|
||||
|
||||
main
|
|
@ -91,14 +91,28 @@ case ${INTEGRATION} in
|
|||
cd -
|
||||
;;
|
||||
crater)
|
||||
git clone --depth=1 https://github.com/rust-lang-nursery/${INTEGRATION}.git
|
||||
git clone --depth=1 https://github.com/rust-lang/${INTEGRATION}.git
|
||||
cd ${INTEGRATION}
|
||||
show_head
|
||||
check_fmt_with_lib_tests
|
||||
cd -
|
||||
;;
|
||||
bitflags)
|
||||
git clone --depth=1 https://github.com/bitflags/${INTEGRATION}.git
|
||||
cd ${INTEGRATION}
|
||||
show_head
|
||||
check_fmt_with_all_tests
|
||||
cd -
|
||||
;;
|
||||
error-chain | tempdir)
|
||||
git clone --depth=1 https://github.com/rust-lang-deprecated/${INTEGRATION}.git
|
||||
cd ${INTEGRATION}
|
||||
show_head
|
||||
check_fmt_with_all_tests
|
||||
cd -
|
||||
;;
|
||||
*)
|
||||
git clone --depth=1 https://github.com/rust-lang-nursery/${INTEGRATION}.git
|
||||
git clone --depth=1 https://github.com/rust-lang/${INTEGRATION}.git
|
||||
cd ${INTEGRATION}
|
||||
show_head
|
||||
check_fmt_with_all_tests
|
||||
|
|
|
@ -22,7 +22,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustfmt-config_proc_macro"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rustfmt-config_proc_macro"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2018"
|
||||
description = "A collection of procedural macros for rustfmt"
|
||||
license = "Apache-2.0/MIT"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
//! 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.
|
||||
//! of `config_type` enum. Currently there are the following attributes
|
||||
//! that could appear on the variants of `config_type` enum:
|
||||
//!
|
||||
//! - `doc_hint`: name-value pair whose value is string literal
|
||||
//! - `value`: name-value pair whose value is string literal
|
||||
//! - `unstable_variant`: name only
|
||||
|
||||
/// Returns the value of the first `doc_hint` attribute in the given slice or
|
||||
/// `None` if `doc_hint` attribute is not available.
|
||||
|
@ -27,6 +29,11 @@ pub fn find_config_value(attrs: &[syn::Attribute]) -> Option<String> {
|
|||
attrs.iter().filter_map(config_value).next()
|
||||
}
|
||||
|
||||
/// Returns `true` if the there is at least one `unstable` attribute in the given slice.
|
||||
pub fn any_unstable_variant(attrs: &[syn::Attribute]) -> bool {
|
||||
attrs.iter().any(is_unstable_variant)
|
||||
}
|
||||
|
||||
/// Returns a string literal value if the given attribute is `value`
|
||||
/// attribute or `None` otherwise.
|
||||
pub fn config_value(attr: &syn::Attribute) -> Option<String> {
|
||||
|
@ -38,6 +45,11 @@ pub fn is_config_value(attr: &syn::Attribute) -> bool {
|
|||
is_attr_name_value(attr, "value")
|
||||
}
|
||||
|
||||
/// Returns `true` if the given attribute is an `unstable` attribute.
|
||||
pub fn is_unstable_variant(attr: &syn::Attribute) -> bool {
|
||||
is_attr_path(attr, "unstable_variant")
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -45,6 +57,13 @@ fn is_attr_name_value(attr: &syn::Attribute, name: &str) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
fn is_attr_path(attr: &syn::Attribute, name: &str) -> bool {
|
||||
attr.parse_meta().ok().map_or(false, |meta| match meta {
|
||||
syn::Meta::Path(path) if path.is_ident(name) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option<String> {
|
||||
attr.parse_meta().ok().and_then(|meta| match meta {
|
||||
syn::Meta::NameValue(syn::MetaNameValue {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
use crate::attrs::*;
|
||||
use crate::utils::*;
|
||||
|
@ -47,12 +48,23 @@ fn process_variant(variant: &syn::Variant) -> TokenStream {
|
|||
let metas = variant
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| !is_doc_hint(attr) && !is_config_value(attr));
|
||||
.filter(|attr| !is_doc_hint(attr) && !is_config_value(attr) && !is_unstable_variant(attr));
|
||||
let attrs = fold_quote(metas, |meta| quote!(#meta));
|
||||
let syn::Variant { ident, fields, .. } = variant;
|
||||
quote!(#attrs #ident #fields)
|
||||
}
|
||||
|
||||
/// Return the correct syntax to pattern match on the enum variant, discarding all
|
||||
/// internal field data.
|
||||
fn fields_in_variant(variant: &syn::Variant) -> TokenStream {
|
||||
// With thanks to https://stackoverflow.com/a/65182902
|
||||
match &variant.fields {
|
||||
syn::Fields::Unnamed(_) => quote_spanned! { variant.span() => (..) },
|
||||
syn::Fields::Unit => quote_spanned! { variant.span() => },
|
||||
syn::Fields::Named(_) => quote_spanned! { variant.span() => {..} },
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream {
|
||||
let doc_hint = variants
|
||||
.iter()
|
||||
|
@ -60,12 +72,26 @@ fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream {
|
|||
.collect::<Vec<_>>()
|
||||
.join("|");
|
||||
let doc_hint = format!("[{}]", doc_hint);
|
||||
|
||||
let variant_stables = variants
|
||||
.iter()
|
||||
.map(|v| (&v.ident, fields_in_variant(&v), !unstable_of_variant(v)));
|
||||
let match_patterns = fold_quote(variant_stables, |(v, fields, stable)| {
|
||||
quote! {
|
||||
#ident::#v #fields => #stable,
|
||||
}
|
||||
});
|
||||
quote! {
|
||||
use crate::config::ConfigType;
|
||||
impl ConfigType for #ident {
|
||||
fn doc_hint() -> String {
|
||||
#doc_hint.to_owned()
|
||||
}
|
||||
fn stable_variant(&self) -> bool {
|
||||
match self {
|
||||
#match_patterns
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,13 +149,21 @@ fn impl_from_str(ident: &syn::Ident, variants: &Variants) -> TokenStream {
|
|||
}
|
||||
|
||||
fn doc_hint_of_variant(variant: &syn::Variant) -> String {
|
||||
find_doc_hint(&variant.attrs).unwrap_or(variant.ident.to_string())
|
||||
let mut text = find_doc_hint(&variant.attrs).unwrap_or(variant.ident.to_string());
|
||||
if unstable_of_variant(&variant) {
|
||||
text.push_str(" (unstable)")
|
||||
};
|
||||
text
|
||||
}
|
||||
|
||||
fn config_value_of_variant(variant: &syn::Variant) -> String {
|
||||
find_config_value(&variant.attrs).unwrap_or(variant.ident.to_string())
|
||||
}
|
||||
|
||||
fn unstable_of_variant(variant: &syn::Variant) -> bool {
|
||||
any_unstable_variant(&variant.attrs)
|
||||
}
|
||||
|
||||
fn impl_serde(ident: &syn::Ident, variants: &Variants) -> TokenStream {
|
||||
let arms = fold_quote(variants.iter(), |v| {
|
||||
let v_ident = &v.ident;
|
||||
|
|
|
@ -69,3 +69,16 @@ pub fn stable_only_test(_args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
TokenStream::from_str("").unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to conditionally output the TokenStream for tests that should be run as part of rustfmts
|
||||
/// test suite, but should be ignored when running in the rust-lang/rust test suite.
|
||||
#[proc_macro_attribute]
|
||||
pub fn rustfmt_only_ci_test(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
if option_env!("RUSTFMT_CI").is_some() {
|
||||
input
|
||||
} else {
|
||||
let mut token_stream = TokenStream::from_str("#[ignore]").unwrap();
|
||||
token_stream.extend(input);
|
||||
token_stream
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
pub mod config {
|
||||
pub trait ConfigType: Sized {
|
||||
fn doc_hint() -> String;
|
||||
fn stable_variant(&self) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2022-06-21"
|
||||
components = ["rustc-dev"]
|
||||
channel = "nightly-2023-01-24"
|
||||
components = ["llvm-tools", "rustc-dev"]
|
||||
|
|
|
@ -336,7 +336,7 @@ impl Rewrite for ast::Attribute {
|
|||
} else {
|
||||
let should_skip = self
|
||||
.ident()
|
||||
.map(|s| context.skip_context.skip_attribute(s.name.as_str()))
|
||||
.map(|s| context.skip_context.attributes.skip(s.name.as_str()))
|
||||
.unwrap_or(false);
|
||||
let prefix = attr_prefix(self);
|
||||
|
||||
|
@ -390,7 +390,7 @@ impl Rewrite for [ast::Attribute] {
|
|||
|
||||
// Determine if the source text is annotated with `#[rustfmt::skip::attributes(derive)]`
|
||||
// or `#![rustfmt::skip::attributes(derive)]`
|
||||
let skip_derives = context.skip_context.skip_attribute("derive");
|
||||
let skip_derives = context.skip_context.attributes.skip("derive");
|
||||
|
||||
// This is not just a simple map because we need to handle doc comments
|
||||
// (where we take as many doc comment attributes as possible) and possibly
|
||||
|
|
|
@ -136,7 +136,7 @@ fn make_opts() -> Options {
|
|||
"l",
|
||||
"files-with-diff",
|
||||
"Prints the names of mismatched files that were formatted. Prints the names of \
|
||||
files that would be formated when used with `--check` mode. ",
|
||||
files that would be formatted when used with `--check` mode. ",
|
||||
);
|
||||
opts.optmulti(
|
||||
"",
|
||||
|
|
|
@ -198,12 +198,10 @@ fn convert_message_format_to_rustfmt_args(
|
|||
Ok(())
|
||||
}
|
||||
"human" => Ok(()),
|
||||
_ => {
|
||||
return Err(format!(
|
||||
"invalid --message-format value: {}. Allowed values are: short|json|human",
|
||||
message_format
|
||||
));
|
||||
}
|
||||
_ => Err(format!(
|
||||
"invalid --message-format value: {}. Allowed values are: short|json|human",
|
||||
message_format
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +213,7 @@ fn print_usage_to_stderr(reason: &str) {
|
|||
.expect("failed to write to stderr");
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Verbosity {
|
||||
Verbose,
|
||||
Normal,
|
||||
|
|
|
@ -70,9 +70,9 @@ fn mandatory_separator() {
|
|||
.is_err()
|
||||
);
|
||||
assert!(
|
||||
!Opts::command()
|
||||
Opts::command()
|
||||
.try_get_matches_from(&["test", "--", "--emit"])
|
||||
.is_err()
|
||||
.is_ok()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,10 +70,64 @@ use crate::rewrite::{Rewrite, RewriteContext};
|
|||
use crate::shape::Shape;
|
||||
use crate::source_map::SpanUtils;
|
||||
use crate::utils::{
|
||||
self, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident,
|
||||
trimmed_last_line_width, wrap_str,
|
||||
self, filtered_str_fits, first_line_width, last_line_extendable, last_line_width, mk_sp,
|
||||
rewrite_ident, trimmed_last_line_width, wrap_str,
|
||||
};
|
||||
|
||||
/// Provides the original input contents from the span
|
||||
/// of a chain element with trailing spaces trimmed.
|
||||
fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option<String> {
|
||||
context.snippet_provider.span_to_snippet(span).map(|s| {
|
||||
s.lines()
|
||||
.map(|l| l.trim_end())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
})
|
||||
}
|
||||
|
||||
fn format_chain_item(
|
||||
item: &ChainItem,
|
||||
context: &RewriteContext<'_>,
|
||||
rewrite_shape: Shape,
|
||||
allow_overflow: bool,
|
||||
) -> Option<String> {
|
||||
if allow_overflow {
|
||||
item.rewrite(context, rewrite_shape)
|
||||
.or_else(|| format_overflow_style(item.span, context))
|
||||
} else {
|
||||
item.rewrite(context, rewrite_shape)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_block_child_shape(
|
||||
prev_ends_with_block: bool,
|
||||
context: &RewriteContext<'_>,
|
||||
shape: Shape,
|
||||
) -> Shape {
|
||||
if prev_ends_with_block {
|
||||
shape.block_indent(0)
|
||||
} else {
|
||||
shape.block_indent(context.config.tab_spaces())
|
||||
}
|
||||
.with_max_width(context.config)
|
||||
}
|
||||
|
||||
fn get_visual_style_child_shape(
|
||||
context: &RewriteContext<'_>,
|
||||
shape: Shape,
|
||||
offset: usize,
|
||||
parent_overflowing: bool,
|
||||
) -> Option<Shape> {
|
||||
if !parent_overflowing {
|
||||
shape
|
||||
.with_max_width(context.config)
|
||||
.offset_left(offset)
|
||||
.map(|s| s.visual_indent(0))
|
||||
} else {
|
||||
Some(shape.visual_indent(offset))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rewrite_chain(
|
||||
expr: &ast::Expr,
|
||||
context: &RewriteContext<'_>,
|
||||
|
@ -496,6 +550,8 @@ struct ChainFormatterShared<'a> {
|
|||
// The number of children in the chain. This is not equal to `self.children.len()`
|
||||
// because `self.children` will change size as we process the chain.
|
||||
child_count: usize,
|
||||
// Whether elements are allowed to overflow past the max_width limit
|
||||
allow_overflow: bool,
|
||||
}
|
||||
|
||||
impl<'a> ChainFormatterShared<'a> {
|
||||
|
@ -505,6 +561,8 @@ impl<'a> ChainFormatterShared<'a> {
|
|||
rewrites: Vec::with_capacity(chain.children.len() + 1),
|
||||
fits_single_line: false,
|
||||
child_count: chain.children.len(),
|
||||
// TODO(calebcartwright)
|
||||
allow_overflow: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,6 +575,14 @@ impl<'a> ChainFormatterShared<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
|
||||
for item in &self.children[..self.children.len() - 1] {
|
||||
let rewrite = format_chain_item(item, context, child_shape, self.allow_overflow)?;
|
||||
self.rewrites.push(rewrite);
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
// Rewrite the last child. The last child of a chain requires special treatment. We need to
|
||||
// know whether 'overflowing' the last child make a better formatting:
|
||||
//
|
||||
|
@ -729,22 +795,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
|
|||
}
|
||||
|
||||
fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape> {
|
||||
Some(
|
||||
if self.root_ends_with_block {
|
||||
shape.block_indent(0)
|
||||
} else {
|
||||
shape.block_indent(context.config.tab_spaces())
|
||||
}
|
||||
.with_max_width(context.config),
|
||||
)
|
||||
let block_end = self.root_ends_with_block;
|
||||
Some(get_block_child_shape(block_end, context, shape))
|
||||
}
|
||||
|
||||
fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
|
||||
for item in &self.shared.children[..self.shared.children.len() - 1] {
|
||||
let rewrite = item.rewrite(context, child_shape)?;
|
||||
self.shared.rewrites.push(rewrite);
|
||||
}
|
||||
Some(())
|
||||
self.shared.format_children(context, child_shape)
|
||||
}
|
||||
|
||||
fn format_last_child(
|
||||
|
@ -808,15 +864,14 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
|
|||
.visual_indent(self.offset)
|
||||
.sub_width(self.offset)?;
|
||||
let rewrite = item.rewrite(context, child_shape)?;
|
||||
match wrap_str(rewrite, context.config.max_width(), shape) {
|
||||
Some(rewrite) => root_rewrite.push_str(&rewrite),
|
||||
None => {
|
||||
// We couldn't fit in at the visual indent, try the last
|
||||
// indent.
|
||||
let rewrite = item.rewrite(context, parent_shape)?;
|
||||
root_rewrite.push_str(&rewrite);
|
||||
self.offset = 0;
|
||||
}
|
||||
if filtered_str_fits(&rewrite, context.config.max_width(), shape) {
|
||||
root_rewrite.push_str(&rewrite);
|
||||
} else {
|
||||
// We couldn't fit in at the visual indent, try the last
|
||||
// indent.
|
||||
let rewrite = item.rewrite(context, parent_shape)?;
|
||||
root_rewrite.push_str(&rewrite);
|
||||
self.offset = 0;
|
||||
}
|
||||
|
||||
self.shared.children = &self.shared.children[1..];
|
||||
|
@ -827,18 +882,17 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
|
|||
}
|
||||
|
||||
fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape> {
|
||||
shape
|
||||
.with_max_width(context.config)
|
||||
.offset_left(self.offset)
|
||||
.map(|s| s.visual_indent(0))
|
||||
get_visual_style_child_shape(
|
||||
context,
|
||||
shape,
|
||||
self.offset,
|
||||
// TODO(calebcartwright): self.shared.permissibly_overflowing_parent,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
|
||||
for item in &self.shared.children[..self.shared.children.len() - 1] {
|
||||
let rewrite = item.rewrite(context, child_shape)?;
|
||||
self.shared.rewrites.push(rewrite);
|
||||
}
|
||||
Some(())
|
||||
self.shared.format_children(context, child_shape)
|
||||
}
|
||||
|
||||
fn format_last_child(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::config::file_lines::FileLines;
|
||||
use crate::config::macro_names::MacroSelectors;
|
||||
use crate::config::options::{IgnoreList, WidthHeuristics};
|
||||
|
||||
/// Trait for types that can be used in `Config`.
|
||||
|
@ -6,6 +7,14 @@ pub(crate) trait ConfigType: Sized {
|
|||
/// Returns hint text for use in `Config::print_docs()`. For enum types, this is a
|
||||
/// pipe-separated list of variants; for other types it returns `<type>`.
|
||||
fn doc_hint() -> String;
|
||||
|
||||
/// Return `true` if the variant (i.e. value of this type) is stable.
|
||||
///
|
||||
/// By default, return true for all values. Enums annotated with `#[config_type]`
|
||||
/// are automatically implemented, based on the `#[unstable_variant]` annotation.
|
||||
fn stable_variant(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigType for bool {
|
||||
|
@ -38,6 +47,12 @@ impl ConfigType for FileLines {
|
|||
}
|
||||
}
|
||||
|
||||
impl ConfigType for MacroSelectors {
|
||||
fn doc_hint() -> String {
|
||||
String::from("[<string>, ...]")
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigType for WidthHeuristics {
|
||||
fn doc_hint() -> String {
|
||||
String::new()
|
||||
|
@ -51,6 +66,13 @@ impl ConfigType for IgnoreList {
|
|||
}
|
||||
|
||||
macro_rules! create_config {
|
||||
// Options passed in to the macro.
|
||||
//
|
||||
// - $i: the ident name of the option
|
||||
// - $ty: the type of the option value
|
||||
// - $def: the default value of the option
|
||||
// - $stb: true if the option is stable
|
||||
// - $dstring: description of the option
|
||||
($($i:ident: $ty:ty, $def:expr, $stb:expr, $( $dstring:expr ),+ );+ $(;)*) => (
|
||||
#[cfg(test)]
|
||||
use std::collections::HashSet;
|
||||
|
@ -61,9 +83,12 @@ macro_rules! create_config {
|
|||
#[derive(Clone)]
|
||||
#[allow(unreachable_pub)]
|
||||
pub struct Config {
|
||||
// For each config item, we store a bool indicating whether it has
|
||||
// been accessed and the value, and a bool whether the option was
|
||||
// manually initialised, or taken from the default,
|
||||
// For each config item, we store:
|
||||
//
|
||||
// - 0: true if the value has been access
|
||||
// - 1: true if the option was manually initialized
|
||||
// - 2: the option value
|
||||
// - 3: true if the option is unstable
|
||||
$($i: (Cell<bool>, bool, $ty, bool)),+
|
||||
}
|
||||
|
||||
|
@ -102,6 +127,7 @@ macro_rules! create_config {
|
|||
| "array_width"
|
||||
| "chain_width" => self.0.set_heuristics(),
|
||||
"merge_imports" => self.0.set_merge_imports(),
|
||||
"fn_args_layout" => self.0.set_fn_args_layout(),
|
||||
&_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -143,24 +169,20 @@ macro_rules! create_config {
|
|||
|
||||
fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
|
||||
$(
|
||||
if let Some(val) = parsed.$i {
|
||||
if self.$i.3 {
|
||||
if let Some(option_value) = parsed.$i {
|
||||
let option_stable = self.$i.3;
|
||||
if $crate::config::config_type::is_stable_option_and_value(
|
||||
stringify!($i), option_stable, &option_value
|
||||
) {
|
||||
self.$i.1 = true;
|
||||
self.$i.2 = val;
|
||||
} else {
|
||||
if crate::is_nightly_channel!() {
|
||||
self.$i.1 = true;
|
||||
self.$i.2 = val;
|
||||
} else {
|
||||
eprintln!("Warning: can't set `{} = {:?}`, unstable features are only \
|
||||
available in nightly channel.", stringify!($i), val);
|
||||
}
|
||||
self.$i.2 = option_value;
|
||||
}
|
||||
}
|
||||
)+
|
||||
self.set_heuristics();
|
||||
self.set_ignore(dir);
|
||||
self.set_merge_imports();
|
||||
self.set_fn_args_layout();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -221,12 +243,22 @@ macro_rules! create_config {
|
|||
match key {
|
||||
$(
|
||||
stringify!($i) => {
|
||||
self.$i.1 = true;
|
||||
self.$i.2 = val.parse::<$ty>()
|
||||
let option_value = val.parse::<$ty>()
|
||||
.expect(&format!("Failed to parse override for {} (\"{}\") as a {}",
|
||||
stringify!($i),
|
||||
val,
|
||||
stringify!($ty)));
|
||||
|
||||
// Users are currently allowed to set unstable
|
||||
// options/variants via the `--config` options override.
|
||||
//
|
||||
// There is ongoing discussion about how to move forward here:
|
||||
// https://github.com/rust-lang/rustfmt/pull/5379
|
||||
//
|
||||
// For now, do not validate whether the option or value is stable,
|
||||
// just always set it.
|
||||
self.$i.1 = true;
|
||||
self.$i.2 = option_value;
|
||||
}
|
||||
)+
|
||||
_ => panic!("Unknown config key in override: {}", key)
|
||||
|
@ -243,14 +275,21 @@ macro_rules! create_config {
|
|||
| "array_width"
|
||||
| "chain_width" => self.set_heuristics(),
|
||||
"merge_imports" => self.set_merge_imports(),
|
||||
"fn_args_layout" => self.set_fn_args_layout(),
|
||||
&_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_pub)]
|
||||
pub fn is_hidden_option(name: &str) -> bool {
|
||||
const HIDE_OPTIONS: [&str; 5] =
|
||||
["verbose", "verbose_diff", "file_lines", "width_heuristics", "merge_imports"];
|
||||
const HIDE_OPTIONS: [&str; 6] = [
|
||||
"verbose",
|
||||
"verbose_diff",
|
||||
"file_lines",
|
||||
"width_heuristics",
|
||||
"merge_imports",
|
||||
"fn_args_layout"
|
||||
];
|
||||
HIDE_OPTIONS.contains(&name)
|
||||
}
|
||||
|
||||
|
@ -400,6 +439,18 @@ macro_rules! create_config {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_fn_args_layout(&mut self) {
|
||||
if self.was_set().fn_args_layout() {
|
||||
eprintln!(
|
||||
"Warning: the `fn_args_layout` option is deprecated. \
|
||||
Use `fn_params_layout`. instead"
|
||||
);
|
||||
if !self.was_set().fn_params_layout() {
|
||||
self.fn_params_layout.2 = self.fn_args_layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_pub)]
|
||||
/// Returns `true` if the config key was explicitly set and is the default value.
|
||||
pub fn is_default(&self, key: &str) -> bool {
|
||||
|
@ -424,3 +475,38 @@ macro_rules! create_config {
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn is_stable_option_and_value<T>(
|
||||
option_name: &str,
|
||||
option_stable: bool,
|
||||
option_value: &T,
|
||||
) -> bool
|
||||
where
|
||||
T: PartialEq + std::fmt::Debug + ConfigType,
|
||||
{
|
||||
let nightly = crate::is_nightly_channel!();
|
||||
let variant_stable = option_value.stable_variant();
|
||||
match (nightly, option_stable, variant_stable) {
|
||||
// Stable with an unstable option
|
||||
(false, false, _) => {
|
||||
eprintln!(
|
||||
"Warning: can't set `{} = {:?}`, unstable features are only \
|
||||
available in nightly channel.",
|
||||
option_name, option_value
|
||||
);
|
||||
false
|
||||
}
|
||||
// Stable with a stable option, but an unstable variant
|
||||
(false, true, false) => {
|
||||
eprintln!(
|
||||
"Warning: can't set `{} = {:?}`, unstable variants are only \
|
||||
available in nightly channel.",
|
||||
option_name, option_value
|
||||
);
|
||||
false
|
||||
}
|
||||
// Nightly: everything allowed
|
||||
// Stable with stable option and variant: allowed
|
||||
(true, _, _) | (false, true, true) => true,
|
||||
}
|
||||
}
|
||||
|
|
118
src/tools/rustfmt/src/config/macro_names.rs
Normal file
118
src/tools/rustfmt/src/config/macro_names.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
//! This module contains types and functions to support formatting specific macros.
|
||||
|
||||
use itertools::Itertools;
|
||||
use std::{fmt, str};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json as json;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Defines the name of a macro.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
pub struct MacroName(String);
|
||||
|
||||
impl MacroName {
|
||||
pub fn new(other: String) -> Self {
|
||||
Self(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MacroName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MacroName> for String {
|
||||
fn from(other: MacroName) -> Self {
|
||||
other.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a selector to match against a macro.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
|
||||
pub enum MacroSelector {
|
||||
Name(MacroName),
|
||||
All,
|
||||
}
|
||||
|
||||
impl fmt::Display for MacroSelector {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Name(name) => name.fmt(f),
|
||||
Self::All => write!(f, "*"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for MacroSelector {
|
||||
type Err = std::convert::Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"*" => MacroSelector::All,
|
||||
name => MacroSelector::Name(MacroName(name.to_owned())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of macro selectors.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
|
||||
pub struct MacroSelectors(pub Vec<MacroSelector>);
|
||||
|
||||
impl fmt::Display for MacroSelectors {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0.iter().format(", "))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MacroSelectorsError {
|
||||
#[error("{0}")]
|
||||
Json(json::Error),
|
||||
}
|
||||
|
||||
// This impl is needed for `Config::override_value` to work for use in tests.
|
||||
impl str::FromStr for MacroSelectors {
|
||||
type Err = MacroSelectorsError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let raw: Vec<&str> = json::from_str(s).map_err(MacroSelectorsError::Json)?;
|
||||
Ok(Self(
|
||||
raw.into_iter()
|
||||
.map(|raw| {
|
||||
MacroSelector::from_str(raw).expect("MacroSelector from_str is infallible")
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn macro_names_from_str() {
|
||||
let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
|
||||
assert_eq!(
|
||||
macro_names,
|
||||
MacroSelectors(
|
||||
[
|
||||
MacroSelector::Name(MacroName("foo".to_owned())),
|
||||
MacroSelector::All,
|
||||
MacroSelector::Name(MacroName("bar".to_owned()))
|
||||
]
|
||||
.into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_names_display() {
|
||||
let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
|
||||
assert_eq!(format!("{}", macro_names), "foo, *, bar");
|
||||
}
|
||||
}
|
|
@ -13,15 +13,20 @@ pub use crate::config::file_lines::{FileLines, FileName, Range};
|
|||
#[allow(unreachable_pub)]
|
||||
pub use crate::config::lists::*;
|
||||
#[allow(unreachable_pub)]
|
||||
pub use crate::config::macro_names::{MacroSelector, MacroSelectors};
|
||||
#[allow(unreachable_pub)]
|
||||
pub use crate::config::options::*;
|
||||
|
||||
#[macro_use]
|
||||
pub(crate) mod config_type;
|
||||
#[macro_use]
|
||||
#[allow(unreachable_pub)]
|
||||
pub(crate) mod options;
|
||||
|
||||
pub(crate) mod file_lines;
|
||||
#[allow(unreachable_pub)]
|
||||
pub(crate) mod lists;
|
||||
pub(crate) mod macro_names;
|
||||
|
||||
// This macro defines configuration options used in rustfmt. Each option
|
||||
// is defined as follows:
|
||||
|
@ -67,6 +72,8 @@ create_config! {
|
|||
format_macro_matchers: bool, false, false,
|
||||
"Format the metavariable matching patterns in macros";
|
||||
format_macro_bodies: bool, true, false, "Format the bodies of macros";
|
||||
skip_macro_invocations: MacroSelectors, MacroSelectors::default(), false,
|
||||
"Skip formatting the bodies of macros invoked with the following names.";
|
||||
hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false,
|
||||
"Format hexadecimal integer literals";
|
||||
|
||||
|
@ -119,7 +126,9 @@ create_config! {
|
|||
force_multiline_blocks: bool, false, false,
|
||||
"Force multiline closure bodies and match arms to be wrapped in a block";
|
||||
fn_args_layout: Density, Density::Tall, true,
|
||||
"Control the layout of arguments in a function";
|
||||
"(deprecated: use fn_params_layout instead)";
|
||||
fn_params_layout: Density, Density::Tall, true,
|
||||
"Control the layout of parameters in function signatures.";
|
||||
brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
|
||||
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
|
||||
"Brace style for control flow constructs";
|
||||
|
@ -175,7 +184,7 @@ create_config! {
|
|||
make_backup: bool, false, false, "Backup changed files";
|
||||
print_misformatted_file_names: bool, false, true,
|
||||
"Prints the names of mismatched files that were formatted. Prints the names of \
|
||||
files that would be formated when used with `--check` mode. ";
|
||||
files that would be formatted when used with `--check` mode. ";
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -191,6 +200,7 @@ impl PartialConfig {
|
|||
cloned.width_heuristics = None;
|
||||
cloned.print_misformatted_file_names = None;
|
||||
cloned.merge_imports = None;
|
||||
cloned.fn_args_layout = None;
|
||||
|
||||
::toml::to_string(&cloned).map_err(ToTomlError)
|
||||
}
|
||||
|
@ -403,11 +413,21 @@ mod test {
|
|||
use super::*;
|
||||
use std::str;
|
||||
|
||||
use crate::config::macro_names::MacroName;
|
||||
use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test};
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod mock {
|
||||
use super::super::*;
|
||||
use rustfmt_config_proc_macro::config_type;
|
||||
|
||||
#[config_type]
|
||||
pub(crate) enum PartiallyUnstableOption {
|
||||
V1,
|
||||
V2,
|
||||
#[unstable_variant]
|
||||
V3,
|
||||
}
|
||||
|
||||
create_config! {
|
||||
// Options that are used by the generated functions
|
||||
|
@ -427,6 +447,12 @@ mod test {
|
|||
"Merge imports";
|
||||
merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
|
||||
|
||||
// fn_args_layout renamed to fn_params_layout
|
||||
fn_args_layout: Density, Density::Tall, true,
|
||||
"(deprecated: use fn_params_layout instead)";
|
||||
fn_params_layout: Density, Density::Tall, true,
|
||||
"Control the layout of parameters in a function signatures.";
|
||||
|
||||
// Width Heuristics
|
||||
use_small_heuristics: Heuristics, Heuristics::Default, true,
|
||||
"Whether to use different formatting for items and \
|
||||
|
@ -451,6 +477,63 @@ mod test {
|
|||
// Options that are used by the tests
|
||||
stable_option: bool, false, true, "A stable option";
|
||||
unstable_option: bool, false, false, "An unstable option";
|
||||
partially_unstable_option: PartiallyUnstableOption, PartiallyUnstableOption::V1, true,
|
||||
"A partially unstable option";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod partially_unstable_option {
|
||||
use super::{Config, PartialConfig, PartiallyUnstableOption};
|
||||
use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test};
|
||||
use std::path::Path;
|
||||
|
||||
/// From the config file, we can fill with a stable variant
|
||||
#[test]
|
||||
fn test_from_toml_stable_value() {
|
||||
let toml = r#"
|
||||
partially_unstable_option = "V2"
|
||||
"#;
|
||||
let partial_config: PartialConfig = toml::from_str(toml).unwrap();
|
||||
let config = Config::default();
|
||||
let config = config.fill_from_parsed_config(partial_config, Path::new(""));
|
||||
assert_eq!(
|
||||
config.partially_unstable_option(),
|
||||
PartiallyUnstableOption::V2
|
||||
);
|
||||
}
|
||||
|
||||
/// From the config file, we cannot fill with an unstable variant (stable only)
|
||||
#[stable_only_test]
|
||||
#[test]
|
||||
fn test_from_toml_unstable_value_on_stable() {
|
||||
let toml = r#"
|
||||
partially_unstable_option = "V3"
|
||||
"#;
|
||||
let partial_config: PartialConfig = toml::from_str(toml).unwrap();
|
||||
let config = Config::default();
|
||||
let config = config.fill_from_parsed_config(partial_config, Path::new(""));
|
||||
assert_eq!(
|
||||
config.partially_unstable_option(),
|
||||
// default value from config, i.e. fill failed
|
||||
PartiallyUnstableOption::V1
|
||||
);
|
||||
}
|
||||
|
||||
/// From the config file, we can fill with an unstable variant (nightly only)
|
||||
#[nightly_only_test]
|
||||
#[test]
|
||||
fn test_from_toml_unstable_value_on_nightly() {
|
||||
let toml = r#"
|
||||
partially_unstable_option = "V3"
|
||||
"#;
|
||||
let partial_config: PartialConfig = toml::from_str(toml).unwrap();
|
||||
let config = Config::default();
|
||||
let config = config.fill_from_parsed_config(partial_config, Path::new(""));
|
||||
assert_eq!(
|
||||
config.partially_unstable_option(),
|
||||
PartiallyUnstableOption::V3
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,6 +572,11 @@ mod test {
|
|||
assert_eq!(config.was_set().verbose(), false);
|
||||
}
|
||||
|
||||
const PRINT_DOCS_STABLE_OPTION: &str = "stable_option <boolean> Default: false";
|
||||
const PRINT_DOCS_UNSTABLE_OPTION: &str = "unstable_option <boolean> Default: false (unstable)";
|
||||
const PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION: &str =
|
||||
"partially_unstable_option [V1|V2|V3 (unstable)] Default: V1";
|
||||
|
||||
#[test]
|
||||
fn test_print_docs_exclude_unstable() {
|
||||
use self::mock::Config;
|
||||
|
@ -497,10 +585,9 @@ mod test {
|
|||
Config::print_docs(&mut output, false);
|
||||
|
||||
let s = str::from_utf8(&output).unwrap();
|
||||
|
||||
assert_eq!(s.contains("stable_option"), true);
|
||||
assert_eq!(s.contains("unstable_option"), false);
|
||||
assert_eq!(s.contains("(unstable)"), false);
|
||||
assert_eq!(s.contains(PRINT_DOCS_STABLE_OPTION), true);
|
||||
assert_eq!(s.contains(PRINT_DOCS_UNSTABLE_OPTION), false);
|
||||
assert_eq!(s.contains(PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -511,9 +598,9 @@ mod test {
|
|||
Config::print_docs(&mut output, true);
|
||||
|
||||
let s = str::from_utf8(&output).unwrap();
|
||||
assert_eq!(s.contains("stable_option"), true);
|
||||
assert_eq!(s.contains("unstable_option"), true);
|
||||
assert_eq!(s.contains("(unstable)"), true);
|
||||
assert_eq!(s.contains(PRINT_DOCS_STABLE_OPTION), true);
|
||||
assert_eq!(s.contains(PRINT_DOCS_UNSTABLE_OPTION), true);
|
||||
assert_eq!(s.contains(PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -541,6 +628,7 @@ normalize_doc_attributes = false
|
|||
format_strings = false
|
||||
format_macro_matchers = false
|
||||
format_macro_bodies = true
|
||||
skip_macro_invocations = []
|
||||
hex_literal_case = "Preserve"
|
||||
empty_item_single_line = true
|
||||
struct_lit_single_line = true
|
||||
|
@ -567,7 +655,7 @@ enum_discrim_align_threshold = 0
|
|||
match_arm_blocks = true
|
||||
match_arm_leading_pipes = "Never"
|
||||
force_multiline_blocks = false
|
||||
fn_args_layout = "Tall"
|
||||
fn_params_layout = "Tall"
|
||||
brace_style = "SameLineWhere"
|
||||
control_brace_style = "AlwaysSameLine"
|
||||
trailing_semicolon = true
|
||||
|
@ -921,4 +1009,45 @@ make_backup = false
|
|||
assert_eq!(config.single_line_if_else_max_width(), 100);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod partially_unstable_option {
|
||||
use super::mock::{Config, PartiallyUnstableOption};
|
||||
use super::*;
|
||||
|
||||
/// From the command line, we can override with a stable variant.
|
||||
#[test]
|
||||
fn test_override_stable_value() {
|
||||
let mut config = Config::default();
|
||||
config.override_value("partially_unstable_option", "V2");
|
||||
assert_eq!(
|
||||
config.partially_unstable_option(),
|
||||
PartiallyUnstableOption::V2
|
||||
);
|
||||
}
|
||||
|
||||
/// From the command line, we can override with an unstable variant.
|
||||
#[test]
|
||||
fn test_override_unstable_value() {
|
||||
let mut config = Config::default();
|
||||
config.override_value("partially_unstable_option", "V3");
|
||||
assert_eq!(
|
||||
config.partially_unstable_option(),
|
||||
PartiallyUnstableOption::V3
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_override_skip_macro_invocations() {
|
||||
let mut config = Config::default();
|
||||
config.override_value("skip_macro_invocations", r#"["*", "println"]"#);
|
||||
assert_eq!(
|
||||
config.skip_macro_invocations(),
|
||||
MacroSelectors(vec![
|
||||
MacroSelector::All,
|
||||
MacroSelector::Name(MacroName::new("println".to_owned()))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ use crate::spanned::Spanned;
|
|||
use crate::string::{rewrite_string, StringFormat};
|
||||
use crate::types::{rewrite_path, PathContext};
|
||||
use crate::utils::{
|
||||
colon_spaces, contains_skip, count_newlines, first_line_ends_with, inner_attributes,
|
||||
last_line_extendable, last_line_width, mk_sp, outer_attributes, semicolon_for_expr,
|
||||
unicode_str_width, wrap_str,
|
||||
colon_spaces, contains_skip, count_newlines, filtered_str_fits, first_line_ends_with,
|
||||
inner_attributes, last_line_extendable, last_line_width, mk_sp, outer_attributes,
|
||||
semicolon_for_expr, unicode_str_width, wrap_str,
|
||||
};
|
||||
use crate::vertical::rewrite_with_alignment;
|
||||
use crate::visitor::FmtVisitor;
|
||||
|
@ -2050,8 +2050,7 @@ fn choose_rhs<R: Rewrite>(
|
|||
|
||||
match (orig_rhs, new_rhs) {
|
||||
(Some(ref orig_rhs), Some(ref new_rhs))
|
||||
if wrap_str(new_rhs.clone(), context.config.max_width(), new_shape)
|
||||
.is_none() =>
|
||||
if !filtered_str_fits(&new_rhs, context.config.max_width(), new_shape) =>
|
||||
{
|
||||
Some(format!("{}{}", before_space_str, orig_rhs))
|
||||
}
|
||||
|
|
|
@ -251,8 +251,8 @@ fn flatten_use_trees(
|
|||
use_trees: Vec<UseTree>,
|
||||
import_granularity: ImportGranularity,
|
||||
) -> Vec<UseTree> {
|
||||
// Return non-sorted single occurance of the use-trees text string;
|
||||
// order is by first occurance of the use-tree.
|
||||
// Return non-sorted single occurrence of the use-trees text string;
|
||||
// order is by first occurrence of the use-tree.
|
||||
use_trees
|
||||
.into_iter()
|
||||
.flat_map(|tree| tree.flatten(import_granularity))
|
||||
|
|
|
@ -1084,7 +1084,11 @@ pub(crate) fn format_trait(
|
|||
let item_snippet = context.snippet(item.span);
|
||||
if let Some(lo) = item_snippet.find('/') {
|
||||
// 1 = `{`
|
||||
let comment_hi = body_lo - BytePos(1);
|
||||
let comment_hi = if generics.params.len() > 0 {
|
||||
generics.span.lo() - BytePos(1)
|
||||
} else {
|
||||
body_lo - BytePos(1)
|
||||
};
|
||||
let comment_lo = item.span.lo() + BytePos(lo as u32);
|
||||
if comment_lo < comment_hi {
|
||||
match recover_missing_comment_in_span(
|
||||
|
@ -1241,7 +1245,7 @@ fn format_unit_struct(
|
|||
) -> Option<String> {
|
||||
let header_str = format_header(context, p.prefix, p.ident, p.vis, offset);
|
||||
let generics_str = if let Some(generics) = p.generics {
|
||||
let hi = context.snippet_provider.span_before(p.span, ";");
|
||||
let hi = context.snippet_provider.span_before_last(p.span, ";");
|
||||
format_generics(
|
||||
context,
|
||||
generics,
|
||||
|
@ -2602,7 +2606,7 @@ fn rewrite_params(
|
|||
¶m_items,
|
||||
context
|
||||
.config
|
||||
.fn_args_layout()
|
||||
.fn_params_layout()
|
||||
.to_list_tactic(param_items.len()),
|
||||
Separator::Comma,
|
||||
one_line_budget,
|
||||
|
|
|
@ -297,9 +297,9 @@ where
|
|||
} else {
|
||||
inner_item.as_ref()
|
||||
};
|
||||
let mut item_last_line_width = item_last_line.len() + item_sep_len;
|
||||
let mut item_last_line_width = unicode_str_width(item_last_line) + item_sep_len;
|
||||
if item_last_line.starts_with(&**indent_str) {
|
||||
item_last_line_width -= indent_str.len();
|
||||
item_last_line_width -= unicode_str_width(indent_str);
|
||||
}
|
||||
|
||||
if !item.is_substantial() {
|
||||
|
@ -449,7 +449,7 @@ where
|
|||
} else if starts_with_newline(comment) {
|
||||
false
|
||||
} else {
|
||||
comment.trim().contains('\n') || comment.trim().len() > width
|
||||
comment.trim().contains('\n') || unicode_str_width(comment.trim()) > width
|
||||
};
|
||||
|
||||
rewrite_comment(
|
||||
|
@ -465,7 +465,7 @@ where
|
|||
if !starts_with_newline(comment) {
|
||||
if formatting.align_comments {
|
||||
let mut comment_alignment =
|
||||
post_comment_alignment(item_max_width, inner_item.len());
|
||||
post_comment_alignment(item_max_width, unicode_str_width(inner_item));
|
||||
if first_line_width(&formatted_comment)
|
||||
+ last_line_width(&result)
|
||||
+ comment_alignment
|
||||
|
@ -475,7 +475,7 @@ where
|
|||
item_max_width = None;
|
||||
formatted_comment = rewrite_post_comment(&mut item_max_width)?;
|
||||
comment_alignment =
|
||||
post_comment_alignment(item_max_width, inner_item.len());
|
||||
post_comment_alignment(item_max_width, unicode_str_width(inner_item));
|
||||
}
|
||||
for _ in 0..=comment_alignment {
|
||||
result.push(' ');
|
||||
|
@ -533,7 +533,7 @@ where
|
|||
let mut first = true;
|
||||
for item in items.clone().into_iter().skip(i) {
|
||||
let item = item.as_ref();
|
||||
let inner_item_width = item.inner_as_ref().len();
|
||||
let inner_item_width = unicode_str_width(item.inner_as_ref());
|
||||
if !first
|
||||
&& (item.is_different_group()
|
||||
|| item.post_comment.is_none()
|
||||
|
@ -552,8 +552,8 @@ where
|
|||
max_width
|
||||
}
|
||||
|
||||
fn post_comment_alignment(item_max_width: Option<usize>, inner_item_len: usize) -> usize {
|
||||
item_max_width.unwrap_or(0).saturating_sub(inner_item_len)
|
||||
fn post_comment_alignment(item_max_width: Option<usize>, inner_item_width: usize) -> usize {
|
||||
item_max_width.unwrap_or(0).saturating_sub(inner_item_width)
|
||||
}
|
||||
|
||||
pub(crate) struct ListItems<'a, I, F1, F2, F3>
|
||||
|
|
|
@ -35,8 +35,8 @@ use crate::shape::{Indent, Shape};
|
|||
use crate::source_map::SpanUtils;
|
||||
use crate::spanned::Spanned;
|
||||
use crate::utils::{
|
||||
format_visibility, indent_next_line, is_empty_line, mk_sp, remove_trailing_white_spaces,
|
||||
rewrite_ident, trim_left_preserve_layout, wrap_str, NodeIdExt,
|
||||
filtered_str_fits, format_visibility, indent_next_line, is_empty_line, mk_sp,
|
||||
remove_trailing_white_spaces, rewrite_ident, trim_left_preserve_layout, NodeIdExt,
|
||||
};
|
||||
use crate::visitor::FmtVisitor;
|
||||
|
||||
|
@ -157,7 +157,8 @@ pub(crate) fn rewrite_macro(
|
|||
) -> Option<String> {
|
||||
let should_skip = context
|
||||
.skip_context
|
||||
.skip_macro(context.snippet(mac.path.span));
|
||||
.macros
|
||||
.skip(context.snippet(mac.path.span));
|
||||
if should_skip {
|
||||
None
|
||||
} else {
|
||||
|
@ -1265,15 +1266,14 @@ impl MacroBranch {
|
|||
}
|
||||
}
|
||||
};
|
||||
let new_body = wrap_str(
|
||||
new_body_snippet.snippet.to_string(),
|
||||
config.max_width(),
|
||||
shape,
|
||||
)?;
|
||||
|
||||
if !filtered_str_fits(&new_body_snippet.snippet, config.max_width(), shape) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Indent the body since it is in a block.
|
||||
let indent_str = body_indent.to_string(&config);
|
||||
let mut new_body = LineClasses::new(new_body.trim_end())
|
||||
let mut new_body = LineClasses::new(new_body_snippet.snippet.trim_end())
|
||||
.enumerate()
|
||||
.fold(
|
||||
(String::new(), true),
|
||||
|
|
|
@ -2,33 +2,84 @@
|
|||
|
||||
use rustc_ast::ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use std::collections::HashSet;
|
||||
|
||||
/// Take care of skip name stack. You can update it by attributes slice or
|
||||
/// by other context. Query this context to know if you need skip a block.
|
||||
/// Track which blocks of code are to be skipped when formatting.
|
||||
///
|
||||
/// You can update it by:
|
||||
///
|
||||
/// - attributes slice
|
||||
/// - manually feeding values into the underlying contexts
|
||||
///
|
||||
/// Query this context to know if you need to skip a block.
|
||||
#[derive(Default, Clone)]
|
||||
pub(crate) struct SkipContext {
|
||||
macros: Vec<String>,
|
||||
attributes: Vec<String>,
|
||||
pub(crate) macros: SkipNameContext,
|
||||
pub(crate) attributes: SkipNameContext,
|
||||
}
|
||||
|
||||
impl SkipContext {
|
||||
pub(crate) fn update_with_attrs(&mut self, attrs: &[ast::Attribute]) {
|
||||
self.macros.append(&mut get_skip_names("macros", attrs));
|
||||
self.attributes
|
||||
.append(&mut get_skip_names("attributes", attrs));
|
||||
self.macros.extend(get_skip_names("macros", attrs));
|
||||
self.attributes.extend(get_skip_names("attributes", attrs));
|
||||
}
|
||||
|
||||
pub(crate) fn update(&mut self, mut other: SkipContext) {
|
||||
self.macros.append(&mut other.macros);
|
||||
self.attributes.append(&mut other.attributes);
|
||||
pub(crate) fn update(&mut self, other: SkipContext) {
|
||||
let SkipContext { macros, attributes } = other;
|
||||
self.macros.update(macros);
|
||||
self.attributes.update(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Track which names to skip.
|
||||
///
|
||||
/// Query this context with a string to know whether to skip it.
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum SkipNameContext {
|
||||
All,
|
||||
Values(HashSet<String>),
|
||||
}
|
||||
|
||||
impl Default for SkipNameContext {
|
||||
fn default() -> Self {
|
||||
Self::Values(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<String> for SkipNameContext {
|
||||
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
|
||||
match self {
|
||||
Self::All => {}
|
||||
Self::Values(values) => values.extend(iter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SkipNameContext {
|
||||
pub(crate) fn update(&mut self, other: Self) {
|
||||
match (self, other) {
|
||||
// If we're already skipping everything, nothing more can be added
|
||||
(Self::All, _) => {}
|
||||
// If we want to skip all, set it
|
||||
(this, Self::All) => {
|
||||
*this = Self::All;
|
||||
}
|
||||
// If we have some new values to skip, add them
|
||||
(Self::Values(existing_values), Self::Values(new_values)) => {
|
||||
existing_values.extend(new_values)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn skip_macro(&self, name: &str) -> bool {
|
||||
self.macros.iter().any(|n| n == name)
|
||||
pub(crate) fn skip(&self, name: &str) -> bool {
|
||||
match self {
|
||||
Self::All => true,
|
||||
Self::Values(values) => values.contains(name),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn skip_attribute(&self, name: &str) -> bool {
|
||||
self.attributes.iter().any(|n| n == name)
|
||||
pub(crate) fn skip_all(&mut self) {
|
||||
*self = Self::All;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,13 @@ impl ConfigurationSection {
|
|||
lazy_static! {
|
||||
static ref CONFIG_NAME_REGEX: regex::Regex =
|
||||
regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern");
|
||||
// Configuration values, which will be passed to `from_str`:
|
||||
//
|
||||
// - must be prefixed with `####`
|
||||
// - must be wrapped in backticks
|
||||
// - may by wrapped in double quotes (which will be stripped)
|
||||
static ref CONFIG_VALUE_REGEX: regex::Regex =
|
||||
regex::Regex::new(r#"^#### `"?([^`"]+)"?`"#)
|
||||
regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#)
|
||||
.expect("failed creating configuration value pattern");
|
||||
}
|
||||
|
||||
|
|
|
@ -982,11 +982,7 @@ fn rustfmt() -> PathBuf {
|
|||
assert!(
|
||||
me.is_file() || me.with_extension("exe").is_file(),
|
||||
"{}",
|
||||
if cfg!(release) {
|
||||
"no rustfmt bin, try running `cargo build --release` before testing"
|
||||
} else {
|
||||
"no rustfmt bin, try running `cargo build` before testing"
|
||||
}
|
||||
"no rustfmt bin, try running `cargo build` or `cargo build --release` before testing"
|
||||
);
|
||||
me
|
||||
}
|
||||
|
|
|
@ -941,6 +941,28 @@ fn join_bounds_inner(
|
|||
ast::GenericBound::Trait(..) => last_line_extendable(s),
|
||||
};
|
||||
|
||||
// Whether a GenericBound item is a PathSegment segment that includes internal array
|
||||
// that contains more than one item
|
||||
let is_item_with_multi_items_array = |item: &ast::GenericBound| match item {
|
||||
ast::GenericBound::Trait(ref poly_trait_ref, ..) => {
|
||||
let segments = &poly_trait_ref.trait_ref.path.segments;
|
||||
if segments.len() > 1 {
|
||||
true
|
||||
} else {
|
||||
if let Some(args_in) = &segments[0].args {
|
||||
matches!(
|
||||
args_in.deref(),
|
||||
ast::GenericArgs::AngleBracketed(bracket_args)
|
||||
if bracket_args.args.len() > 1
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let result = items.iter().enumerate().try_fold(
|
||||
(String::new(), None, false),
|
||||
|(strs, prev_trailing_span, prev_extendable), (i, item)| {
|
||||
|
@ -1035,10 +1057,24 @@ fn join_bounds_inner(
|
|||
},
|
||||
)?;
|
||||
|
||||
if !force_newline
|
||||
&& items.len() > 1
|
||||
&& (result.0.contains('\n') || result.0.len() > shape.width)
|
||||
{
|
||||
// Whether to retry with a forced newline:
|
||||
// Only if result is not already multiline and did not exceed line width,
|
||||
// and either there is more than one item;
|
||||
// or the single item is of type `Trait`,
|
||||
// and any of the internal arrays contains more than one item;
|
||||
let retry_with_force_newline = match context.config.version() {
|
||||
Version::One => {
|
||||
!force_newline
|
||||
&& items.len() > 1
|
||||
&& (result.0.contains('\n') || result.0.len() > shape.width)
|
||||
}
|
||||
Version::Two if force_newline => false,
|
||||
Version::Two if (!result.0.contains('\n') && result.0.len() <= shape.width) => false,
|
||||
Version::Two if items.len() > 1 => true,
|
||||
Version::Two => is_item_with_multi_items_array(&items[0]),
|
||||
};
|
||||
|
||||
if retry_with_force_newline {
|
||||
join_bounds_inner(context, shape, items, need_indent, true)
|
||||
} else {
|
||||
Some(result.0)
|
||||
|
|
|
@ -384,14 +384,15 @@ macro_rules! skip_out_of_file_lines_range_visitor {
|
|||
// Wraps String in an Option. Returns Some when the string adheres to the
|
||||
// Rewrite constraints defined for the Rewrite trait and None otherwise.
|
||||
pub(crate) fn wrap_str(s: String, max_width: usize, shape: Shape) -> Option<String> {
|
||||
if is_valid_str(&filter_normal_code(&s), max_width, shape) {
|
||||
if filtered_str_fits(&s, max_width, shape) {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_valid_str(snippet: &str, max_width: usize, shape: Shape) -> bool {
|
||||
pub(crate) fn filtered_str_fits(snippet: &str, max_width: usize, shape: Shape) -> bool {
|
||||
let snippet = &filter_normal_code(snippet);
|
||||
if !snippet.is_empty() {
|
||||
// First line must fits with `shape.width`.
|
||||
if first_line_width(snippet) > shape.width {
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_span::{symbol, BytePos, Pos, Span};
|
|||
use crate::attr::*;
|
||||
use crate::comment::{contains_comment, rewrite_comment, CodeCharKind, CommentCodeSlices};
|
||||
use crate::config::Version;
|
||||
use crate::config::{BraceStyle, Config};
|
||||
use crate::config::{BraceStyle, Config, MacroSelector};
|
||||
use crate::coverage::transform_missing_snippet;
|
||||
use crate::items::{
|
||||
format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate,
|
||||
|
@ -770,6 +770,15 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
|||
snippet_provider: &'a SnippetProvider,
|
||||
report: FormatReport,
|
||||
) -> FmtVisitor<'a> {
|
||||
let mut skip_context = SkipContext::default();
|
||||
let mut macro_names = Vec::new();
|
||||
for macro_selector in config.skip_macro_invocations().0 {
|
||||
match macro_selector {
|
||||
MacroSelector::Name(name) => macro_names.push(name.to_string()),
|
||||
MacroSelector::All => skip_context.macros.skip_all(),
|
||||
}
|
||||
}
|
||||
skip_context.macros.extend(macro_names);
|
||||
FmtVisitor {
|
||||
parent_context: None,
|
||||
parse_sess: parse_session,
|
||||
|
@ -784,7 +793,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
|||
is_macro_def: false,
|
||||
macro_rewrite_failure: false,
|
||||
report,
|
||||
skip_context: Default::default(),
|
||||
skip_context,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ use std::env;
|
|||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use rustfmt_config_proc_macro::rustfmt_only_ci_test;
|
||||
|
||||
/// Run the cargo-fmt executable and return its output.
|
||||
fn cargo_fmt(args: &[&str]) -> (String, String) {
|
||||
let mut bin_dir = env::current_exe().unwrap();
|
||||
|
@ -47,7 +49,7 @@ macro_rules! assert_that {
|
|||
};
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn version() {
|
||||
assert_that!(&["--version"], starts_with("rustfmt "));
|
||||
|
@ -56,7 +58,7 @@ fn version() {
|
|||
assert_that!(&["--", "--version"], starts_with("rustfmt "));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn print_config() {
|
||||
assert_that!(
|
||||
|
@ -65,7 +67,7 @@ fn print_config() {
|
|||
);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn rustfmt_help() {
|
||||
assert_that!(&["--", "--help"], contains("Format Rust code"));
|
||||
|
@ -73,7 +75,7 @@ fn rustfmt_help() {
|
|||
assert_that!(&["--", "--help=config"], contains("Configuration Options:"));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn cargo_fmt_out_of_line_test_modules() {
|
||||
// See also https://github.com/rust-lang/rustfmt/issues/5119
|
||||
|
@ -96,3 +98,22 @@ fn cargo_fmt_out_of_line_test_modules() {
|
|||
assert!(stdout.contains(&format!("Diff in {}", path.display())))
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn cargo_fmt_emits_error_on_line_overflow_true() {
|
||||
// See also https://github.com/rust-lang/rustfmt/issues/3164
|
||||
let args = [
|
||||
"--check",
|
||||
"--manifest-path",
|
||||
"tests/cargo-fmt/source/issue_3164/Cargo.toml",
|
||||
"--",
|
||||
"--config",
|
||||
"error_on_line_overflow=true",
|
||||
];
|
||||
|
||||
let (_stdout, stderr) = cargo_fmt(&args);
|
||||
assert!(stderr.contains(
|
||||
"line formatted, but exceeded maximum width (maximum: 100 (see `max_width` option)"
|
||||
))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "issue_3164"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,13 @@
|
|||
#[allow(unused_macros)]
|
||||
macro_rules! foo {
|
||||
($id:ident) => {
|
||||
macro_rules! bar {
|
||||
($id2:tt) => {
|
||||
#[cfg(any(target_feature = $id2, target_feature = $id2, target_feature = $id2, target_feature = $id2, target_feature = $id2))]
|
||||
fn $id() {}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -3,7 +3,7 @@ comment_width = 80
|
|||
tab_spaces = 2
|
||||
newline_style = "Unix"
|
||||
brace_style = "SameLineWhere"
|
||||
fn_args_layout = "Tall"
|
||||
fn_params_layout = "Tall"
|
||||
trailing_comma = "Vertical"
|
||||
indent_style = "Block"
|
||||
reorder_imports = false
|
||||
|
|
|
@ -9,7 +9,7 @@ The directory name './lib/c/d/' conflicts with the './lib/c/d.rs' file name.
|
|||
* mod g;
|
||||
|
||||
Module resolution will fail if we look for './lib/c/d/e.rs' or './lib/c/d/e/mod.rs',
|
||||
so we should fall back to looking for './lib/c/e.rs', which correctly finds the modlue, that
|
||||
so we should fall back to looking for './lib/c/e.rs', which correctly finds the module, that
|
||||
rustfmt should format.
|
||||
|
||||
'./lib/c/d/f.rs' and './lib/c/d/g/mod.rs' exist at the default submodule paths so we should be able
|
||||
|
|
|
@ -9,7 +9,7 @@ The directory name './lib' conflicts with the './lib.rs' file name.
|
|||
* mod c;
|
||||
|
||||
Module resolution will fail if we look for './lib/a.rs' or './lib/a/mod.rs',
|
||||
so we should fall back to looking for './a.rs', which correctly finds the modlue that
|
||||
so we should fall back to looking for './a.rs', which correctly finds the module that
|
||||
rustfmt should format.
|
||||
|
||||
'./lib/b.rs' and './lib/c/mod.rs' exist at the default submodule paths so we should be able
|
||||
|
|
|
@ -5,6 +5,8 @@ use std::fs::remove_file;
|
|||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use rustfmt_config_proc_macro::rustfmt_only_ci_test;
|
||||
|
||||
/// Run the rustfmt executable and return its output.
|
||||
fn rustfmt(args: &[&str]) -> (String, String) {
|
||||
let mut bin_dir = env::current_exe().unwrap();
|
||||
|
@ -47,7 +49,7 @@ macro_rules! assert_that {
|
|||
};
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn print_config() {
|
||||
assert_that!(
|
||||
|
@ -76,7 +78,7 @@ fn print_config() {
|
|||
remove_file("minimal-config").unwrap();
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[rustfmt_only_ci_test]
|
||||
#[test]
|
||||
fn inline_config() {
|
||||
// single invocation
|
||||
|
@ -157,3 +159,18 @@ fn mod_resolution_error_path_attribute_does_not_exist() {
|
|||
// The path attribute points to a file that does not exist
|
||||
assert!(stderr.contains("does_not_exist.rs does not exist"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rustfmt_emits_error_on_line_overflow_true() {
|
||||
// See also https://github.com/rust-lang/rustfmt/issues/3164
|
||||
let args = [
|
||||
"--config",
|
||||
"error_on_line_overflow=true",
|
||||
"tests/cargo-fmt/source/issue_3164/src/main.rs",
|
||||
];
|
||||
|
||||
let (_stdout, stderr) = rustfmt(&args);
|
||||
assert!(stderr.contains(
|
||||
"line formatted, but exceeded maximum width (maximum: 100 (see `max_width` option)"
|
||||
))
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ pub enum Feature {
|
|||
tbm,
|
||||
/// POPCNT (Population Count)
|
||||
popcnt,
|
||||
/// FXSR (Floating-point context fast save and restor)
|
||||
/// FXSR (Floating-point context fast save and restore)
|
||||
fxsr,
|
||||
/// XSAVE (Save Processor Extended States)
|
||||
xsave,
|
||||
|
|
140
src/tools/rustfmt/tests/source/comments_unicode.rs
Normal file
140
src/tools/rustfmt/tests/source/comments_unicode.rs
Normal file
|
@ -0,0 +1,140 @@
|
|||
impl Default for WhitespaceCharacters {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
space: '·', // U+00B7
|
||||
nbsp: '⍽', // U+237D
|
||||
tab: '→', // U+2192
|
||||
newline: '⏎', // U+23CE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const RAINBOWS: &[&str] = &[
|
||||
"rаinЬοѡ", // hue: 0
|
||||
"raіnЬοw", // hue: 2
|
||||
"rаіɴЬow", // hue: 2
|
||||
"raіɴЬoѡ", // hue: 8
|
||||
"ʀainЬow", // hue: 8
|
||||
"ʀaіɴboѡ", // hue: 8
|
||||
"ʀаіnbοw", // hue: 11
|
||||
"rainЬoѡ", // hue: 14
|
||||
"raіɴbow", // hue: 14
|
||||
"rаiɴЬow", // hue: 20
|
||||
"raіnЬow", // hue: 26
|
||||
"ʀaiɴbοw", // hue: 32
|
||||
"raіɴboѡ", // hue: 35
|
||||
"rаiɴbow", // hue: 35
|
||||
"rаіnbοw", // hue: 38
|
||||
"rаinЬow", // hue: 47
|
||||
"ʀaіnboѡ", // hue: 47
|
||||
"ʀaіnЬoѡ", // hue: 47
|
||||
"ʀаіɴbοw", // hue: 53
|
||||
"ʀaіnЬοѡ", // hue: 57
|
||||
"raiɴЬoѡ", // hue: 68
|
||||
"ʀainbοѡ", // hue: 68
|
||||
"ʀаinboѡ", // hue: 68
|
||||
"ʀаiɴbοw", // hue: 68
|
||||
"ʀаіnbow", // hue: 68
|
||||
"rаіnЬοѡ", // hue: 69
|
||||
"ʀainЬοw", // hue: 71
|
||||
"raiɴbow", // hue: 73
|
||||
"raіnЬoѡ", // hue: 74
|
||||
"rаіɴbοw", // hue: 77
|
||||
"raіnЬοѡ", // hue: 81
|
||||
"raiɴЬow", // hue: 83
|
||||
"ʀainbοw", // hue: 83
|
||||
"ʀаinbow", // hue: 83
|
||||
"ʀаiɴbοѡ", // hue: 83
|
||||
"ʀаіnboѡ", // hue: 83
|
||||
"ʀаіɴЬοѡ", // hue: 84
|
||||
"rainЬow", // hue: 85
|
||||
"ʀаiɴЬοw", // hue: 86
|
||||
"ʀаіnbοѡ", // hue: 89
|
||||
"ʀаіnЬοw", // hue: 92
|
||||
"rаiɴbοw", // hue: 95
|
||||
"ʀаіɴbοѡ", // hue: 98
|
||||
"ʀаiɴЬοѡ", // hue: 99
|
||||
"raіnbοw", // hue: 101
|
||||
"ʀаіɴЬοw", // hue: 101
|
||||
"ʀaiɴboѡ", // hue: 104
|
||||
"ʀаinbοѡ", // hue: 104
|
||||
"rаiɴbοѡ", // hue: 107
|
||||
"ʀаinЬοw", // hue: 107
|
||||
"rаiɴЬοw", // hue: 110
|
||||
"rаіnboѡ", // hue: 110
|
||||
"rаіnbοѡ", // hue: 113
|
||||
"ʀainЬοѡ", // hue: 114
|
||||
"rаіnЬοw", // hue: 116
|
||||
"ʀaіɴЬow", // hue: 116
|
||||
"rаinbοw", // hue: 122
|
||||
"ʀаіɴboѡ", // hue: 125
|
||||
"rаinbοѡ", // hue: 131
|
||||
"rainbow", // hue: 134
|
||||
"rаinЬοw", // hue: 134
|
||||
"ʀаiɴboѡ", // hue: 140
|
||||
"rainЬοѡ", // hue: 141
|
||||
"raіɴЬow", // hue: 143
|
||||
"ʀainЬoѡ", // hue: 143
|
||||
"ʀaіɴbow", // hue: 143
|
||||
"ʀainbow", // hue: 148
|
||||
"rаіɴboѡ", // hue: 149
|
||||
"ʀainboѡ", // hue: 155
|
||||
"ʀaіnbow", // hue: 155
|
||||
"ʀaіnЬow", // hue: 155
|
||||
"raiɴbοw", // hue: 158
|
||||
"ʀаiɴЬoѡ", // hue: 158
|
||||
"rainbοw", // hue: 160
|
||||
"rаinbow", // hue: 160
|
||||
"ʀaіɴbοѡ", // hue: 164
|
||||
"ʀаiɴbow", // hue: 164
|
||||
"ʀаіnЬoѡ", // hue: 164
|
||||
"ʀaiɴЬοѡ", // hue: 165
|
||||
"rаiɴboѡ", // hue: 167
|
||||
"ʀaіɴЬοw", // hue: 167
|
||||
"ʀaіɴЬοѡ", // hue: 171
|
||||
"raіnboѡ", // hue: 173
|
||||
"ʀаіɴЬoѡ", // hue: 173
|
||||
"rаіɴbοѡ", // hue: 176
|
||||
"ʀаinЬow", // hue: 176
|
||||
"rаiɴЬοѡ", // hue: 177
|
||||
"rаіɴЬοw", // hue: 179
|
||||
"ʀаinЬoѡ", // hue: 179
|
||||
"ʀаіɴbow", // hue: 179
|
||||
"rаiɴЬoѡ", // hue: 182
|
||||
"raіɴbοѡ", // hue: 188
|
||||
"rаіnЬoѡ", // hue: 188
|
||||
"raiɴЬοѡ", // hue: 189
|
||||
"raіɴЬοw", // hue: 191
|
||||
"ʀaіɴbοw", // hue: 191
|
||||
"ʀаіnЬow", // hue: 191
|
||||
"rainbοѡ", // hue: 194
|
||||
"rаinboѡ", // hue: 194
|
||||
"rаіnbow", // hue: 194
|
||||
"rainЬοw", // hue: 197
|
||||
"rаinЬoѡ", // hue: 206
|
||||
"rаіɴbow", // hue: 206
|
||||
"rаіɴЬοѡ", // hue: 210
|
||||
"ʀaiɴЬow", // hue: 212
|
||||
"raіɴbοw", // hue: 218
|
||||
"rаіnЬow", // hue: 218
|
||||
"ʀaiɴbοѡ", // hue: 221
|
||||
"ʀaiɴЬοw", // hue: 224
|
||||
"ʀaіnbοѡ", // hue: 227
|
||||
"raiɴboѡ", // hue: 230
|
||||
"ʀaіnbοw", // hue: 230
|
||||
"ʀaіnЬοw", // hue: 230
|
||||
"ʀаinЬοѡ", // hue: 231
|
||||
"rainboѡ", // hue: 232
|
||||
"raіnbow", // hue: 232
|
||||
"ʀаіɴЬow", // hue: 233
|
||||
"ʀaіɴЬoѡ", // hue: 239
|
||||
"ʀаіnЬοѡ", // hue: 246
|
||||
"raiɴbοѡ", // hue: 248
|
||||
"ʀаiɴЬow", // hue: 248
|
||||
"raіɴЬοѡ", // hue: 249
|
||||
"raiɴЬοw", // hue: 251
|
||||
"rаіɴЬoѡ", // hue: 251
|
||||
"ʀaiɴbow", // hue: 251
|
||||
"ʀаinbοw", // hue: 251
|
||||
"raіnbοѡ", // hue: 254
|
||||
];
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-fn_params_layout: Compressed
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Tall
|
||||
// rustfmt-fn_params_layout: Tall
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -36,7 +36,7 @@ enum StructLikeVariants {
|
|||
Normal(u32, String, ),
|
||||
StructLike { x: i32, // Test comment
|
||||
// Pre-comment
|
||||
#[Attr50] y: SomeType, // Aanother Comment
|
||||
#[Attr50] y: SomeType, // Another Comment
|
||||
}, SL { a: A }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// rustfmt-normalize_comments: true
|
||||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
// rustfmt-brace_style: AlwaysNextLine
|
||||
|
||||
// Case with only one variable.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-fn_params_layout: Compressed
|
||||
// Test some of the ways function signatures can be customised.
|
||||
|
||||
// Test compressed layout of args.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
|
||||
// Empty list should stay on one line.
|
||||
fn do_bar(
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// rustfmt-format_macro_bodies: true
|
||||
|
||||
// with comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct {
|
||||
field: (
|
||||
42 + //comment 1
|
||||
42
|
||||
//comment 2
|
||||
),
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
// without comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct {
|
||||
field: (
|
||||
42 +
|
||||
42
|
||||
),
|
||||
};
|
||||
}};
|
||||
}
|
23
src/tools/rustfmt/tests/source/issue-4643.rs
Normal file
23
src/tools/rustfmt/tests/source/issue-4643.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// output doesn't get corrupted when using comments within generic type parameters of a trait
|
||||
|
||||
pub trait Something<
|
||||
A,
|
||||
// some comment
|
||||
B,
|
||||
C
|
||||
> {
|
||||
fn a(&self, x: A) -> i32;
|
||||
fn b(&self, x: B) -> i32;
|
||||
fn c(&self, x: C) -> i32;
|
||||
}
|
||||
|
||||
pub trait SomethingElse<
|
||||
A,
|
||||
/* some comment */
|
||||
B,
|
||||
C
|
||||
> {
|
||||
fn a(&self, x: A) -> i32;
|
||||
fn b(&self, x: B) -> i32;
|
||||
fn c(&self, x: C) -> i32;
|
||||
}
|
149
src/tools/rustfmt/tests/source/issue-4689/one.rs
Normal file
149
src/tools/rustfmt/tests/source/issue-4689/one.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
// rustfmt-version: One
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1 + fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
)
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
149
src/tools/rustfmt/tests/source/issue-4689/two.rs
Normal file
149
src/tools/rustfmt/tests/source/issue-4689/two.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
// rustfmt-version: Two
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1 + fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
)
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
29
src/tools/rustfmt/tests/source/issue_1306.rs
Normal file
29
src/tools/rustfmt/tests/source/issue_1306.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// rustfmt-max_width: 160
|
||||
// rustfmt-fn_call_width: 96
|
||||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-trailing_comma: Always
|
||||
// rustfmt-wrap_comments: true
|
||||
|
||||
fn foo() {
|
||||
for elem in try!(gen_epub_book::ops::parse_descriptor_file(&mut try!(File::open(&opts.source_file.1).map_err(|_| {
|
||||
gen_epub_book::Error::Io {
|
||||
desc: "input file",
|
||||
op: "open",
|
||||
more: None,
|
||||
}
|
||||
})),
|
||||
"input file")) {
|
||||
println!("{}", elem);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_content() {
|
||||
io::copy(try!(File::open(in_f).map_err(|_| {
|
||||
Error::Io {
|
||||
desc: "Content",
|
||||
op: "open",
|
||||
more: None,
|
||||
}
|
||||
})),
|
||||
w);
|
||||
}
|
4
src/tools/rustfmt/tests/source/issue_3245.rs
Normal file
4
src/tools/rustfmt/tests/source/issue_3245.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
fn main() {
|
||||
let x = 1;
|
||||
;let y = 3;
|
||||
}
|
6
src/tools/rustfmt/tests/source/issue_3561.rs
Normal file
6
src/tools/rustfmt/tests/source/issue_3561.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
fn main() {;7
|
||||
}
|
||||
|
||||
fn main() {
|
||||
;7
|
||||
}
|
11
src/tools/rustfmt/tests/source/skip_macro_invocations/all.rs
Normal file
11
src/tools/rustfmt/tests/source/skip_macro_invocations/all.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["*"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["*","items"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should also skip this invocation, as the wildcard covers it
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: []
|
||||
|
||||
// Should not skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should not skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["items"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should not skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-skip_macro_invocations: ["unknown"]
|
||||
|
||||
// Should not skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,16 @@
|
|||
// rustfmt-skip_macro_invocations: ["foo","bar"]
|
||||
|
||||
// Should skip this invocation
|
||||
foo!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should skip this invocation
|
||||
bar!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should not skip this invocation
|
||||
baz!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-skip_macro_invocations: ["items"]
|
||||
|
||||
// Should not skip this invocation
|
||||
self::items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-skip_macro_invocations: ["self::items"]
|
||||
|
||||
// Should skip this invocation
|
||||
self::items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-skip_macro_invocations: ["self::items"]
|
||||
|
||||
// Should not skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,32 @@
|
|||
// rustfmt-skip_macro_invocations: ["aaa","ccc"]
|
||||
|
||||
// These tests demonstrate a realistic use case with use aliases.
|
||||
// The use statements should not impact functionality in any way.
|
||||
|
||||
use crate::{aaa, bbb, ddd};
|
||||
|
||||
// No use alias, invocation in list
|
||||
// Should skip this invocation
|
||||
aaa!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Use alias, invocation in list
|
||||
// Should skip this invocation
|
||||
use crate::bbb as ccc;
|
||||
ccc!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Use alias, invocation not in list
|
||||
// Should not skip this invocation
|
||||
use crate::ddd as eee;
|
||||
eee!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// No use alias, invocation not in list
|
||||
// Should not skip this invocation
|
||||
fff!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -1,4 +1,4 @@
|
|||
// Test tuple litterals
|
||||
// Test tuple literals
|
||||
|
||||
fn foo() {
|
||||
let a = (a, a, a, a, a);
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
///
|
||||
fn foo() {}
|
||||
|
||||
/// A long commment for wrapping
|
||||
/// A long comment for wrapping
|
||||
/// This is a long long long long long long long long long long long long long long long long long long long long sentence.
|
||||
fn bar() {}
|
||||
|
|
|
@ -314,7 +314,7 @@ pub enum Feature {
|
|||
tbm,
|
||||
/// POPCNT (Population Count)
|
||||
popcnt,
|
||||
/// FXSR (Floating-point context fast save and restor)
|
||||
/// FXSR (Floating-point context fast save and restore)
|
||||
fxsr,
|
||||
/// XSAVE (Save Processor Extended States)
|
||||
xsave,
|
||||
|
|
140
src/tools/rustfmt/tests/target/comments_unicode.rs
Normal file
140
src/tools/rustfmt/tests/target/comments_unicode.rs
Normal file
|
@ -0,0 +1,140 @@
|
|||
impl Default for WhitespaceCharacters {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
space: '·', // U+00B7
|
||||
nbsp: '⍽', // U+237D
|
||||
tab: '→', // U+2192
|
||||
newline: '⏎', // U+23CE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const RAINBOWS: &[&str] = &[
|
||||
"rаinЬοѡ", // hue: 0
|
||||
"raіnЬοw", // hue: 2
|
||||
"rаіɴЬow", // hue: 2
|
||||
"raіɴЬoѡ", // hue: 8
|
||||
"ʀainЬow", // hue: 8
|
||||
"ʀaіɴboѡ", // hue: 8
|
||||
"ʀаіnbοw", // hue: 11
|
||||
"rainЬoѡ", // hue: 14
|
||||
"raіɴbow", // hue: 14
|
||||
"rаiɴЬow", // hue: 20
|
||||
"raіnЬow", // hue: 26
|
||||
"ʀaiɴbοw", // hue: 32
|
||||
"raіɴboѡ", // hue: 35
|
||||
"rаiɴbow", // hue: 35
|
||||
"rаіnbοw", // hue: 38
|
||||
"rаinЬow", // hue: 47
|
||||
"ʀaіnboѡ", // hue: 47
|
||||
"ʀaіnЬoѡ", // hue: 47
|
||||
"ʀаіɴbοw", // hue: 53
|
||||
"ʀaіnЬοѡ", // hue: 57
|
||||
"raiɴЬoѡ", // hue: 68
|
||||
"ʀainbοѡ", // hue: 68
|
||||
"ʀаinboѡ", // hue: 68
|
||||
"ʀаiɴbοw", // hue: 68
|
||||
"ʀаіnbow", // hue: 68
|
||||
"rаіnЬοѡ", // hue: 69
|
||||
"ʀainЬοw", // hue: 71
|
||||
"raiɴbow", // hue: 73
|
||||
"raіnЬoѡ", // hue: 74
|
||||
"rаіɴbοw", // hue: 77
|
||||
"raіnЬοѡ", // hue: 81
|
||||
"raiɴЬow", // hue: 83
|
||||
"ʀainbοw", // hue: 83
|
||||
"ʀаinbow", // hue: 83
|
||||
"ʀаiɴbοѡ", // hue: 83
|
||||
"ʀаіnboѡ", // hue: 83
|
||||
"ʀаіɴЬοѡ", // hue: 84
|
||||
"rainЬow", // hue: 85
|
||||
"ʀаiɴЬοw", // hue: 86
|
||||
"ʀаіnbοѡ", // hue: 89
|
||||
"ʀаіnЬοw", // hue: 92
|
||||
"rаiɴbοw", // hue: 95
|
||||
"ʀаіɴbοѡ", // hue: 98
|
||||
"ʀаiɴЬοѡ", // hue: 99
|
||||
"raіnbοw", // hue: 101
|
||||
"ʀаіɴЬοw", // hue: 101
|
||||
"ʀaiɴboѡ", // hue: 104
|
||||
"ʀаinbοѡ", // hue: 104
|
||||
"rаiɴbοѡ", // hue: 107
|
||||
"ʀаinЬοw", // hue: 107
|
||||
"rаiɴЬοw", // hue: 110
|
||||
"rаіnboѡ", // hue: 110
|
||||
"rаіnbοѡ", // hue: 113
|
||||
"ʀainЬοѡ", // hue: 114
|
||||
"rаіnЬοw", // hue: 116
|
||||
"ʀaіɴЬow", // hue: 116
|
||||
"rаinbοw", // hue: 122
|
||||
"ʀаіɴboѡ", // hue: 125
|
||||
"rаinbοѡ", // hue: 131
|
||||
"rainbow", // hue: 134
|
||||
"rаinЬοw", // hue: 134
|
||||
"ʀаiɴboѡ", // hue: 140
|
||||
"rainЬοѡ", // hue: 141
|
||||
"raіɴЬow", // hue: 143
|
||||
"ʀainЬoѡ", // hue: 143
|
||||
"ʀaіɴbow", // hue: 143
|
||||
"ʀainbow", // hue: 148
|
||||
"rаіɴboѡ", // hue: 149
|
||||
"ʀainboѡ", // hue: 155
|
||||
"ʀaіnbow", // hue: 155
|
||||
"ʀaіnЬow", // hue: 155
|
||||
"raiɴbοw", // hue: 158
|
||||
"ʀаiɴЬoѡ", // hue: 158
|
||||
"rainbοw", // hue: 160
|
||||
"rаinbow", // hue: 160
|
||||
"ʀaіɴbοѡ", // hue: 164
|
||||
"ʀаiɴbow", // hue: 164
|
||||
"ʀаіnЬoѡ", // hue: 164
|
||||
"ʀaiɴЬοѡ", // hue: 165
|
||||
"rаiɴboѡ", // hue: 167
|
||||
"ʀaіɴЬοw", // hue: 167
|
||||
"ʀaіɴЬοѡ", // hue: 171
|
||||
"raіnboѡ", // hue: 173
|
||||
"ʀаіɴЬoѡ", // hue: 173
|
||||
"rаіɴbοѡ", // hue: 176
|
||||
"ʀаinЬow", // hue: 176
|
||||
"rаiɴЬοѡ", // hue: 177
|
||||
"rаіɴЬοw", // hue: 179
|
||||
"ʀаinЬoѡ", // hue: 179
|
||||
"ʀаіɴbow", // hue: 179
|
||||
"rаiɴЬoѡ", // hue: 182
|
||||
"raіɴbοѡ", // hue: 188
|
||||
"rаіnЬoѡ", // hue: 188
|
||||
"raiɴЬοѡ", // hue: 189
|
||||
"raіɴЬοw", // hue: 191
|
||||
"ʀaіɴbοw", // hue: 191
|
||||
"ʀаіnЬow", // hue: 191
|
||||
"rainbοѡ", // hue: 194
|
||||
"rаinboѡ", // hue: 194
|
||||
"rаіnbow", // hue: 194
|
||||
"rainЬοw", // hue: 197
|
||||
"rаinЬoѡ", // hue: 206
|
||||
"rаіɴbow", // hue: 206
|
||||
"rаіɴЬοѡ", // hue: 210
|
||||
"ʀaiɴЬow", // hue: 212
|
||||
"raіɴbοw", // hue: 218
|
||||
"rаіnЬow", // hue: 218
|
||||
"ʀaiɴbοѡ", // hue: 221
|
||||
"ʀaiɴЬοw", // hue: 224
|
||||
"ʀaіnbοѡ", // hue: 227
|
||||
"raiɴboѡ", // hue: 230
|
||||
"ʀaіnbοw", // hue: 230
|
||||
"ʀaіnЬοw", // hue: 230
|
||||
"ʀаinЬοѡ", // hue: 231
|
||||
"rainboѡ", // hue: 232
|
||||
"raіnbow", // hue: 232
|
||||
"ʀаіɴЬow", // hue: 233
|
||||
"ʀaіɴЬoѡ", // hue: 239
|
||||
"ʀаіnЬοѡ", // hue: 246
|
||||
"raiɴbοѡ", // hue: 248
|
||||
"ʀаiɴЬow", // hue: 248
|
||||
"raіɴЬοѡ", // hue: 249
|
||||
"raiɴЬοw", // hue: 251
|
||||
"rаіɴЬoѡ", // hue: 251
|
||||
"ʀaiɴbow", // hue: 251
|
||||
"ʀаinbοw", // hue: 251
|
||||
"raіnbοѡ", // hue: 254
|
||||
];
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-fn_params_layout: Compressed
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Tall
|
||||
// rustfmt-fn_params_layout: Tall
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
// Function arguments density
|
||||
|
||||
trait Lorem {
|
|
@ -43,7 +43,7 @@ enum StructLikeVariants {
|
|||
x: i32, // Test comment
|
||||
// Pre-comment
|
||||
#[Attr50]
|
||||
y: SomeType, // Aanother Comment
|
||||
y: SomeType, // Another Comment
|
||||
},
|
||||
SL {
|
||||
a: A,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// rustfmt-normalize_comments: true
|
||||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
// rustfmt-brace_style: AlwaysNextLine
|
||||
|
||||
// Case with only one variable.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-fn_params_layout: Compressed
|
||||
// Test some of the ways function signatures can be customised.
|
||||
|
||||
// Test compressed layout of args.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// rustfmt-fn_args_layout: Vertical
|
||||
// rustfmt-fn_params_layout: Vertical
|
||||
|
||||
// Empty list should stay on one line.
|
||||
fn do_bar() -> u8 {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-format_macro_matchers: false
|
||||
|
||||
macro_rules! foo {
|
||||
($a:ident : $b:ty) => {};
|
||||
($a:ident $b:ident $c:ident) => {};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// rustfmt-format_macro_matchers: true
|
||||
|
||||
macro_rules! foo {
|
||||
($a:ident : $b:ty) => {};
|
||||
($a:ident $b:ident $c:ident) => {};
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// rustfmt-format_macro_bodies: false
|
||||
|
||||
// with comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct {
|
||||
field: (
|
||||
42 + //comment 1
|
||||
42
|
||||
//comment 2
|
||||
),
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
// without comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct {
|
||||
field: (
|
||||
42 +
|
||||
42
|
||||
),
|
||||
};
|
||||
}};
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// rustfmt-format_macro_bodies: true
|
||||
|
||||
// with comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct {
|
||||
field: (
|
||||
42 + //comment 1
|
||||
42
|
||||
//comment 2
|
||||
),
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
// without comments
|
||||
macro_rules! macros {
|
||||
() => {{
|
||||
Struct { field: (42 + 42) };
|
||||
}};
|
||||
}
|
19
src/tools/rustfmt/tests/target/issue-4643.rs
Normal file
19
src/tools/rustfmt/tests/target/issue-4643.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// output doesn't get corrupted when using comments within generic type parameters of a trait
|
||||
|
||||
pub trait Something<
|
||||
A,
|
||||
// some comment
|
||||
B,
|
||||
C,
|
||||
>
|
||||
{
|
||||
fn a(&self, x: A) -> i32;
|
||||
fn b(&self, x: B) -> i32;
|
||||
fn c(&self, x: C) -> i32;
|
||||
}
|
||||
|
||||
pub trait SomethingElse<A, /* some comment */ B, C> {
|
||||
fn a(&self, x: A) -> i32;
|
||||
fn b(&self, x: B) -> i32;
|
||||
fn c(&self, x: C) -> i32;
|
||||
}
|
150
src/tools/rustfmt/tests/target/issue-4689/one.rs
Normal file
150
src/tools/rustfmt/tests/target/issue-4689/one.rs
Normal file
|
@ -0,0 +1,150 @@
|
|||
// rustfmt-version: One
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
),
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd,
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
152
src/tools/rustfmt/tests/target/issue-4689/two.rs
Normal file
152
src/tools/rustfmt/tests/target/issue-4689/two.rs
Normal file
|
@ -0,0 +1,152 @@
|
|||
// rustfmt-version: Two
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
),
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd,
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
|
@ -1,7 +1,7 @@
|
|||
// rustfmt-brace_style: SameLineWhere
|
||||
// rustfmt-comment_width: 100
|
||||
// rustfmt-edition: 2018
|
||||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-fn_params_layout: Compressed
|
||||
// rustfmt-hard_tabs: false
|
||||
// rustfmt-match_block_trailing_comma: true
|
||||
// rustfmt-max_width: 100
|
||||
|
|
4
src/tools/rustfmt/tests/target/issue-5358.rs
Normal file
4
src/tools/rustfmt/tests/target/issue-5358.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
// Test /* comment */ inside trait generics does not get duplicated.
|
||||
trait Test</* comment */ T> {}
|
||||
|
||||
trait TestTwo</* comment */ T, /* comment */ V> {}
|
33
src/tools/rustfmt/tests/target/issue_1306.rs
Normal file
33
src/tools/rustfmt/tests/target/issue_1306.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
// rustfmt-max_width: 160
|
||||
// rustfmt-fn_call_width: 96
|
||||
// rustfmt-fn_args_layout: Compressed
|
||||
// rustfmt-trailing_comma: Always
|
||||
// rustfmt-wrap_comments: true
|
||||
|
||||
fn foo() {
|
||||
for elem in try!(gen_epub_book::ops::parse_descriptor_file(
|
||||
&mut try!(File::open(&opts.source_file.1).map_err(|_| {
|
||||
gen_epub_book::Error::Io {
|
||||
desc: "input file",
|
||||
op: "open",
|
||||
more: None,
|
||||
}
|
||||
})),
|
||||
"input file"
|
||||
)) {
|
||||
println!("{}", elem);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_content() {
|
||||
io::copy(
|
||||
try!(File::open(in_f).map_err(|_| {
|
||||
Error::Io {
|
||||
desc: "Content",
|
||||
op: "open",
|
||||
more: None,
|
||||
}
|
||||
})),
|
||||
w,
|
||||
);
|
||||
}
|
2
src/tools/rustfmt/tests/target/issue_3033.rs
Normal file
2
src/tools/rustfmt/tests/target/issue_3033.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerBinding::
|
||||
BluetoothRemoteGATTServerMethods;
|
4
src/tools/rustfmt/tests/target/issue_3245.rs
Normal file
4
src/tools/rustfmt/tests/target/issue_3245.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
fn main() {
|
||||
let x = 1;
|
||||
let y = 3;
|
||||
}
|
7
src/tools/rustfmt/tests/target/issue_3561.rs
Normal file
7
src/tools/rustfmt/tests/target/issue_3561.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
fn main() {
|
||||
7
|
||||
}
|
||||
|
||||
fn main() {
|
||||
7
|
||||
}
|
13
src/tools/rustfmt/tests/target/issue_4350.rs
Normal file
13
src/tools/rustfmt/tests/target/issue_4350.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
//rustfmt-format_macro_bodies: true
|
||||
|
||||
macro_rules! mto_text_left {
|
||||
($buf:ident, $n:ident, $pos:ident, $state:ident) => {{
|
||||
let cursor = loop {
|
||||
state = match iter.next() {
|
||||
None if $pos == DP::Start => break last_char_idx($buf),
|
||||
None /*some comment */ => break 0,
|
||||
};
|
||||
};
|
||||
Ok(saturate_cursor($buf, cursor))
|
||||
}};
|
||||
}
|
8
src/tools/rustfmt/tests/target/issue_5668.rs
Normal file
8
src/tools/rustfmt/tests/target/issue_5668.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
type Foo = impl Send;
|
||||
struct Struct<
|
||||
const C: usize = {
|
||||
let _: Foo = ();
|
||||
//~^ ERROR: mismatched types
|
||||
0
|
||||
},
|
||||
>;
|
11
src/tools/rustfmt/tests/target/skip_macro_invocations/all.rs
Normal file
11
src/tools/rustfmt/tests/target/skip_macro_invocations/all.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["*"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["*","items"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should also skip this invocation, as the wildcard covers it
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: []
|
||||
|
||||
// Should not skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should not skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
// rustfmt-skip_macro_invocations: ["items"]
|
||||
|
||||
// Should skip this invocation
|
||||
items!(
|
||||
const _: u8 = 0;
|
||||
);
|
||||
|
||||
// Should not skip this invocation
|
||||
renamed_items!(
|
||||
const _: u8 = 0;
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue