about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui-internal/auxiliary/paths.rs2
-rw-r--r--tests/ui-internal/match_type_on_diag_item.rs39
-rw-r--r--tests/ui-internal/match_type_on_diag_item.stderr27
-rw-r--r--tests/ui-internal/unnecessary_def_path.fixed62
-rw-r--r--tests/ui-internal/unnecessary_def_path.rs62
-rw-r--r--tests/ui-internal/unnecessary_def_path.stderr101
-rw-r--r--tests/ui/doc_link_with_quotes.rs7
-rw-r--r--tests/ui/doc_link_with_quotes.stderr6
-rw-r--r--tests/ui/eta.fixed13
-rw-r--r--tests/ui/eta.rs13
-rw-r--r--tests/ui/eta.stderr20
-rw-r--r--tests/ui/floating_point_exp.fixed1
-rw-r--r--tests/ui/floating_point_exp.rs1
-rw-r--r--tests/ui/floating_point_exp.stderr10
-rw-r--r--tests/ui/floating_point_log.fixed2
-rw-r--r--tests/ui/floating_point_log.rs2
-rw-r--r--tests/ui/floating_point_logbase.fixed1
-rw-r--r--tests/ui/floating_point_logbase.rs1
-rw-r--r--tests/ui/floating_point_logbase.stderr10
-rw-r--r--tests/ui/floating_point_mul_add.fixed2
-rw-r--r--tests/ui/floating_point_mul_add.rs2
-rw-r--r--tests/ui/floating_point_mul_add.stderr30
-rw-r--r--tests/ui/floating_point_powf.fixed1
-rw-r--r--tests/ui/floating_point_powf.rs1
-rw-r--r--tests/ui/floating_point_powf.stderr62
-rw-r--r--tests/ui/floating_point_powi.fixed3
-rw-r--r--tests/ui/floating_point_powi.rs3
-rw-r--r--tests/ui/floating_point_powi.stderr24
-rw-r--r--tests/ui/implicit_saturating_add.fixed106
-rw-r--r--tests/ui/implicit_saturating_add.rs154
-rw-r--r--tests/ui/implicit_saturating_add.stderr197
-rw-r--r--tests/ui/manual_assert.edition2018.fixed13
-rw-r--r--tests/ui/manual_assert.edition2018.stderr74
-rw-r--r--tests/ui/manual_assert.edition2021.fixed13
-rw-r--r--tests/ui/manual_assert.edition2021.stderr74
-rw-r--r--tests/ui/manual_assert.fixed45
-rw-r--r--tests/ui/manual_assert.rs14
-rw-r--r--tests/ui/manual_bits.fixed3
-rw-r--r--tests/ui/manual_bits.rs3
-rw-r--r--tests/ui/manual_bits.stderr58
-rw-r--r--tests/ui/manual_clamp.rs304
-rw-r--r--tests/ui/manual_clamp.stderr375
-rw-r--r--tests/ui/min_max.rs1
-rw-r--r--tests/ui/min_max.stderr26
-rw-r--r--tests/ui/min_rust_version_attr.rs12
-rw-r--r--tests/ui/min_rust_version_attr.stderr8
-rw-r--r--tests/ui/needless_borrowed_ref.fixed41
-rw-r--r--tests/ui/needless_borrowed_ref.rs41
-rw-r--r--tests/ui/needless_borrowed_ref.stderr121
-rw-r--r--tests/ui/option_take_on_temporary.fixed15
-rw-r--r--tests/ui/ptr_offset_with_cast.fixed1
-rw-r--r--tests/ui/ptr_offset_with_cast.rs1
-rw-r--r--tests/ui/ptr_offset_with_cast.stderr4
-rw-r--r--tests/ui/unnecessary_cast.fixed14
-rw-r--r--tests/ui/unnecessary_cast.rs14
-rw-r--r--tests/ui/unnecessary_cast.stderr20
-rw-r--r--tests/ui/upper_case_acronyms.rs9
-rw-r--r--tests/ui/upper_case_acronyms.stderr14
58 files changed, 1995 insertions, 288 deletions
diff --git a/tests/ui-internal/auxiliary/paths.rs b/tests/ui-internal/auxiliary/paths.rs
new file mode 100644
index 00000000000..52fcaec4df3
--- /dev/null
+++ b/tests/ui-internal/auxiliary/paths.rs
@@ -0,0 +1,2 @@
+pub static OPTION: [&str; 3] = ["core", "option", "Option"];
+pub const RESULT: &[&str] = &["core", "result", "Result"];
diff --git a/tests/ui-internal/match_type_on_diag_item.rs b/tests/ui-internal/match_type_on_diag_item.rs
deleted file mode 100644
index 4b41ff15e80..00000000000
--- a/tests/ui-internal/match_type_on_diag_item.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-#![deny(clippy::internal)]
-#![allow(clippy::missing_clippy_version_attribute)]
-#![feature(rustc_private)]
-
-extern crate clippy_utils;
-extern crate rustc_hir;
-extern crate rustc_lint;
-extern crate rustc_middle;
-
-#[macro_use]
-extern crate rustc_session;
-use clippy_utils::{paths, ty::match_type};
-use rustc_hir::Expr;
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::Ty;
-
-declare_lint! {
-    pub TEST_LINT,
-    Warn,
-    ""
-}
-
-declare_lint_pass!(Pass => [TEST_LINT]);
-
-static OPTION: [&str; 3] = ["core", "option", "Option"];
-
-impl<'tcx> LateLintPass<'tcx> for Pass {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
-        let ty = cx.typeck_results().expr_ty(expr);
-
-        let _ = match_type(cx, ty, &OPTION);
-        let _ = match_type(cx, ty, &["core", "result", "Result"]);
-
-        let rc_path = &["alloc", "rc", "Rc"];
-        let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
-    }
-}
-
-fn main() {}
diff --git a/tests/ui-internal/match_type_on_diag_item.stderr b/tests/ui-internal/match_type_on_diag_item.stderr
deleted file mode 100644
index e3cb6b6c22e..00000000000
--- a/tests/ui-internal/match_type_on_diag_item.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:31:17
-   |
-LL |         let _ = match_type(cx, ty, &OPTION);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Option)`
-   |
-note: the lint level is defined here
-  --> $DIR/match_type_on_diag_item.rs:1:9
-   |
-LL | #![deny(clippy::internal)]
-   |         ^^^^^^^^^^^^^^^^
-   = note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
-
-error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:32:17
-   |
-LL |         let _ = match_type(cx, ty, &["core", "result", "Result"]);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Result)`
-
-error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:35:17
-   |
-LL |         let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
-
-error: aborting due to 3 previous errors
-
diff --git a/tests/ui-internal/unnecessary_def_path.fixed b/tests/ui-internal/unnecessary_def_path.fixed
new file mode 100644
index 00000000000..4c050332f2c
--- /dev/null
+++ b/tests/ui-internal/unnecessary_def_path.fixed
@@ -0,0 +1,62 @@
+// run-rustfix
+// aux-build:paths.rs
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+extern crate clippy_utils;
+extern crate paths;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+extern crate rustc_span;
+
+#[allow(unused)]
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
+#[allow(unused)]
+use clippy_utils::{
+    is_expr_path_def_path, is_path_diagnostic_item, is_res_diagnostic_ctor, is_res_lang_ctor, is_trait_method,
+    match_def_path, match_trait_method, path_res,
+};
+
+#[allow(unused)]
+use rustc_hir::LangItem;
+#[allow(unused)]
+use rustc_span::sym;
+
+use rustc_hir::def_id::DefId;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
+
+#[allow(unused)]
+static OPTION: [&str; 3] = ["core", "option", "Option"];
+#[allow(unused)]
+const RESULT: &[&str] = &["core", "result", "Result"];
+
+fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
+    let _ = is_type_diagnostic_item(cx, ty, sym::Option);
+    let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+    let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+
+    #[allow(unused)]
+    let rc_path = &["alloc", "rc", "Rc"];
+    let _ = is_type_diagnostic_item(cx, ty, sym::Rc);
+
+    let _ = is_type_diagnostic_item(cx, ty, sym::Option);
+    let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+
+    let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
+    let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
+
+    let _ = cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did);
+    let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
+    let _ = cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did);
+
+    let _ = is_trait_method(cx, expr, sym::AsRef);
+
+    let _ = is_path_diagnostic_item(cx, expr, sym::Option);
+    let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id));
+    let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
+}
+
+fn main() {}
diff --git a/tests/ui-internal/unnecessary_def_path.rs b/tests/ui-internal/unnecessary_def_path.rs
new file mode 100644
index 00000000000..6506f1f164a
--- /dev/null
+++ b/tests/ui-internal/unnecessary_def_path.rs
@@ -0,0 +1,62 @@
+// run-rustfix
+// aux-build:paths.rs
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+extern crate clippy_utils;
+extern crate paths;
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+extern crate rustc_span;
+
+#[allow(unused)]
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
+#[allow(unused)]
+use clippy_utils::{
+    is_expr_path_def_path, is_path_diagnostic_item, is_res_diagnostic_ctor, is_res_lang_ctor, is_trait_method,
+    match_def_path, match_trait_method, path_res,
+};
+
+#[allow(unused)]
+use rustc_hir::LangItem;
+#[allow(unused)]
+use rustc_span::sym;
+
+use rustc_hir::def_id::DefId;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
+
+#[allow(unused)]
+static OPTION: [&str; 3] = ["core", "option", "Option"];
+#[allow(unused)]
+const RESULT: &[&str] = &["core", "result", "Result"];
+
+fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
+    let _ = match_type(cx, ty, &OPTION);
+    let _ = match_type(cx, ty, RESULT);
+    let _ = match_type(cx, ty, &["core", "result", "Result"]);
+
+    #[allow(unused)]
+    let rc_path = &["alloc", "rc", "Rc"];
+    let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+
+    let _ = match_type(cx, ty, &paths::OPTION);
+    let _ = match_type(cx, ty, paths::RESULT);
+
+    let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
+    let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
+
+    let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
+    let _ = match_def_path(cx, did, &["core", "option", "Option"]);
+    let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
+
+    let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
+
+    let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
+    let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
+    let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
+}
+
+fn main() {}
diff --git a/tests/ui-internal/unnecessary_def_path.stderr b/tests/ui-internal/unnecessary_def_path.stderr
new file mode 100644
index 00000000000..a99a8f71fa6
--- /dev/null
+++ b/tests/ui-internal/unnecessary_def_path.stderr
@@ -0,0 +1,101 @@
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:37:13
+   |
+LL |     let _ = match_type(cx, ty, &OPTION);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
+   |
+note: the lint level is defined here
+  --> $DIR/unnecessary_def_path.rs:3:9
+   |
+LL | #![deny(clippy::internal)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: `#[deny(clippy::unnecessary_def_path)]` implied by `#[deny(clippy::internal)]`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:38:13
+   |
+LL |     let _ = match_type(cx, ty, RESULT);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:39:13
+   |
+LL |     let _ = match_type(cx, ty, &["core", "result", "Result"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:43:13
+   |
+LL |     let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Rc)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:45:13
+   |
+LL |     let _ = match_type(cx, ty, &paths::OPTION);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:46:13
+   |
+LL |     let _ = match_type(cx, ty, paths::RESULT);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
+
+error: use of a def path to a `LangItem`
+  --> $DIR/unnecessary_def_path.rs:48:13
+   |
+LL |     let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_lang_item(cx, ty, LangItem::OwnedBox)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:49:13
+   |
+LL |     let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit)`
+
+error: use of a def path to a `LangItem`
+  --> $DIR/unnecessary_def_path.rs:51:13
+   |
+LL |     let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:52:13
+   |
+LL |     let _ = match_def_path(cx, did, &["core", "option", "Option"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.is_diagnostic_item(sym::Option, did)`
+
+error: use of a def path to a `LangItem`
+  --> $DIR/unnecessary_def_path.rs:53:13
+   |
+LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did)`
+   |
+   = help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:55:13
+   |
+LL |     let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_trait_method(cx, expr, sym::AsRef)`
+
+error: use of a def path to a diagnostic item
+  --> $DIR/unnecessary_def_path.rs:57:13
+   |
+LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_path_diagnostic_item(cx, expr, sym::Option)`
+
+error: use of a def path to a `LangItem`
+  --> $DIR/unnecessary_def_path.rs:58:13
+   |
+LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id))`
+
+error: use of a def path to a `LangItem`
+  --> $DIR/unnecessary_def_path.rs:59:13
+   |
+LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome)`
+
+error: aborting due to 15 previous errors
+
diff --git a/tests/ui/doc_link_with_quotes.rs b/tests/ui/doc_link_with_quotes.rs
index ab52fb1a4a6..17c04c34e24 100644
--- a/tests/ui/doc_link_with_quotes.rs
+++ b/tests/ui/doc_link_with_quotes.rs
@@ -4,9 +4,14 @@ fn main() {
     foo()
 }
 
-/// Calls ['bar']
+/// Calls ['bar'] uselessly
 pub fn foo() {
     bar()
 }
 
+/// # Examples
+/// This demonstrates issue \#8961
+/// ```
+/// let _ = vec!['w', 'a', 't'];
+/// ```
 pub fn bar() {}
