New Lint: Manual Flatten
This is a draft PR for [Issue 6564](https://github.com/rust-lang/rust-clippy/issues/6564).
r? `@camsteffen`
- \[x] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`
---
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: Add new lint [`manual_flatten`] to check for loops over a single `if let` expression with `Result` or `Option`.
Fix let_and_return false positive
The issue:
See this Rust playground link: https://play.rust-lang.org/?edition=2018&gist=12cb5d1e7527f8c37743b87fc4a53748
Run the above with clippy to see the following warning:
```
warning: returning the result of a `let` binding from a block
--> src/main.rs:24:5
|
23 | let value = Foo::new(&x).value();
| --------------------------------- unnecessary `let` binding
24 | value
| ^^^^^
|
= note: `#[warn(clippy::let_and_return)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
help: return the expression directly
|
23 |
24 | Foo::new(&x).value()
|
```
Implementing the suggested fix, removing the temporary let binding,
yields a compiler error:
```
error[E0597]: `x` does not live long enough
--> src/main.rs:23:14
|
23 | Foo::new(&x).value()
| ---------^^-
| | |
| | borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
24 | }
| -
| |
| `x` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `Foo`
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
23 | let x = Foo::new(&x).value(); x
| ^^^^^^^ ^^^
```
The fix:
Of course, clippy looks like it should already handle this edge case;
however, it appears `utils::fn_def_id` is not returning a `DefId` for
`Foo::new`. Changing the `qpath_res` lookup to use the child Path
`hir_id` instead of the parent Call `hir_id` fixes the issue.
changelog: none
Do not lint when range is completely included into another one
This fix has been developed following this [comment](https://github.com/rust-lang/rust-clippy/issues/5986#issuecomment-703313548).
So this will be linted:
```
|----------|
|-----------|
```
Now this won't be linted:
```
|---|
|--------------------|
```
and this will still lint:
```
|--------|
|--------------|
```
Fixes: #5986
changelog: Fix FPs in match_overlapping_arm, when first arm is completely included in second arm
The issue:
See this Rust playground link: https://play.rust-lang.org/?edition=2018&gist=12cb5d1e7527f8c37743b87fc4a53748
Run the above with clippy to see the following warning:
```
warning: returning the result of a `let` binding from a block
--> src/main.rs:24:5
|
23 | let value = Foo::new(&x).value();
| --------------------------------- unnecessary `let` binding
24 | value
| ^^^^^
|
= note: `#[warn(clippy::let_and_return)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
help: return the expression directly
|
23 |
24 | Foo::new(&x).value()
|
```
Implementing the suggested fix, removing the temporary let binding,
yields a compiler error:
```
error[E0597]: `x` does not live long enough
--> src/main.rs:23:14
|
23 | Foo::new(&x).value()
| ---------^^-
| | |
| | borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
24 | }
| -
| |
| `x` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `Foo`
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
23 | let x = Foo::new(&x).value(); x
| ^^^^^^^ ^^^
```
The fix:
Of course, clippy looks like it should already handle this edge case;
however, it appears `utils::fn_def_id` is not returning a `DefId` for
`Foo::new`. Changing the `qpath_res` lookup to use the child Path
`hir_id` instead of the parent Call `hir_id` fixes the issue.
Improve safety of `LateContext::qpath_res`
This is my first rustc code change, inspired by hacking on clippy!
The first change is to clear cached `TypeckResults` from `LateContext` when visiting a nested item. I took a hint from [here](5e91c4ecc0/compiler/rustc_privacy/src/lib.rs (L1300)).
Clippy has a `qpath_res` util function to avoid a possible ICE in `LateContext::qpath_res`. But the docs of `LateContext::qpath_res` promise no ICE. So this updates the `LateContext` method to keep its promises, and removes the util function.
Related: rust-lang/rust-clippy#4545
CC ````````````@eddyb```````````` since you've done related work
CC ````````````@flip1995```````````` FYI
Make more traits of the From/Into family diagnostic items
Following traits are now diagnostic items:
- `From` (unchanged)
- `Into`
- `TryFrom`
- `TryInto`
This also adds symbols for those items:
- `into_trait`
- `try_from_trait`
- `try_into_trait`
Related: https://github.com/rust-lang/rust-clippy/pull/6620#discussion_r562482587
Refractor a few more types to `rustc_type_ir`
In the continuation of #79169, ~~blocked on that PR~~.
This PR:
- moves `IntVarValue`, `FloatVarValue`, `InferTy` (and friends) and `Variance`
- creates the `IntTy`, `UintTy` and `FloatTy` enums in `rustc_type_ir`, based on their `ast` and `chalk_ir` equilavents, and uses them for types in the rest of the compiler.
~~I will split up that commit to make this easier to review and to have a better commit history.~~
EDIT: done, I split the PR in commits of 200-ish lines each
r? `````@nikomatsakis````` cc `````@jackh726`````
Similar names ignore underscore prefixed names
changelog: Ignore underscore-prefixed names for similar_names
IMO, this lint is not very helpful for underscore-prefixed variables. Usually they are unused or are just there to ignore part of a destructuring.
`manual_filter_map` and `manual_find_map`
changelog: Add `manual_filter_map` and replace `find_map` with `manual_find_map`
Replaces #6453Fixes#3188Fixes#4193
~Depends on #6567 (to fix an internal lint false positive)~
This replaces `filter_map` and `find_map` with `manual_filter_map` and `manual_find_map` respectively. However, `filter_map` is left in place since it is used for a variety of other cases. See discussion in #6453.
Following traits are now diagnostic items:
- `From` (unchanged)
- `Into`
- `TryFrom`
- `TryInto`
This also adds symbols for those items:
- `into_trait`
- `try_from_trait`
- `try_into_trait`
Doc markdown
I added "WebGL" along the lines of the existing "OpenGL" to the whitelist of `doc_markdown` as I found this to be a pretty common term.
(this is a follow-up of the now closed https://github.com/rust-lang/rust-clippy/pull/6388)
changelog: Whitelist "WebGL" in `doc_markdown`.
Fix false positive in write_literal and print_literal (numeric literals)
changelog: No longer lint numeric literals in [`write_literal`] and [`print_literal`].
Fixes#6335
Fix the reversed suggestion message of `stable_sort_primitive`.
Now Clippy emits `stable_sort_primitive` warning as follows:
```
warning: used sort instead of sort_unstable to sort primitive type `usize`
--> src\asm.rs:41:13
|
41 | self.successors.sort();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `self.successors.sort_unstable()`
|
= note: `#[warn(clippy::stable_sort_primitive)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive
```
I think the position of `sort` and `sort_unstable` in the first line should be reversed.
changelog: Fix the reversed suggestion message of `stable_sort_primitive`.
Fixes#81007
Previously, we would fail to collect tokens in the proper place when
only builtin attributes were present. As a result, we would end up with
attribute tokens in the collected `TokenStream`, leading to duplication
when we attempted to prepend the attributes from the AST node.
We now explicitly track when token collection must be performed due to
nomterminal parsing.
Fix path_to_res for enum inherent items
changelog: none
I tried to add `Option::is_some` to the paths but got a false positive from the invalid paths lint. Turns out the `path_to_res` function does not find inherent impls for enums. I fixed this and took the liberty to do some additional cleanup in the method.
It is fairly common to divide some length in bytes by the byte-size of a
single element before creating a `from_raw_parts` slice or similar
operation. This lint would erroneously disallow such expressions.
Just in case, instead of simply disabling this lint in the RHS of a
division, keep track of the inversion and enable it again on recursive
division.
New Lint: inspect_then_for_each
**Work In Progress**
This PR addresses [Issue 5209](https://github.com/rust-lang/rust-clippy/issues/5209) and adds a new lint called `inspect_then_for_each`.
Current seek some guidance.
If you added a new lint, here's a checklist for things that will be
checked during review or continuous integration.
- \[x] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
---
changelog: Add [`inspect_for_each`] lint for the use of `inspect().for_each()` on `Iterators`.
New lint: redundant_slicing
changelog: Added lint: `redundant_slicing`
fixes#6519
This will trigger on any type which implements `Index<RangeFull>` that returns the input type. This would be a false positive if the implementation does something other than return itself, but I'm not sure why you would ever want to do that.
Fix the ICE 6539
Fixes#6539
It happened because `zero_sized_map_values` used `layout_of` with types from type aliases, which is essentially the same as the ICE 4968.
---
changelog: Fix an ICE in `zero_sized_map_values`
Fix FP with empty return for `needless_return` lint
This fixes a false positive in `needless_return` lint, when triggered in a closure using `return` statement without value.
Fixes: #6501
changelog: none
Case sensitive file extensions
Closes#6425
Looks for ends_with methods calls with case sensitive extension comparisons.
changelog: Add new lint that warns about case-sensitive file extension comparisons.
Rework diagnostics for wrong number of generic args (fixes#66228 and #71924)
This PR reworks the `wrong number of {} arguments` message, so that it provides more details and contextual hints.
This makes it possible to pass the `Impl` directly to functions, instead
of having to pass each of the many fields one at a time. It also
simplifies matches in many cases.
Catch `pointer::cast` too in `cast_ptr_alignment`
Fixes#4708
Although there were some discussion in the issue, this PR implements the original feature. I think `cast_ptr_alignment` should exist as it is, separated from `ptr_as_ptr`.
---
changelog: Extend `cast_ptr_alignment` lint for the `pointer::cast` method
Fix FP for `boxed_local` lint in default trait fn impl
Fix FP on default trait function implementation on `boxed_local` lint.
Maybe I checked too much when looking if `self` is carrying `Self` in its bound type.
I can't find a good test case for this, so it could be too much conservative.
Let me know if you think only detecting `self` parameter is enough.
Fixes: #4804
changelog: none
Fix derive and macro related false positives in `field_reassign_with_default`
Closes#6545
changelog: Fix derive and macro related false positives in [`field_reassign_with_default`]
Add a new lint `ptr_as_ptr`
This PR adds a new lint `ptr_as_ptr` which checks for `as` casts between raw pointers without changing its mutability and suggest replacing it with `pointer::cast`. Closes#5890.
Open question: should this lint be `pedantic` or `style`? I set it `pedantic` for now because the original post suggests using it, but I think the lint also fits well to `style`.
---
changelog: New lint `ptr_as_ptr`
Fix: Empty enum never type suggested only if the feature is enabled
This PR addresses [Issue 6422](https://github.com/rust-lang/rust-clippy/issues/6422). Instead of always recommending `never type` for empty enums, Clippy would only recommend [the lint](https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum) if [LatePass.TyCtxt](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html) has `features().never_type` enabled.
- \[ ] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`
---
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: Only trigger [`empty_enum`] lint if `never_type` feature is enabled.
New lint: vec_init_then_push
fixes: #1483
This will trigger on `new`, `default`, and `with_capacity` when the given capacity is less than or equal to the number of push calls. Is there anything else this should trigger on?
changelog: Added lint: `vec_init_then_push`
This splits up clippy::collapsible_if into collapsible_if for
if x {
if y { }
}
=>
if x && y { }
and collapsible_else_if for
if x {
} else {
if y { }
}
=>
if x {
} else if y {
}
so that we can lint for only the latter but not the first if we desire.
changelog: collapsible_if: split up linting for if x {} else { if y {} } into collapsible_else_if lint
Clippy treated Rust 2021 as Rust 2015, because 2018 was checked with
`==` instead of `>=`. This fixes that, such that 2018-specific things
are also enabled for 2021.
- Adds optional default values to const generic parameters in the AST
and HIR
- Parses these optional default values
- Adds a `const_generics_defaults` feature gate
Reassign default private
changelog: fix field_reassign_with_default false positive
* Fix#6344
* Fix assumption that `field: Default::default()` is the same as `..Default::default()`
* Cleanup some redundant logic
Added from_over_into lint
Closes#6456
Added a lint that searches for implementations of `Into<..>` and suggests to implement `From<..>` instead, as it comes with a default implementation of `Into`. Category: style.
changelog: added `from_over_into` lint
Lint also in trait def for `wrong_self_convention`
Extends `wrong_self_convention` to lint also in trait definition.
By the way, I think the `wrong_pub_self_convention` [example](dd826b4626/clippy_lints/src/methods/mod.rs (L197)) is misleading.
On [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=32615ab3f6009e7e42cc3754be0ca17f), it fires `wrong_self_convention`, so the example (or the lint maybe?) needs to be reworked.
The difference with `wrong_self_convention` [example](dd826b4626/clippy_lints/src/methods/mod.rs (L172)) is mainly the `pub` keyword on the method `as_str`, but the lint doesn't use the function visibility as condition to choose which lint to fire (in fact it uses the visibility of the impl item).
fixes: #6307
changelog: Lint `wrong_self_convention` lint in trait def also
needless_doctest_main: handle correctly parse errors
Before this change, finding an error when parsing a doctest would make Clippy exit without emitting an error. Now we properly catch a fatal error and ignore it.
Also, if a doctest specifies an edition in the info line, it will be used when parsing it.
changelog: needless_doctest_main: handle correctly parse errors
Fixes#6022
Move binder for dyn to each list item
This essentially changes `ty::Binder<&'tcx List<ExistentialTraitRef>>` to `&'tcx List<ty::Binder<ExistentialTraitRef>>`.
This is a first step in moving the `dyn Trait` representation closer to Chalk, which we've talked about in `@rust-lang/wg-traits.`
r? `@nikomatsakis`
Implement if-let match guards
Implements rust-lang/rfcs#2294 (tracking issue: #51114).
I probably should do a few more things before this can be merged:
- [x] Add tests (added basic tests, more advanced tests could be done in the future?)
- [x] Add lint for exhaustive if-let guard (comparable to normal if-let statements)
- [x] Fix clippy
However since this is a nightly feature maybe it's fine to land this and do those steps in follow-up PRs.
Thanks a lot `@matthewjasper` ❤️ for helping me with lowering to MIR! Would you be interested in reviewing this?
r? `@ghost` for now
Fixing a false positive for the `match_single_binding` lint #5552
This is a fix for a false positive in the `match_single_binding` lint when using `#[cfg()]` on a branch. It is sadly a bit hacky but maybe the best solution as rust removes the other branch from the AST before we can even validate it. This fix looks at the code snippet itself and returns if it includes another thick arrow `=>` besides the one matching arm we found. This can again cause false negatives if someone has the following code:
```rust
match x {
// => <-- Causes a false negative
_ => 1,
}
```
I thought about making the code more complex and maybe validating against other things like the `#[cfg()]` macro but I believe that this is the best solution. This has basically switched the issue from a false positive to a false negative in a very specific case.
I'm happy to make some changes if you have any suggestions 🙃.
---
Fixes#5552
changelog: Fixed a false positive in the `match_single_binding` lint with `#[cfg()]` macro
Add MSRV to more lints specified in #6097
add MSRV to more lints specified in #6097
add instructions for adding msrv in other lints
update tests
- [x] `redundant_field_names` requires Rust 1.17 due to suggest feature stablized in that version.
- [x] `redundant_static_lifetimes` requires Rust 1.17 due to suggest feature stablized in that version.
- [x] `filter_map_next` requires Rust 1.30 due to suggest `Iterator::find_map`.
- [x] `checked_conversions` requires Rust 1.34 due to suggest `TryFrom`.
- [x] `match_like_matches_macro` requires Rust 1.42 due to suggest `matches!`. Addressed in #6201
- [x] `manual_strip` requires Rust 1.45 due to suggest `str::{strip_prefix, strip_suffix}`. Addressed in #6201
- [x] `option_as_ref_deref` requires Rust 1.40 due to suggest `Option::{as_deref, as_deref_mut}`. Addressed in #6201
- [x] `manual_non_exhaustive` requires Rust 1.40 due to suggest `#[non_exhaustive]`. Addressed in #6201
- [x] `manual_range_contains` requires Rust 1.35 due to suggest `Range*::contains`.
- [x] `use_self` requires Rust 1.37 due to suggest `Self::Variant on enum`.
- [x] `mem_replace_with_default` requires Rust 1.40 due to suggest `mem::take`.
- [x] `map_unwrap_or` requires Rust 1.41 due to suggest `Result::{map_or, map_or_else}`.
- [x] `missing_const_for_fn` requires Rust 1.46 due to `match/if/loop in const fn` needs that version.
changelog: Add MSRV config to more lints. ^This is now the complete list, AFAWK
Add lint print_stderr
Resolves#6348
Almost identical to print_stdout, this lint applies to the `eprintln!` and `eprint!` macros rather than `println!` and `print!`.
changelog: Add new lint [`print_stderr`]. [`println_empty_string`] and [`print_with_newline`] now apply to `eprint!()` and `eprintln!()` respectively.
Added a lint-fraction-readability flag to the configuration
This adds an option to disable the `unreadable_literal` lint for floats with a longer fraction. This allows users to write `0.100200300` without getting a warning. Fixes#4176
I have some open questions about this PR:
1. I've named the option `lint-fraction-readability` is this a good name or should I rename it to something else?
2. What should the default configuration value be?
* The current default value is `true` as this was also the previous default.
3. Do I have to document this new option somewhere else or will it be extracted from the code comment?
4. The current fix option will also rewrite the fraction if the integer part violates the `unreadable_literal` lint it would otherwise also trigger the `inconsistent_digit_grouping` lint. Is this also okay?
* `1.100200300` will be unaffected by the fix function
* `100200300.100200300` will be effected and fixed to `100_200_300.100_200_300`
---
The project needed some getting used to but I'm happy with the result. A big thank you to `@flip1995` for giving me some pointers for this implementation and to everyone for the great introduction documentation!
---
changelog: Added the `unreadable-literal-lint-fractions` configuration to disable the `unreadable_literal` lint for fractions
Moved map_err_ignore to restriction and updated help message
This MR moves map_err_ignore lint from `pedantic` to the `restriction` category of lints and updates the help message to give the user an option to ignore the lint by naming the closure variable e.g. `.map_err(|_ignored| ...`
---
changelog: move map_err_ignore to restriction category
Specifically ptr::{sub, wrapping_sub, add, wrapping_add, offset, wrapping_offset} and slice::{from_raw_parts, from_raw_parts_mut}
The lint now also looks for size_of calls through casts (Since offset takes an isize)
Also fix review comments:
- Use const arrays and iterate them for the method/function names
- merge 2 if_chain's into one using a rest pattern
- remove unnecessary unsafe block in test
And make the lint only point to the count expression instead of the entire function call