Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
100 changes: 99 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,105 @@ document.

## Unreleased / Beta / In Rust Nightly

[3e3715c3...master](https://github.com/rust-lang/rust-clippy/compare/3e3715c3...master)
[1e5237f4...master](https://github.com/rust-lang/rust-clippy/compare/1e5237f4...master)

## Rust 1.87

Current stable, released 2025-05-15

[View all 127 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-02-06T14%3A54%3A28Z..2025-03-20T20%3A07%3A53Z+base%3Amaster)

### New Lints

* Added [`doc_comment_double_space_linebreaks`] to `pedantic` [#12876](https://github.com/rust-lang/rust-clippy/pull/12876)
* Added [`manual_midpoint`] to `pedantic` [#13851](https://github.com/rust-lang/rust-clippy/pull/13851)
* Added [`io_other_error`] to `style` [#14022](https://github.com/rust-lang/rust-clippy/pull/14022)
* Added [`owned_cow`] to `pedantic` [#13948](https://github.com/rust-lang/rust-clippy/pull/13948)
* Added [`manual_contains`] to `perf` [#13817](https://github.com/rust-lang/rust-clippy/pull/13817)
* Added [`unnecessary_debug_formatting`] to `pedantic` [#13893](https://github.com/rust-lang/rust-clippy/pull/13893)
* Added [`elidable_lifetime_names`] to `pedantic` [#13960](https://github.com/rust-lang/rust-clippy/pull/13960)
* Added [`mem_replace_option_with_some`] to `style` [#14197](https://github.com/rust-lang/rust-clippy/pull/14197)
* Added [`unbuffered_bytes`] to `perf` [#14089](https://github.com/rust-lang/rust-clippy/pull/14089)
* Added [`single_option_map`] to `nursery` [#14033](https://github.com/rust-lang/rust-clippy/pull/14033)

### Moves and Deprecations

* Moved [`comparison_chain`] to `pedantic` (from `style`)
[#14219](https://github.com/rust-lang/rust-clippy/pull/14219)
* Moved [`manual_ok_or`] to `style` (from `pedantic`)
[#14027](https://github.com/rust-lang/rust-clippy/pull/14027)
* Deprecated [`option_map_or_err_ok`] in favor of [`manual_ok_or`]
[#14027](https://github.com/rust-lang/rust-clippy/pull/14027)

### Enhancements

* Add `allow_expect_in_consts` and `allow_unwrap_in_consts` configuration options to [`unwrap_used`], [`expect_used`]
[#14200](https://github.com/rust-lang/rust-clippy/pull/14200)
* Add `check-incompatible-msrv-in-tests` configuration option to [`incompatible_msrv`]
[#14279](https://github.com/rust-lang/rust-clippy/pull/14279)
* [`len_zero`] now also triggers if deref target implements `is_empty()`
[#13871](https://github.com/rust-lang/rust-clippy/pull/13871)
* [`ptr_eq`] now handles more cases, including `!=` in addition to `==`
[#14339](https://github.com/rust-lang/rust-clippy/pull/14339)
* [`struct_field_names`] now also checks private fields of public structs
[#14076](https://github.com/rust-lang/rust-clippy/pull/14076)
* [`needless_pass_by_value`] suggests using a reference on the innermost `Option` content
[#14392](https://github.com/rust-lang/rust-clippy/pull/14392)
* [`obfuscated_if_else`] now supports `then().unwrap_or_else()` and `then_some().unwrap_or_else()`
[#14165](https://github.com/rust-lang/rust-clippy/pull/14165)
* Format macros: all format-handling lints now validate `todo!` and `unimplemented!` macros
[#14266](https://github.com/rust-lang/rust-clippy/pull/14266)
* [`disallowed_methods`] now supports replacements
[#13669](https://github.com/rust-lang/rust-clippy/pull/13669)
* Added MSRV checks for several lints:
* [`question_mark`] [#14436](https://github.com/rust-lang/rust-clippy/pull/14436)
* [`repeat_vec_with_capacity`] [#14126](https://github.com/rust-lang/rust-clippy/pull/14126)
* [`manual_flatten`] [#14086](https://github.com/rust-lang/rust-clippy/pull/14086)
* [`lines_filter_map_ok`] [#14130](https://github.com/rust-lang/rust-clippy/pull/14130)

### False Positive Fixes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After sleeping over this: I would like to keep the "new" style of only mentioning the most important changes, rather than all. This list of changes is really overwhelming IMO.

Sorry for not mentioning this sooner and you adding all of them :/ I know how much work this is...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean "False Positive Fixes" section?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, generally. See the previous changelogs, which are quite short. This is because the changelog author made judgements about what entries are important enough to list.

For example, I don't think that

[range_zip_with_len] now has an autofix

will be interesting to most people. On the other hand, changes to configuration values like the first 2 and the last point of ## Enhancements are worth to include in the changelog.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps something like this

### Enhancements

* Add `allow_expect_in_consts` and `allow_unwrap_in_consts` configuration options to [`unwrap_used`], [`expect_used`]
  [#14200](https://github.com/rust-lang/rust-clippy/pull/14200)
* Add `check-incompatible-msrv-in-tests` configuration option to [`incompatible_msrv`]
  [#14279](https://github.com/rust-lang/rust-clippy/pull/14279)
* [`len_zero`] now also triggers if deref target implements `is_empty()`
  [#13871](https://github.com/rust-lang/rust-clippy/pull/13871)
* [`ptr_eq`] now handles more cases, including `!=` in addition to `==`
  [#14339](https://github.com/rust-lang/rust-clippy/pull/14339)
* [`struct_field_names`] now also checks private fields of public structs
  [#14076](https://github.com/rust-lang/rust-clippy/pull/14076)
* [`needless_pass_by_value`] suggests using a reference on the innermost `Option` content
  [#14392](https://github.com/rust-lang/rust-clippy/pull/14392)
* [`obfuscated_if_else`] now supports `then().unwrap_or_else()` and `then_some().unwrap_or_else()`
  [#14165](https://github.com/rust-lang/rust-clippy/pull/14165)
* Format macros: all format-handling lints now validate `todo!` and `unimplemented!` macros
  [#14266](https://github.com/rust-lang/rust-clippy/pull/14266)
* [`disallowed_methods`] now supports replacements
  [#13669](https://github.com/rust-lang/rust-clippy/pull/13669)
* Added MSRV checks for several lints:
  * [`question_mark`] [#14436](https://github.com/rust-lang/rust-clippy/pull/14436)
  * [`repeat_vec_with_capacity`] [#14126](https://github.com/rust-lang/rust-clippy/pull/14126)
  * [`manual_flatten`] [#14086](https://github.com/rust-lang/rust-clippy/pull/14086)
  * [`lines_filter_map_ok`] [#14130](https://github.com/rust-lang/rust-clippy/pull/14130)

As for the rest sections they look quite short, except false positive, but not sure what can be removed from them, seems they're equal

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This selection looks good!

I would say for the FP section, I would remove everything that doesn't give enough information on its own. For example [map_entry] Fix false positive ...: What FP? What was fixed? People won't click on a PR anyway and investigate what exactly was fixed. So those entries could be removed.

So think "Would I understand this change, if I was not working on Clippy, just from this one line?" And if the answer is "No", then it should probably be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and I think that the ### Suggestion Fixes/Improvements section can be completely removed (also from the docs). I don't think that anyone is interested in that. As in: "Oh this lint suggestion was fixed, so let me re-run cargo clippy --fix again". Probably doesn't happen, as they most likely already fixed the things by hand.


* [`missing_const_for_fn`] no longer triggers on unstable const traits [#14294](https://github.com/rust-lang/rust-clippy/pull/14294)
* [`unnecessary_to_owned`] now avoids suggesting to call `iter()` on a temporary object [#14243](https://github.com/rust-lang/rust-clippy/pull/14243)
* [`unnecessary_debug_formatting`] no longer triggers in tests [#14347](https://github.com/rust-lang/rust-clippy/pull/14347)
* [`option_if_let_else`] now handles cases when value is partially moved [#14209](https://github.com/rust-lang/rust-clippy/pull/14209)
* [`blocks_in_conditions`] no longer triggers when the condition contains a `return` [#14338](https://github.com/rust-lang/rust-clippy/pull/14338)
* [`undocumented_unsafe_blocks`] no longer triggers on trait/impl items [#13888](https://github.com/rust-lang/rust-clippy/pull/13888)
* [`manual_slice_fill`] no longer triggers due to missing index checks [#14193](https://github.com/rust-lang/rust-clippy/pull/14193)
* [`useless_asref`] no longer suggests using `.clone()` if the target type doesn't implement `Clone` [#14174](https://github.com/rust-lang/rust-clippy/pull/14174)
* [`unnecessary_safety_comment`] no longer triggers on desugared assign [#14371](https://github.com/rust-lang/rust-clippy/pull/14371)
* [`unnecessary_map_or`] no longer consumes the comparison value if it does not implement `Copy` [#14207](https://github.com/rust-lang/rust-clippy/pull/14207)
* [`let_and_return`] no longer triggers involving short-lived block temporary variables [#14180](https://github.com/rust-lang/rust-clippy/pull/14180)
* [`manual_async_fn`] no longer emits suggestions inside macros [#14142](https://github.com/rust-lang/rust-clippy/pull/14142)
* [`use_self`] skips analysis inside macro expansions of a `impl Self` block [#13128](https://github.com/rust-lang/rust-clippy/pull/13128)
* [`double_ended_iterator_last`] no longer triggers on non-reference immutable receiver [#14140](https://github.com/rust-lang/rust-clippy/pull/14140)

### ICE Fixes

* [`macro_use_imports`] Fix ICE when checking attributes
[#14317](https://github.com/rust-lang/rust-clippy/pull/14317)
* [`doc_nested_refdefs`] Fix ICE by avoiding invalid ranges
[#14308](https://github.com/rust-lang/rust-clippy/pull/14308)
* [`just_underscores_and_digits`] Fix ICE in error recovery scenario
[#14168](https://github.com/rust-lang/rust-clippy/pull/14168)
* [`declare_interior_mutable_const`], [`borrow_interior_mutable_const`] Fix ICE by properly resolving `<T as Trait>::AssocT` projections
[#14125](https://github.com/rust-lang/rust-clippy/pull/14125)

### Documentation Improvements

* [`struct_excessive_bools`] Documentation improved with rationale
[#14351](https://github.com/rust-lang/rust-clippy/pull/14351)

### Others

* Use edition=2021 in `rustc_tools_util`
[#14211](https://github.com/rust-lang/rust-clippy/pull/14211)
* Fix rustc_tools_util's `version.host_compiler` release channel, expose the rustc version, and add tests
[#14123](https://github.com/rust-lang/rust-clippy/pull/14123)
* Make UI test annotations mandatory
[#11421](https://github.com/rust-lang/rust-clippy/pull/11421)
[#14388](https://github.com/rust-lang/rust-clippy/pull/14388)
[#14393](https://github.com/rust-lang/rust-clippy/pull/14393)

## Rust 1.86

Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ declare_clippy_lint! {
/// x.chars()
/// }
/// ```
#[clippy::version = "1.84.0"]
#[clippy::version = "1.87.0"]
pub ELIDABLE_LIFETIME_NAMES,
pedantic,
"lifetime name that can be replaced with the anonymous lifetime"
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/mem_replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ declare_clippy_lint! {
/// let mut an_option = Some(0);
/// let taken = an_option.replace(1);
/// ```
#[clippy::version = "1.86.0"]
#[clippy::version = "1.87.0"]
pub MEM_REPLACE_OPTION_WITH_SOME,
style,
"replacing an `Option` with `Some` instead of `replace()`"
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4428,7 +4428,7 @@ declare_clippy_lint! {
/// let file = BufReader::new(std::fs::File::open("./bytes.txt").unwrap());
/// file.bytes();
/// ```
#[clippy::version = "1.86.0"]
#[clippy::version = "1.87.0"]
pub UNBUFFERED_BYTES,
perf,
"calling .bytes() is very inefficient when data is not in memory"
Expand All @@ -4453,7 +4453,7 @@ declare_clippy_lint! {
/// values.contains(&10)
/// }
/// ```
#[clippy::version = "1.86.0"]
#[clippy::version = "1.87.0"]
pub MANUAL_CONTAINS,
perf,
"unnecessary `iter().any()` on slices that can be replaced with `contains()`"
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/single_option_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ declare_clippy_lint! {
/// param * 2
/// }
/// ```
#[clippy::version = "1.86.0"]
#[clippy::version = "1.87.0"]
pub SINGLE_OPTION_MAP,
nursery,
"Checks for functions with method calls to `.map(_)` on an arg of type `Option` as the outermost expression."
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ declare_clippy_lint! {
/// ```no_run
/// let right: std::borrow::Cow<'_, [u8]>;
/// ```
#[clippy::version = "1.85.0"]
#[clippy::version = "1.87.0"]
pub OWNED_COW,
style,
"needlessly owned Cow type"
Expand Down