Commit graph

1820 commits

Author SHA1 Message Date
Samuel Tardieu
acfbbc65b5 Remove obsolete comment and simplify code
The `IoBufRead` diagnostic has been added during the latest rustup.
2025-02-20 18:03:40 +01:00
Philipp Krones
12025085b9
Merge remote-tracking branch 'upstream/master' into rustup 2025-02-20 15:26:07 +01:00
Catherine Flores
975a813c5a
.last() to .next_back() requires a mutable receiver (#14140)
In the case where `iter` is a `DoubleEndedIterator`, replacing a call to
`iter.last()` (which consumes `iter`) by `iter.next_back()` (which
requires a mutable reference to `iter`) cannot be done when `iter` is a
non-mutable binding which is not a mutable reference. When possible, a
local immutable binding is made into a mutable one.

Also, the applicability is switched to `MaybeIncorrect` and a note is
added to the output when the element types have a significant drop,
because the drop order will potentially be modified because
`.next_back()` does not consume the iterator nor the elements before the
last one.

Fix #14139

changelog: [`double_ended_iterator_last`]: do not trigger on
non-reference immutable receiver, and warn about possible drop order
change
2025-02-19 09:05:46 +00:00
Samuel Tardieu
dcd643a652 double_ended_iterator_last: note when drop order is changed
`iter.last()` will drop all elements of `iter` in order, while
`iter.next_back()` will drop the non-last elements of `iter` when
`iter` goes out of scope since `.next_back()` does not consume its
argument.

When the transformation proposed by `double_ended_iterator_last` would
concern an iterator whose element type has a significant drop, a note is
added to warn about the possible drop order change, and the suggestion
is switched from `MachineApplicable` to `MaybeIncorrect`.
2025-02-19 09:26:39 +01:00
Samuel Tardieu
45f7a60d31 .last() to .next_back() requires a mutable receiver
In the case where `iter` is a `DoubleEndedIterator`, replacing a call to
`iter.last()` (which consumes `iter`) by `iter.next_back()` (which
requires a mutable reference to `iter`) cannot be done when `iter`
Is not a mutable binding or a mutable reference.

When `iter` is a local binding, it can be made mutable by fixing its
definition site.
2025-02-18 13:51:01 +01:00
Nicholas Nethercote
835e6a694b Move methods from Map to TyCtxt, part 2.
Continuing the work started in #136466.

Every method gains a `hir_` prefix, though for the ones that already
have a `par_` or `try_par_` prefix I added the `hir_` after that.
2025-02-18 10:17:44 +11:00
Nicholas Nethercote
91481e3bcf Overhaul the intravisit::Map trait.
First of all, note that `Map` has three different relevant meanings.
- The `intravisit::Map` trait.
- The `map::Map` struct.
- The `NestedFilter::Map` associated type.

The `intravisit::Map` trait is impl'd twice.
- For `!`, where the methods are all unreachable.
- For `map::Map`, which gets HIR stuff from the `TyCtxt`.

As part of getting rid of `map::Map`, this commit changes `impl
intravisit::Map for map::Map` to `impl intravisit::Map for TyCtxt`. It's
fairly straightforward except various things are renamed, because the
existing names would no longer have made sense.

- `trait intravisit::Map` becomes `trait intravisit::HirTyCtxt`, so named
  because it gets some HIR stuff from a `TyCtxt`.
- `NestedFilter::Map` assoc type becomes `NestedFilter::MaybeTyCtxt`,
  because it's always `!` or `TyCtxt`.
- `Visitor::nested_visit_map` becomes `Visitor::maybe_tcx`.

I deliberately made the new trait and associated type names different to
avoid the old `type Map: Map` situation, which I found confusing. We now
have `type MaybeTyCtxt: HirTyCtxt`.
2025-02-17 13:21:35 +11:00
Nicholas Nethercote
8cf9eea5b3 Move some Map methods onto TyCtxt.
The end goal is to eliminate `Map` altogether.

I added a `hir_` prefix to all of them, that seemed simplest. The
exceptions are `module_items` which became `hir_module_free_items` because
there was already a `hir_module_items`, and `items` which became
`hir_free_items` for consistency with `hir_module_free_items`.
2025-02-17 13:21:02 +11:00
lapla-cogito
fd17bfe57d
add manual_contains lint 2025-02-16 06:21:57 +09:00
Samuel Tardieu
f826193aec unnecessary_map_or: do not consume the non-Copy comparison value 2025-02-13 12:00:38 +01:00
jonathan
8b6de49ef7
New lint: unbuffered_bytes 2025-02-12 14:57:07 +01:00
Samuel Tardieu
da6a05977d {expect,unwrap}_used: add options to lint at compilation time
By default, do not lint `.unwrap()` and `.expect(…)` in always const
contexts, as a failure would be detected at compile time anyway.

New options `allow_expect_in_consts` and `allow_unwrap_in_consts`,
defaulting to `true`, can be turned unset to still lint in always const
contexts.
2025-02-11 22:14:52 +01:00
Esteban Küber
39d73d5bbb Use MIR body to identify more "default equivalent" calls
When looking for `Default` impls that could be derived, we look at the
body of their `fn default()` and if it is an fn call or literal we check
if they are equivalent to what `#[derive(Default)]` would have used.

Now, when checking those fn calls in the `fn default()` body, we also
compare against the corresponding type's `Default::default` body to see
if our call is equivalent to that one.

For example, given

```rust
struct S;

impl S {
    fn new() -> S { S }
}

impl Default for S {
    fn default() -> S { S::new() }
}
```

`<S as Default>::default()` and `S::new()` are considered equivalent.
Given that, if the user also writes

```rust
struct R {
    s: S,
}

impl Default for R {
    fn default() -> R {
        R { s: S::new() }
    }
}
```

the `derivable_impls` lint will now trigger.
2025-02-11 02:59:06 +00:00
Alejandra González
8c01600e23
Fix obfuscated_if_else suggestion on left side of a binary expr (#14124)
An `if … { … } else { … }` used as the left operand of a binary
expression requires parentheses to be parsed as an expression.

Fix #11141

changelog: [`obfuscated_if_else`]: fix bug in suggestion by issuing
required parentheses around the left side of a binary expression
2025-02-09 01:22:58 +00:00
Samuel Tardieu
ac0a11a8bc Fix obfuscated_if_else suggestion on left side of a binary expr
An `if … { … } else { … }` used as the left operand of a binary
expression requires parentheses to be parsed as an expression.
2025-02-09 02:11:37 +01:00
dswij
8cc596cf95
autofix for range_zip_with_len (#14136)
changelog: [`range_zip_with_len`]: add autofix
2025-02-08 05:20:10 +00:00
Jubilee Young
b18bb0a483 clippy: directly use rustc_abi instead of reexports 2025-02-07 11:21:53 -08:00
dswij
4e5d00a0a7
Deprecate redundant lint option_map_or_err_ok and take manual_ok_or out of pedantic (#14027)
While extending the `option_map_or_err_ok` lint (warn by default,
"style") to recognize η-expanded forms of `Ok`, as in

```rust
    // Should suggest `opt.ok_or("foobar")`
   let _ = opt.map_or(Err("foobar"), |x| Ok(x));
```

I discovered that the `manual_ok_or` lint (allow by default, "pedantic")
already covered exactly the cases handled by `option_map_or_err_ok`,
including the one I was adding. Apparently, `option_map_or_err_ok` was
added without realizing that the lint already existed under the
`manual_ok_or` name. As a matter of fact, artifacts of this second lint
were even present in the first lint `stderr` file and went unnoticed for
more than a year.

This PR:
- deprecates `option_map_or_err_ok` with a message saying to use
`manual_ok_or`
- moves `manual_ok_or` from "pedantic" to "style" (the category in which
`option_map_or_err_ok` was)

In addition, I think that this lint, which is short, machine applicable,
and leads to shorter and clearer code with less arguments (`Ok`
disappears) and the removal of one level of call (`Err(x)` is replaced
by `x`), is a reason by itself to be in "style".

changelog: [`option_map_or_err_ok` and `manual_ok_or`]: move
`manual_ok_or` from "pedantic" to "style", and deprecate the redundant
style lint `option_map_or_err_ok`.
2025-02-07 17:34:21 +00:00
Catherine Flores
0d3bf65bd4
useless_asref: no lint if in a closure to change the ref depth (#14090)
Removing the `.as_ref()` or `.as_mut()` as the top-level expression in a
closure may change the type of the result. In this case, it may be
better not to lint rather than proposing a fix that would not work.

changelog: [`useless_asref`]: do not remove the `.as_ref()` or
`.as_mut()` call if this would change the type of the enclosing closure

Fix #14088
2025-02-07 13:33:18 +00:00
Catherine Flores
b5ea2491b3
[path_buf_push_overwrite]: mark suggestion as MaybeIncorrect (#14010)
Proposing to replace

```rust
let mut x = PathBuf::from("/foo");
x.push("/bar");
```

by

```rust
let mut x = PathBuf::from("/foo");
x.push("bar");
```

changes the content of `x` (`/bar` ⇒ `/foo/bar`). This is not equivalent
and should not be `MachineApplicable`, even if the original code is
suspicious.

changelog: none
2025-02-07 12:27:35 +00:00
Timo
4a94ad6c52
Simplify reindent_multiline() signature (#14101)
- `reindent_multiline()` always returns the result of
`reindent_multiline_inner()` which returns a `String`. Make
`reindent_multiline()` return a `String` as well, instead of a
systematically owned `Cow<'_, str>`.
- There is no reason for `reindent_multiline()` to force a caller to
build a `Cow<'_, str>` instead of passing a `&str` directly, especially
considering that a `String` will always be returned.

Also, both the input parameter and return value (of type `Cow<'_, str>`)
shared the same (elided) lifetime for no reason: this worked only
because the result was always the `Cow::Owned` variant which is
compatible with any lifetime.

As a consequence, the signature changes from:

```rust
fn reindent_multiline(s: Cow<'_, str>, …) -> Cow<'_, str> { … }
```

to

```rust
fn reindent_multiline(s: &str, …) -> String { … }
```

changelog: none
2025-02-07 00:45:33 +00:00
Philipp Krones
5aa9d7ae7f Merge commit '3e3715c312' into clippy-subtree-update 2025-02-06 15:00:24 +01:00
Philipp Krones
f549562b81
Merge remote-tracking branch 'upstream/master' into rustup 2025-02-06 14:31:01 +01:00
Samuel Tardieu
64dec0760e Simplify reindent_multiline() signature
- `reindent_multiline()` always returns the result of
  `reindent_multiline_inner()` which returns a `String`. Make
  `reindent_multiline()` return a `String` as well, instead of a
  systematically owned `Cow<'_, str>`.
- There is no reason for `reindent_multiline()` to force a caller to
  build a `Cow<'_, str>` instead of passing a `&str` directly,
  especially considering that a `String` will always be returned.

Also, both the input parameter and return value (of type `Cow<'_, str>`)
shared the same (elided) lifetime for no reason: this worked only because
the result was always the `Cow::Owned` variant which is compatible with
any lifetime.

As a consequence, the signature changes from:

```rust
fn reindent_multiline(s: Cow<'_, str>, …) -> Cow<'_, str> { … }
```

to

```rust
fn reindent_multiline(s: &str, …) -> String { … }
```
2025-02-03 23:47:08 +01:00
lapla-cogito
a5329bd8d3
autofix for range_zip_with_len 2025-02-02 23:44:22 +09:00
Nicholas Nethercote
d30f045fce Convert two rustc_middle::lint functions to Span methods.
`rustc_middle` is a huge crate and it's always good to move stuff out of
it. There are lots of similar methods already on `Span`, so these two
functions, `in_external_macro` and `is_from_async_await`, fit right in.
The diff is big because `in_external_macro` is used a lot by clippy
lints.
2025-02-02 13:57:34 +11:00
Samuel Tardieu
5aa8bc11cd sliced_string_as_bytes: fix typo in lint description 2025-01-30 21:27:57 +01:00
Aaron Ang
84fb6b1651 Add new lint return_and_then 2025-01-29 10:43:59 -08:00
Catherine Flores
e02c8857e8
Move format_push_string and format_collect to pedantic (#13894)
Closes #11434 by moving `format_push_string` and `format_collect` to
pedantic.

changelog: Move `format_push_string` and `format_collect` to pedantic
2025-01-28 19:32:24 +00:00
llogiq
9ede32fe00
needless_option_take: add autofix (#14042)
changelog: [`needless_option_take`]: add autofix
2025-01-28 18:49:27 +00:00
Philipp Krones
9da9ddb7db Merge commit '51d49c1ae2' into clippy-subtree-update 2025-01-28 19:33:54 +01:00
Philipp Krones
145d5adf04
Merge remote-tracking branch 'upstream/master' into rustup 2025-01-28 19:14:45 +01:00
Catherine Flores
66dc8a1a30
proper applicability for obfuscated_if_else (#14061)
fix #14034

The currect implementation of `obfuscated_if_else` sometimes makes
incorrect suggestions when the original code have side effects (see the
example in the above issue). I think this can be fixed by changing the
applicability depending on whether it can have side effects or not.

changelog: [`obfuscated_if_else`]: change applicability when the
original code can have side effects
2025-01-28 06:57:12 +00:00
Samuel Tardieu
16e2196fc2 useless_asref: no lint if in a closure to change the ref depth
Removing the `.as_ref()` or `.as_mut()` as the top-level expression in a
closure may change the type of the result. In this case, it may be
better not to lint rather than proposing a fix that would not work.
2025-01-28 00:08:39 +01:00
Manish Goregaokar
83bde363b6
correct suggestions in no_std (#13999)
I opened https://github.com/rust-lang/rust-clippy/pull/13896 before.
However, I found that there're more cases where Clippy suggests to use
modules that belong to the `std` crate even in a `no_std` environment.
Therefore, this PR include the changes I've made in #13896 and new
changes to fix cases I found this time to prevent wrong suggestions in
`no_std` environments as well.

changelog: [`redundant_closure`]: correct suggestion in `no_std`
changelog: [`repeat_vec_with_capacity`]: correct suggestion in `no_std`
changelog: [`single_range_in_vec_init`]: don't emit suggestion to use
`Vec` in `no_std`
changelog: [`drain_collect`]: correct suggestion in `no_std`
changelog: [`map_with_unused_argument_over_ranges`]: correct suggestion
in `no_std`

also close #13895
2025-01-27 21:36:12 +00:00
lapla-cogito
3b0b8b080e
correct suggestion for map_with_unused_argument_over_ranges in a no_std environment 2025-01-28 06:29:47 +09:00
lapla-cogito
d99eae4325
correct suggestion for drain_collect in a no_std environment 2025-01-28 06:29:45 +09:00
Manish Goregaokar
85bbba69b0
New lint sliced_string_as_bytes (#14002)
resurrection of https://github.com/rust-lang/rust-clippy/pull/10984

fixes https://github.com/rust-lang/rust-clippy/issues/10981

changelog: [`sliced_string_as_bytes`]: add new lint
`sliced_string_as_bytes`
2025-01-27 20:34:48 +00:00
Alejandra González
057f5b36f5
Make unnecessary_map_or work with ref and Deref to Option/Result (#14024)
Receivers which are references to `Option` and `Result`, or who
implement `Deref` to one of those types, will be linted as well.

changelog: [`unnecessary_map_or`]: work with ref and `Deref` to `Option`
and `Result` as well

Fixes #14023

**Note:** this patch must be merged after #13998 – only the second
commit must be reviewed, the first one repeats the patch in #13998 for
mergeability reasons.
2025-01-26 18:06:49 +00:00
lapla-cogito
2640f657ec
change the applicability of obfuscated_if_else depending on whether the original code can have side effects 2025-01-26 10:03:20 +09:00
llogiq
913592373d
trigger obfuscated_if_else for .then(..).unwrap_or(..) (#14021)
part of https://github.com/rust-lang/rust-clippy/issues/9100

The `obfuscated_if_else` lint currently only triggers for the pattern
`.then_some(..).unwrap_or(..)`, but there're other cases where this lint
should be triggered, one of which is `.then(..).unwrap_or(..)`.

changelog: [`obfuscated_if_else`]: trigger lint for the
`.then(..).unwrap_or(..)` pattern as well
2025-01-25 23:48:02 +00:00
wowinter13
beeb6f7432 slice-as-bytes: pedantic -> perf 2025-01-25 18:43:07 +01:00
wowinter13
4e94d22291 nit: change placeholders 2025-01-25 18:43:07 +01:00
wowinter13
5855e0a2f1 Small refactoring: irrefutable let pattern 2025-01-25 18:43:07 +01:00
wowinter13
26a7b322a3 Rename slice_as_bytes -> sliced_string_as_bytes 2025-01-25 18:43:07 +01:00
wowinter13
7124d822b4 Fix function signature 2025-01-25 18:42:45 +01:00
wowinter13
d8752dbf40 New lint 2025-01-25 18:42:43 +01:00
lapla-cogito
db977689fd
trigger obfuscated_if_else for .then(..).unwrap_or(..) 2025-01-25 19:57:22 +09:00
Boxy
109440b830 The clipper :3c 2025-01-23 06:01:36 +00:00
Samuel Tardieu
a03242f8e0 Move manual_ok_or from pedantic to style
`manual_ok_or` covers the same case that were covered by
`option_map_or_err_ok` which is not deprecated. The latter was in the
"style" category. Also, the lint is machine applicable, and leads to
shorter and more readable code, so "style" is appropriate.

The only difference is that the η-expanded form of `Result::Ok()` was
not covered by `option_map_or_err_ok` while it is by `manual_ok_or`, so
the category change may expose some new occurrences.
2025-01-23 00:28:09 +01:00