Skip to content

Update Clippy #115790

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 119 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
f76615a
New chapter: Emitting lints
blyxyas Apr 5, 2023
8277e7d
Don't pass extra generic arguments in `needless_borrow`
Jarcho Jul 30, 2023
f746e19
allow trait alias DefIds in `implements_trait_with_env_from_iter`
y21 Aug 14, 2023
3c50a0a
Add new chapter: "Trait Checking"
blyxyas Apr 10, 2023
94387ef
Fixes based on reviews
blyxyas Apr 18, 2023
b2e1ede
Change Tokio example description to Core
blyxyas Apr 19, 2023
2a3f75b
Fix CI
blyxyas Apr 19, 2023
289bafa
New chapter: Writing tests
blyxyas Apr 3, 2023
864df49
Formatting, slimming and ui-toml tests
flip1995 Apr 16, 2023
32dc7c5
Applying review suggestions
flip1995 Aug 18, 2023
9b8b835
Formatting and minor wording fixes
flip1995 Aug 18, 2023
8ee6ca0
Update rustfix section to new ui-test crate
flip1995 Aug 18, 2023
7721567
fix [`undocumented_unsafe_blocks`] not able to detect comment for glo…
J-ZhengLi Aug 22, 2023
82f2e52
Fix span when linting `explicit_auto_deref` immediately after `needle…
Jarcho Aug 22, 2023
42c6492
[`unnecessary_unwrap`]: lint on `.as_ref().unwrap()`
y21 Aug 23, 2023
fb6fad2
[`iter_overeager_cloned`]: detect .cloned().all() and .cloned().any()
lengyijun Aug 20, 2023
70f6321
when terminating during unwinding, show the reason why
RalfJung Aug 21, 2023
2faa43c
[arithmetic_side_effects] Fix #11393
c410-f3r Aug 24, 2023
d802ab2
Dogfood
c410-f3r Aug 24, 2023
86b6644
new lint: `iter_out_of_bounds`
y21 Aug 24, 2023
cc61aee
Merge commit '080b587854a73f2a8cbaecff1884860a78e2ff37' into clippyup
flip1995 Aug 24, 2023
d65c459
Auto merge of #11360 - lengyijun:any_all, r=blyxyas
bors Aug 24, 2023
dba7763
[`if_then_some_else_none`]: look into local initializers
y21 Aug 24, 2023
19eaafb
Auto merge of #11338 - y21:issue11337, r=Centri3
bors Aug 24, 2023
11072b5
lint vecs, version bump, more tests
y21 Aug 24, 2023
706c48b
Auto merge of #11395 - c410-f3r:let-chain, r=Manishearth
bors Aug 25, 2023
6eec4a3
remove unecessary code
J-ZhengLi Aug 25, 2023
90fcc67
fix "derivable_impls: attributes are ignored"
kiscad Aug 25, 2023
e43c234
allow float_cmp when lhs is a custom type
markhuang1212 Aug 23, 2023
d78d26a
Remove redundant auxiliary test files
Alexendoo Aug 25, 2023
f80c55d
add a test for statics and doc comments
y21 Aug 25, 2023
7ff8716
Typo
smoelius Aug 25, 2023
d2f6522
update uitest enum_clike_unportable_variant
kiscad Aug 24, 2023
4736908
Auto merge of #11404 - mojave2:issue-11368, r=matthiaskrgr
bors Aug 26, 2023
74a46a7
Auto merge of #11391 - mojave2:fix-uitest-enum_clike_unportable_varia…
bors Aug 26, 2023
8c20739
Auto merge of #11411 - smoelius:patch-1, r=Alexendoo
bors Aug 26, 2023
33cc140
add more negative tests
y21 Aug 27, 2023
8de52e5
Auto merge of #11405 - Alexendoo:redundant-aux, r=giraffate
bors Aug 28, 2023
be55a96
Add config flag for reborrows in explicit_iter_loop
Benjscho Aug 28, 2023
4118738
Auto merge of #11401 - y21:issue11394, r=xFrednet
bors Aug 28, 2023
5cc5f27
Auto merge of #11385 - markhuang1212:master, r=blyxyas
bors Aug 28, 2023
b97eaab
Auto merge of #11387 - y21:issue11371, r=blyxyas
bors Aug 28, 2023
6a876f2
Bump ui_test
oli-obk Aug 29, 2023
af02b43
Auto merge of #115183 - flip1995:clippyup, r=Manishearth,oli-obk
bors Aug 29, 2023
11d8e55
Bump ui_test to 0.18.1
oli-obk Aug 30, 2023
6eb7a46
Documentation Formatting
TDecking Aug 30, 2023
1f8b204
Second instance of `vec!` with parenthesis.
TDecking Aug 30, 2023
3da21b0
Auto merge of #11396 - y21:issue11345, r=Jarcho
bors Aug 30, 2023
563abf9
[`implied_bounds_in_impls`]: move to nursery and fix ICEs
y21 Aug 30, 2023
55bd0fe
Fix metadata collection
Benjscho Aug 30, 2023
c50d86f
Auto merge of #11418 - Benjscho:explicit_iter_loop_config, r=llogiq
bors Aug 31, 2023
77e395e
Auto merge of #11376 - Jarcho:issue_11366, r=llogiq
bors Aug 31, 2023
299fbce
Check binary operators and attributes in disallowed_macros
Alexendoo Aug 31, 2023
b54bac9
new lint: `missing_assert_for_indexing`
y21 Apr 21, 2023
790922c
update ui tests and some minor cleanups
y21 Aug 31, 2023
79c684d
Auto merge of #10692 - y21:missing-asserts, r=Alexendoo
bors Aug 31, 2023
c1f8ae3
Auto merge of #11430 - TDecking:vec-fmt, r=giraffate
bors Sep 1, 2023
b3136a8
[`clippy`] Use symbols intended for `arithmetic_side_effects`
c410-f3r Aug 31, 2023
aeed86c
Bump ui_test to 0.20
oli-obk Aug 31, 2023
acdffd7
Auto merge of #11427 - oli-obk:ui_test_bump, r=Alexendoo
bors Sep 1, 2023
f595f1e
Use multipart suggestions for raw string lints
Alexendoo Aug 27, 2023
a8b5245
Auto merge of #11416 - Alexendoo:raw-strings-multipart, r=xFrednet
bors Sep 1, 2023
b0eaa84
fix some comments
cuishuang Sep 1, 2023
f5efade
Merge from rustc
RalfJung Sep 2, 2023
6801189
Rewrite `never_loop` as a strict reachability pass
digama0 Sep 2, 2023
e1a3f63
Apply suggestion
blyxyas Sep 2, 2023
aa371eb
Auto merge of #10596 - blyxyas:book-write_tests, r=flip1995
bors Sep 2, 2023
79e31cb
DefaultUnionRepresentation: explain why we only warn about unions wit…
RalfJung Sep 2, 2023
a26937f
Fix links
blyxyas Sep 2, 2023
3cf1087
Auto merge of #10598 - blyxyas:book-emit_lints, r=flip1995
bors Sep 2, 2023
a45feda
Auto merge of #11445 - cuishuang:master, r=Centri3
bors Sep 2, 2023
7cf96da
Auto merge of #11448 - RalfJung:DefaultUnionRepresentation, r=blyxyas
bors Sep 2, 2023
92d47db
Add `emitting_lints` link to `Writing tests` and remove that `FIXME`
blyxyas Aug 18, 2023
b65e544
Auto merge of #10626 - blyxyas:book-trait_checking, r=flip1995
bors Sep 2, 2023
39b316d
an empty match diverges
digama0 Sep 2, 2023
b3980d8
catch never loops through diverging functions
digama0 Sep 2, 2023
44f64ac
`never_loop` catches `loop { panic!() }`
digama0 Sep 2, 2023
b9906ac
Auto merge of #11450 - digama0:never_loop2, r=llogiq
bors Sep 2, 2023
78983d9
[`slow_vector_initialization`]: use the source span of `vec![]` macro
y21 Sep 2, 2023
5120632
[`slow_vector_initialization`]: only warn on `vec![]` expn
y21 Sep 2, 2023
61a2f97
skip `todo` / `unimplemented` in `never_loop`
digama0 Sep 3, 2023
a0ebcc3
Merge from rustc
RalfJung Sep 3, 2023
e0014af
Add suggestions for std_instead_of_core
tom-anders Sep 3, 2023
c317077
Use relative positions inside a SourceFile.
cjgillot Sep 3, 2023
d5f0f44
Fix clippy.
cjgillot Sep 3, 2023
1317378
fix todo item check, remove unimplemented
digama0 Sep 3, 2023
3de0f19
Auto merge of #11437 - y21:issue-11422, r=xFrednet
bors Sep 3, 2023
7262145
[`implied_bounds_in_impl`]: fix suggestion for assoc types
y21 Sep 3, 2023
60a18b7
Auto merge of #11449 - blyxyas:book-write_tests, r=flip1995
bors Sep 3, 2023
32e2511
extract lint emitting into separate fn
y21 Sep 3, 2023
f13e1f4
Auto merge of #11259 - Jarcho:ice_10253, r=dswij
bors Sep 4, 2023
4e0a346
fix vec.rs test, comment
digama0 Sep 4, 2023
da882f0
Auto merge of #11455 - digama0:never_loop3, r=Centri3,dswij
bors Sep 4, 2023
bcf856b
Auto merge of #11375 - J-ZhengLi:issue11246, r=Centri3
bors Sep 4, 2023
a86e758
Adjust clippy tests with new rustc help suggestion for lints
Urgau Aug 1, 2023
822c7df
Add ui_test error annotations in existing tests
samueltardieu Sep 4, 2023
2f5c445
Ignore wildcards in function arguments and local bindings
samueltardieu Sep 2, 2023
eb0df1d
Auto merge of #11454 - samueltardieu:issue-11403, r=Centri3
bors Sep 5, 2023
bbf67c3
Preserve literals and range kinds in `manual_range_patterns`
Alexendoo Sep 4, 2023
30846b1
add comments in code to clarify and fix typo
y21 Sep 5, 2023
953901e
Auto merge of #115507 - cjgillot:relative-source-file, r=oli-obk
bors Sep 5, 2023
0d36d57
Auto merge of #11439 - Alexendoo:disallowed-macros-bins-attrs, r=xFre…
bors Sep 6, 2023
60ffff0
Fix i686-unknown-linux-gnu CI job
Alexendoo Sep 6, 2023
69fcbfd
Auto merge of #11466 - Alexendoo:ci-32bit, r=flip1995
bors Sep 6, 2023
415ba21
Auto merge of #11451 - y21:issue11408, r=xFrednet
bors Sep 7, 2023
6150bf5
Auto merge of #11462 - Alexendoo:manual-range-patterns-preserve-liter…
bors Sep 7, 2023
d2b0843
Merge remote-tracking branch 'upstream/master' into rustup
flip1995 Sep 7, 2023
d780573
Bump nightly version -> 2023-09-07
flip1995 Sep 7, 2023
25e8639
Fix clippy driver stderr test
flip1995 Sep 7, 2023
184c971
Fix 32bit tests
flip1995 Sep 7, 2023
253f1c4
Auto merge of #11469 - flip1995:rustup, r=flip1995
bors Sep 7, 2023
b99921a
Rename incorrect_impls to non_canonical_impls, move them to warn by d…
Alexendoo Sep 8, 2023
27165ac
Auto merge of #11456 - tom-anders:std_instead_of_core_suggestion, r=M…
bors Sep 8, 2023
ec6f1bd
Auto merge of #11358 - Alexendoo:incorrect-to-manual-impls, r=Jarcho
bors Sep 9, 2023
8c48b93
Auto merge of #11459 - y21:issue11435, r=blyxyas
bors Sep 9, 2023
c548d11
Auto deref does not apply on union field
samueltardieu Sep 10, 2023
98363cb
Auto merge of #11477 - samueltardieu:11474, r=xFrednet
bors Sep 11, 2023
9ff2e4e
Merge commit '98363cbf6a7c3f8b571a7d92a3c645bb4376e4a6' into clippyup
flip1995 Sep 12, 2023
780cbf3
Update Cargo.lock (ui_test update)
flip1995 Sep 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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