Skip to content

Commit

Permalink
Auto merge of #115790 - flip1995:clippyup, r=Manishearth
Browse files Browse the repository at this point in the history
Update Clippy

r? `@Manishearth`
  • Loading branch information
bors committed Sep 12, 2023
2 parents e5fedce + 2bd6936 commit efc1a0a
Show file tree
Hide file tree
Showing 175 changed files with 4,685 additions and 1,638 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ dependencies = [
"tester",
"tokio",
"toml 0.7.5",
"ui_test 0.18.1",
"ui_test 0.20.0",
"walkdir",
]

Expand Down Expand Up @@ -5596,9 +5596,9 @@ dependencies = [

[[package]]
name = "ui_test"
version = "0.18.1"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "640159421816683e558867ffc0e60ed3a3ed97ec6ccb22c03adb41bf87c5cfa4"
checksum = "bfd8fb9b15c8332cf51bfc2dc4830063b2446a9c9d732421b56f2478024a3971"
dependencies = [
"annotate-snippets",
"anyhow",
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/.github/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ unset CARGO_MANIFEST_DIR
# Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
# FIXME: How to match the clippy invocation in compile-test.rs?
./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/double_neg.rs 2>double_neg.stderr && exit 1
sed -e "s,tests/ui,\$DIR," -e "/= help/d" double_neg.stderr >normalized.stderr
sed -e "s,tests/ui,\$DIR," -e "/= help: for/d" double_neg.stderr > normalized.stderr
diff -u normalized.stderr tests/ui/double_neg.stderr

# make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
Expand Down
33 changes: 16 additions & 17 deletions src/tools/clippy/.github/workflows/clippy_bors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,14 @@ jobs:
needs: changelog
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
host: [x86_64-unknown-linux-gnu, i686-unknown-linux-gnu, x86_64-apple-darwin, x86_64-pc-windows-msvc]
exclude:
include:
- os: ubuntu-latest
host: x86_64-apple-darwin
- os: ubuntu-latest
host: x86_64-pc-windows-msvc
- os: macos-latest
host: x86_64-unknown-linux-gnu
- os: macos-latest
host: i686-unknown-linux-gnu
- os: macos-latest
host: x86_64-pc-windows-msvc
- os: windows-latest
host: x86_64-unknown-linux-gnu
- os: windows-latest
- os: ubuntu-latest
host: i686-unknown-linux-gnu
- os: windows-latest
host: x86_64-pc-windows-msvc
- os: macos-latest
host: x86_64-apple-darwin

runs-on: ${{ matrix.os }}
Expand All @@ -84,8 +74,17 @@ jobs:
- name: Checkout
uses: actions/checkout@v3

- name: Install i686 dependencies
if: matrix.host == 'i686-unknown-linux-gnu'
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install gcc-multilib zlib1g-dev:i386
- name: Install toolchain
run: rustup show active-toolchain
run: |
rustup set default-host ${{ matrix.host }}
rustup show active-toolchain
# Run
- name: Set LD_LIBRARY_PATH (Linux)
Expand All @@ -109,11 +108,11 @@ jobs:
run: cargo build --tests --features deny-warnings,internal

- name: Test
if: runner.os == 'Linux'
if: matrix.host == 'x86_64-unknown-linux-gnu'
run: cargo test --features deny-warnings,internal

- name: Test
if: runner.os != 'Linux'
if: matrix.host != 'x86_64-unknown-linux-gnu'
run: cargo test --features deny-warnings,internal -- --skip dogfood

- name: Test clippy_lints
Expand Down
5 changes: 5 additions & 0 deletions src/tools/clippy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5031,6 +5031,7 @@ Released 2018-09-13
[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections
[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items
[`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_out_of_bounds
[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
[`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero
Expand Down Expand Up @@ -5131,6 +5132,7 @@ Released 2018-09-13
[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_assert_message
[`missing_asserts_for_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_asserts_for_indexing
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames
Expand Down Expand Up @@ -5204,6 +5206,8 @@ Released 2018-09-13
[`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_underscore_binding
[`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_mangle_with_rust_abi
[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal
[`non_canonical_clone_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_clone_impl
[`non_canonical_partial_ord_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_partial_ord_impl
[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg
[`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions
[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty
Expand Down Expand Up @@ -5570,4 +5574,5 @@ Released 2018-09-13
[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
<!-- end autogenerated links to configuration documentation -->
2 changes: 1 addition & 1 deletion src/tools/clippy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ tempfile = { version = "3.2", optional = true }
termize = "0.1"

[dev-dependencies]
ui_test = "0.18.1"
ui_test = "0.20"
tester = "0.9"
regex = "1.5"
toml = "0.7.3"
Expand Down
3 changes: 3 additions & 0 deletions src/tools/clippy/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
- [Basics](development/basics.md)
- [Adding Lints](development/adding_lints.md)
- [Defining Lints](development/defining_lints.md)
- [Writing tests](development/writing_tests.md)
- [Lint Passes](development/lint_passes.md)
- [Emitting lints](development/emitting_lints.md)
- [Type Checking](development/type_checking.md)
- [Trait Checking](development/trait_checking.md)
- [Method Checking](development/method_checking.md)
- [Macro Expansions](development/macro_expansions.md)
- [Common Tools](development/common_tools_writing_lints.md)
Expand Down
217 changes: 217 additions & 0 deletions src/tools/clippy/book/src/development/emitting_lints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Emitting a lint

Once we have [defined a lint](defining_lints.md), written [UI
tests](writing_tests.md) and chosen [the lint pass](lint_passes.md) for the lint,
we can begin the implementation of the lint logic so that we can emit it and
gradually work towards a lint that behaves as expected.

Note that we will not go into concrete implementation of a lint logic in this
chapter. We will go into details in later chapters as well as in two examples of
real Clippy lints.

To emit a lint, we must implement a pass (see [Lint Passes](lint_passes.md)) for
the lint that we have declared. In this example we'll implement a "late" lint,
so take a look at the [LateLintPass][late_lint_pass] documentation, which
provides an abundance of methods that we can implement for our lint.

```rust
pub trait LateLintPass<'tcx>: LintPass {
// Trait methods
}
```

By far the most common method used for Clippy lints is [`check_expr`
method][late_check_expr], this is because Rust is an expression language and,
more often than not, the lint we want to work on must examine expressions.

> _Note:_ If you don't fully understand what expressions are in Rust, take a
> look at the official documentation on [expressions][rust_expressions]
Other common ones include the [`check_fn` method][late_check_fn] and the
[`check_item` method][late_check_item].

### Emitting a lint

Inside the trait method that we implement, we can write down the lint logic and
emit the lint with suggestions.

Clippy's [diagnostics] provides quite a few diagnostic functions that we can use
to emit lints. Take a look at the documentation to pick one that suits your
lint's needs the best. Some common ones you will encounter in the Clippy
repository includes:

- [`span_lint`]: Emits a lint without providing any other information
- [`span_lint_and_note`]: Emits a lint and adds a note
- [`span_lint_and_help`]: Emits a lint and provides a helpful message
- [`span_lint_and_sugg`]: Emits a lint and provides a suggestion to fix the code
- [`span_lint_and_then`]: Like `span_lint`, but allows for a lot of output
customization.

```rust
impl<'tcx> LateLintPass<'tcx> for LintName {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint
if some_lint_expr_logic(expr) {
span_lint_and_help(
cx, // < The context
LINT_NAME, // < The name of the lint in ALL CAPS
expr.span, // < The span to lint
"message on why the lint is emitted",
None, // < An optional help span (to highlight something in the lint)
"message that provides a helpful suggestion",
);
}
}
}
```

> Note: The message should be matter of fact and avoid capitalization and
> punctuation. If multiple sentences are needed, the messages should probably be
> split up into an error + a help / note / suggestion message.
## Suggestions: Automatic fixes

Some lints know what to change in order to fix the code. For example, the lint
[`range_plus_one`][range_plus_one] warns for ranges where the user wrote `x..y +
1` instead of using an [inclusive range][inclusive_range] (`x..=y`). The fix to
this code would be changing the `x..y + 1` expression to `x..=y`. **This is
where suggestions come in**.

A suggestion is a change that the lint provides to fix the issue it is linting.
The output looks something like this (from the example earlier):

```text
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:37:14
|
LL | for _ in 1..1 + 1 {}
| ^^^^^^^^ help: use: `1..=1`
```

**Not all suggestions are always right**, some of them require human
supervision, that's why we have [Applicability][applicability].

Applicability indicates confidence in the correctness of the suggestion, some
are always right (`Applicability::MachineApplicable`), but we use
`Applicability::MaybeIncorrect` and others when talking about a suggestion that
may be incorrect.

### Example

The same lint `LINT_NAME` but that emits a suggestion would look something like this:

```rust
impl<'tcx> LateLintPass<'tcx> for LintName {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint
if some_lint_expr_logic(expr) {
span_lint_and_sugg( // < Note this change
cx,
LINT_NAME,
span,
"message on why the lint is emitted",
"use",
format!("foo + {} * bar", snippet(cx, expr.span, "<default>")), // < Suggestion
Applicability::MachineApplicable,
);
}
}
}
```

Suggestions generally use the [`format!`][format_macro] macro to interpolate the
old values with the new ones. To get code snippets, use one of the `snippet*`
functions from `clippy_utils::source`.

## How to choose between notes, help messages and suggestions

Notes are presented separately from the main lint message, they provide useful
information that the user needs to understand why the lint was activated. They
are the most helpful when attached to a span.

Examples:

### Notes

```text
error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.
--> $DIR/drop_forget_ref.rs:10:5
|
10 | forget(&SomeStruct);
| ^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::forget-ref` implied by `-D warnings`
note: argument has type &SomeStruct
--> $DIR/drop_forget_ref.rs:10:12
|
10 | forget(&SomeStruct);
| ^^^^^^^^^^^
```

### Help Messages

Help messages are specifically to help the user. These are used in situation
where you can't provide a specific machine applicable suggestion. They can also
be attached to a span.

Example:

```text
error: constant division of 0.0 with 0.0 will always result in NaN
--> $DIR/zero_div_zero.rs:6:25
|
6 | let other_f64_nan = 0.0f64 / 0.0;
| ^^^^^^^^^^^^
|
= help: consider using `f64::NAN` if you would like a constant representing NaN
```

### Suggestions

Suggestions are the most helpful, they are changes to the source code to fix the
error. The magic in suggestions is that tools like `rustfix` can detect them and
automatically fix your code.

Example:

```text
error: This `.fold` can be more succinctly expressed as `.any`
--> $DIR/methods.rs:390:13
|
390 | let _ = (0..3).fold(false, |acc, x| acc || x > 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`
|
```

### Snippets

Snippets are pieces of the source code (as a string), they are extracted
generally using the [`snippet`][snippet_fn] function.

For example, if you want to know how an item looks (and you know the item's
span), you could use `snippet(cx, span, "..")`.

## Final: Run UI Tests to Emit the Lint

Now, if we run our [UI test](writing_tests.md), we should see that Clippy now
produces output that contains the lint message we designed.

The next step is to implement the logic properly, which is a detail that we will
cover in the next chapters.

[diagnostics]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/index.html
[late_check_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_expr
[late_check_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_fn
[late_check_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_item
[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
[rust_expressions]: https://doc.rust-lang.org/reference/expressions.html
[`span_lint`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint.html
[`span_lint_and_note`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_note.html
[`span_lint_and_help`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html
[`span_lint_and_sugg`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
[`span_lint_and_then`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_then.html
[range_plus_one]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one
[inclusive_range]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html
[applicability]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_errors/enum.Applicability.html
[snippet_fn]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/source/fn.snippet.html
[format_macro]: https://doc.rust-lang.org/std/macro.format.html
Loading

0 comments on commit efc1a0a

Please sign in to comment.