diff --git a/tests/ui/doc_link_with_quotes.stderr b/tests/ui/doc_link_with_quotes.stderr
index bf6d57d8afe..ea730e667d6 100644
--- a/tests/ui/doc_link_with_quotes.stderr
+++ b/tests/ui/doc_link_with_quotes.stderr
@@ -1,8 +1,8 @@
 error: possible intra-doc link using quotes instead of backticks
-  --> $DIR/doc_link_with_quotes.rs:7:1
+  --> $DIR/doc_link_with_quotes.rs:7:12
    |
-LL | /// Calls ['bar']
-   | ^^^^^^^^^^^^^^^^^
+LL | /// Calls ['bar'] uselessly
+   |            ^^^^^
    |
    = note: `-D clippy::doc-link-with-quotes` implied by `-D warnings`
 
diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed
index f8d559bf226..e257b3b3afa 100644
--- a/tests/ui/eta.fixed
+++ b/tests/ui/eta.fixed
@@ -303,3 +303,16 @@ fn not_general_enough() {
     fn f(_: impl FnMut(&Path) -> std::io::Result<()>) {}
     f(|path| std::fs::remove_file(path));
 }
+
+// https://github.com/rust-lang/rust-clippy/issues/9369
+pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() {
+    fn takes_fn_mut(_: impl FnMut()) {}
+    takes_fn_mut(&mut f);
+
+    fn takes_fn_once(_: impl FnOnce()) {}
+    takes_fn_once(&mut f);
+
+    f();
+
+    move || takes_fn_mut(&mut f_used_once)
+}
diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs
index f0fb55a1e5f..486a251f30b 100644
--- a/tests/ui/eta.rs
+++ b/tests/ui/eta.rs
@@ -303,3 +303,16 @@ fn not_general_enough() {
     fn f(_: impl FnMut(&Path) -> std::io::Result<()>) {}
     f(|path| std::fs::remove_file(path));
 }
+
+// https://github.com/rust-lang/rust-clippy/issues/9369
+pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() {
+    fn takes_fn_mut(_: impl FnMut()) {}
+    takes_fn_mut(|| f());
+
+    fn takes_fn_once(_: impl FnOnce()) {}
+    takes_fn_once(|| f());
+
+    f();
+
+    move || takes_fn_mut(|| f_used_once())
+}
diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr
index bf2e97e744a..434706b7e25 100644
--- a/tests/ui/eta.stderr
+++ b/tests/ui/eta.stderr
@@ -116,5 +116,23 @@ error: redundant closure
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
-error: aborting due to 19 previous errors
+error: redundant closure
+  --> $DIR/eta.rs:310:18
+   |
+LL |     takes_fn_mut(|| f());
+   |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
+
+error: redundant closure
+  --> $DIR/eta.rs:313:19
+   |
+LL |     takes_fn_once(|| f());
+   |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
+
+error: redundant closure
+  --> $DIR/eta.rs:317:26
+   |
+LL |     move || takes_fn_mut(|| f_used_once())
+   |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
+
+error: aborting due to 22 previous errors
 
diff --git a/tests/ui/floating_point_exp.fixed b/tests/ui/floating_point_exp.fixed
index c86a502d15f..b9e3d89c2b2 100644
--- a/tests/ui/floating_point_exp.fixed
+++ b/tests/ui/floating_point_exp.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::imprecise_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 2f32;
diff --git a/tests/ui/floating_point_exp.rs b/tests/ui/floating_point_exp.rs
index e59589f912a..ef008dd9be0 100644
--- a/tests/ui/floating_point_exp.rs
+++ b/tests/ui/floating_point_exp.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::imprecise_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 2f32;
diff --git a/tests/ui/floating_point_exp.stderr b/tests/ui/floating_point_exp.stderr
index f84eede1987..b92fae56e42 100644
--- a/tests/ui/floating_point_exp.stderr
+++ b/tests/ui/floating_point_exp.stderr
@@ -1,5 +1,5 @@
 error: (e.pow(x) - 1) can be computed more accurately
-  --> $DIR/floating_point_exp.rs:6:13
+  --> $DIR/floating_point_exp.rs:7:13
    |
 LL |     let _ = x.exp() - 1.0;
    |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
@@ -7,25 +7,25 @@ LL |     let _ = x.exp() - 1.0;
    = note: `-D clippy::imprecise-flops` implied by `-D warnings`
 
 error: (e.pow(x) - 1) can be computed more accurately
-  --> $DIR/floating_point_exp.rs:7:13
+  --> $DIR/floating_point_exp.rs:8:13
    |
 LL |     let _ = x.exp() - 1.0 + 2.0;
    |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
 
 error: (e.pow(x) - 1) can be computed more accurately
-  --> $DIR/floating_point_exp.rs:8:13
+  --> $DIR/floating_point_exp.rs:9:13
    |
 LL |     let _ = (x as f32).exp() - 1.0 + 2.0;
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()`
 
 error: (e.pow(x) - 1) can be computed more accurately
-  --> $DIR/floating_point_exp.rs:14:13
+  --> $DIR/floating_point_exp.rs:15:13
    |
 LL |     let _ = x.exp() - 1.0;
    |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
 
 error: (e.pow(x) - 1) can be computed more accurately
-  --> $DIR/floating_point_exp.rs:15:13
+  --> $DIR/floating_point_exp.rs:16:13
    |
 LL |     let _ = x.exp() - 1.0 + 2.0;
    |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed
index 4def9300bb7..ee540646160 100644
--- a/tests/ui/floating_point_log.fixed
+++ b/tests/ui/floating_point_log.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(dead_code, clippy::double_parens)]
+#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]
 #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
 
 const TWO: f32 = 2.0;
diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs
index 1e04caa7d2a..0590670a50b 100644
--- a/tests/ui/floating_point_log.rs
+++ b/tests/ui/floating_point_log.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(dead_code, clippy::double_parens)]
+#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]
 #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
 
 const TWO: f32 = 2.0;
diff --git a/tests/ui/floating_point_logbase.fixed b/tests/ui/floating_point_logbase.fixed
index 936462f9406..7347bf72cbe 100644
--- a/tests/ui/floating_point_logbase.fixed
+++ b/tests/ui/floating_point_logbase.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 3f32;
diff --git a/tests/ui/floating_point_logbase.rs b/tests/ui/floating_point_logbase.rs
index 0b56fa8fa41..ba5b8d40692 100644
--- a/tests/ui/floating_point_logbase.rs
+++ b/tests/ui/floating_point_logbase.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 3f32;
diff --git a/tests/ui/floating_point_logbase.stderr b/tests/ui/floating_point_logbase.stderr
index 384e3554cbb..9d736b5e1a2 100644
--- a/tests/ui/floating_point_logbase.stderr
+++ b/tests/ui/floating_point_logbase.stderr
@@ -1,5 +1,5 @@
 error: log base can be expressed more clearly
-  --> $DIR/floating_point_logbase.rs:7:13
+  --> $DIR/floating_point_logbase.rs:8:13
    |
 LL |     let _ = x.ln() / y.ln();
    |             ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
@@ -7,25 +7,25 @@ LL |     let _ = x.ln() / y.ln();
    = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
 
 error: log base can be expressed more clearly
-  --> $DIR/floating_point_logbase.rs:8:13
+  --> $DIR/floating_point_logbase.rs:9:13
    |
 LL |     let _ = (x as f32).ln() / y.ln();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)`
 
 error: log base can be expressed more clearly
-  --> $DIR/floating_point_logbase.rs:9:13
+  --> $DIR/floating_point_logbase.rs:10:13
    |
 LL |     let _ = x.log2() / y.log2();
    |             ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
 
 error: log base can be expressed more clearly
-  --> $DIR/floating_point_logbase.rs:10:13
+  --> $DIR/floating_point_logbase.rs:11:13
    |
 LL |     let _ = x.log10() / y.log10();
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
 
 error: log base can be expressed more clearly
-  --> $DIR/floating_point_logbase.rs:11:13
+  --> $DIR/floating_point_logbase.rs:12:13
    |
 LL |     let _ = x.log(5f32) / y.log(5f32);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
