fix: false positive for `option_env!` in `ifs_same_cond`
Clippy had a false positive for with `ifs_same_cond` when two if-let expressions have an `option_env!` macro. The fix is similar to the `env!` macro fix.
The following example had a clippy error:
```rust
if let Some(env1) = option_env!("ENV1") {
// ...
} else if let Some(env2) = option_env!("ENV2") {
// ...
}
```
See https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=01b85c61b56ddd900117fb247af04824
changelog: [`ifs_same_cond`]: fix false positive when using `option_env!` in if-let expressions.
[`unnecessary_literal_unwrap`]: Fix ICE on None.unwrap_or_default()
Fixes#11099Fixes#11064
I'm running into #11099 (cc `@y21)` on my Rust codebase. Clippy ICEs on this code when evaluating the `unnecessary_literal_unwrap` lint:
```rust
fn main() {
let val1: u8 = None.unwrap_or_default();
}
```
This fixes that ICE and adds an message specifically for that case:
```
error: used `unwrap_or_default()` on `None` value
--> $DIR/unnecessary_literal_unwrap.rs:26:5
|
LL | None::<String>.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()`
```
This PR also fixes the same ICE with `None.unwrap_or_else` (by giving the generic error message for the lint in that case).
changelog: Fix ICE in `unnecessary_literal_unwrap` on `None.unwrap_or_default()`
Clippy had a false positive for with `ifs_same_cond` when two
if-let expressions have an `option_env!` macro. The fix is similar to the
`env!` macro fix.
The following example had a clippy error:
```rust
if let Some(env1) = option_env!("ENV1") {
// ...
} else if let Some(env2) = option_env!("ENV2") {
// ...
}
```
See https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=01b85c61b56ddd900117fb247af04824
changelog: Fix [`ifs_same_cond`] false positive when using `option_env!` in if-let expressions.
[`manual_filter_map`]: lint on `matches` and pattern matching
Fixes#8010
Previously this lint only worked specifically for a very limited set of methods on the filter call (`.filter(|opt| opt.is_some())` and `.filter(|res| res.is_ok())`). This PR extends it to also recognize `matches!` in the `filter` and pattern matching with `if let` or `match` in the `map`.
Example:
```rs
enum Enum {
A(i32),
B,
}
let _ = [Enum::A(123), Enum::B].into_iter()
.filter(|x| matches!(x, Enum::A(_)))
.map(|x| if let Enum::A(s) = x { s } else { unreachable!() });
```
Now suggests:
```diff
- .filter(|x| matches!(x, Enum::A(_))).map(if let Enum::A(s) = x { s } else { unreachable!() })
+ .filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })
```
Adding this required a somewhat large change in code because it originally seemed to be specifically written with only method calls in the filter in mind, and `matches!` has different behavior in the map, so this new setup should make it possible to support more "generic" cases that need different handling for the filter and map calls.
changelog: [`manual_filter_map`]: lint on `matches` and pattern matching (and some internal refactoring)
Fix `unwrap_or_else_default` false positive
This PR fixes a false positive in the handling of `unwrap_or_else` with a default value when the value is needed for type inference.
An easy example to exhibit the false positive is the following:
```rust
let option = None;
option.unwrap_or_else(Vec::new).push(1);
```
The following code would not compile, because the fact that the value is a `Vec` has been lost:
```rust
let option = None;
option.unwrap_or_default().push(1);
```
The fix is to:
- implement a heuristic to tell whether an expression's type can be determined purely from its subexpressions, and the arguments and locals they use;
- apply the heuristic to `unwrap_or_else`'s receiver.
The heuristic returns false when applied to `option` in the above example, but it returns true when applied to `option` in either of the following examples:
```rust
let option: Option<Vec<u64>> = None;
option.unwrap_or_else(Vec::new).push(1);
```
```rust
let option = None::<Vec<u64>>;
option.unwrap_or_else(Vec::new).push(1);
```
(Aside: https://github.com/rust-lang/rust-clippy/pull/10120 unfairly contained multiple changes in one PR. I am trying to break that PR up into smaller pieces.)
---
changelog: FP: [`unwrap_or_else_default`]: No longer lints if the default value is needed for type inference
Remove `#![allow(unused)]` and `--crate-name` from `cargo dev new_lint` generated tests
changelog: none
Also removes some unused flags from `ui-cargo` tests because the entrypoint is now the `Cargo.toml`, not the `.rs` files
Rewrite [`tuple_array_conversions`]
Fixes#11100Fixes#11144Fixes#11124#11082 still needs discussion and #11085 likely can't be fixed.
changelog: [`tuple_array_conversions`]: Move to `pedantic`
changelog: [`tuple_array_conversions`]: Don't lint if mutability of references changes
changelog: [`tuple_array_conversions`]: Don't lint if bindings don't come from the exact same pattern
changelog: [`tuple_array_conversions`]: Don't lint if bindings are used for more than just the conversion
Add `imports_granularity = "Module"` to rustfmt.toml
This lets rustfmt split/merge imports, `Module` seems to be the most common style in clippy
https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#imports_granularity
changelog: none
Almost all the updates other than the config file change are from `cargo dev fmt` or blessed tests, the exceptions being
- `tests/ui/single_component_path_imports.rs`
- `tests/ui/single_component_path_imports_nested_first.rs`
- `tests/ui/single_component_path_imports_self_after.rs`
- `tests/ui/single_component_path_imports_self_before.rs`
- `tests/ui/unsafe_removed_from_name.rs` (added a test with merged imports as a drive by)
- `tests/ui/wildcard_imports.rs`
- `tests/ui/wildcard_imports_2021.rs`
[`arithmetic_side_effect`]: allow different types on the right hand side for `Wrapping<T>`
Fixes#11145
This lint has a list of allowed types, one of which is `Wrapping<T>`, but it was only actually allowed if the type on the right hand side was also `Wrapping<T>`, which meant that, for example, `Wrapping<u32> += u32` would still lint. It now allows binary ops involving `Wrapping<T>` regardless of the type on the rhs.
These impls have only existed since Rust 1.60.0, so that is probably why the lint was previously not handling this correctly
changelog: [`arithmetic_side_effect`]: allow different types on the right hand side for `Wrapping<T>` (e.g. `Wrapping<T> += T`)
[`unnecessary_literal_unwrap`]: also lint `unwrap_(err_)unchecked`
Closes#11093
changelog: [`unnecessary_literal_unwrap`]: also lint `unwrap_unchecked` and `unwrap_err_unchecked`
Use depinfo to discover UI test dependencies
changelog: none
context: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Building.20test.20dependencies
This restores [the old `EXTERN_FLAGS` method](4cf5bdc60c/tests/compile-test.rs (L67-L75)) of passing `--extern` flags for building UI tests with minor changes
- Unused deps were removed
- It's now a `Vec` of args instead of a command string
- It uses a `BTreeMap` so the extern flags are in alphabetical order and deterministic
I don't know if the `HOST_LIBS` part is still required, but I figured it best to leave it in for now. If the change is accepted we can take a look if it's needed in `rust-lang/rust` after the next sync
This isn't as pleasant as having a `Cargo.toml`, though there is something satisfying about knowing the dependencies are already built and not needing to invoke `cargo`
r? `@flip1995`
This commit fixes#11025 by removing checks for `todo!`,
`unimplemented!` and `unreachable!`.
Signed-off-by: Panagiotis Foliadis <pfoliadis@hotmail.com>
Uplift `clippy::fn_null_check` lint
This PR aims at uplifting the `clippy::fn_null_check` lint into rustc.
## `incorrect_fn_null_checks`
(warn-by-default)
The `incorrect_fn_null_checks` lint checks for expression that checks if a function pointer is null.
### Example
```rust
let fn_ptr: fn() = /* somehow obtained nullable function pointer */
if (fn_ptr as *const ()).is_null() { /* ... */ }
```
### Explanation
Function pointers are assumed to be non-null, checking for their nullity is incorrect.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
`@rustbot` label: +I-lang-nominated
r? compiler