diff --git a/tests/ui/floating_point_mul_add.fixed b/tests/ui/floating_point_mul_add.fixed
index 169ec02f82b..d3e536ba350 100644
--- a/tests/ui/floating_point_mul_add.fixed
+++ b/tests/ui/floating_point_mul_add.fixed
@@ -19,7 +19,9 @@ fn main() {
     let d: f64 = 0.0001;
 
     let _ = a.mul_add(b, c);
+    let _ = a.mul_add(b, -c);
     let _ = a.mul_add(b, c);
+    let _ = a.mul_add(-b, c);
     let _ = 2.0f64.mul_add(4.0, a);
     let _ = 2.0f64.mul_add(4., a);
 
diff --git a/tests/ui/floating_point_mul_add.rs b/tests/ui/floating_point_mul_add.rs
index 5338d4fc2b7..5d4a9e35cfc 100644
--- a/tests/ui/floating_point_mul_add.rs
+++ b/tests/ui/floating_point_mul_add.rs
@@ -19,7 +19,9 @@ fn main() {
     let d: f64 = 0.0001;
 
     let _ = a * b + c;
+    let _ = a * b - c;
     let _ = c + a * b;
+    let _ = c - a * b;
     let _ = a + 2.0 * 4.0;
     let _ = a + 2. * 4.;
 
diff --git a/tests/ui/floating_point_mul_add.stderr b/tests/ui/floating_point_mul_add.stderr
index e637bbf90ca..a79ae94e8d4 100644
--- a/tests/ui/floating_point_mul_add.stderr
+++ b/tests/ui/floating_point_mul_add.stderr
@@ -9,56 +9,68 @@ LL |     let _ = a * b + c;
 error: multiply and add expressions can be calculated more efficiently and accurately
   --> $DIR/floating_point_mul_add.rs:22:13
    |
+LL |     let _ = a * b - c;
+   |             ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> $DIR/floating_point_mul_add.rs:23:13
+   |
 LL |     let _ = c + a * b;
    |             ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:23:13
+  --> $DIR/floating_point_mul_add.rs:24:13
+   |
+LL |     let _ = c - a * b;
+   |             ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> $DIR/floating_point_mul_add.rs:25:13
    |
 LL |     let _ = a + 2.0 * 4.0;
    |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:24:13
+  --> $DIR/floating_point_mul_add.rs:26:13
    |
 LL |     let _ = a + 2. * 4.;
    |             ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:26:13
+  --> $DIR/floating_point_mul_add.rs:28:13
    |
 LL |     let _ = (a * b) + c;
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:27:13
+  --> $DIR/floating_point_mul_add.rs:29:13
    |
 LL |     let _ = c + (a * b);
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:28:13
+  --> $DIR/floating_point_mul_add.rs:30:13
    |
 LL |     let _ = a * b * c + d;
    |             ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:30:13
+  --> $DIR/floating_point_mul_add.rs:32:13
    |
 LL |     let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:31:13
+  --> $DIR/floating_point_mul_add.rs:33:13
    |
 LL |     let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_mul_add.rs:33:13
+  --> $DIR/floating_point_mul_add.rs:35:13
    |
 LL |     let _ = (a * a + b).sqrt();
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/tests/ui/floating_point_powf.fixed b/tests/ui/floating_point_powf.fixed
index e7ef45634df..f7f93de2957 100644
--- a/tests/ui/floating_point_powf.fixed
+++ b/tests/ui/floating_point_powf.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 3f32;
diff --git a/tests/ui/floating_point_powf.rs b/tests/ui/floating_point_powf.rs
index d749aa2d48a..499fc0e15e4 100644
--- a/tests/ui/floating_point_powf.rs
+++ b/tests/ui/floating_point_powf.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let x = 3f32;
diff --git a/tests/ui/floating_point_powf.stderr b/tests/ui/floating_point_powf.stderr
index e9693de8fc9..7c9d50db2f7 100644
--- a/tests/ui/floating_point_powf.stderr
+++ b/tests/ui/floating_point_powf.stderr
@@ -1,5 +1,5 @@
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:6:13
+  --> $DIR/floating_point_powf.rs:7:13
    |
 LL |     let _ = 2f32.powf(x);
    |             ^^^^^^^^^^^^ help: consider using: `x.exp2()`
@@ -7,43 +7,43 @@ LL |     let _ = 2f32.powf(x);
    = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:7:13
+  --> $DIR/floating_point_powf.rs:8:13
    |
 LL |     let _ = 2f32.powf(3.1);
    |             ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:8:13
+  --> $DIR/floating_point_powf.rs:9:13
    |
 LL |     let _ = 2f32.powf(-3.1);
    |             ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:9:13
+  --> $DIR/floating_point_powf.rs:10:13
    |
 LL |     let _ = std::f32::consts::E.powf(x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:10:13
+  --> $DIR/floating_point_powf.rs:11:13
    |
 LL |     let _ = std::f32::consts::E.powf(3.1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:11:13
+  --> $DIR/floating_point_powf.rs:12:13
    |
 LL |     let _ = std::f32::consts::E.powf(-3.1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()`
 
 error: square-root of a number can be computed more efficiently and accurately
-  --> $DIR/floating_point_powf.rs:12:13
+  --> $DIR/floating_point_powf.rs:13:13
    |
 LL |     let _ = x.powf(1.0 / 2.0);
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
 
 error: cube-root of a number can be computed more accurately
-  --> $DIR/floating_point_powf.rs:13:13
+  --> $DIR/floating_point_powf.rs:14:13
    |
 LL |     let _ = x.powf(1.0 / 3.0);
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
@@ -51,139 +51,139 @@ LL |     let _ = x.powf(1.0 / 3.0);
    = note: `-D clippy::imprecise-flops` implied by `-D warnings`
 
 error: cube-root of a number can be computed more accurately
-  --> $DIR/floating_point_powf.rs:14:13
+  --> $DIR/floating_point_powf.rs:15:13
    |
 LL |     let _ = (x as f32).powf(1.0 / 3.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:15:13
+  --> $DIR/floating_point_powf.rs:16:13
    |
 LL |     let _ = x.powf(3.0);
    |             ^^^^^^^^^^^ help: consider using: `x.powi(3)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:16:13
+  --> $DIR/floating_point_powf.rs:17:13
    |
 LL |     let _ = x.powf(-2.0);
    |             ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:17:13
+  --> $DIR/floating_point_powf.rs:18:13
    |
 LL |     let _ = x.powf(16_777_215.0);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:18:13
+  --> $DIR/floating_point_powf.rs:19:13
    |
 LL |     let _ = x.powf(-16_777_215.0);
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:19:13
+  --> $DIR/floating_point_powf.rs:20:13
    |
 LL |     let _ = (x as f32).powf(-16_777_215.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:20:13
+  --> $DIR/floating_point_powf.rs:21:13
    |
 LL |     let _ = (x as f32).powf(3.0);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)`
 
 error: cube-root of a number can be computed more accurately
-  --> $DIR/floating_point_powf.rs:21:13
+  --> $DIR/floating_point_powf.rs:22:13
    |
 LL |     let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()`
 
 error: cube-root of a number can be computed more accurately
-  --> $DIR/floating_point_powf.rs:22:13
+  --> $DIR/floating_point_powf.rs:23:13
    |
 LL |     let _ = 1.5_f64.powf(1.0 / 3.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()`
 
 error: square-root of a number can be computed more efficiently and accurately
-  --> $DIR/floating_point_powf.rs:23:13
+  --> $DIR/floating_point_powf.rs:24:13
    |
 LL |     let _ = 1.5_f64.powf(1.0 / 2.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:24:13
+  --> $DIR/floating_point_powf.rs:25:13
    |
 LL |     let _ = 1.5_f64.powf(3.0);
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:33:13
+  --> $DIR/floating_point_powf.rs:34:13
    |
 LL |     let _ = 2f64.powf(x);
    |             ^^^^^^^^^^^^ help: consider using: `x.exp2()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:34:13
+  --> $DIR/floating_point_powf.rs:35:13
    |
 LL |     let _ = 2f64.powf(3.1);
    |             ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:35:13
+  --> $DIR/floating_point_powf.rs:36:13
    |
 LL |     let _ = 2f64.powf(-3.1);
    |             ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:36:13
+  --> $DIR/floating_point_powf.rs:37:13
    |
 LL |     let _ = std::f64::consts::E.powf(x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:37:13
+  --> $DIR/floating_point_powf.rs:38:13
    |
 LL |     let _ = std::f64::consts::E.powf(3.1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()`
 
 error: exponent for bases 2 and e can be computed more accurately
-  --> $DIR/floating_point_powf.rs:38:13
+  --> $DIR/floating_point_powf.rs:39:13
    |
 LL |     let _ = std::f64::consts::E.powf(-3.1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()`
 
 error: square-root of a number can be computed more efficiently and accurately
-  --> $DIR/floating_point_powf.rs:39:13
+  --> $DIR/floating_point_powf.rs:40:13
    |
 LL |     let _ = x.powf(1.0 / 2.0);
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
 
 error: cube-root of a number can be computed more accurately
-  --> $DIR/floating_point_powf.rs:40:13
+  --> $DIR/floating_point_powf.rs:41:13
    |
 LL |     let _ = x.powf(1.0 / 3.0);
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:41:13
+  --> $DIR/floating_point_powf.rs:42:13
    |
 LL |     let _ = x.powf(3.0);
    |             ^^^^^^^^^^^ help: consider using: `x.powi(3)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:42:13
+  --> $DIR/floating_point_powf.rs:43:13
    |
 LL |     let _ = x.powf(-2.0);
    |             ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:43:13
+  --> $DIR/floating_point_powf.rs:44:13
    |
 LL |     let _ = x.powf(-2_147_483_648.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)`
 
 error: exponentiation with integer powers can be computed more efficiently
-  --> $DIR/floating_point_powf.rs:44:13
+  --> $DIR/floating_point_powf.rs:45:13
    |
 LL |     let _ = x.powf(2_147_483_647.0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)`
diff --git a/tests/ui/floating_point_powi.fixed b/tests/ui/floating_point_powi.fixed
index 5758db7c6c8..884d05fed71 100644
--- a/tests/ui/floating_point_powi.fixed
+++ b/tests/ui/floating_point_powi.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let one = 1;
@@ -7,7 +8,9 @@ fn main() {
 
     let y = 4f32;
     let _ = x.mul_add(x, y);
+    let _ = x.mul_add(x, -y);
     let _ = y.mul_add(y, x);
+    let _ = y.mul_add(-y, x);
     let _ = (y as f32).mul_add(y as f32, x);
     let _ = x.mul_add(x, y).sqrt();
     let _ = y.mul_add(y, x).sqrt();
diff --git a/tests/ui/floating_point_powi.rs b/tests/ui/floating_point_powi.rs
index 5926bf1b000..e6a1c895371 100644
--- a/tests/ui/floating_point_powi.rs
+++ b/tests/ui/floating_point_powi.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::suboptimal_flops)]
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let one = 1;
@@ -7,7 +8,9 @@ fn main() {
 
     let y = 4f32;
     let _ = x.powi(2) + y;
+    let _ = x.powi(2) - y;
     let _ = x + y.powi(2);
+    let _ = x - y.powi(2);
     let _ = x + (y as f32).powi(2);
     let _ = (x.powi(2) + y).sqrt();
     let _ = (x + y.powi(2)).sqrt();
diff --git a/tests/ui/floating_point_powi.stderr b/tests/ui/floating_point_powi.stderr
index a3c74544212..5df0de1fef2 100644
--- a/tests/ui/floating_point_powi.stderr
+++ b/tests/ui/floating_point_powi.stderr
@@ -1,5 +1,5 @@
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_powi.rs:9:13
+  --> $DIR/floating_point_powi.rs:10:13
    |
 LL |     let _ = x.powi(2) + y;
    |             ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
@@ -7,28 +7,40 @@ LL |     let _ = x.powi(2) + y;
    = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_powi.rs:10:13
+  --> $DIR/floating_point_powi.rs:11:13
+   |
+LL |     let _ = x.powi(2) - y;
+   |             ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, -y)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> $DIR/floating_point_powi.rs:12:13
    |
 LL |     let _ = x + y.powi(2);
    |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_powi.rs:11:13
+  --> $DIR/floating_point_powi.rs:13:13
+   |
+LL |     let _ = x - y.powi(2);
+   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(-y, x)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> $DIR/floating_point_powi.rs:14:13
    |
 LL |     let _ = x + (y as f32).powi(2);
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_powi.rs:12:13
+  --> $DIR/floating_point_powi.rs:15:13
    |
 LL |     let _ = (x.powi(2) + y).sqrt();
    |             ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> $DIR/floating_point_powi.rs:13:13
+  --> $DIR/floating_point_powi.rs:16:13
    |
 LL |     let _ = (x + y.powi(2)).sqrt();
    |             ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/implicit_saturating_add.fixed b/tests/ui/implicit_saturating_add.fixed
new file mode 100644
index 00000000000..7d363d59a6f
--- /dev/null
+++ b/tests/ui/implicit_saturating_add.fixed
@@ -0,0 +1,106 @@
+// run-rustfix
+
+#![allow(unused)]
+#![warn(clippy::implicit_saturating_add)]
+
+fn main() {
+    let mut u_8: u8 = 255;
+    let mut u_16: u16 = 500;
+    let mut u_32: u32 = 7000;
+    let mut u_64: u64 = 7000;
+    let mut i_8: i8 = 30;
+    let mut i_16: i16 = 500;
+    let mut i_32: i32 = 7000;
+    let mut i_64: i64 = 7000;
+
+    if i_8 < 42 {
+        i_8 += 1;
+    }
+    if i_8 != 42 {
+        i_8 += 1;
+    }
+
+    u_8 = u_8.saturating_add(1);
+
+    u_8 = u_8.saturating_add(1);
+
+    if u_8 < 15 {
+        u_8 += 1;
+    }
+
+    u_16 = u_16.saturating_add(1);
+
+    u_16 = u_16.saturating_add(1);
+
+    u_16 = u_16.saturating_add(1);
+
+    u_32 = u_32.saturating_add(1);
+
+    u_32 = u_32.saturating_add(1);
+
+    u_32 = u_32.saturating_add(1);
+
+    u_64 = u_64.saturating_add(1);
+
+    u_64 = u_64.saturating_add(1);
+
+    u_64 = u_64.saturating_add(1);
+
+    i_8 = i_8.saturating_add(1);
+
+    i_8 = i_8.saturating_add(1);
+
+    i_8 = i_8.saturating_add(1);
+
+    i_16 = i_16.saturating_add(1);
+
+    i_16 = i_16.saturating_add(1);
+
+    i_16 = i_16.saturating_add(1);
+
+    i_32 = i_32.saturating_add(1);
+
+    i_32 = i_32.saturating_add(1);
+
+    i_32 = i_32.saturating_add(1);
+
+    i_64 = i_64.saturating_add(1);
+
+    i_64 = i_64.saturating_add(1);
+
+    i_64 = i_64.saturating_add(1);
+
+    if i_64 < 42 {
+        i_64 += 1;
+    }
+
+    if 42 > i_64 {
+        i_64 += 1;
+    }
+
+    let a = 12;
+    let mut b = 8;
+
+    if a < u8::MAX {
+        b += 1;
+    }
+
+    if u8::MAX > a {
+        b += 1;
+    }
+
+    if u_32 < u32::MAX {
+        u_32 += 1;
+    } else {
+        println!("don't lint this");
+    }
+
+    if u_32 < u32::MAX {
+        println!("don't lint this");
+        u_32 += 1;
+    }
+
+    if u_32 < 42 {
+        println!("brace yourself!");
+    } else {u_32 = u_32.saturating_add(1); }
+}
diff --git a/tests/ui/implicit_saturating_add.rs b/tests/ui/implicit_saturating_add.rs
new file mode 100644
index 00000000000..31a5916277f
--- /dev/null
+++ b/tests/ui/implicit_saturating_add.rs
@@ -0,0 +1,154 @@
+// run-rustfix
+
+#![allow(unused)]
+#![warn(clippy::implicit_saturating_add)]
+
+fn main() {
+    let mut u_8: u8 = 255;
+    let mut u_16: u16 = 500;
+    let mut u_32: u32 = 7000;
+    let mut u_64: u64 = 7000;
+    let mut i_8: i8 = 30;
+    let mut i_16: i16 = 500;
+    let mut i_32: i32 = 7000;
+    let mut i_64: i64 = 7000;
+
+    if i_8 < 42 {
+        i_8 += 1;
+    }
+    if i_8 != 42 {
+        i_8 += 1;
+    }
+
+    if u_8 != u8::MAX {
+        u_8 += 1;
+    }
+
+    if u_8 < u8::MAX {
+        u_8 += 1;
+    }
+
+    if u_8 < 15 {
+        u_8 += 1;
+    }
+
+    if u_16 != u16::MAX {
+        u_16 += 1;
+    }
+
+    if u_16 < u16::MAX {
+        u_16 += 1;
+    }
+
+    if u16::MAX > u_16 {
+        u_16 += 1;
+    }
+
+    if u_32 != u32::MAX {
+        u_32 += 1;
+    }
+
+    if u_32 < u32::MAX {
+        u_32 += 1;
+    }
+
+    if u32::MAX > u_32 {
+        u_32 += 1;
+    }
+
+    if u_64 != u64::MAX {
+        u_64 += 1;
+    }
+
+    if u_64 < u64::MAX {
+        u_64 += 1;
+    }
+
+    if u64::MAX > u_64 {
+        u_64 += 1;
+    }
+
+    if i_8 != i8::MAX {
+        i_8 += 1;
+    }
+
+    if i_8 < i8::MAX {
+        i_8 += 1;
+    }
+
+    if i8::MAX > i_8 {
+        i_8 += 1;
+    }
+
+    if i_16 != i16::MAX {
+        i_16 += 1;
+    }
+
+    if i_16 < i16::MAX {
+        i_16 += 1;
+    }
+
+    if i16::MAX > i_16 {
+        i_16 += 1;
+    }
+
+    if i_32 != i32::MAX {
+        i_32 += 1;
+    }
+
+    if i_32 < i32::MAX {
+        i_32 += 1;
+    }
+
+    if i32::MAX > i_32 {
+        i_32 += 1;
+    }
+
+    if i_64 != i64::MAX {
+        i_64 += 1;
+    }
+
+    if i_64 < i64::MAX {
+        i_64 += 1;
+    }
+
+    if i64::MAX > i_64 {
+        i_64 += 1;
+    }
+
+    if i_64 < 42 {
+        i_64 += 1;
+    }
+
+    if 42 > i_64 {
+        i_64 += 1;
+    }
+
+    let a = 12;
+    let mut b = 8;
+
+    if a < u8::MAX {
+        b += 1;
+    }
+
+    if u8::MAX > a {
+        b += 1;
+    }
+
+    if u_32 < u32::MAX {
+        u_32 += 1;
+    } else {
+        println!("don't lint this");
+    }
+
+    if u_32 < u32::MAX {
+        println!("don't lint this");
+        u_32 += 1;
+    }
+
+    if u_32 < 42 {
+        println!("brace yourself!");
+    } else if u_32 < u32::MAX {
+        u_32 += 1;
+    }
+}
diff --git a/tests/ui/implicit_saturating_add.stderr b/tests/ui/implicit_saturating_add.stderr
new file mode 100644
index 00000000000..42ae1b48885
--- /dev/null
+++ b/tests/ui/implicit_saturating_add.stderr
@@ -0,0 +1,197 @@
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:23:5
+   |
+LL | /     if u_8 != u8::MAX {
+LL | |         u_8 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`
+   |
+   = note: `-D clippy::implicit-saturating-add` implied by `-D warnings`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:27:5
+   |
+LL | /     if u_8 < u8::MAX {
+LL | |         u_8 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:35:5
+   |
+LL | /     if u_16 != u16::MAX {
+LL | |         u_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:39:5
+   |
+LL | /     if u_16 < u16::MAX {
+LL | |         u_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:43:5
+   |
+LL | /     if u16::MAX > u_16 {
+LL | |         u_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:47:5
+   |
+LL | /     if u_32 != u32::MAX {
+LL | |         u_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:51:5
+   |
+LL | /     if u_32 < u32::MAX {
+LL | |         u_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:55:5
+   |
+LL | /     if u32::MAX > u_32 {
+LL | |         u_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:59:5
+   |
+LL | /     if u_64 != u64::MAX {
+LL | |         u_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:63:5
+   |
+LL | /     if u_64 < u64::MAX {
+LL | |         u_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:67:5
+   |
+LL | /     if u64::MAX > u_64 {
+LL | |         u_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:71:5
+   |
+LL | /     if i_8 != i8::MAX {
+LL | |         i_8 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:75:5
+   |
+LL | /     if i_8 < i8::MAX {
+LL | |         i_8 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:79:5
+   |
+LL | /     if i8::MAX > i_8 {
+LL | |         i_8 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:83:5
+   |
+LL | /     if i_16 != i16::MAX {
+LL | |         i_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:87:5
+   |
+LL | /     if i_16 < i16::MAX {
+LL | |         i_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:91:5
+   |
+LL | /     if i16::MAX > i_16 {
+LL | |         i_16 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:95:5
+   |
+LL | /     if i_32 != i32::MAX {
+LL | |         i_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:99:5
+   |
+LL | /     if i_32 < i32::MAX {
+LL | |         i_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:103:5
+   |
+LL | /     if i32::MAX > i_32 {
+LL | |         i_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:107:5
+   |
+LL | /     if i_64 != i64::MAX {
+LL | |         i_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:111:5
+   |
+LL | /     if i_64 < i64::MAX {
+LL | |         i_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:115:5
+   |
+LL | /     if i64::MAX > i_64 {
+LL | |         i_64 += 1;
+LL | |     }
+   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
+
+error: manual saturating add detected
+  --> $DIR/implicit_saturating_add.rs:151:12
+   |
+LL |       } else if u_32 < u32::MAX {
+   |  ____________^
+LL | |         u_32 += 1;
+LL | |     }
+   | |_____^ help: use instead: `{u_32 = u_32.saturating_add(1); }`
+
+error: aborting due to 24 previous errors
+
diff --git a/tests/ui/manual_assert.edition2018.fixed b/tests/ui/manual_assert.edition2018.fixed
index 65598f1eacc..84f6855f338 100644
--- a/tests/ui/manual_assert.edition2018.fixed
+++ b/tests/ui/manual_assert.edition2018.fixed
@@ -4,7 +4,7 @@
 // run-rustfix
 
 #![warn(clippy::manual_assert)]
-#![allow(clippy::nonminimal_bool)]
+#![allow(dead_code, unused_doc_comments, clippy::nonminimal_bool)]
 
 macro_rules! one {
     () => {
@@ -50,3 +50,14 @@ fn main() {
     assert!(!(a.is_empty() || !b.is_empty()), "panic5");
     assert!(!a.is_empty(), "with expansion {}", one!());
 }
+
+fn issue7730(a: u8) {
+    // Suggestion should preserve comment
+    // comment
+/* this is a
+        multiline
+        comment */
+/// Doc comment
+// comment after `panic!`
+assert!(!(a > 2), "panic with comment");
+}
diff --git a/tests/ui/manual_assert.edition2018.stderr b/tests/ui/manual_assert.edition2018.stderr
index a0f31afd6eb..dbd21be2da9 100644
--- a/tests/ui/manual_assert.edition2018.stderr
+++ b/tests/ui/manual_assert.edition2018.stderr
@@ -4,9 +4,13 @@ error: only a `panic!` in `if`-then statement
 LL | /     if !a.is_empty() {
 LL | |         panic!("qaqaq{:?}", a);
 LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qaqaq{:?}", a);`
+   | |_____^
    |
    = note: `-D clippy::manual-assert` implied by `-D warnings`
+help: try instead
+   |
+LL |     assert!(a.is_empty(), "qaqaq{:?}", a);
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:33:5
@@ -14,7 +18,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if !a.is_empty() {
 LL | |         panic!("qwqwq");
 LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(a.is_empty(), "qwqwq");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:50:5
@@ -22,7 +31,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() {
 LL | |         panic!("panic1");
 LL | |     }
-   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!b.is_empty(), "panic1");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:53:5
@@ -30,7 +44,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() && a.is_empty() {
 LL | |         panic!("panic2");
 LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(b.is_empty() && a.is_empty()), "panic2");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:56:5
@@ -38,7 +57,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() && !b.is_empty() {
 LL | |         panic!("panic3");
 LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:59:5
@@ -46,7 +70,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() || a.is_empty() {
 LL | |         panic!("panic4");
 LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(b.is_empty() || a.is_empty()), "panic4");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:62:5
@@ -54,7 +83,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() || !b.is_empty() {
 LL | |         panic!("panic5");
 LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a.is_empty() || !b.is_empty()), "panic5");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:65:5
@@ -62,7 +96,29 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() {
 LL | |         panic!("with expansion {}", one!())
 LL | |     }
-   | |_____^ help: try: `assert!(!a.is_empty(), "with expansion {}", one!());`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!a.is_empty(), "with expansion {}", one!());
+   |
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:72:5
+   |
+LL | /     if a > 2 {
+LL | |         // comment
+LL | |         /* this is a
+LL | |         multiline
+...  |
+LL | |         panic!("panic with comment") // comment after `panic!`
+LL | |     }
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a > 2), "panic with comment");
+   |
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/manual_assert.edition2021.fixed b/tests/ui/manual_assert.edition2021.fixed
index 65598f1eacc..84f6855f338 100644
--- a/tests/ui/manual_assert.edition2021.fixed
+++ b/tests/ui/manual_assert.edition2021.fixed
@@ -4,7 +4,7 @@
 // run-rustfix
 
 #![warn(clippy::manual_assert)]
-#![allow(clippy::nonminimal_bool)]
+#![allow(dead_code, unused_doc_comments, clippy::nonminimal_bool)]
 
 macro_rules! one {
     () => {
@@ -50,3 +50,14 @@ fn main() {
     assert!(!(a.is_empty() || !b.is_empty()), "panic5");
     assert!(!a.is_empty(), "with expansion {}", one!());
 }
+
+fn issue7730(a: u8) {
+    // Suggestion should preserve comment
+    // comment
+/* this is a
+        multiline
+        comment */
+/// Doc comment
+// comment after `panic!`
+assert!(!(a > 2), "panic with comment");
+}
diff --git a/tests/ui/manual_assert.edition2021.stderr b/tests/ui/manual_assert.edition2021.stderr
index a0f31afd6eb..dbd21be2da9 100644
--- a/tests/ui/manual_assert.edition2021.stderr
+++ b/tests/ui/manual_assert.edition2021.stderr
@@ -4,9 +4,13 @@ error: only a `panic!` in `if`-then statement
 LL | /     if !a.is_empty() {
 LL | |         panic!("qaqaq{:?}", a);
 LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qaqaq{:?}", a);`
+   | |_____^
    |
    = note: `-D clippy::manual-assert` implied by `-D warnings`
+help: try instead
+   |
+LL |     assert!(a.is_empty(), "qaqaq{:?}", a);
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:33:5
@@ -14,7 +18,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if !a.is_empty() {
 LL | |         panic!("qwqwq");
 LL | |     }
-   | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(a.is_empty(), "qwqwq");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:50:5
@@ -22,7 +31,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() {
 LL | |         panic!("panic1");
 LL | |     }
-   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!b.is_empty(), "panic1");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:53:5
@@ -30,7 +44,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() && a.is_empty() {
 LL | |         panic!("panic2");
 LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(b.is_empty() && a.is_empty()), "panic2");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:56:5
@@ -38,7 +57,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() && !b.is_empty() {
 LL | |         panic!("panic3");
 LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:59:5
@@ -46,7 +70,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if b.is_empty() || a.is_empty() {
 LL | |         panic!("panic4");
 LL | |     }
-   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(b.is_empty() || a.is_empty()), "panic4");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:62:5
@@ -54,7 +83,12 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() || !b.is_empty() {
 LL | |         panic!("panic5");
 LL | |     }
-   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a.is_empty() || !b.is_empty()), "panic5");
+   |
 
 error: only a `panic!` in `if`-then statement
   --> $DIR/manual_assert.rs:65:5
@@ -62,7 +96,29 @@ error: only a `panic!` in `if`-then statement
 LL | /     if a.is_empty() {
 LL | |         panic!("with expansion {}", one!())
 LL | |     }
-   | |_____^ help: try: `assert!(!a.is_empty(), "with expansion {}", one!());`
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!a.is_empty(), "with expansion {}", one!());
+   |
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/manual_assert.rs:72:5
+   |
+LL | /     if a > 2 {
+LL | |         // comment
+LL | |         /* this is a
+LL | |         multiline
+...  |
+LL | |         panic!("panic with comment") // comment after `panic!`
+LL | |     }
+   | |_____^
+   |
+help: try instead
+   |
+LL |     assert!(!(a > 2), "panic with comment");
+   |
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/manual_assert.fixed b/tests/ui/manual_assert.fixed
deleted file mode 100644
index a2393674fe6..00000000000
--- a/tests/ui/manual_assert.fixed
+++ /dev/null
@@ -1,45 +0,0 @@
-// revisions: edition2018 edition2021
-// [edition2018] edition:2018
-// [edition2021] edition:2021
-// run-rustfix
-
-#![warn(clippy::manual_assert)]
-#![allow(clippy::nonminimal_bool)]
-
-fn main() {
-    let a = vec![1, 2, 3];
-    let c = Some(2);
-    if !a.is_empty()
-        && a.len() == 3
-        && c.is_some()
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-        && !a.is_empty()
-        && a.len() == 3
-    {
-        panic!("qaqaq{:?}", a);
-    }
-    assert!(a.is_empty(), "qaqaq{:?}", a);
-    assert!(a.is_empty(), "qwqwq");
-    if a.len() == 3 {
-        println!("qwq");
-        println!("qwq");
-        println!("qwq");
-    }
-    if let Some(b) = c {
-        panic!("orz {}", b);
-    }
-    if a.len() == 3 {
-        panic!("qaqaq");
-    } else {
-        println!("qwq");
-    }
-    let b = vec![1, 2, 3];
-    assert!(!b.is_empty(), "panic1");
-    assert!(!(b.is_empty() && a.is_empty()), "panic2");
-    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
-    assert!(!(b.is_empty() || a.is_empty()), "panic4");
-    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
-}
diff --git a/tests/ui/manual_assert.rs b/tests/ui/manual_assert.rs
index 4d2706dd621..14abf94965a 100644
--- a/tests/ui/manual_assert.rs
+++ b/tests/ui/manual_assert.rs
@@ -4,7 +4,7 @@
 // run-rustfix
 
 #![warn(clippy::manual_assert)]
-#![allow(clippy::nonminimal_bool)]
+#![allow(dead_code, unused_doc_comments, clippy::nonminimal_bool)]
 
 macro_rules! one {
     () => {
@@ -66,3 +66,15 @@ fn main() {
         panic!("with expansion {}", one!())
     }
 }
+
+fn issue7730(a: u8) {
+    // Suggestion should preserve comment
+    if a > 2 {
+        // comment
+        /* this is a
+        multiline
+        comment */
+        /// Doc comment
+        panic!("panic with comment") // comment after `panic!`
+    }
+}
diff --git a/tests/ui/manual_bits.fixed b/tests/ui/manual_bits.fixed
index 386360dbdcd..e7f8cd878ca 100644
--- a/tests/ui/manual_bits.fixed
+++ b/tests/ui/manual_bits.fixed
@@ -6,7 +6,8 @@
     clippy::useless_conversion,
     path_statements,
     unused_must_use,
-    clippy::unnecessary_operation
+    clippy::unnecessary_operation,
+    clippy::unnecessary_cast
 )]
 
 use std::mem::{size_of, size_of_val};
diff --git a/tests/ui/manual_bits.rs b/tests/ui/manual_bits.rs
index 62638f047eb..7b1d1549528 100644
--- a/tests/ui/manual_bits.rs
+++ b/tests/ui/manual_bits.rs
@@ -6,7 +6,8 @@
     clippy::useless_conversion,
     path_statements,
     unused_must_use,
-    clippy::unnecessary_operation
+    clippy::unnecessary_operation,
+    clippy::unnecessary_cast
 )]
 
 use std::mem::{size_of, size_of_val};
diff --git a/tests/ui/manual_bits.stderr b/tests/ui/manual_bits.stderr
index 69c591a203d..652fafbc41d 100644
--- a/tests/ui/manual_bits.stderr
+++ b/tests/ui/manual_bits.stderr
@@ -1,5 +1,5 @@
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:15:5
+  --> $DIR/manual_bits.rs:16:5
    |
 LL |     size_of::<i8>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
@@ -7,169 +7,169 @@ LL |     size_of::<i8>() * 8;
    = note: `-D clippy::manual-bits` implied by `-D warnings`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:16:5
+  --> $DIR/manual_bits.rs:17:5
    |
 LL |     size_of::<i16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:17:5
+  --> $DIR/manual_bits.rs:18:5
    |
 LL |     size_of::<i32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:18:5
+  --> $DIR/manual_bits.rs:19:5
    |
 LL |     size_of::<i64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:19:5
+  --> $DIR/manual_bits.rs:20:5
    |
 LL |     size_of::<i128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:20:5
+  --> $DIR/manual_bits.rs:21:5
    |
 LL |     size_of::<isize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:22:5
+  --> $DIR/manual_bits.rs:23:5
    |
 LL |     size_of::<u8>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:23:5
+  --> $DIR/manual_bits.rs:24:5
    |
 LL |     size_of::<u16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:24:5
+  --> $DIR/manual_bits.rs:25:5
    |
 LL |     size_of::<u32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:25:5
+  --> $DIR/manual_bits.rs:26:5
    |
 LL |     size_of::<u64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:26:5
+  --> $DIR/manual_bits.rs:27:5
    |
 LL |     size_of::<u128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:27:5
+  --> $DIR/manual_bits.rs:28:5
    |
 LL |     size_of::<usize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:29:5
+  --> $DIR/manual_bits.rs:30:5
    |
 LL |     8 * size_of::<i8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:30:5
+  --> $DIR/manual_bits.rs:31:5
    |
 LL |     8 * size_of::<i16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:31:5
+  --> $DIR/manual_bits.rs:32:5
    |
 LL |     8 * size_of::<i32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:32:5
+  --> $DIR/manual_bits.rs:33:5
    |
 LL |     8 * size_of::<i64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:33:5
+  --> $DIR/manual_bits.rs:34:5
    |
 LL |     8 * size_of::<i128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:34:5
+  --> $DIR/manual_bits.rs:35:5
    |
 LL |     8 * size_of::<isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:36:5
+  --> $DIR/manual_bits.rs:37:5
    |
 LL |     8 * size_of::<u8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:37:5
+  --> $DIR/manual_bits.rs:38:5
    |
 LL |     8 * size_of::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:38:5
+  --> $DIR/manual_bits.rs:39:5
    |
 LL |     8 * size_of::<u32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:39:5
+  --> $DIR/manual_bits.rs:40:5
    |
 LL |     8 * size_of::<u64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:40:5
+  --> $DIR/manual_bits.rs:41:5
    |
 LL |     8 * size_of::<u128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:41:5
+  --> $DIR/manual_bits.rs:42:5
    |
 LL |     8 * size_of::<usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:51:5
+  --> $DIR/manual_bits.rs:52:5
    |
 LL |     size_of::<Word>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:55:18
+  --> $DIR/manual_bits.rs:56:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8) as u32;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:56:18
+  --> $DIR/manual_bits.rs:57:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:57:13
+  --> $DIR/manual_bits.rs:58:13
    |
 LL |     let _ = (size_of::<u128>() * 8).pow(5);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:58:14
+  --> $DIR/manual_bits.rs:59:14
    |
 LL |     let _ = &(size_of::<u128>() * 8);
    |              ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
diff --git a/tests/ui/manual_clamp.rs b/tests/ui/manual_clamp.rs
new file mode 100644
index 00000000000..54fd888af99
--- /dev/null
+++ b/tests/ui/manual_clamp.rs
@@ -0,0 +1,304 @@
+#![warn(clippy::manual_clamp)]
+#![allow(
+    unused,
+    dead_code,
+    clippy::unnecessary_operation,
+    clippy::no_effect,
+    clippy::if_same_then_else
+)]
+
+use std::cmp::{max as cmp_max, min as cmp_min};
+
+const CONST_MAX: i32 = 10;
+const CONST_MIN: i32 = 4;
+
+const CONST_F64_MAX: f64 = 10.0;
+const CONST_F64_MIN: f64 = 4.0;
+
+fn main() {
+    let (input, min, max) = (0, -2, 3);
+    // Lint
+    let x0 = if max < input {
+        max
+    } else if min > input {
+        min
+    } else {
+        input
+    };
+
+    let x1 = if input > max {
+        max
+    } else if input < min {
+        min
+    } else {
+        input
+    };
+
+    let x2 = if input < min {
+        min
+    } else if input > max {
+        max
+    } else {
+        input
+    };
+
+    let x3 = if min > input {
+        min
+    } else if max < input {
+        max
+    } else {
+        input
+    };
+
+    let x4 = input.max(min).min(max);
+
+    let x5 = input.min(max).max(min);
+
+    let x6 = match input {
+        x if x > max => max,
+        x if x < min => min,
+        x => x,
+    };
+
+    let x7 = match input {
+        x if x < min => min,
+        x if x > max => max,
+        x => x,
+    };
+
+    let x8 = match input {
+        x if max < x => max,
+        x if min > x => min,
+        x => x,
+    };
+
+    let mut x9 = input;
+    if x9 < min {
+        x9 = min;
+    }
+    if x9 > max {
+        x9 = max;
+    }
+
+    let x10 = match input {
+        x if min > x => min,
+        x if max < x => max,
+        x => x,
+    };
+
+    let mut x11 = input;
+    let _ = 1;
+    if x11 > max {
+        x11 = max;
+    }
+    if x11 < min {
+        x11 = min;
+    }
+
+    let mut x12 = input;
+    if min > x12 {
+        x12 = min;
+    }
+    if max < x12 {
+        x12 = max;
+    }
+
+    let mut x13 = input;
+    if max < x13 {
+        x13 = max;
+    }
+    if min > x13 {
+        x13 = min;
+    }
+
+    let x14 = if input > CONST_MAX {
+        CONST_MAX
+    } else if input < CONST_MIN {
+        CONST_MIN
+    } else {
+        input
+    };
+    {
+        let (input, min, max) = (0.0f64, -2.0, 3.0);
+        let x15 = if input > max {
+            max
+        } else if input < min {
+            min
+        } else {
+            input
+        };
+    }
+    {
+        let input: i32 = cmp_min_max(1);
+        // These can only be detected if exactly one of the arguments to the inner function is const.
+        let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
+        let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
+        let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
+        let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
+        let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
+        let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
+        let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
+        let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
+        let input: f64 = cmp_min_max(1) as f64;
+        let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
+        let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
+        let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
+        let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
+        let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
+        let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
+        let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
+        let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
+    }
+    let mut x32 = input;
+    if x32 < min {
+        x32 = min;
+    } else if x32 > max {
+        x32 = max;
+    }
+
+    // It's important this be the last set of statements
+    let mut x33 = input;
+    if max < x33 {
+        x33 = max;
+    }
+    if min > x33 {
+        x33 = min;
+    }
+}
+
+// This code intentionally nonsense.
+fn no_lint() {
+    let (input, min, max) = (0, -2, 3);
+    let x0 = if max < input {
+        max
+    } else if min > input {
+        max
+    } else {
+        min
+    };
+
+    let x1 = if input > max {
+        max
+    } else if input > min {
+        min
+    } else {
+        max
+    };
+
+    let x2 = if max < min {
+        min
+    } else if input > max {
+        input
+    } else {
+        input
+    };
+
+    let x3 = if min > input {
+        input
+    } else if max < input {
+        max
+    } else {
+        max
+    };
+
+    let x6 = match input {
+        x if x < max => x,
+        x if x < min => x,
+        x => x,
+    };
+
+    let x7 = match input {
+        x if x < min => max,
+        x if x > max => min,
+        x => x,
+    };
+
+    let x8 = match input {
+        x if max > x => max,
+        x if min > x => min,
+        x => x,
+    };
+
+    let mut x9 = input;
+    if x9 > min {
+        x9 = min;
+    }
+    if x9 > max {
+        x9 = max;
+    }
+
+    let x10 = match input {
+        x if min > x => min,
+        x if max < x => max,
+        x => min,
+    };
+
+    let mut x11 = input;
+    if x11 > max {
+        x11 = min;
+    }
+    if x11 < min {
+        x11 = max;
+    }
+
+    let mut x12 = input;
+    if min > x12 {
+        x12 = max * 3;
+    }
+    if max < x12 {
+        x12 = min;
+    }
+
+    let mut x13 = input;
+    if max < x13 {
+        let x13 = max;
+    }
+    if min > x13 {
+        x13 = min;
+    }
+    let mut x14 = input;
+    if x14 < min {
+        x14 = 3;
+    } else if x14 > max {
+        x14 = max;
+    }
+    {
+        let input: i32 = cmp_min_max(1);
+        // These can only be detected if exactly one of the arguments to the inner function is const.
+        let x16 = cmp_max(cmp_max(input, CONST_MAX), CONST_MIN);
+        let x17 = cmp_min(cmp_min(input, CONST_MIN), CONST_MAX);
+        let x18 = cmp_max(CONST_MIN, cmp_max(input, CONST_MAX));
+        let x19 = cmp_min(CONST_MAX, cmp_min(input, CONST_MIN));
+        let x20 = cmp_max(cmp_max(CONST_MAX, input), CONST_MIN);
+        let x21 = cmp_min(cmp_min(CONST_MIN, input), CONST_MAX);
+        let x22 = cmp_max(CONST_MIN, cmp_max(CONST_MAX, input));
+        let x23 = cmp_min(CONST_MAX, cmp_min(CONST_MIN, input));
+        let input: f64 = cmp_min_max(1) as f64;
+        let x24 = f64::max(f64::max(input, CONST_F64_MAX), CONST_F64_MIN);
+        let x25 = f64::min(f64::min(input, CONST_F64_MIN), CONST_F64_MAX);
+        let x26 = f64::max(CONST_F64_MIN, f64::max(input, CONST_F64_MAX));
+        let x27 = f64::min(CONST_F64_MAX, f64::min(input, CONST_F64_MIN));
+        let x28 = f64::max(f64::max(CONST_F64_MAX, input), CONST_F64_MIN);
+        let x29 = f64::min(f64::min(CONST_F64_MIN, input), CONST_F64_MAX);
+        let x30 = f64::max(CONST_F64_MIN, f64::max(CONST_F64_MAX, input));
+        let x31 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, input));
+        let x32 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, CONST_F64_MAX));
+    }
+}
+
+fn dont_tell_me_what_to_do() {
+    let (input, min, max) = (0, -2, 3);
+    let mut x_never = input;
+    #[allow(clippy::manual_clamp)]
+    if x_never < min {
+        x_never = min;
+    }
+    if x_never > max {
+        x_never = max;
+    }
+}
+
+/// Just to ensure this isn't const evaled
+fn cmp_min_max(input: i32) -> i32 {
+    input * 3
+}
diff --git a/tests/ui/manual_clamp.stderr b/tests/ui/manual_clamp.stderr
new file mode 100644
index 00000000000..25650483595
--- /dev/null
+++ b/tests/ui/manual_clamp.stderr
@@ -0,0 +1,375 @@
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:76:5
+   |
+LL | /     if x9 < min {
+LL | |         x9 = min;
+LL | |     }
+LL | |     if x9 > max {
+LL | |         x9 = max;
+LL | |     }
+   | |_____^ help: replace with clamp: `x9 = x9.clamp(min, max);`
+   |
+   = note: `-D clippy::manual-clamp` implied by `-D warnings`
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:91:5
+   |
+LL | /     if x11 > max {
+LL | |         x11 = max;
+LL | |     }
+LL | |     if x11 < min {
+LL | |         x11 = min;
+LL | |     }
+   | |_____^ help: replace with clamp: `x11 = x11.clamp(min, max);`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:99:5
+   |
+LL | /     if min > x12 {
+LL | |         x12 = min;
+LL | |     }
+LL | |     if max < x12 {
+LL | |         x12 = max;
+LL | |     }
+   | |_____^ help: replace with clamp: `x12 = x12.clamp(min, max);`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:107:5
+   |
+LL | /     if max < x13 {
+LL | |         x13 = max;
+LL | |     }
+LL | |     if min > x13 {
+LL | |         x13 = min;
+LL | |     }
+   | |_____^ help: replace with clamp: `x13 = x13.clamp(min, max);`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:161:5
+   |
+LL | /     if max < x33 {
+LL | |         x33 = max;
+LL | |     }
+LL | |     if min > x33 {
+LL | |         x33 = min;
+LL | |     }
+   | |_____^ help: replace with clamp: `x33 = x33.clamp(min, max);`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:21:14
+   |
+LL |       let x0 = if max < input {
+   |  ______________^
+LL | |         max
+LL | |     } else if min > input {
+LL | |         min
+LL | |     } else {
+LL | |         input
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:29:14
+   |
+LL |       let x1 = if input > max {
+   |  ______________^
+LL | |         max
+LL | |     } else if input < min {
+LL | |         min
+LL | |     } else {
+LL | |         input
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:37:14
+   |
+LL |       let x2 = if input < min {
+   |  ______________^
+LL | |         min
+LL | |     } else if input > max {
+LL | |         max
+LL | |     } else {
+LL | |         input
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:45:14
+   |
+LL |       let x3 = if min > input {
+   |  ______________^
+LL | |         min
+LL | |     } else if max < input {
+LL | |         max
+LL | |     } else {
+LL | |         input
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:53:14
+   |
+LL |     let x4 = input.max(min).min(max);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:55:14
+   |
+LL |     let x5 = input.min(max).max(min);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:57:14
+   |
+LL |       let x6 = match input {
+   |  ______________^
+LL | |         x if x > max => max,
+LL | |         x if x < min => min,
+LL | |         x => x,
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:63:14
+   |
+LL |       let x7 = match input {
+   |  ______________^
+LL | |         x if x < min => min,
+LL | |         x if x > max => max,
+LL | |         x => x,
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:69:14
+   |
+LL |       let x8 = match input {
+   |  ______________^
+LL | |         x if max < x => max,
+LL | |         x if min > x => min,
+LL | |         x => x,
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:83:15
+   |
+LL |       let x10 = match input {
+   |  _______________^
+LL | |         x if min > x => min,
+LL | |         x if max < x => max,
+LL | |         x => x,
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:114:15
+   |
+LL |       let x14 = if input > CONST_MAX {
+   |  _______________^
+LL | |         CONST_MAX
+LL | |     } else if input < CONST_MIN {
+LL | |         CONST_MIN
+LL | |     } else {
+LL | |         input
+LL | |     };
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:123:19
+   |
+LL |           let x15 = if input > max {
+   |  ___________________^
+LL | |             max
+LL | |         } else if input < min {
+LL | |             min
+LL | |         } else {
+LL | |             input
+LL | |         };
+   | |_________^ help: replace with clamp: `input.clamp(min, max)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:134:19
+   |
+LL |         let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:135:19
+   |
+LL |         let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:136:19
+   |
+LL |         let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:137:19
+   |
+LL |         let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:138:19
+   |
+LL |         let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:139:19
+   |
+LL |         let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:140:19
+   |
+LL |         let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:141:19
+   |
+LL |         let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
+   |
+   = note: clamp will panic if max < min
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:143:19
+   |
+LL |         let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:144:19
+   |
+LL |         let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:145:19
+   |
+LL |         let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:146:19
+   |
+LL |         let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:147:19
+   |
+LL |         let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:148:19
+   |
+LL |         let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:149:19
+   |
+LL |         let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:150:19
+   |
+LL |         let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
+   |
+   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+   = note: clamp returns NaN if the input is NaN
+
+error: clamp-like pattern without using clamp function
+  --> $DIR/manual_clamp.rs:153:5
+   |
+LL | /     if x32 < min {
+LL | |         x32 = min;
+LL | |     } else if x32 > max {
+LL | |         x32 = max;
+LL | |     }
+   | |_____^ help: replace with clamp: `x32 = x32.clamp(min, max);`
+   |
+   = note: clamp will panic if max < min
+
+error: aborting due to 34 previous errors
+
diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs
index b2bc97f4744..24e52afd691 100644
--- a/tests/ui/min_max.rs
+++ b/tests/ui/min_max.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::all)]
+#![allow(clippy::manual_clamp)]
 
 use std::cmp::max as my_max;
 use std::cmp::min as my_min;
diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr
index c70b77eabbd..069d9068657 100644
--- a/tests/ui/min_max.stderr
+++ b/tests/ui/min_max.stderr
@@ -1,5 +1,5 @@
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:23:5
+  --> $DIR/min_max.rs:24:5
    |
 LL |     min(1, max(3, x));
    |     ^^^^^^^^^^^^^^^^^
@@ -7,73 +7,73 @@ LL |     min(1, max(3, x));
    = note: `-D clippy::min-max` implied by `-D warnings`
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:24:5
+  --> $DIR/min_max.rs:25:5
    |
 LL |     min(max(3, x), 1);
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:25:5
+  --> $DIR/min_max.rs:26:5
    |
 LL |     max(min(x, 1), 3);
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:26:5
+  --> $DIR/min_max.rs:27:5
    |
 LL |     max(3, min(x, 1));
    |     ^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:28:5
+  --> $DIR/min_max.rs:29:5
    |
 LL |     my_max(3, my_min(x, 1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:38:5
+  --> $DIR/min_max.rs:39:5
    |
 LL |     min("Apple", max("Zoo", s));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:39:5
+  --> $DIR/min_max.rs:40:5
    |
 LL |     max(min(s, "Apple"), "Zoo");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:44:5
+  --> $DIR/min_max.rs:45:5
    |
 LL |     x.min(1).max(3);
    |     ^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:45:5
+  --> $DIR/min_max.rs:46:5
    |
 LL |     x.max(3).min(1);
    |     ^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:46:5
+  --> $DIR/min_max.rs:47:5
    |
 LL |     f.max(3f32).min(1f32);
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:52:5
+  --> $DIR/min_max.rs:53:5
    |
 LL |     max(x.min(1), 3);
    |     ^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:55:5
+  --> $DIR/min_max.rs:56:5
    |
 LL |     s.max("Zoo").min("Apple");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `min`/`max` combination leads to constant result
-  --> $DIR/min_max.rs:56:5
+  --> $DIR/min_max.rs:57:5
    |
 LL |     s.min("Apple").max("Zoo");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/min_rust_version_attr.rs b/tests/ui/min_rust_version_attr.rs
index 44e407bd1ab..c4c6391bb4c 100644
--- a/tests/ui/min_rust_version_attr.rs
+++ b/tests/ui/min_rust_version_attr.rs
@@ -160,6 +160,17 @@ fn manual_rem_euclid() {
     let _: i32 = ((x % 4) + 4) % 4;
 }
 
+fn manual_clamp() {
+    let (input, min, max) = (0, -1, 2);
+    let _ = if input < min {
+        min
+    } else if input > max {
+        max
+    } else {
+        input
+    };
+}
+
 fn main() {
     filter_map_next();
     checked_conversion();
@@ -180,6 +191,7 @@ fn main() {
     err_expect();
     cast_abs_to_unsigned();
     manual_rem_euclid();
+    manual_clamp();
 }
 
 mod just_under_msrv {
diff --git a/tests/ui/min_rust_version_attr.stderr b/tests/ui/min_rust_version_attr.stderr
index b1c23b539ff..faabb0e4386 100644
--- a/tests/ui/min_rust_version_attr.stderr
+++ b/tests/ui/min_rust_version_attr.stderr
@@ -1,12 +1,12 @@
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:204:24
+  --> $DIR/min_rust_version_attr.rs:216:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:203:9
+  --> $DIR/min_rust_version_attr.rs:215:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,13 +17,13 @@ LL ~             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
    |
 
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:216:24
+  --> $DIR/min_rust_version_attr.rs:228:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:215:9
+  --> $DIR/min_rust_version_attr.rs:227:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/needless_borrowed_ref.fixed b/tests/ui/needless_borrowed_ref.fixed
index a0937a2c5f6..bcb4eb2dd48 100644
--- a/tests/ui/needless_borrowed_ref.fixed
+++ b/tests/ui/needless_borrowed_ref.fixed
@@ -1,17 +1,38 @@
 // run-rustfix
 
-#[warn(clippy::needless_borrowed_reference)]
-#[allow(unused_variables)]
-fn main() {
+#![warn(clippy::needless_borrowed_reference)]
+#![allow(unused, clippy::needless_borrow)]
+
+fn main() {}
+
+fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
     let mut v = Vec::<String>::new();
     let _ = v.iter_mut().filter(|a| a.is_empty());
-    //                            ^ should be linted
 
     let var = 3;
     let thingy = Some(&var);
-    if let Some(&ref v) = thingy {
-        //          ^ should be linted
-    }
+    if let Some(v) = thingy {}
+
+    if let &[a, ref b] = slice_of_refs {}
+
+    let [a, ..] = &array;
+    let [a, b, ..] = &array;
+
+    if let [a, b] = slice {}
+    if let [a, b] = &vec[..] {}
+
+    if let [a, b, ..] = slice {}
+    if let [a, .., b] = slice {}
+    if let [.., a, b] = slice {}
+}
+
+fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+    if let [ref a] = slice {}
+    if let &[ref a, b] = slice {}
+    if let &[ref a, .., b] = slice {}
+
+    // must not be removed as variables must be bound consistently across | patterns
+    if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
 
     let mut var2 = 5;
     let thingy2 = Some(&mut var2);
@@ -28,17 +49,15 @@ fn main() {
     }
 }
 
-#[allow(dead_code)]
 enum Animal {
     Cat(u64),
     Dog(u64),
 }
 
-#[allow(unused_variables)]
-#[allow(dead_code)]
 fn foo(a: &Animal, b: &Animal) {
     match (a, b) {
-        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
+        // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
+        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
         //                  ^    and   ^ should **not** be linted
         (&Animal::Dog(ref a), &Animal::Dog(_)) => (), //              ^ should **not** be linted
     }
diff --git a/tests/ui/needless_borrowed_ref.rs b/tests/ui/needless_borrowed_ref.rs
index 500ac448f0d..f6de1a6d83d 100644
--- a/tests/ui/needless_borrowed_ref.rs
+++ b/tests/ui/needless_borrowed_ref.rs
@@ -1,17 +1,38 @@
 // run-rustfix
 
-#[warn(clippy::needless_borrowed_reference)]
-#[allow(unused_variables)]
-fn main() {
+#![warn(clippy::needless_borrowed_reference)]
+#![allow(unused, clippy::needless_borrow)]
+
+fn main() {}
+
+fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
     let mut v = Vec::<String>::new();
     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
-    //                            ^ should be linted
 
     let var = 3;
     let thingy = Some(&var);
-    if let Some(&ref v) = thingy {
-        //          ^ should be linted
-    }
+    if let Some(&ref v) = thingy {}
+
+    if let &[&ref a, ref b] = slice_of_refs {}
+
+    let &[ref a, ..] = &array;
+    let &[ref a, ref b, ..] = &array;
+
+    if let &[ref a, ref b] = slice {}
+    if let &[ref a, ref b] = &vec[..] {}
+
+    if let &[ref a, ref b, ..] = slice {}
+    if let &[ref a, .., ref b] = slice {}
+    if let &[.., ref a, ref b] = slice {}
+}
+
+fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+    if let [ref a] = slice {}
+    if let &[ref a, b] = slice {}
+    if let &[ref a, .., b] = slice {}
+
+    // must not be removed as variables must be bound consistently across | patterns
+    if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
 
     let mut var2 = 5;
     let thingy2 = Some(&mut var2);
@@ -28,17 +49,15 @@ fn main() {
     }
 }
 
-#[allow(dead_code)]
 enum Animal {
     Cat(u64),
     Dog(u64),
 }
 
-#[allow(unused_variables)]
-#[allow(dead_code)]
 fn foo(a: &Animal, b: &Animal) {
     match (a, b) {
-        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
+        // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
+        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
         //                  ^    and   ^ should **not** be linted
         (&Animal::Dog(ref a), &Animal::Dog(_)) => (), //              ^ should **not** be linted
     }
diff --git a/tests/ui/needless_borrowed_ref.stderr b/tests/ui/needless_borrowed_ref.stderr
index 0a5cfb3db0b..7453542e673 100644
--- a/tests/ui/needless_borrowed_ref.stderr
+++ b/tests/ui/needless_borrowed_ref.stderr
@@ -1,10 +1,123 @@
-error: this pattern takes a reference on something that is being de-referenced
-  --> $DIR/needless_borrowed_ref.rs:7:34
+error: this pattern takes a reference on something that is being dereferenced
+  --> $DIR/needless_borrowed_ref.rs:10:34
    |
 LL |     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
-   |                                  ^^^^^^ help: try removing the `&ref` part and just keep: `a`
+   |                                  ^^^^^^
    |
    = note: `-D clippy::needless-borrowed-reference` implied by `-D warnings`
+help: try removing the `&ref` part
+   |
+LL -     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
+LL +     let _ = v.iter_mut().filter(|a| a.is_empty());
+   |
+
+error: this pattern takes a reference on something that is being dereferenced
+  --> $DIR/needless_borrowed_ref.rs:14:17
+   |
+LL |     if let Some(&ref v) = thingy {}
+   |                 ^^^^^^
+   |
+help: try removing the `&ref` part
+   |
+LL -     if let Some(&ref v) = thingy {}
+LL +     if let Some(v) = thingy {}
+   |
+
+error: this pattern takes a reference on something that is being dereferenced
+  --> $DIR/needless_borrowed_ref.rs:16:14
+   |
+LL |     if let &[&ref a, ref b] = slice_of_refs {}
+   |              ^^^^^^
+   |
+help: try removing the `&ref` part
+   |
+LL -     if let &[&ref a, ref b] = slice_of_refs {}
+LL +     if let &[a, ref b] = slice_of_refs {}
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:18:9
+   |
+LL |     let &[ref a, ..] = &array;
+   |         ^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     let &[ref a, ..] = &array;
+LL +     let [a, ..] = &array;
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:19:9
+   |
+LL |     let &[ref a, ref b, ..] = &array;
+   |         ^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     let &[ref a, ref b, ..] = &array;
+LL +     let [a, b, ..] = &array;
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:21:12
+   |
+LL |     if let &[ref a, ref b] = slice {}
+   |            ^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[ref a, ref b] = slice {}
+LL +     if let [a, b] = slice {}
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:22:12
+   |
+LL |     if let &[ref a, ref b] = &vec[..] {}
+   |            ^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[ref a, ref b] = &vec[..] {}
+LL +     if let [a, b] = &vec[..] {}
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:24:12
+   |
+LL |     if let &[ref a, ref b, ..] = slice {}
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[ref a, ref b, ..] = slice {}
+LL +     if let [a, b, ..] = slice {}
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:25:12
+   |
+LL |     if let &[ref a, .., ref b] = slice {}
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[ref a, .., ref b] = slice {}
+LL +     if let [a, .., b] = slice {}
+   |
+
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:26:12
+   |
+LL |     if let &[.., ref a, ref b] = slice {}
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[.., ref a, ref b] = slice {}
+LL +     if let [.., a, b] = slice {}
+   |
 
-error: aborting due to previous error
+error: aborting due to 10 previous errors
 
diff --git a/tests/ui/option_take_on_temporary.fixed b/tests/ui/option_take_on_temporary.fixed
deleted file mode 100644
index 29691e81666..00000000000
--- a/tests/ui/option_take_on_temporary.fixed
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-rustfix
-
-fn main() {
-    println!("Testing non erroneous option_take_on_temporary");
-    let mut option = Some(1);
-    let _ = Box::new(move || option.take().unwrap());
-
-    println!("Testing non erroneous option_take_on_temporary");
-    let x = Some(3);
-    x.as_ref();
-
-    println!("Testing erroneous option_take_on_temporary");
-    let x = Some(3);
-    x.as_ref();
-}
diff --git a/tests/ui/ptr_offset_with_cast.fixed b/tests/ui/ptr_offset_with_cast.fixed
index 718e391e8bf..c57e2990fb9 100644
--- a/tests/ui/ptr_offset_with_cast.fixed
+++ b/tests/ui/ptr_offset_with_cast.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let vec = vec![b'a', b'b', b'c'];
diff --git a/tests/ui/ptr_offset_with_cast.rs b/tests/ui/ptr_offset_with_cast.rs
index f613742c741..3de7997acdd 100644
--- a/tests/ui/ptr_offset_with_cast.rs
+++ b/tests/ui/ptr_offset_with_cast.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(clippy::unnecessary_cast)]
 
 fn main() {
     let vec = vec![b'a', b'b', b'c'];
diff --git a/tests/ui/ptr_offset_with_cast.stderr b/tests/ui/ptr_offset_with_cast.stderr
index fd45224ca06..3ba40593d64 100644
--- a/tests/ui/ptr_offset_with_cast.stderr
+++ b/tests/ui/ptr_offset_with_cast.stderr
@@ -1,5 +1,5 @@
 error: use of `offset` with a `usize` casted to an `isize`
-  --> $DIR/ptr_offset_with_cast.rs:12:17
+  --> $DIR/ptr_offset_with_cast.rs:13:17
    |
 LL |         let _ = ptr.offset(offset_usize as isize);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr.add(offset_usize)`
@@ -7,7 +7,7 @@ LL |         let _ = ptr.offset(offset_usize as isize);
    = note: `-D clippy::ptr-offset-with-cast` implied by `-D warnings`
 
 error: use of `wrapping_offset` with a `usize` casted to an `isize`
-  --> $DIR/ptr_offset_with_cast.rs:16:17
+  --> $DIR/ptr_offset_with_cast.rs:17:17
    |
 LL |         let _ = ptr.wrapping_offset(offset_usize as isize);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr.wrapping_add(offset_usize)`
diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed
index ee9f157342d..94dc9642726 100644
--- a/tests/ui/unnecessary_cast.fixed
+++ b/tests/ui/unnecessary_cast.fixed
@@ -97,4 +97,18 @@ mod fixable {
 
         let _ = -(1 + 1) as i64;
     }
+
+    fn issue_9563() {
+        let _: f64 = (-8.0_f64).exp();
+        #[allow(clippy::precedence)]
+        let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+    }
+
+    fn issue_9562_non_literal() {
+        fn foo() -> f32 {
+            0.
+        }
+
+        let _num = foo();
+    }
 }
diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs
index 5b70412424c..e5150256f69 100644
--- a/tests/ui/unnecessary_cast.rs
+++ b/tests/ui/unnecessary_cast.rs
@@ -97,4 +97,18 @@ mod fixable {
 
         let _ = -(1 + 1) as i64;
     }
+
+    fn issue_9563() {
+        let _: f64 = (-8.0 as f64).exp();
+        #[allow(clippy::precedence)]
+        let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+    }
+
+    fn issue_9562_non_literal() {
+        fn foo() -> f32 {
+            0.
+        }
+
+        let _num = foo() as f32;
+    }
 }
diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr
index f7829ff3b0e..e5c3dd5e53f 100644
--- a/tests/ui/unnecessary_cast.stderr
+++ b/tests/ui/unnecessary_cast.stderr
@@ -162,5 +162,23 @@ error: casting integer literal to `i64` is unnecessary
 LL |         let _: i64 = -(1) as i64;
    |                      ^^^^^^^^^^^ help: try: `-1_i64`
 
-error: aborting due to 27 previous errors
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:102:22
+   |
+LL |         let _: f64 = (-8.0 as f64).exp();
+   |                      ^^^^^^^^^^^^^ help: try: `(-8.0_f64)`
+
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:104:23
+   |
+LL |         let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+   |                       ^^^^^^^^^^^^ help: try: `8.0_f64`
+
+error: casting to the same type is unnecessary (`f32` -> `f32`)
+  --> $DIR/unnecessary_cast.rs:112:20
+   |
+LL |         let _num = foo() as f32;
+   |                    ^^^^^^^^^^^^ help: try: `foo()`
+
+error: aborting due to 30 previous errors
 
diff --git a/tests/ui/upper_case_acronyms.rs b/tests/ui/upper_case_acronyms.rs
index 48bb9e54b12..9b7c2f28e1c 100644
--- a/tests/ui/upper_case_acronyms.rs
+++ b/tests/ui/upper_case_acronyms.rs
@@ -38,4 +38,13 @@ enum ParseErrorPrivate<T> {
     Parse(T, String),
 }
 
+// do lint here
+struct JSON;
+
+// do lint here
+enum YAML {
+    Num(u32),
+    Str(String),
+}
+
 fn main() {}
diff --git a/tests/ui/upper_case_acronyms.stderr b/tests/ui/upper_case_acronyms.stderr
index 250b196a99e..74082ec16dd 100644
--- a/tests/ui/upper_case_acronyms.stderr
+++ b/tests/ui/upper_case_acronyms.stderr
@@ -54,5 +54,17 @@ error: name `WASD` contains a capitalized acronym
 LL |     WASD(u8),
    |     ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd`
 
-error: aborting due to 9 previous errors
+error: name `JSON` contains a capitalized acronym
+  --> $DIR/upper_case_acronyms.rs:42:8
+   |
+LL | struct JSON;
+   |        ^^^^ help: consider making the acronym lowercase, except the initial letter: `Json`
+
+error: name `YAML` contains a capitalized acronym
+  --> $DIR/upper_case_acronyms.rs:45:6
+   |
+LL | enum YAML {
+   |      ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml`
+
+error: aborting due to 11 previous errors