about summary refs log tree commit diff
path: root/src/tools/clippy/tests
diff options
context:
space:
mode:
authorflip1995 <hello@philkrones.com>2020-09-24 14:49:22 +0200
committerflip1995 <hello@philkrones.com>2020-09-24 14:49:22 +0200
commitf1f1e0ba8ea1895eb2568e9d19378bbe43a17bcb (patch)
tree07605b9855fd4fe6e1904fb0f15c4bd9cc828369 /src/tools/clippy/tests
parent86b4172305bb28612510db9ad3ebf2a4bb86f70f (diff)
parente636b88aa180e8cab9e28802aac90adbc984234d (diff)
downloadrust-f1f1e0ba8ea1895eb2568e9d19378bbe43a17bcb.tar.gz
rust-f1f1e0ba8ea1895eb2568e9d19378bbe43a17bcb.zip
Merge commit 'e636b88aa180e8cab9e28802aac90adbc984234d' into clippyup
Diffstat (limited to 'src/tools/clippy/tests')
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_exchange.rs45
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_exchange.stderr131
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.rs47
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.stderr131
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_fetch_update.rs45
-rw-r--r--src/tools/clippy/tests/ui/atomic_ordering_fetch_update.stderr131
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs20
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr44
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2636.rs22
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2636.stderr17
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const.rs161
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const.stderr84
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.rs1
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.stderr36
-rw-r--r--src/tools/clippy/tests/ui/float_cmp.stderr22
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.stderr30
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs3
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr20
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.stderr26
-rw-r--r--src/tools/clippy/tests/ui/into_iter_on_ref.stderr54
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.rs1
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.stderr8
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.rs66
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.stderr132
-rw-r--r--src/tools/clippy/tests/ui/map_err.rs25
-rw-r--r--src/tools/clippy/tests/ui/map_err.stderr11
-rw-r--r--src/tools/clippy/tests/ui/match_type_on_diag_item.rs50
-rw-r--r--src/tools/clippy/tests/ui/match_type_on_diag_item.stderr33
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed10
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs15
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr36
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.rs70
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.stderr105
-rw-r--r--src/tools/clippy/tests/ui/print_with_newline.rs1
-rw-r--r--src/tools/clippy/tests/ui/print_with_newline.stderr23
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer.rs26
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer.stderr52
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_arc.rs25
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_arc.stderr52
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_redefined_string.rs12
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_redefined_string.stderr0
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching.fixed83
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching.rs98
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching.stderr174
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed85
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs100
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr134
-rw-r--r--src/tools/clippy/tests/ui/trailing_zeros.rs1
-rw-r--r--src/tools/clippy/tests/ui/trailing_zeros.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed43
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs25
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr112
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr22
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.stderr18
-rw-r--r--src/tools/clippy/tests/ui/write_with_newline.rs1
-rw-r--r--src/tools/clippy/tests/ui/write_with_newline.stderr23
56 files changed, 2089 insertions, 657 deletions
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_exchange.rs b/src/tools/clippy/tests/ui/atomic_ordering_exchange.rs
new file mode 100644
index 00000000000..1ddc12f9ab2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_exchange.rs
@@ -0,0 +1,45 @@
+#![warn(clippy::invalid_atomic_ordering)]
+
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+fn main() {
+    // `compare_exchange` (not weak) testing
+    let x = AtomicUsize::new(0);
+
+    // Allowed ordering combos
+    let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Relaxed);
+    let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Acquire);
+    let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Relaxed);
+    let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Relaxed);
+    let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Acquire);
+    let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Relaxed);
+    let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Relaxed);
+    let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Acquire);
+    let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::SeqCst);
+
+    // AcqRel is always forbidden as a failure ordering
+    let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
+    let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::AcqRel);
+    let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::AcqRel);
+    let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::AcqRel);
+    let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::AcqRel);
+
+    // Release is always forbidden as a failure ordering
+    let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Release);
+    let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
+    let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Release);
+    let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
+    let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Release);
+
+    // Release success order forbids failure order of Acquire or SeqCst
+    let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Acquire);
+    let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::SeqCst);
+
+    // Relaxed success order also forbids failure order of Acquire or SeqCst
+    let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::SeqCst);
+    let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Acquire);
+
+    // Acquire/AcqRel forbids failure order of SeqCst
+    let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::SeqCst);
+    let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::SeqCst);
+}
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_exchange.stderr b/src/tools/clippy/tests/ui/atomic_ordering_exchange.stderr
new file mode 100644
index 00000000000..4b9bfef7974
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_exchange.stderr
@@ -0,0 +1,131 @@
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:21:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::invalid-atomic-ordering` implied by `-D warnings`
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:22:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::AcqRel);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:23:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::AcqRel);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:24:56
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::AcqRel);
+   |                                                        ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:25:56
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::AcqRel);
+   |                                                        ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:28:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Release);
+   |                                                         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:29:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
+   |                                                         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:30:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Release);
+   |                                                         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:31:56
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
+   |                                                        ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:32:56
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Release);
+   |                                                        ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_exchange.rs:35:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Acquire);
+   |                                                         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_exchange.rs:36:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::SeqCst);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_exchange.rs:39:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::SeqCst);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_exchange.rs:40:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Acquire);
+   |                                                         ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `Acquire`
+  --> $DIR/atomic_ordering_exchange.rs:43:57
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::SeqCst);
+   |                                                         ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange's failure ordering may not be stronger than the success ordering of `AcqRel`
+  --> $DIR/atomic_ordering_exchange.rs:44:56
+   |
+LL |     let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::SeqCst);
+   |                                                        ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.rs b/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.rs
new file mode 100644
index 00000000000..59069902507
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.rs
@@ -0,0 +1,47 @@
+#![warn(clippy::invalid_atomic_ordering)]
+
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+fn main() {
+    let ptr = &mut 5;
+    let ptr2 = &mut 10;
+    // `compare_exchange_weak` testing
+    let x = AtomicPtr::new(ptr);
+
+    // Allowed ordering combos
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Relaxed);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Acquire);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Relaxed);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Relaxed);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Acquire);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Relaxed);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Relaxed);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Acquire);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::SeqCst);
+
+    // AcqRel is always forbidden as a failure ordering
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::AcqRel);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::AcqRel);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::AcqRel);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::SeqCst, Ordering::AcqRel);
+
+    // Release is always forbidden as a failure ordering
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Release);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Release);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Release);
+
+    // Release success order forbids failure order of Acquire or SeqCst
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::Acquire);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::SeqCst);
+
+    // Relaxed success order also forbids failure order of Acquire or SeqCst
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::SeqCst);
+    let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Acquire);
+
+    // Acquire/AcqRel forbids failure order of SeqCst
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::SeqCst);
+    let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::SeqCst);
+}
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.stderr b/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.stderr
new file mode 100644
index 00000000000..de7026f3ffa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_exchange_weak.stderr
@@ -0,0 +1,131 @@
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:23:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::invalid-atomic-ordering` implied by `-D warnings`
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:24:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::AcqRel);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:25:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::AcqRel);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:26:66
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::AcqRel);
+   |                                                                  ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:27:66
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::SeqCst, Ordering::AcqRel);
+   |                                                                  ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:30:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Release);
+   |                                                                   ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:31:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
+   |                                                                   ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:32:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Release);
+   |                                                                   ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:33:66
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
+   |                                                                  ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:34:66
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Release);
+   |                                                                  ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_exchange_weak.rs:37:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::Acquire);
+   |                                                                   ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_exchange_weak.rs:38:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::SeqCst);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_exchange_weak.rs:41:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::SeqCst);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_exchange_weak.rs:42:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Acquire);
+   |                                                                   ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Acquire`
+  --> $DIR/atomic_ordering_exchange_weak.rs:45:67
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::SeqCst);
+   |                                                                   ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `AcqRel`
+  --> $DIR/atomic_ordering_exchange_weak.rs:46:66
+   |
+LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::SeqCst);
+   |                                                                  ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.rs b/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.rs
new file mode 100644
index 00000000000..550bdb001e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.rs
@@ -0,0 +1,45 @@
+#![warn(clippy::invalid_atomic_ordering)]
+
+use std::sync::atomic::{AtomicIsize, Ordering};
+
+fn main() {
+    // `fetch_update` testing
+    let x = AtomicIsize::new(0);
+
+    // Allowed ordering combos
+    let _ = x.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1));
+
+    // AcqRel is always forbidden as a failure ordering
+    let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
+
+    // Release is always forbidden as a failure ordering
+    let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
+
+    // Release success order forbids failure order of Acquire or SeqCst
+    let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
+
+    // Relaxed success order also forbids failure order of Acquire or SeqCst
+    let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
+
+    // Acquire/AcqRel forbids failure order of SeqCst
+    let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
+    let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
+}
diff --git a/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.stderr b/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.stderr
new file mode 100644
index 00000000000..694548ece97
--- /dev/null
+++ b/src/tools/clippy/tests/ui/atomic_ordering_fetch_update.stderr
@@ -0,0 +1,131 @@
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:21:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::invalid-atomic-ordering` implied by `-D warnings`
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:22:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:23:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:24:46
+   |
+LL |     let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
+   |                                              ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:25:46
+   |
+LL |     let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
+   |                                              ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:28:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:29:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:30:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:31:46
+   |
+LL |     let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
+   |                                              ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:32:46
+   |
+LL |     let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
+   |                                              ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_fetch_update.rs:35:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `Release`
+  --> $DIR/atomic_ordering_fetch_update.rs:36:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_fetch_update.rs:39:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `Relaxed`
+  --> $DIR/atomic_ordering_fetch_update.rs:40:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering mode `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `Acquire`
+  --> $DIR/atomic_ordering_fetch_update.rs:43:47
+   |
+LL |     let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
+   |                                               ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: fetch_update's failure ordering may not be stronger than the success ordering of `AcqRel`
+  --> $DIR/atomic_ordering_fetch_update.rs:44:46
+   |
+LL |     let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
+   |                                              ^^^^^^^^^^^^^^^^
+   |
+   = help: consider using ordering modes `Acquire` or `Relaxed` instead
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
index 39f87510548..9fcc9ece49b 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
@@ -19,16 +19,30 @@ const NO_ANN: &dyn Display = &70;
 static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
 const ONCE_INIT: Once = Once::new();
 
-trait Trait<T>: Copy {
-    type NonCopyType;
+trait Trait<T> {
+    type AssocType;
 
     const ATOMIC: AtomicUsize;
+    const INPUT: T;
+    const ASSOC: Self::AssocType;
+
+    fn function() {
+        let _ = &Self::INPUT;
+        let _ = &Self::ASSOC;
+    }
 }
 
 impl Trait<u32> for u64 {
-    type NonCopyType = u16;
+    type AssocType = AtomicUsize;
 
     const ATOMIC: AtomicUsize = AtomicUsize::new(9);
+    const INPUT: u32 = 10;
+    const ASSOC: Self::AssocType = AtomicUsize::new(11);
+
+    fn function() {
+        let _ = &Self::INPUT;
+        let _ = &Self::ASSOC; //~ ERROR interior mutability
+    }
 }
 
 // This is just a pointer that can be safely dereferended,
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
index 5800af7e960..ed726a6b46e 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
@@ -1,14 +1,22 @@
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:66:5
+  --> $DIR/borrow_interior_mutable_const.rs:44:18
+   |
+LL |         let _ = &Self::ASSOC; //~ ERROR interior mutability
+   |                  ^^^^^^^^^^^
+   |
+   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
+   = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
+  --> $DIR/borrow_interior_mutable_const.rs:80:5
    |
 LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^
    |
-   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:67:16
+  --> $DIR/borrow_interior_mutable_const.rs:81:16
    |
 LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
    |                ^^^^^^
@@ -16,7 +24,7 @@ LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutabi
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:70:22
+  --> $DIR/borrow_interior_mutable_const.rs:84:22
    |
 LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    |                      ^^^^^^^^^
@@ -24,7 +32,7 @@ LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:71:25
+  --> $DIR/borrow_interior_mutable_const.rs:85:25
    |
 LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    |                         ^^^^^^^^^
@@ -32,7 +40,7 @@ LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:72:27
+  --> $DIR/borrow_interior_mutable_const.rs:86:27
    |
 LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    |                           ^^^^^^^^^
@@ -40,7 +48,7 @@ LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:73:26
+  --> $DIR/borrow_interior_mutable_const.rs:87:26
    |
 LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    |                          ^^^^^^^^^
@@ -48,7 +56,7 @@ LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:84:14
+  --> $DIR/borrow_interior_mutable_const.rs:98:14
    |
 LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -56,7 +64,7 @@ LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:85:14
+  --> $DIR/borrow_interior_mutable_const.rs:99:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -64,7 +72,7 @@ LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:86:19
+  --> $DIR/borrow_interior_mutable_const.rs:100:19
    |
 LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    |                   ^^^^^^^^^^^^
@@ -72,7 +80,7 @@ LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:87:14
+  --> $DIR/borrow_interior_mutable_const.rs:101:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -80,7 +88,7 @@ LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:88:13
+  --> $DIR/borrow_interior_mutable_const.rs:102:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -88,7 +96,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mu
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:94:13
+  --> $DIR/borrow_interior_mutable_const.rs:108:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -96,7 +104,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:99:5
+  --> $DIR/borrow_interior_mutable_const.rs:113:5
    |
 LL |     CELL.set(2); //~ ERROR interior mutability
    |     ^^^^
@@ -104,7 +112,7 @@ LL |     CELL.set(2); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:100:16
+  --> $DIR/borrow_interior_mutable_const.rs:114:16
    |
 LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    |                ^^^^
@@ -112,7 +120,7 @@ LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:113:5
+  --> $DIR/borrow_interior_mutable_const.rs:127:5
    |
 LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^^^^^^
@@ -120,12 +128,12 @@ LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:114:16
+  --> $DIR/borrow_interior_mutable_const.rs:128:16
    |
 LL |     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
    |                ^^^^^^^^^^^
    |
    = help: assign this const to a local or static variable, and use the variable here
 
-error: aborting due to 16 previous errors
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2636.rs b/src/tools/clippy/tests/ui/crashes/ice-2636.rs
deleted file mode 100644
index e0b58157590..00000000000
--- a/src/tools/clippy/tests/ui/crashes/ice-2636.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-#![allow(dead_code)]
-
-enum Foo {
-    A,
-    B,
-    C,
-}
-
-macro_rules! test_hash {
-    ($foo:expr, $($t:ident => $ord:expr),+ ) => {
-        use self::Foo::*;
-        match $foo {
-            $ ( & $t => $ord,
-            )*
-        };
-    };
-}
-
-fn main() {
-    let a = Foo::A;
-    test_hash!(&a, A => 0, B => 1, C => 2);
-}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2636.stderr b/src/tools/clippy/tests/ui/crashes/ice-2636.stderr
deleted file mode 100644
index 53799b4fbf1..00000000000
--- a/src/tools/clippy/tests/ui/crashes/ice-2636.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: you don't need to add `&` to both the expression and the patterns
-  --> $DIR/ice-2636.rs:12:9
-   |
-LL | /         match $foo {
-LL | |             $ ( & $t => $ord,
-LL | |             )*
-LL | |         };
-   | |_________^
-...
-LL |       test_hash!(&a, A => 0, B => 1, C => 2);
-   |       --------------------------------------- in this macro invocation
-   |
-   = note: `-D clippy::match-ref-pats` implied by `-D warnings`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const.rs
index b4003ed8932..3afcdca2f04 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const.rs
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const.rs
@@ -34,60 +34,141 @@ static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
 #[allow(clippy::declare_interior_mutable_const)]
 const ONCE_INIT: Once = Once::new();
 
-trait Trait<T>: Copy {
-    type NonCopyType;
-
+// a constant whose type is a concrete type should be linted at the definition site.
+trait ConcreteTypes {
     const ATOMIC: AtomicUsize; //~ ERROR interior mutable
     const INTEGER: u64;
     const STRING: String;
-    const SELF: Self; // (no error)
-    const INPUT: T;
-    //~^ ERROR interior mutable
-    //~| HELP consider requiring `T` to be `Copy`
-    const ASSOC: Self::NonCopyType;
-    //~^ ERROR interior mutable
-    //~| HELP consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
+    declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
+}
 
-    const AN_INPUT: T = Self::INPUT;
-    //~^ ERROR interior mutable
-    //~| ERROR consider requiring `T` to be `Copy`
-    declare_const!(ANOTHER_INPUT: T = Self::INPUT); //~ ERROR interior mutable
+impl ConcreteTypes for u64 {
+    const ATOMIC: AtomicUsize = AtomicUsize::new(9);
+    const INTEGER: u64 = 10;
+    const STRING: String = String::new();
 }
 
-trait Trait2 {
-    type CopyType: Copy;
+// a helper trait used below
+trait ConstDefault {
+    const DEFAULT: Self;
+}
+
+// a constant whose type is a generic type should be linted at the implementation site.
+trait GenericTypes<T, U> {
+    const TO_REMAIN_GENERIC: T;
+    const TO_BE_CONCRETE: U;
 
-    const SELF_2: Self;
-    //~^ ERROR interior mutable
-    //~| HELP consider requiring `Self` to be `Copy`
-    const ASSOC_2: Self::CopyType; // (no error)
+    const HAVING_DEFAULT: T = Self::TO_REMAIN_GENERIC;
+    declare_const!(IN_MACRO: T = Self::TO_REMAIN_GENERIC);
 }
 
-// we don't lint impl of traits, because an impl has no power to change the interface.
-impl Trait<u32> for u64 {
-    type NonCopyType = u16;
+impl<T: ConstDefault> GenericTypes<T, AtomicUsize> for u64 {
+    const TO_REMAIN_GENERIC: T = T::DEFAULT;
+    const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
+}
 
-    const ATOMIC: AtomicUsize = AtomicUsize::new(9);
-    const INTEGER: u64 = 10;
-    const STRING: String = String::new();
-    const SELF: Self = 11;
-    const INPUT: u32 = 12;
-    const ASSOC: Self::NonCopyType = 13;
+// a helper type used below
+struct Wrapper<T>(T);
+
+// a constant whose type is an associated type should be linted at the implementation site, too.
+trait AssocTypes {
+    type ToBeFrozen;
+    type ToBeUnfrozen;
+    type ToBeGenericParam;
+
+    const TO_BE_FROZEN: Self::ToBeFrozen;
+    const TO_BE_UNFROZEN: Self::ToBeUnfrozen;
+    const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen>;
+    // to ensure it can handle things when a generic type remains after normalization.
+    const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam>;
 }
 
-struct Local<T, U>(T, U);
+impl<T: ConstDefault> AssocTypes for Vec<T> {
+    type ToBeFrozen = u16;
+    type ToBeUnfrozen = AtomicUsize;
+    type ToBeGenericParam = T;
+
+    const TO_BE_FROZEN: Self::ToBeFrozen = 12;
+    const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
+    const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
+    const WRAPPED_TO_BE_GENERIC_PARAM: Wrapper<Self::ToBeGenericParam> = Wrapper(T::DEFAULT);
+}
+
+// a helper trait used below
+trait AssocTypesHelper {
+    type NotToBeBounded;
+    type ToBeBounded;
+
+    const NOT_TO_BE_BOUNDED: Self::NotToBeBounded;
+}
 
-impl<T: Trait2 + Trait<u32>, U: Trait2> Local<T, U> {
-    const ASSOC_3: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
+// a constant whose type is an assoc type originated from a generic param bounded at the definition
+// site should be linted at there.
+trait AssocTypesFromGenericParam<T>
+where
+    T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+    const NOT_BOUNDED: T::NotToBeBounded;
+    const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
+}
+
+impl<T> AssocTypesFromGenericParam<T> for u64
+where
+    T: AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+    // an associated type could remain unknown in a trait impl.
+    const NOT_BOUNDED: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+    const BOUNDED: T::ToBeBounded = AtomicUsize::new(15);
+}
+
+// a constant whose type is `Self` should be linted at the implementation site as well.
+// (`Option` requires `Sized` bound.)
+trait SelfType: Sized {
+    const SELF: Self;
+    // this was the one in the original issue (#5050).
+    const WRAPPED_SELF: Option<Self>;
+}
+
+impl SelfType for u64 {
+    const SELF: Self = 16;
+    const WRAPPED_SELF: Option<Self> = Some(20);
+}
+
+impl SelfType for AtomicUsize {
+    // this (interior mutable `Self` const) exists in `parking_lot`.
+    // `const_trait_impl` will replace it in the future, hopefully.
+    const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
+    const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
+}
+
+// Even though a constant contains a generic type, if it also have a interior mutable type,
+// it should be linted at the definition site.
+trait BothOfCellAndGeneric<T> {
+    // this is a false negative in the current implementation.
+    const DIRECT: Cell<T>;
+    const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
+}
+
+impl<T: ConstDefault> BothOfCellAndGeneric<T> for u64 {
+    const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
+    const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
+}
+
+struct Local<T>(T);
+
+// a constant in an inherent impl are essentially the same as a normal const item
+// except there can be a generic or associated type.
+impl<T> Local<T>
+where
+    T: ConstDefault + AssocTypesHelper<ToBeBounded = AtomicUsize>,
+{
+    const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
     const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy");
-    const T_SELF: T = T::SELF_2;
-    const U_SELF: U = U::SELF_2;
-    //~^ ERROR interior mutable
-    //~| HELP consider requiring `U` to be `Copy`
-    const T_ASSOC: T::NonCopyType = T::ASSOC;
-    //~^ ERROR interior mutable
-    //~| HELP consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
-    const U_ASSOC: U::CopyType = U::ASSOC_2;
+
+    const GENERIC_TYPE: T = T::DEFAULT;
+
+    const ASSOC_TYPE: T::NotToBeBounded = T::NOT_TO_BE_BOUNDED;
+    const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const.stderr
index 6a9a57361f9..5cb10be88d8 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const.stderr
@@ -36,75 +36,75 @@ LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:40:5
+  --> $DIR/declare_interior_mutable_const.rs:39:5
    |
 LL |     const ATOMIC: AtomicUsize; //~ ERROR interior mutable
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:44:5
+  --> $DIR/declare_interior_mutable_const.rs:16:9
+   |
+LL |         const $name: $ty = $e;
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
+   |     ----------------------------------------------------------- in this macro invocation
    |
-LL |     const INPUT: T;
-   |     ^^^^^^^^^^^^^-^
-   |                  |
-   |                  consider requiring `T` to be `Copy`
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:47:5
+  --> $DIR/declare_interior_mutable_const.rs:67:5
    |
-LL |     const ASSOC: Self::NonCopyType;
-   |     ^^^^^^^^^^^^^-----------------^
-   |                  |
-   |                  consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
+LL |     const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:51:5
+  --> $DIR/declare_interior_mutable_const.rs:92:5
    |
-LL |     const AN_INPUT: T = Self::INPUT;
-   |     ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^
-   |                     |
-   |                     consider requiring `T` to be `Copy`
+LL |     const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:16:9
+  --> $DIR/declare_interior_mutable_const.rs:93:5
    |
-LL |         const $name: $ty = $e;
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-...
-LL |     declare_const!(ANOTHER_INPUT: T = Self::INPUT); //~ ERROR interior mutable
-   |     ----------------------------------------------- in this macro invocation
+LL |     const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14)); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+  --> $DIR/declare_interior_mutable_const.rs:112:5
    |
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL |     const BOUNDED: T::ToBeBounded; //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+  --> $DIR/declare_interior_mutable_const.rs:140:5
+   |
+LL |     const SELF: Self = AtomicUsize::new(17); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:60:5
+  --> $DIR/declare_interior_mutable_const.rs:141:5
    |
-LL |     const SELF_2: Self;
-   |     ^^^^^^^^^^^^^^----^
-   |                   |
-   |                   consider requiring `Self` to be `Copy`
+LL |     const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21)); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:81:5
+  --> $DIR/declare_interior_mutable_const.rs:149:5
    |
-LL |     const ASSOC_3: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const INDIRECT: Cell<*const T>; //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:84:5
+  --> $DIR/declare_interior_mutable_const.rs:165:5
    |
-LL |     const U_SELF: U = U::SELF_2;
-   |     ^^^^^^^^^^^^^^-^^^^^^^^^^^^^
-   |                   |
-   |                   consider requiring `U` to be `Copy`
+LL |     const ATOMIC: AtomicUsize = AtomicUsize::new(18); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> $DIR/declare_interior_mutable_const.rs:87:5
+  --> $DIR/declare_interior_mutable_const.rs:171:5
    |
-LL |     const T_ASSOC: T::NonCopyType = T::ASSOC;
-   |     ^^^^^^^^^^^^^^^--------------^^^^^^^^^^^^
-   |                    |
-   |                    consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
+LL |     const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 13 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/src/tools/clippy/tests/ui/drop_ref.rs
index 9181d789d4f..6b5bcdaa78e 100644
--- a/src/tools/clippy/tests/ui/drop_ref.rs
+++ b/src/tools/clippy/tests/ui/drop_ref.rs
@@ -1,5 +1,6 @@
 #![warn(clippy::drop_ref)]
 #![allow(clippy::toplevel_ref_arg)]
+#![allow(clippy::map_err_ignore)]
 
 use std::mem::drop;
 
diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr
index 35ae88b78a4..7974bf56d44 100644
--- a/src/tools/clippy/tests/ui/drop_ref.stderr
+++ b/src/tools/clippy/tests/ui/drop_ref.stderr
@@ -1,108 +1,108 @@
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:9:5
+  --> $DIR/drop_ref.rs:10:5
    |
 LL |     drop(&SomeStruct);
    |     ^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::drop-ref` implied by `-D warnings`
 note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:9:10
+  --> $DIR/drop_ref.rs:10:10
    |
 LL |     drop(&SomeStruct);
    |          ^^^^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:12:5
+  --> $DIR/drop_ref.rs:13:5
    |
 LL |     drop(&owned1);
    |     ^^^^^^^^^^^^^
    |
 note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:12:10
+  --> $DIR/drop_ref.rs:13:10
    |
 LL |     drop(&owned1);
    |          ^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:13:5
+  --> $DIR/drop_ref.rs:14:5
    |
 LL |     drop(&&owned1);
    |     ^^^^^^^^^^^^^^
    |
 note: argument has type `&&SomeStruct`
-  --> $DIR/drop_ref.rs:13:10
+  --> $DIR/drop_ref.rs:14:10
    |
 LL |     drop(&&owned1);
    |          ^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:14:5
+  --> $DIR/drop_ref.rs:15:5
    |
 LL |     drop(&mut owned1);
    |     ^^^^^^^^^^^^^^^^^
    |
 note: argument has type `&mut SomeStruct`
-  --> $DIR/drop_ref.rs:14:10
+  --> $DIR/drop_ref.rs:15:10
    |
 LL |     drop(&mut owned1);
    |          ^^^^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:18:5
+  --> $DIR/drop_ref.rs:19:5
    |
 LL |     drop(reference1);
    |     ^^^^^^^^^^^^^^^^
    |
 note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:18:10
+  --> $DIR/drop_ref.rs:19:10
    |
 LL |     drop(reference1);
    |          ^^^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:21:5
+  --> $DIR/drop_ref.rs:22:5
    |
 LL |     drop(reference2);
    |     ^^^^^^^^^^^^^^^^
    |
 note: argument has type `&mut SomeStruct`
-  --> $DIR/drop_ref.rs:21:10
+  --> $DIR/drop_ref.rs:22:10
    |
 LL |     drop(reference2);
    |          ^^^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:24:5
+  --> $DIR/drop_ref.rs:25:5
    |
 LL |     drop(reference3);
    |     ^^^^^^^^^^^^^^^^
    |
 note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:24:10
+  --> $DIR/drop_ref.rs:25:10
    |
 LL |     drop(reference3);
    |          ^^^^^^^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:29:5
+  --> $DIR/drop_ref.rs:30:5
    |
 LL |     drop(&val);
    |     ^^^^^^^^^^
    |
 note: argument has type `&T`
-  --> $DIR/drop_ref.rs:29:10
+  --> $DIR/drop_ref.rs:30:10
    |
 LL |     drop(&val);
    |          ^^^^
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing.
-  --> $DIR/drop_ref.rs:37:5
+  --> $DIR/drop_ref.rs:38:5
    |
 LL |     std::mem::drop(&SomeStruct);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:37:20
+  --> $DIR/drop_ref.rs:38:20
    |
 LL |     std::mem::drop(&SomeStruct);
    |                    ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/float_cmp.stderr b/src/tools/clippy/tests/ui/float_cmp.stderr
index 2d454e8e70d..f7c380fc915 100644
--- a/src/tools/clippy/tests/ui/float_cmp.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp.stderr
@@ -2,34 +2,34 @@ error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:65:5
    |
 LL |     ONE as f64 != 2.0;
-   |     ^^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(ONE as f64 - 2.0).abs() > error`
+   |     ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`
    |
    = note: `-D clippy::float-cmp` implied by `-D warnings`
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:70:5
    |
 LL |     x == 1.0;
-   |     ^^^^^^^^ help: consider comparing them within some error: `(x - 1.0).abs() < error`
+   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:73:5
    |
 LL |     twice(x) != twice(ONE as f64);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(twice(x) - twice(ONE as f64)).abs() > error`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:93:5
    |
 LL |     NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` arrays
   --> $DIR/float_cmp.rs:98:5
@@ -37,15 +37,15 @@ error: strict comparison of `f32` or `f64` arrays
 LL |     a1 == a2;
    |     ^^^^^^^^
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:99:5
    |
 LL |     a1[0] == a2[0];
-   |     ^^^^^^^^^^^^^^ help: consider comparing them within some error: `(a1[0] - a2[0]).abs() < error`
+   |     ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr
index 19dc4a284b7..5d0455363e8 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr
@@ -2,58 +2,58 @@ error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:20:5
    |
 LL |     1f32 == ONE;
-   |     ^^^^^^^^^^^ help: consider comparing them within some error: `(1f32 - ONE).abs() < error`
+   |     ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin`
    |
    = note: `-D clippy::float-cmp-const` implied by `-D warnings`
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:21:5
    |
 LL |     TWO == ONE;
-   |     ^^^^^^^^^^ help: consider comparing them within some error: `(TWO - ONE).abs() < error`
+   |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:22:5
    |
 LL |     TWO != ONE;
-   |     ^^^^^^^^^^ help: consider comparing them within some error: `(TWO - ONE).abs() > error`
+   |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:23:5
    |
 LL |     ONE + ONE == TWO;
-   |     ^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(ONE + ONE - TWO).abs() < error`
+   |     ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:25:5
    |
 LL |     x as f32 == ONE;
-   |     ^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(x as f32 - ONE).abs() < error`
+   |     ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:28:5
    |
 LL |     v == ONE;
-   |     ^^^^^^^^ help: consider comparing them within some error: `(v - ONE).abs() < error`
+   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:29:5
    |
 LL |     v != ONE;
-   |     ^^^^^^^^ help: consider comparing them within some error: `(v - ONE).abs() > error`
+   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin`
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: strict comparison of `f32` or `f64` constant arrays
   --> $DIR/float_cmp_const.rs:61:5
@@ -61,7 +61,7 @@ error: strict comparison of `f32` or `f64` constant arrays
 LL |     NON_ZERO_ARRAY == NON_ZERO_ARRAY2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error`
+   = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index 000d5269930..ca8ca53c80c 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -15,7 +15,8 @@ fn main() {
     x[3]; // Ok, should not produce stderr.
 
     let y = &x;
-    y[0];
+    y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
+    y[4]; // Ok, rustc will handle references too.
 
     let v = vec![0; 5];
     v[0];
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 2b3f9be2dfb..2f6c9e2f4e5 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -8,15 +8,7 @@ LL |     x[index];
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:18:5
-   |
-LL |     y[0];
-   |     ^^^^
-   |
-   = help: Consider using `.get(n)` or `.get_mut(n)` instead
-
-error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:21:5
+  --> $DIR/indexing_slicing_index.rs:22:5
    |
 LL |     v[0];
    |     ^^^^
@@ -24,7 +16,7 @@ LL |     v[0];
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:22:5
+  --> $DIR/indexing_slicing_index.rs:23:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -32,7 +24,7 @@ LL |     v[10];
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:23:5
+  --> $DIR/indexing_slicing_index.rs:24:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -40,7 +32,7 @@ LL |     v[1 << 3];
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:29:5
+  --> $DIR/indexing_slicing_index.rs:30:5
    |
 LL |     v[N];
    |     ^^^^
@@ -48,12 +40,12 @@ LL |     v[N];
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic.
-  --> $DIR/indexing_slicing_index.rs:30:5
+  --> $DIR/indexing_slicing_index.rs:31:5
    |
 LL |     v[M];
    |     ^^^^
    |
    = help: Consider using `.get(n)` or `.get_mut(n)` instead
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
index ec6c157ac1a..2231deee833 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
@@ -71,29 +71,17 @@ LL |     &x[1..][..5];
    |
    = help: Consider using `.get(..n)`or `.get_mut(..n)` instead
 
-error: slicing may panic.
-  --> $DIR/indexing_slicing_slice.rs:24:6
-   |
-LL |     &y[1..2];
-   |      ^^^^^^^
-   |
-   = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead
-
-error: slicing may panic.
-  --> $DIR/indexing_slicing_slice.rs:25:6
+error: range is out of bounds
+  --> $DIR/indexing_slicing_slice.rs:25:12
    |
 LL |     &y[0..=4];
-   |      ^^^^^^^^
-   |
-   = help: Consider using `.get(n..m)` or `.get_mut(n..m)` instead
+   |            ^
 
-error: slicing may panic.
-  --> $DIR/indexing_slicing_slice.rs:26:6
+error: range is out of bounds
+  --> $DIR/indexing_slicing_slice.rs:26:11
    |
 LL |     &y[..=4];
-   |      ^^^^^^^
-   |
-   = help: Consider using `.get(..n)`or `.get_mut(..n)` instead
+   |           ^
 
 error: slicing may panic.
   --> $DIR/indexing_slicing_slice.rs:31:6
@@ -133,5 +121,5 @@ LL |     &v[..100];
    |
    = help: Consider using `.get(..n)`or `.get_mut(..n)` instead
 
-error: aborting due to 17 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.stderr b/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
index 1cd6400b019..28003b365bb 100644
--- a/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
+++ b/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
@@ -1,4 +1,4 @@
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `Vec`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`
   --> $DIR/into_iter_on_ref.rs:14:30
    |
 LL |     let _ = (&vec![1, 2, 3]).into_iter(); //~ WARN equivalent to .iter()
@@ -6,157 +6,157 @@ LL |     let _ = (&vec![1, 2, 3]).into_iter(); //~ WARN equivalent to .iter()
    |
    = note: `-D clippy::into-iter-on-ref` implied by `-D warnings`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `slice`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
   --> $DIR/into_iter_on_ref.rs:15:46
    |
 LL |     let _ = vec![1, 2, 3].into_boxed_slice().into_iter(); //~ WARN equivalent to .iter()
    |                                              ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `slice`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
   --> $DIR/into_iter_on_ref.rs:16:41
    |
 LL |     let _ = std::rc::Rc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter()
    |                                         ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `slice`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
   --> $DIR/into_iter_on_ref.rs:17:44
    |
 LL |     let _ = std::sync::Arc::from(&[X][..]).into_iter(); //~ WARN equivalent to .iter()
    |                                            ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `array`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
   --> $DIR/into_iter_on_ref.rs:19:32
    |
 LL |     let _ = (&&&&&&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter()
    |                                ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `array`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
   --> $DIR/into_iter_on_ref.rs:20:36
    |
 LL |     let _ = (&&&&mut &&&[1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter()
    |                                    ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `array`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array`
   --> $DIR/into_iter_on_ref.rs:21:40
    |
 LL |     let _ = (&mut &mut &mut [1, 2, 3]).into_iter(); //~ ERROR equivalent to .iter_mut()
    |                                        ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `Option`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option`
   --> $DIR/into_iter_on_ref.rs:23:24
    |
 LL |     let _ = (&Some(4)).into_iter(); //~ WARN equivalent to .iter()
    |                        ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `Option`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option`
   --> $DIR/into_iter_on_ref.rs:24:28
    |
 LL |     let _ = (&mut Some(5)).into_iter(); //~ WARN equivalent to .iter_mut()
    |                            ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `Result`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result`
   --> $DIR/into_iter_on_ref.rs:25:32
    |
 LL |     let _ = (&Ok::<_, i32>(6)).into_iter(); //~ WARN equivalent to .iter()
    |                                ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `Result`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result`
   --> $DIR/into_iter_on_ref.rs:26:37
    |
 LL |     let _ = (&mut Err::<i32, _>(7)).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                     ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `Vec`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`
   --> $DIR/into_iter_on_ref.rs:27:34
    |
 LL |     let _ = (&Vec::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                  ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `Vec`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec`
   --> $DIR/into_iter_on_ref.rs:28:38
    |
 LL |     let _ = (&mut Vec::<i32>::new()).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                      ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `BTreeMap`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap`
   --> $DIR/into_iter_on_ref.rs:29:44
    |
 LL |     let _ = (&BTreeMap::<i32, u64>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                            ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `BTreeMap`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap`
   --> $DIR/into_iter_on_ref.rs:30:48
    |
 LL |     let _ = (&mut BTreeMap::<i32, u64>::new()).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                                ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `VecDeque`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque`
   --> $DIR/into_iter_on_ref.rs:31:39
    |
 LL |     let _ = (&VecDeque::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                       ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `VecDeque`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque`
   --> $DIR/into_iter_on_ref.rs:32:43
    |
 LL |     let _ = (&mut VecDeque::<i32>::new()).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                           ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `LinkedList`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList`
   --> $DIR/into_iter_on_ref.rs:33:41
    |
 LL |     let _ = (&LinkedList::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                         ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `LinkedList`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList`
   --> $DIR/into_iter_on_ref.rs:34:45
    |
 LL |     let _ = (&mut LinkedList::<i32>::new()).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                             ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `HashMap`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap`
   --> $DIR/into_iter_on_ref.rs:35:43
    |
 LL |     let _ = (&HashMap::<i32, u64>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                           ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not move the `HashMap`
+error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap`
   --> $DIR/into_iter_on_ref.rs:36:47
    |
 LL |     let _ = (&mut HashMap::<i32, u64>::new()).into_iter(); //~ WARN equivalent to .iter_mut()
    |                                               ^^^^^^^^^ help: call directly: `iter_mut`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `BTreeSet`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet`
   --> $DIR/into_iter_on_ref.rs:38:39
    |
 LL |     let _ = (&BTreeSet::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                       ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `BinaryHeap`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap`
   --> $DIR/into_iter_on_ref.rs:39:41
    |
 LL |     let _ = (&BinaryHeap::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                         ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `HashSet`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet`
   --> $DIR/into_iter_on_ref.rs:40:38
    |
 LL |     let _ = (&HashSet::<i32>::new()).into_iter(); //~ WARN equivalent to .iter()
    |                                      ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `Path`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path`
   --> $DIR/into_iter_on_ref.rs:41:43
    |
 LL |     let _ = std::path::Path::new("12/34").into_iter(); //~ WARN equivalent to .iter()
    |                                           ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `PathBuf`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf`
   --> $DIR/into_iter_on_ref.rs:42:47
    |
 LL |     let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR equivalent to .iter()
    |                                               ^^^^^^^^^ help: call directly: `iter`
 
-error: this `.into_iter()` call is equivalent to `.iter()` and will not move the `array`
+error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
   --> $DIR/into_iter_on_ref.rs:44:26
    |
 LL |     let _ = (&[1, 2, 3]).into_iter().next(); //~ WARN equivalent to .iter()
diff --git a/src/tools/clippy/tests/ui/let_if_seq.rs b/src/tools/clippy/tests/ui/let_if_seq.rs
index 802beeb4be6..32a67f181df 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.rs
+++ b/src/tools/clippy/tests/ui/let_if_seq.rs
@@ -33,6 +33,7 @@ fn issue985_alt() -> i32 {
     x
 }
 
+#[allow(clippy::manual_strip)]
 fn issue975() -> String {
     let mut udn = "dummy".to_string();
     if udn.starts_with("uuid:") {
diff --git a/src/tools/clippy/tests/ui/let_if_seq.stderr b/src/tools/clippy/tests/ui/let_if_seq.stderr
index c53a63a541b..7de560c7348 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.stderr
+++ b/src/tools/clippy/tests/ui/let_if_seq.stderr
@@ -1,5 +1,5 @@
 error: `if _ { .. } else { .. }` is an expression
-  --> $DIR/let_if_seq.rs:63:5
+  --> $DIR/let_if_seq.rs:64:5
    |
 LL | /     let mut foo = 0;
 LL | |     if f() {
@@ -11,7 +11,7 @@ LL | |     }
    = note: you might not need `mut` at all
 
 error: `if _ { .. } else { .. }` is an expression
-  --> $DIR/let_if_seq.rs:68:5
+  --> $DIR/let_if_seq.rs:69:5
    |
 LL | /     let mut bar = 0;
 LL | |     if f() {
@@ -25,7 +25,7 @@ LL | |     }
    = note: you might not need `mut` at all
 
 error: `if _ { .. } else { .. }` is an expression
-  --> $DIR/let_if_seq.rs:76:5
+  --> $DIR/let_if_seq.rs:77:5
    |
 LL | /     let quz;
 LL | |     if f() {
@@ -36,7 +36,7 @@ LL | |     }
    | |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };`
 
 error: `if _ { .. } else { .. }` is an expression
-  --> $DIR/let_if_seq.rs:105:5
+  --> $DIR/let_if_seq.rs:106:5
    |
 LL | /     let mut baz = 0;
 LL | |     if f() {
diff --git a/src/tools/clippy/tests/ui/manual_strip.rs b/src/tools/clippy/tests/ui/manual_strip.rs
new file mode 100644
index 00000000000..cbb84eb5c7e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_strip.rs
@@ -0,0 +1,66 @@
+#![warn(clippy::manual_strip)]
+
+fn main() {
+    let s = "abc";
+
+    if s.starts_with("ab") {
+        str::to_string(&s["ab".len()..]);
+        s["ab".len()..].to_string();
+
+        str::to_string(&s[2..]);
+        s[2..].to_string();
+    }
+
+    if s.ends_with("bc") {
+        str::to_string(&s[..s.len() - "bc".len()]);
+        s[..s.len() - "bc".len()].to_string();
+
+        str::to_string(&s[..s.len() - 2]);
+        s[..s.len() - 2].to_string();
+    }
+
+    // Character patterns
+    if s.starts_with('a') {
+        str::to_string(&s[1..]);
+        s[1..].to_string();
+    }
+
+    // Variable prefix
+    let prefix = "ab";
+    if s.starts_with(prefix) {
+        str::to_string(&s[prefix.len()..]);
+    }
+
+    // Constant prefix
+    const PREFIX: &str = "ab";
+    if s.starts_with(PREFIX) {
+        str::to_string(&s[PREFIX.len()..]);
+        str::to_string(&s[2..]);
+    }
+
+    // Constant target
+    const TARGET: &str = "abc";
+    if TARGET.starts_with(prefix) {
+        str::to_string(&TARGET[prefix.len()..]);
+    }
+
+    // String target - not mutated.
+    let s1: String = "abc".into();
+    if s1.starts_with("ab") {
+        s1[2..].to_uppercase();
+    }
+
+    // String target - mutated. (Don't lint.)
+    let mut s2: String = "abc".into();
+    if s2.starts_with("ab") {
+        s2.push('d');
+        s2[2..].to_uppercase();
+    }
+
+    // Target not stripped. (Don't lint.)
+    let s3 = String::from("abcd");
+    let s4 = String::from("efgh");
+    if s3.starts_with("ab") {
+        s4[2..].to_string();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr
new file mode 100644
index 00000000000..1352a8713d4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_strip.stderr
@@ -0,0 +1,132 @@
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:7:24
+   |
+LL |         str::to_string(&s["ab".len()..]);
+   |                        ^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::manual-strip` implied by `-D warnings`
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:6:5
+   |
+LL |     if s.starts_with("ab") {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = s.strip_prefix("ab") {
+LL |         str::to_string(<stripped>);
+LL |         <stripped>.to_string();
+LL | 
+LL |         str::to_string(<stripped>);
+LL |         <stripped>.to_string();
+   |
+
+error: stripping a suffix manually
+  --> $DIR/manual_strip.rs:15:24
+   |
+LL |         str::to_string(&s[..s.len() - "bc".len()]);
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the suffix was tested here
+  --> $DIR/manual_strip.rs:14:5
+   |
+LL |     if s.ends_with("bc") {
+   |     ^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_suffix` method
+   |
+LL |     if let Some(<stripped>) = s.strip_suffix("bc") {
+LL |         str::to_string(<stripped>);
+LL |         <stripped>.to_string();
+LL | 
+LL |         str::to_string(<stripped>);
+LL |         <stripped>.to_string();
+   |
+
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:24:24
+   |
+LL |         str::to_string(&s[1..]);
+   |                        ^^^^^^^
+   |
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:23:5
+   |
+LL |     if s.starts_with('a') {
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = s.strip_prefix('a') {
+LL |         str::to_string(<stripped>);
+LL |         <stripped>.to_string();
+   |
+
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:31:24
+   |
+LL |         str::to_string(&s[prefix.len()..]);
+   |                        ^^^^^^^^^^^^^^^^^^
+   |
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:30:5
+   |
+LL |     if s.starts_with(prefix) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = s.strip_prefix(prefix) {
+LL |         str::to_string(<stripped>);
+   |
+
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:37:24
+   |
+LL |         str::to_string(&s[PREFIX.len()..]);
+   |                        ^^^^^^^^^^^^^^^^^^
+   |
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:36:5
+   |
+LL |     if s.starts_with(PREFIX) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = s.strip_prefix(PREFIX) {
+LL |         str::to_string(<stripped>);
+LL |         str::to_string(<stripped>);
+   |
+
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:44:24
+   |
+LL |         str::to_string(&TARGET[prefix.len()..]);
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:43:5
+   |
+LL |     if TARGET.starts_with(prefix) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = TARGET.strip_prefix(prefix) {
+LL |         str::to_string(<stripped>);
+   |
+
+error: stripping a prefix manually
+  --> $DIR/manual_strip.rs:50:9
+   |
+LL |         s1[2..].to_uppercase();
+   |         ^^^^^^^
+   |
+note: the prefix was tested here
+  --> $DIR/manual_strip.rs:49:5
+   |
+LL |     if s1.starts_with("ab") {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+help: try using the `strip_prefix` method
+   |
+LL |     if let Some(<stripped>) = s1.strip_prefix("ab") {
+LL |         <stripped>.to_uppercase();
+   |
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/map_err.rs b/src/tools/clippy/tests/ui/map_err.rs
new file mode 100644
index 00000000000..617b6422872
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_err.rs
@@ -0,0 +1,25 @@
+#![warn(clippy::map_err_ignore)]
+use std::convert::TryFrom;
+use std::error::Error;
+use std::fmt;
+
+#[derive(Debug)]
+enum Errors {
+    Ignored,
+}
+
+impl Error for Errors {}
+
+impl fmt::Display for Errors {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "Error")
+    }
+}
+
+fn main() -> Result<(), Errors> {
+    let x = u32::try_from(-123_i32);
+
+    println!("{:?}", x.map_err(|_| Errors::Ignored));
+
+    Ok(())
+}
diff --git a/src/tools/clippy/tests/ui/map_err.stderr b/src/tools/clippy/tests/ui/map_err.stderr
new file mode 100644
index 00000000000..7273f460380
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_err.stderr
@@ -0,0 +1,11 @@
+error: `map_err(|_|...` ignores the original error
+  --> $DIR/map_err.rs:22:32
+   |
+LL |     println!("{:?}", x.map_err(|_| Errors::Ignored));
+   |                                ^^^
+   |
+   = note: `-D clippy::map-err-ignore` implied by `-D warnings`
+   = help: Consider wrapping the error in an enum variant
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/match_type_on_diag_item.rs b/src/tools/clippy/tests/ui/match_type_on_diag_item.rs
new file mode 100644
index 00000000000..fe950b0aa7c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/match_type_on_diag_item.rs
@@ -0,0 +1,50 @@
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+extern crate rustc_hir;
+extern crate rustc_lint;
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_session;
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::Ty;
+
+mod paths {
+    pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
+}
+
+mod utils {
+    use super::*;
+
+    pub fn match_type(_cx: &LateContext<'_>, _ty: Ty<'_>, _path: &[&str]) -> bool {
+        false
+    }
+}
+
+use utils::match_type;
+
+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, &paths::VEC);
+        let _ = match_type(cx, ty, &OPTION);
+        let _ = match_type(cx, ty, &["core", "result", "Result"]);
+
+        let rc_path = &["alloc", "rc", "Rc"];
+        let _ = utils::match_type(cx, ty, rc_path);
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/match_type_on_diag_item.stderr b/src/tools/clippy/tests/ui/match_type_on_diag_item.stderr
new file mode 100644
index 00000000000..5e5fe9e3a3e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/match_type_on_diag_item.stderr
@@ -0,0 +1,33 @@
+error: usage of `utils::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:41:17
+   |
+LL |         let _ = match_type(cx, ty, &paths::VEC);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym!(vec_type))`
+   |
+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 `utils::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:42:17
+   |
+LL |         let _ = match_type(cx, ty, &OPTION);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym!(option_type))`
+
+error: usage of `utils::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:43:17
+   |
+LL |         let _ = match_type(cx, ty, &["core", "result", "Result"]);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym!(result_type))`
+
+error: usage of `utils::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:46:17
+   |
+LL |         let _ = utils::match_type(cx, ty, rc_path);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym!(Rc))`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index 695a460cc4e..a7fb00a2705 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
+#![allow(clippy::redundant_closure)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     string.map_or((false, "hello"), |x| (true, x))
@@ -36,6 +37,14 @@ fn longer_body(arg: Option<u32>) -> u32 {
     })
 }
 
+fn impure_else(arg: Option<i32>) {
+    let side_effect = || {
+        println!("return 1");
+        1
+    };
+    let _ = arg.map_or_else(|| side_effect(), |x| x);
+}
+
 fn test_map_or_else(arg: Option<u32>) {
     let _ = arg.map_or_else(|| {
         let mut y = 1;
@@ -71,4 +80,5 @@ fn main() {
     let _ = longer_body(None);
     test_map_or_else(None);
     let _ = negative_tests(None);
+    let _ = impure_else(None);
 }
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index dee80d26bd9..895fd86321f 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
+#![allow(clippy::redundant_closure)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     if let Some(x) = string {
@@ -52,6 +53,19 @@ fn longer_body(arg: Option<u32>) -> u32 {
     }
 }
 
+fn impure_else(arg: Option<i32>) {
+    let side_effect = || {
+        println!("return 1");
+        1
+    };
+    let _ = if let Some(x) = arg {
+        x
+    } else {
+        // map_or_else must be suggested
+        side_effect()
+    };
+}
+
 fn test_map_or_else(arg: Option<u32>) {
     let _ = if let Some(x) = arg {
         x * x * x * x
@@ -89,4 +103,5 @@ fn main() {
     let _ = longer_body(None);
     test_map_or_else(None);
     let _ = negative_tests(None);
+    let _ = impure_else(None);
 }
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 7005850efaf..b69fe767682 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -1,5 +1,5 @@
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:5:5
+  --> $DIR/option_if_let_else.rs:6:5
    |
 LL | /     if let Some(x) = string {
 LL | |         (true, x)
@@ -11,7 +11,7 @@ LL | |     }
    = note: `-D clippy::option-if-let-else` implied by `-D warnings`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:15:12
+  --> $DIR/option_if_let_else.rs:16:12
    |
 LL |       } else if let Some(x) = string {
    |  ____________^
@@ -22,19 +22,19 @@ LL | |     }
    | |_____^ help: try: `{ string.map_or(Some((false, "")), |x| Some((true, x))) }`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:23:13
+  --> $DIR/option_if_let_else.rs:24:13
    |
 LL |     let _ = if let Some(s) = *string { s.len() } else { 0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:24:13
+  --> $DIR/option_if_let_else.rs:25:13
    |
 LL |     let _ = if let Some(s) = &num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:25:13
+  --> $DIR/option_if_let_else.rs:26:13
    |
 LL |       let _ = if let Some(s) = &mut num {
    |  _____________^
@@ -54,13 +54,13 @@ LL |     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:31:13
+  --> $DIR/option_if_let_else.rs:32:13
    |
 LL |     let _ = if let Some(ref s) = num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:32:13
+  --> $DIR/option_if_let_else.rs:33:13
    |
 LL |       let _ = if let Some(mut s) = num {
    |  _____________^
@@ -80,7 +80,7 @@ LL |     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:38:13
+  --> $DIR/option_if_let_else.rs:39:13
    |
 LL |       let _ = if let Some(ref mut s) = num {
    |  _____________^
@@ -100,7 +100,7 @@ LL |     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:47:5
+  --> $DIR/option_if_let_else.rs:48:5
    |
 LL | /     if let Some(x) = arg {
 LL | |         let y = x * x;
@@ -119,7 +119,19 @@ LL |     })
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:56:13
+  --> $DIR/option_if_let_else.rs:61:13
+   |
+LL |       let _ = if let Some(x) = arg {
+   |  _____________^
+LL | |         x
+LL | |     } else {
+LL | |         // map_or_else must be suggested
+LL | |         side_effect()
+LL | |     };
+   | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
+
+error: use Option::map_or_else instead of an if let/else
+  --> $DIR/option_if_let_else.rs:70:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -142,10 +154,10 @@ LL |     }, |x| x * x * x * x);
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:85:13
+  --> $DIR/option_if_let_else.rs:99:13
    |
 LL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.rs b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
new file mode 100644
index 00000000000..287726f7a2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
@@ -0,0 +1,70 @@
+#![warn(clippy::panic_in_result_fn)]
+
+struct A;
+
+impl A {
+    fn result_with_panic() -> Result<bool, String> // should emit lint
+    {
+        panic!("error");
+    }
+
+    fn result_with_unimplemented() -> Result<bool, String> // should emit lint
+    {
+        unimplemented!();
+    }
+
+    fn result_with_unreachable() -> Result<bool, String> // should emit lint
+    {
+        unreachable!();
+    }
+
+    fn result_with_todo() -> Result<bool, String> // should emit lint
+    {
+        todo!("Finish this");
+    }
+
+    fn other_with_panic() // should not emit lint
+    {
+        panic!("");
+    }
+
+    fn other_with_unreachable() // should not emit lint
+    {
+        unreachable!();
+    }
+
+    fn other_with_unimplemented() // should not emit lint
+    {
+        unimplemented!();
+    }
+
+    fn other_with_todo() // should not emit lint
+    {
+        todo!("finish this")
+    }
+
+    fn result_without_banned_functions() -> Result<bool, String> // should not emit lint
+    {
+        Ok(true)
+    }
+}
+
+fn function_result_with_panic() -> Result<bool, String> // should emit lint
+{
+    panic!("error");
+}
+
+fn todo() {
+    println!("something");
+}
+
+fn function_result_with_custom_todo() -> Result<bool, String> // should not emit lint
+{
+    todo();
+    Ok(true)
+}
+
+fn main() -> Result<(), String> {
+    todo!("finish main method");
+    Ok(())
+}
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
new file mode 100644
index 00000000000..c6936fd8692
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
@@ -0,0 +1,105 @@
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:6:5
+   |
+LL | /     fn result_with_panic() -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         panic!("error");
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:8:9
+   |
+LL |         panic!("error");
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:11:5
+   |
+LL | /     fn result_with_unimplemented() -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         unimplemented!();
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:13:9
+   |
+LL |         unimplemented!();
+   |         ^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:16:5
+   |
+LL | /     fn result_with_unreachable() -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         unreachable!();
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:18:9
+   |
+LL |         unreachable!();
+   |         ^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:21:5
+   |
+LL | /     fn result_with_todo() -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         todo!("Finish this");
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:23:9
+   |
+LL |         todo!("Finish this");
+   |         ^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:52:1
+   |
+LL | / fn function_result_with_panic() -> Result<bool, String> // should emit lint
+LL | | {
+LL | |     panic!("error");
+LL | | }
+   | |_^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:54:5
+   |
+LL |     panic!("error");
+   |     ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+  --> $DIR/panic_in_result_fn.rs:67:1
+   |
+LL | / fn main() -> Result<(), String> {
+LL | |     todo!("finish main method");
+LL | |     Ok(())
+LL | | }
+   | |_^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn.rs:68:5
+   |
+LL |     todo!("finish main method");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/print_with_newline.rs b/src/tools/clippy/tests/ui/print_with_newline.rs
index 3f710540e90..a43a1fc4f52 100644
--- a/src/tools/clippy/tests/ui/print_with_newline.rs
+++ b/src/tools/clippy/tests/ui/print_with_newline.rs
@@ -9,6 +9,7 @@ fn main() {
     print!("Hello {}\n", "world");
     print!("Hello {} {}\n", "world", "#2");
     print!("{}\n", 1265);
+    print!("\n");
 
     // these are all fine
     print!("");
diff --git a/src/tools/clippy/tests/ui/print_with_newline.stderr b/src/tools/clippy/tests/ui/print_with_newline.stderr
index 05fe88915d6..54b3ad75b31 100644
--- a/src/tools/clippy/tests/ui/print_with_newline.stderr
+++ b/src/tools/clippy/tests/ui/print_with_newline.stderr
@@ -44,7 +44,18 @@ LL |     println!("{}", 1265);
    |     ^^^^^^^    --
 
 error: using `print!()` with a format string that ends in a single newline
-  --> $DIR/print_with_newline.rs:30:5
+  --> $DIR/print_with_newline.rs:12:5
+   |
+LL |     print!("/n");
+   |     ^^^^^^^^^^^^
+   |
+help: use `println!` instead
+   |
+LL |     println!();
+   |     ^^^^^^^ --
+
+error: using `print!()` with a format string that ends in a single newline
+  --> $DIR/print_with_newline.rs:31:5
    |
 LL |     print!("//n"); // should fail
    |     ^^^^^^^^^^^^^^
@@ -55,7 +66,7 @@ LL |     println!("/"); // should fail
    |     ^^^^^^^    --
 
 error: using `print!()` with a format string that ends in a single newline
-  --> $DIR/print_with_newline.rs:37:5
+  --> $DIR/print_with_newline.rs:38:5
    |
 LL | /     print!(
 LL | |         "
@@ -70,7 +81,7 @@ LL |         ""
    |
 
 error: using `print!()` with a format string that ends in a single newline
-  --> $DIR/print_with_newline.rs:41:5
+  --> $DIR/print_with_newline.rs:42:5
    |
 LL | /     print!(
 LL | |         r"
@@ -85,7 +96,7 @@ LL |         r""
    |
 
 error: using `print!()` with a format string that ends in a single newline
-  --> $DIR/print_with_newline.rs:49:5
+  --> $DIR/print_with_newline.rs:50:5
    |
 LL |     print!("/r/n"); //~ ERROR
    |     ^^^^^^^^^^^^^^^
@@ -96,7 +107,7 @@ LL |     println!("/r"); //~ ERROR
    |     ^^^^^^^     --
 
 error: using `print!()` with a format string that ends in a single newline
-  --> $DIR/print_with_newline.rs:50:5
+  --> $DIR/print_with_newline.rs:51:5
    |
 LL |     print!("foo/rbar/n") // ~ ERROR
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -106,5 +117,5 @@ help: use `println!` instead
 LL |     println!("foo/rbar") // ~ ERROR
    |     ^^^^^^^          --
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/rc_buffer.rs b/src/tools/clippy/tests/ui/rc_buffer.rs
new file mode 100644
index 00000000000..1fa98643936
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer.rs
@@ -0,0 +1,26 @@
+#![warn(clippy::rc_buffer)]
+
+use std::cell::RefCell;
+use std::ffi::OsString;
+use std::path::PathBuf;
+use std::rc::Rc;
+
+struct S {
+    // triggers lint
+    bad1: Rc<String>,
+    bad2: Rc<PathBuf>,
+    bad3: Rc<Vec<u8>>,
+    bad4: Rc<OsString>,
+    // does not trigger lint
+    good1: Rc<RefCell<String>>,
+}
+
+// triggers lint
+fn func_bad1(_: Rc<String>) {}
+fn func_bad2(_: Rc<PathBuf>) {}
+fn func_bad3(_: Rc<Vec<u8>>) {}
+fn func_bad4(_: Rc<OsString>) {}
+// does not trigger lint
+fn func_good1(_: Rc<RefCell<String>>) {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/rc_buffer.stderr b/src/tools/clippy/tests/ui/rc_buffer.stderr
new file mode 100644
index 00000000000..e4cc169af07
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer.stderr
@@ -0,0 +1,52 @@
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:10:11
+   |
+LL |     bad1: Rc<String>,
+   |           ^^^^^^^^^^ help: try: `Rc<str>`
+   |
+   = note: `-D clippy::rc-buffer` implied by `-D warnings`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:11:11
+   |
+LL |     bad2: Rc<PathBuf>,
+   |           ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:12:11
+   |
+LL |     bad3: Rc<Vec<u8>>,
+   |           ^^^^^^^^^^^ help: try: `Rc<[u8]>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:13:11
+   |
+LL |     bad4: Rc<OsString>,
+   |           ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:19:17
+   |
+LL | fn func_bad1(_: Rc<String>) {}
+   |                 ^^^^^^^^^^ help: try: `Rc<str>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:20:17
+   |
+LL | fn func_bad2(_: Rc<PathBuf>) {}
+   |                 ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:21:17
+   |
+LL | fn func_bad3(_: Rc<Vec<u8>>) {}
+   |                 ^^^^^^^^^^^ help: try: `Rc<[u8]>`
+
+error: usage of `Rc<T>` when T is a buffer type
+  --> $DIR/rc_buffer.rs:22:17
+   |
+LL | fn func_bad4(_: Rc<OsString>) {}
+   |                 ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.rs b/src/tools/clippy/tests/ui/rc_buffer_arc.rs
new file mode 100644
index 00000000000..5d586584817
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer_arc.rs
@@ -0,0 +1,25 @@
+#![warn(clippy::rc_buffer)]
+
+use std::ffi::OsString;
+use std::path::PathBuf;
+use std::sync::{Arc, Mutex};
+
+struct S {
+    // triggers lint
+    bad1: Arc<String>,
+    bad2: Arc<PathBuf>,
+    bad3: Arc<Vec<u8>>,
+    bad4: Arc<OsString>,
+    // does not trigger lint
+    good1: Arc<Mutex<String>>,
+}
+
+// triggers lint
+fn func_bad1(_: Arc<String>) {}
+fn func_bad2(_: Arc<PathBuf>) {}
+fn func_bad3(_: Arc<Vec<u8>>) {}
+fn func_bad4(_: Arc<OsString>) {}
+// does not trigger lint
+fn func_good1(_: Arc<Mutex<String>>) {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.stderr b/src/tools/clippy/tests/ui/rc_buffer_arc.stderr
new file mode 100644
index 00000000000..8252270d2ac
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer_arc.stderr
@@ -0,0 +1,52 @@
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:9:11
+   |
+LL |     bad1: Arc<String>,
+   |           ^^^^^^^^^^^ help: try: `Arc<str>`
+   |
+   = note: `-D clippy::rc-buffer` implied by `-D warnings`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:10:11
+   |
+LL |     bad2: Arc<PathBuf>,
+   |           ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:11:11
+   |
+LL |     bad3: Arc<Vec<u8>>,
+   |           ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:12:11
+   |
+LL |     bad4: Arc<OsString>,
+   |           ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:18:17
+   |
+LL | fn func_bad1(_: Arc<String>) {}
+   |                 ^^^^^^^^^^^ help: try: `Arc<str>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:19:17
+   |
+LL | fn func_bad2(_: Arc<PathBuf>) {}
+   |                 ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:20:17
+   |
+LL | fn func_bad3(_: Arc<Vec<u8>>) {}
+   |                 ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:21:17
+   |
+LL | fn func_bad4(_: Arc<OsString>) {}
+   |                 ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/rc_buffer_redefined_string.rs b/src/tools/clippy/tests/ui/rc_buffer_redefined_string.rs
new file mode 100644
index 00000000000..5d31a848cf7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer_redefined_string.rs
@@ -0,0 +1,12 @@
+#![warn(clippy::rc_buffer)]
+
+use std::rc::Rc;
+
+struct String;
+
+struct S {
+    // does not trigger lint
+    good1: Rc<String>,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/rc_buffer_redefined_string.stderr b/src/tools/clippy/tests/ui/rc_buffer_redefined_string.stderr
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/rc_buffer_redefined_string.stderr
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching.fixed
index 8084fdefdc2..fe8f62503b7 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching.fixed
@@ -18,39 +18,14 @@ fn main() {
 
     if Err::<i32, i32>(42).is_err() {}
 
-    if None::<()>.is_none() {}
-
-    if Some(42).is_some() {}
-
-    if Some(42).is_some() {
-        foo();
-    } else {
-        bar();
-    }
-
-    while Some(42).is_some() {}
-
-    while Some(42).is_none() {}
-
-    while None::<()>.is_none() {}
-
     while Ok::<i32, i32>(10).is_ok() {}
 
     while Ok::<i32, i32>(10).is_err() {}
 
-    let mut v = vec![1, 2, 3];
-    while v.pop().is_some() {
-        foo();
-    }
-
     if Ok::<i32, i32>(42).is_ok() {}
 
     if Err::<i32, i32>(42).is_err() {}
 
-    if None::<i32>.is_none() {}
-
-    if Some(42).is_some() {}
-
     if let Ok(x) = Ok::<i32, i32>(42) {
         println!("{}", x);
     }
@@ -63,48 +38,25 @@ fn main() {
 
     Err::<i32, i32>(42).is_ok();
 
-    Some(42).is_some();
-
-    None::<()>.is_none();
-
-    let _ = None::<()>.is_none();
-
     let _ = if Ok::<usize, ()>(4).is_ok() { true } else { false };
 
-    let opt = Some(false);
-    let x = if opt.is_some() { true } else { false };
-    takes_bool(x);
-
     issue5504();
     issue6067();
+    issue6065();
 
-    let _ = if gen_opt().is_some() {
+    let _ = if gen_res().is_ok() {
         1
-    } else if gen_opt().is_none() {
-        2
-    } else if gen_res().is_ok() {
-        3
     } else if gen_res().is_err() {
-        4
+        2
     } else {
-        5
+        3
     };
 }
 
-fn gen_opt() -> Option<()> {
-    None
-}
-
 fn gen_res() -> Result<(), ()> {
     Ok(())
 }
 
-fn takes_bool(_: bool) {}
-
-fn foo() {}
-
-fn bar() {}
-
 macro_rules! m {
     () => {
         Some(42u32)
@@ -128,31 +80,30 @@ fn issue5504() {
     while m!().is_some() {}
 }
 
+fn issue6065() {
+    macro_rules! if_let_in_macro {
+        ($pat:pat, $x:expr) => {
+            if let Some($pat) = $x {}
+        };
+    }
+
+    // shouldn't be linted
+    if_let_in_macro!(_, Some(42));
+}
+
 // Methods that are unstable const should not be suggested within a const context, see issue #5697.
-// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result`, and `is_some` and `is_none`
-// of `Option` were stabilized as const, so the following should be linted.
+// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,
+// so the following should be linted.
 const fn issue6067() {
     if Ok::<i32, i32>(42).is_ok() {}
 
     if Err::<i32, i32>(42).is_err() {}
 
-    if Some(42).is_some() {}
-
-    if None::<()>.is_none() {}
-
     while Ok::<i32, i32>(10).is_ok() {}
 
     while Ok::<i32, i32>(10).is_err() {}
 
-    while Some(42).is_some() {}
-
-    while None::<()>.is_none() {}
-
     Ok::<i32, i32>(42).is_ok();
 
     Err::<i32, i32>(42).is_err();
-
-    Some(42).is_some();
-
-    None::<()>.is_none();
 }
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching.rs
index 48a32cb1c7b..09426a6e590 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching.rs
@@ -18,39 +18,14 @@ fn main() {
 
     if let Err(_) = Err::<i32, i32>(42) {}
 
-    if let None = None::<()> {}
-
-    if let Some(_) = Some(42) {}
-
-    if let Some(_) = Some(42) {
-        foo();
-    } else {
-        bar();
-    }
-
-    while let Some(_) = Some(42) {}
-
-    while let None = Some(42) {}
-
-    while let None = None::<()> {}
-
     while let Ok(_) = Ok::<i32, i32>(10) {}
 
     while let Err(_) = Ok::<i32, i32>(10) {}
 
-    let mut v = vec![1, 2, 3];
-    while let Some(_) = v.pop() {
-        foo();
-    }
-
     if Ok::<i32, i32>(42).is_ok() {}
 
     if Err::<i32, i32>(42).is_err() {}
 
-    if None::<i32>.is_none() {}
-
-    if Some(42).is_some() {}
-
     if let Ok(x) = Ok::<i32, i32>(42) {
         println!("{}", x);
     }
@@ -75,57 +50,25 @@ fn main() {
         Err(_) => false,
     };
 
-    match Some(42) {
-        Some(_) => true,
-        None => false,
-    };
-
-    match None::<()> {
-        Some(_) => false,
-        None => true,
-    };
-
-    let _ = match None::<()> {
-        Some(_) => false,
-        None => true,
-    };
-
     let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
 
-    let opt = Some(false);
-    let x = if let Some(_) = opt { true } else { false };
-    takes_bool(x);
-
     issue5504();
     issue6067();
+    issue6065();
 
-    let _ = if let Some(_) = gen_opt() {
+    let _ = if let Ok(_) = gen_res() {
         1
-    } else if let None = gen_opt() {
-        2
-    } else if let Ok(_) = gen_res() {
-        3
     } else if let Err(_) = gen_res() {
-        4
+        2
     } else {
-        5
+        3
     };
 }
 
-fn gen_opt() -> Option<()> {
-    None
-}
-
 fn gen_res() -> Result<(), ()> {
     Ok(())
 }
 
-fn takes_bool(_: bool) {}
-
-fn foo() {}
-
-fn bar() {}
-
 macro_rules! m {
     () => {
         Some(42u32)
@@ -149,26 +92,29 @@ fn issue5504() {
     while let Some(_) = m!() {}
 }
 
+fn issue6065() {
+    macro_rules! if_let_in_macro {
+        ($pat:pat, $x:expr) => {
+            if let Some($pat) = $x {}
+        };
+    }
+
+    // shouldn't be linted
+    if_let_in_macro!(_, Some(42));
+}
+
 // Methods that are unstable const should not be suggested within a const context, see issue #5697.
-// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result`, and `is_some` and `is_none`
-// of `Option` were stabilized as const, so the following should be linted.
+// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,
+// so the following should be linted.
 const fn issue6067() {
     if let Ok(_) = Ok::<i32, i32>(42) {}
 
     if let Err(_) = Err::<i32, i32>(42) {}
 
-    if let Some(_) = Some(42) {}
-
-    if let None = None::<()> {}
-
     while let Ok(_) = Ok::<i32, i32>(10) {}
 
     while let Err(_) = Ok::<i32, i32>(10) {}
 
-    while let Some(_) = Some(42) {}
-
-    while let None = None::<()> {}
-
     match Ok::<i32, i32>(42) {
         Ok(_) => true,
         Err(_) => false,
@@ -178,14 +124,4 @@ const fn issue6067() {
         Ok(_) => false,
         Err(_) => true,
     };
-
-    match Some(42) {
-        Some(_) => true,
-        None => false,
-    };
-
-    match None::<()> {
-        Some(_) => false,
-        None => true,
-    };
 }
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching.stderr
index 17185217e89..3473ceea00e 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching.stderr
@@ -18,62 +18,20 @@ error: redundant pattern matching, consider using `is_err()`
 LL |     if let Err(_) = Err::<i32, i32>(42) {}
    |     -------^^^^^^---------------------- help: try this: `if Err::<i32, i32>(42).is_err()`
 
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:21:12
-   |
-LL |     if let None = None::<()> {}
-   |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
-
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:23:12
-   |
-LL |     if let Some(_) = Some(42) {}
-   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:25:12
-   |
-LL |     if let Some(_) = Some(42) {
-   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:31:15
-   |
-LL |     while let Some(_) = Some(42) {}
-   |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:33:15
-   |
-LL |     while let None = Some(42) {}
-   |     ----------^^^^----------- help: try this: `while Some(42).is_none()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:35:15
-   |
-LL |     while let None = None::<()> {}
-   |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:37:15
+  --> $DIR/redundant_pattern_matching.rs:21:15
    |
 LL |     while let Ok(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:39:15
+  --> $DIR/redundant_pattern_matching.rs:23:15
    |
 LL |     while let Err(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_err()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:42:15
-   |
-LL |     while let Some(_) = v.pop() {
-   |     ----------^^^^^^^---------- help: try this: `while v.pop().is_some()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:58:5
+  --> $DIR/redundant_pattern_matching.rs:33:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -82,7 +40,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:63:5
+  --> $DIR/redundant_pattern_matching.rs:38:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -91,7 +49,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:68:5
+  --> $DIR/redundant_pattern_matching.rs:43:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -100,7 +58,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:73:5
+  --> $DIR/redundant_pattern_matching.rs:48:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -108,144 +66,74 @@ LL | |         Err(_) => false,
 LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_ok()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:78:5
-   |
-LL | /     match Some(42) {
-LL | |         Some(_) => true,
-LL | |         None => false,
-LL | |     };
-   | |_____^ help: try this: `Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:83:5
-   |
-LL | /     match None::<()> {
-LL | |         Some(_) => false,
-LL | |         None => true,
-LL | |     };
-   | |_____^ help: try this: `None::<()>.is_none()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:88:13
-   |
-LL |       let _ = match None::<()> {
-   |  _____________^
-LL | |         Some(_) => false,
-LL | |         None => true,
-LL | |     };
-   | |_____^ help: try this: `None::<()>.is_none()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:93:20
+  --> $DIR/redundant_pattern_matching.rs:53:20
    |
 LL |     let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
    |             -------^^^^^--------------------- help: try this: `if Ok::<usize, ()>(4).is_ok()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:96:20
-   |
-LL |     let x = if let Some(_) = opt { true } else { false };
-   |             -------^^^^^^^------ help: try this: `if opt.is_some()`
-
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:102:20
-   |
-LL |     let _ = if let Some(_) = gen_opt() {
-   |             -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:104:19
-   |
-LL |     } else if let None = gen_opt() {
-   |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:106:19
+  --> $DIR/redundant_pattern_matching.rs:59:20
    |
-LL |     } else if let Ok(_) = gen_res() {
-   |            -------^^^^^------------ help: try this: `if gen_res().is_ok()`
+LL |     let _ = if let Ok(_) = gen_res() {
+   |             -------^^^^^------------ help: try this: `if gen_res().is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:108:19
+  --> $DIR/redundant_pattern_matching.rs:61:19
    |
 LL |     } else if let Err(_) = gen_res() {
    |            -------^^^^^^------------ help: try this: `if gen_res().is_err()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:141:19
+  --> $DIR/redundant_pattern_matching.rs:84:19
    |
 LL |         while let Some(_) = r#try!(result_opt()) {}
    |         ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:142:16
+  --> $DIR/redundant_pattern_matching.rs:85:16
    |
 LL |         if let Some(_) = r#try!(result_opt()) {}
    |         -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:148:12
+  --> $DIR/redundant_pattern_matching.rs:91:12
    |
 LL |     if let Some(_) = m!() {}
    |     -------^^^^^^^------- help: try this: `if m!().is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:149:15
+  --> $DIR/redundant_pattern_matching.rs:92:15
    |
 LL |     while let Some(_) = m!() {}
    |     ----------^^^^^^^------- help: try this: `while m!().is_some()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:156:12
+  --> $DIR/redundant_pattern_matching.rs:110:12
    |
 LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
    |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:158:12
+  --> $DIR/redundant_pattern_matching.rs:112:12
    |
 LL |     if let Err(_) = Err::<i32, i32>(42) {}
    |     -------^^^^^^---------------------- help: try this: `if Err::<i32, i32>(42).is_err()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:160:12
-   |
-LL |     if let Some(_) = Some(42) {}
-   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:162:12
-   |
-LL |     if let None = None::<()> {}
-   |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:164:15
+  --> $DIR/redundant_pattern_matching.rs:114:15
    |
 LL |     while let Ok(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:166:15
+  --> $DIR/redundant_pattern_matching.rs:116:15
    |
 LL |     while let Err(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_err()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:168:15
-   |
-LL |     while let Some(_) = Some(42) {}
-   |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:170:15
-   |
-LL |     while let None = None::<()> {}
-   |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
-
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:172:5
+  --> $DIR/redundant_pattern_matching.rs:118:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -254,7 +142,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:177:5
+  --> $DIR/redundant_pattern_matching.rs:123:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -262,23 +150,5 @@ LL | |         Err(_) => true,
 LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 
-error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:182:5
-   |
-LL | /     match Some(42) {
-LL | |         Some(_) => true,
-LL | |         None => false,
-LL | |     };
-   | |_____^ help: try this: `Some(42).is_some()`
-
-error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:187:5
-   |
-LL | /     match None::<()> {
-LL | |         Some(_) => false,
-LL | |         None => true,
-LL | |     };
-   | |_____^ help: try this: `None::<()>.is_none()`
-
-error: aborting due to 41 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed
new file mode 100644
index 00000000000..499b975b2bb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed
@@ -0,0 +1,85 @@
+// run-rustfix
+
+#![warn(clippy::all)]
+#![warn(clippy::redundant_pattern_matching)]
+#![allow(
+    clippy::unit_arg,
+    unused_must_use,
+    clippy::needless_bool,
+    clippy::match_like_matches_macro,
+    deprecated
+)]
+
+fn main() {
+    if None::<()>.is_none() {}
+
+    if Some(42).is_some() {}
+
+    if Some(42).is_some() {
+        foo();
+    } else {
+        bar();
+    }
+
+    while Some(42).is_some() {}
+
+    while Some(42).is_none() {}
+
+    while None::<()>.is_none() {}
+
+    let mut v = vec![1, 2, 3];
+    while v.pop().is_some() {
+        foo();
+    }
+
+    if None::<i32>.is_none() {}
+
+    if Some(42).is_some() {}
+
+    Some(42).is_some();
+
+    None::<()>.is_none();
+
+    let _ = None::<()>.is_none();
+
+    let opt = Some(false);
+    let x = if opt.is_some() { true } else { false };
+    takes_bool(x);
+
+    issue6067();
+
+    let _ = if gen_opt().is_some() {
+        1
+    } else if gen_opt().is_none() {
+        2
+    } else {
+        3
+    };
+}
+
+fn gen_opt() -> Option<()> {
+    None
+}
+
+fn takes_bool(_: bool) {}
+
+fn foo() {}
+
+fn bar() {}
+
+// Methods that are unstable const should not be suggested within a const context, see issue #5697.
+// However, in Rust 1.48.0 the methods `is_some` and `is_none` of `Option` were stabilized as const,
+// so the following should be linted.
+const fn issue6067() {
+    if Some(42).is_some() {}
+
+    if None::<()>.is_none() {}
+
+    while Some(42).is_some() {}
+
+    while None::<()>.is_none() {}
+
+    Some(42).is_some();
+
+    None::<()>.is_none();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs
new file mode 100644
index 00000000000..2a98435e790
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs
@@ -0,0 +1,100 @@
+// run-rustfix
+
+#![warn(clippy::all)]
+#![warn(clippy::redundant_pattern_matching)]
+#![allow(
+    clippy::unit_arg,
+    unused_must_use,
+    clippy::needless_bool,
+    clippy::match_like_matches_macro,
+    deprecated
+)]
+
+fn main() {
+    if let None = None::<()> {}
+
+    if let Some(_) = Some(42) {}
+
+    if let Some(_) = Some(42) {
+        foo();
+    } else {
+        bar();
+    }
+
+    while let Some(_) = Some(42) {}
+
+    while let None = Some(42) {}
+
+    while let None = None::<()> {}
+
+    let mut v = vec![1, 2, 3];
+    while let Some(_) = v.pop() {
+        foo();
+    }
+
+    if None::<i32>.is_none() {}
+
+    if Some(42).is_some() {}
+
+    match Some(42) {
+        Some(_) => true,
+        None => false,
+    };
+
+    match None::<()> {
+        Some(_) => false,
+        None => true,
+    };
+
+    let _ = match None::<()> {
+        Some(_) => false,
+        None => true,
+    };
+
+    let opt = Some(false);
+    let x = if let Some(_) = opt { true } else { false };
+    takes_bool(x);
+
+    issue6067();
+
+    let _ = if let Some(_) = gen_opt() {
+        1
+    } else if let None = gen_opt() {
+        2
+    } else {
+        3
+    };
+}
+
+fn gen_opt() -> Option<()> {
+    None
+}
+
+fn takes_bool(_: bool) {}
+
+fn foo() {}
+
+fn bar() {}
+
+// Methods that are unstable const should not be suggested within a const context, see issue #5697.
+// However, in Rust 1.48.0 the methods `is_some` and `is_none` of `Option` were stabilized as const,
+// so the following should be linted.
+const fn issue6067() {
+    if let Some(_) = Some(42) {}
+
+    if let None = None::<()> {}
+
+    while let Some(_) = Some(42) {}
+
+    while let None = None::<()> {}
+
+    match Some(42) {
+        Some(_) => true,
+        None => false,
+    };
+
+    match None::<()> {
+        Some(_) => false,
+        None => true,
+    };
+}
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr
new file mode 100644
index 00000000000..eebb3448491
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr
@@ -0,0 +1,134 @@
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:14:12
+   |
+LL |     if let None = None::<()> {}
+   |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
+   |
+   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:16:12
+   |
+LL |     if let Some(_) = Some(42) {}
+   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:18:12
+   |
+LL |     if let Some(_) = Some(42) {
+   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:24:15
+   |
+LL |     while let Some(_) = Some(42) {}
+   |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:26:15
+   |
+LL |     while let None = Some(42) {}
+   |     ----------^^^^----------- help: try this: `while Some(42).is_none()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:28:15
+   |
+LL |     while let None = None::<()> {}
+   |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:31:15
+   |
+LL |     while let Some(_) = v.pop() {
+   |     ----------^^^^^^^---------- help: try this: `while v.pop().is_some()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:39:5
+   |
+LL | /     match Some(42) {
+LL | |         Some(_) => true,
+LL | |         None => false,
+LL | |     };
+   | |_____^ help: try this: `Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:44:5
+   |
+LL | /     match None::<()> {
+LL | |         Some(_) => false,
+LL | |         None => true,
+LL | |     };
+   | |_____^ help: try this: `None::<()>.is_none()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:49:13
+   |
+LL |       let _ = match None::<()> {
+   |  _____________^
+LL | |         Some(_) => false,
+LL | |         None => true,
+LL | |     };
+   | |_____^ help: try this: `None::<()>.is_none()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:55:20
+   |
+LL |     let x = if let Some(_) = opt { true } else { false };
+   |             -------^^^^^^^------ help: try this: `if opt.is_some()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:60:20
+   |
+LL |     let _ = if let Some(_) = gen_opt() {
+   |             -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:62:19
+   |
+LL |     } else if let None = gen_opt() {
+   |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:83:12
+   |
+LL |     if let Some(_) = Some(42) {}
+   |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:85:12
+   |
+LL |     if let None = None::<()> {}
+   |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:87:15
+   |
+LL |     while let Some(_) = Some(42) {}
+   |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:89:15
+   |
+LL |     while let None = None::<()> {}
+   |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
+
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:91:5
+   |
+LL | /     match Some(42) {
+LL | |         Some(_) => true,
+LL | |         None => false,
+LL | |     };
+   | |_____^ help: try this: `Some(42).is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:96:5
+   |
+LL | /     match None::<()> {
+LL | |         Some(_) => false,
+LL | |         None => true,
+LL | |     };
+   | |_____^ help: try this: `None::<()>.is_none()`
+
+error: aborting due to 19 previous errors
+
diff --git a/src/tools/clippy/tests/ui/trailing_zeros.rs b/src/tools/clippy/tests/ui/trailing_zeros.rs
index 1cef8c2cfc9..fbdc977b769 100644
--- a/src/tools/clippy/tests/ui/trailing_zeros.rs
+++ b/src/tools/clippy/tests/ui/trailing_zeros.rs
@@ -1,4 +1,5 @@
 #![allow(unused_parens)]
+#![warn(clippy::verbose_bit_mask)]
 
 fn main() {
     let x: i32 = 42;
diff --git a/src/tools/clippy/tests/ui/trailing_zeros.stderr b/src/tools/clippy/tests/ui/trailing_zeros.stderr
index 320d9cc3f64..79855111830 100644
--- a/src/tools/clippy/tests/ui/trailing_zeros.stderr
+++ b/src/tools/clippy/tests/ui/trailing_zeros.stderr
@@ -1,5 +1,5 @@
 error: bit mask could be simplified with a call to `trailing_zeros`
-  --> $DIR/trailing_zeros.rs:5:13
+  --> $DIR/trailing_zeros.rs:6:13
    |
 LL |     let _ = (x & 0b1111 == 0); // suggest trailing_zeros
    |             ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 4`
@@ -7,7 +7,7 @@ LL |     let _ = (x & 0b1111 == 0); // suggest trailing_zeros
    = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`
 
 error: bit mask could be simplified with a call to `trailing_zeros`
-  --> $DIR/trailing_zeros.rs:6:13
+  --> $DIR/trailing_zeros.rs:7:13
    |
 LL |     let _ = x & 0b1_1111 == 0; // suggest trailing_zeros
    |             ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 5`
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
index fa66e68794e..4ba2a0a5dbc 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
@@ -2,6 +2,7 @@
 #![warn(clippy::unnecessary_lazy_evaluations)]
 #![allow(clippy::redundant_closure)]
 #![allow(clippy::bind_instead_of_map)]
+#![allow(clippy::map_identity)]
 
 struct Deep(Option<usize>);
 
@@ -34,13 +35,13 @@ fn main() {
     let _ = opt.unwrap_or(2);
     let _ = opt.unwrap_or(astronomers_pi);
     let _ = opt.unwrap_or(ext_str.some_field);
-    let _ = opt.unwrap_or(ext_arr[0]);
+    let _ = opt.unwrap_or_else(|| ext_arr[0]);
     let _ = opt.and(ext_opt);
     let _ = opt.or(ext_opt);
     let _ = opt.or(None);
     let _ = opt.get_or_insert(2);
     let _ = opt.ok_or(2);
-    let _ = opt.ok_or(ext_arr[0]);
+    let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));
 
     // Cases when unwrap is not called on a simple variable
     let _ = Some(10).unwrap_or(2);
@@ -60,7 +61,6 @@ fn main() {
     // Should not lint - Option
     let _ = opt.unwrap_or_else(|| ext_str.return_some_field());
     let _ = nested_opt.unwrap_or_else(|| Some(some_call()));
-    let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
     let _ = nested_tuple_opt.unwrap_or_else(|| Some((some_call(), some_call())));
     let _ = opt.or_else(some_call);
     let _ = opt.or_else(|| some_call());
@@ -69,13 +69,16 @@ fn main() {
     let _ = deep.0.get_or_insert_with(|| some_call());
     let _ = deep.0.or_else(some_call);
     let _ = deep.0.or_else(|| some_call());
+    let _ = opt.ok_or_else(|| ext_arr[0]);
 
-    // These are handled by bind_instead_of_map
+    // should not lint, bind_instead_of_map takes priority
     let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
     let _ = Some(10).and_then(|idx| Some(idx));
-    let _: Option<usize> = None.or_else(|| Some(3));
-    let _ = deep.0.or_else(|| Some(3));
-    let _ = opt.or_else(|| Some(3));
+
+    // should lint, bind_instead_of_map doesn't apply
+    let _: Option<usize> = None.or(Some(3));
+    let _ = deep.0.or(Some(3));
+    let _ = opt.or(Some(3));
 
     // Should lint - Result
     let res: Result<usize, usize> = Err(5);
@@ -92,26 +95,28 @@ fn main() {
     let _ = res2.unwrap_or_else(|err| err.return_some_field());
     let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());
 
+    // should not lint, bind_instead_of_map takes priority
     let _: Result<usize, usize> = res.and_then(|x| Ok(x));
-    let _: Result<usize, usize> = res.and_then(|x| Err(x));
-
-    let _: Result<usize, usize> = res.or_else(|err| Ok(err));
     let _: Result<usize, usize> = res.or_else(|err| Err(err));
 
-    // These are handled by bind_instead_of_map
     let _: Result<usize, usize> = res.and_then(|_| Ok(2));
     let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));
     let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));
 
-    let _: Result<usize, usize> = res.and_then(|_| Err(2));
-    let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
-    let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
-
-    let _: Result<usize, usize> = res.or_else(|_| Ok(2));
-    let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
-    let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
-
     let _: Result<usize, usize> = res.or_else(|_| Err(2));
     let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));
     let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));
+
+    // should lint, bind_instead_of_map doesn't apply
+    let _: Result<usize, usize> = res.and(Err(2));
+    let _: Result<usize, usize> = res.and(Err(astronomers_pi));
+    let _: Result<usize, usize> = res.and(Err(ext_str.some_field));
+
+    let _: Result<usize, usize> = res.or(Ok(2));
+    let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
+    let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
+
+    // neither bind_instead_of_map nor unnecessary_lazy_eval applies here
+    let _: Result<usize, usize> = res.and_then(|x| Err(x));
+    let _: Result<usize, usize> = res.or_else(|err| Ok(err));
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
index 04f47d1aa29..466915217e4 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
@@ -2,6 +2,7 @@
 #![warn(clippy::unnecessary_lazy_evaluations)]
 #![allow(clippy::redundant_closure)]
 #![allow(clippy::bind_instead_of_map)]
+#![allow(clippy::map_identity)]
 
 struct Deep(Option<usize>);
 
@@ -40,7 +41,7 @@ fn main() {
     let _ = opt.or_else(|| None);
     let _ = opt.get_or_insert_with(|| 2);
     let _ = opt.ok_or_else(|| 2);
-    let _ = opt.ok_or_else(|| ext_arr[0]);
+    let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
 
     // Cases when unwrap is not called on a simple variable
     let _ = Some(10).unwrap_or_else(|| 2);
@@ -60,7 +61,6 @@ fn main() {
     // Should not lint - Option
     let _ = opt.unwrap_or_else(|| ext_str.return_some_field());
     let _ = nested_opt.unwrap_or_else(|| Some(some_call()));
-    let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
     let _ = nested_tuple_opt.unwrap_or_else(|| Some((some_call(), some_call())));
     let _ = opt.or_else(some_call);
     let _ = opt.or_else(|| some_call());
@@ -69,10 +69,13 @@ fn main() {
     let _ = deep.0.get_or_insert_with(|| some_call());
     let _ = deep.0.or_else(some_call);
     let _ = deep.0.or_else(|| some_call());
+    let _ = opt.ok_or_else(|| ext_arr[0]);
 
-    // These are handled by bind_instead_of_map
+    // should not lint, bind_instead_of_map takes priority
     let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
     let _ = Some(10).and_then(|idx| Some(idx));
+
+    // should lint, bind_instead_of_map doesn't apply
     let _: Option<usize> = None.or_else(|| Some(3));
     let _ = deep.0.or_else(|| Some(3));
     let _ = opt.or_else(|| Some(3));
@@ -92,17 +95,19 @@ fn main() {
     let _ = res2.unwrap_or_else(|err| err.return_some_field());
     let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());
 
+    // should not lint, bind_instead_of_map takes priority
     let _: Result<usize, usize> = res.and_then(|x| Ok(x));
-    let _: Result<usize, usize> = res.and_then(|x| Err(x));
-
-    let _: Result<usize, usize> = res.or_else(|err| Ok(err));
     let _: Result<usize, usize> = res.or_else(|err| Err(err));
 
-    // These are handled by bind_instead_of_map
     let _: Result<usize, usize> = res.and_then(|_| Ok(2));
     let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));
     let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));
 
+    let _: Result<usize, usize> = res.or_else(|_| Err(2));
+    let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));
+    let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));
+
+    // should lint, bind_instead_of_map doesn't apply
     let _: Result<usize, usize> = res.and_then(|_| Err(2));
     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
@@ -111,7 +116,7 @@ fn main() {
     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
 
-    let _: Result<usize, usize> = res.or_else(|_| Err(2));
-    let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));
-    let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));
+    // neither bind_instead_of_map nor unnecessary_lazy_eval applies here
+    let _: Result<usize, usize> = res.and_then(|x| Err(x));
+    let _: Result<usize, usize> = res.or_else(|err| Ok(err));
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index 5c1b2eb1f14..44dcd0cafbb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -1,5 +1,5 @@
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:34:13
+  --> $DIR/unnecessary_lazy_eval.rs:35:13
    |
 LL |     let _ = opt.unwrap_or_else(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(2)`
@@ -7,142 +7,190 @@ LL |     let _ = opt.unwrap_or_else(|| 2);
    = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:35:13
+  --> $DIR/unnecessary_lazy_eval.rs:36:13
    |
 LL |     let _ = opt.unwrap_or_else(|| astronomers_pi);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(astronomers_pi)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:36:13
+  --> $DIR/unnecessary_lazy_eval.rs:37:13
    |
 LL |     let _ = opt.unwrap_or_else(|| ext_str.some_field);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(ext_str.some_field)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:37:13
-   |
-LL |     let _ = opt.unwrap_or_else(|| ext_arr[0]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `opt.unwrap_or(ext_arr[0])`
-
-error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:38:13
+  --> $DIR/unnecessary_lazy_eval.rs:39:13
    |
 LL |     let _ = opt.and_then(|_| ext_opt);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `opt.and(ext_opt)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:39:13
+  --> $DIR/unnecessary_lazy_eval.rs:40:13
    |
 LL |     let _ = opt.or_else(|| ext_opt);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(ext_opt)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:40:13
+  --> $DIR/unnecessary_lazy_eval.rs:41:13
    |
 LL |     let _ = opt.or_else(|| None);
    |             ^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(None)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:41:13
+  --> $DIR/unnecessary_lazy_eval.rs:42:13
    |
 LL |     let _ = opt.get_or_insert_with(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `opt.get_or_insert(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:42:13
+  --> $DIR/unnecessary_lazy_eval.rs:43:13
    |
 LL |     let _ = opt.ok_or_else(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `opt.ok_or(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:43:13
+  --> $DIR/unnecessary_lazy_eval.rs:44:13
    |
-LL |     let _ = opt.ok_or_else(|| ext_arr[0]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `opt.ok_or(ext_arr[0])`
+LL |     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `nested_tuple_opt.unwrap_or(Some((1, 2)))`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:46:13
+  --> $DIR/unnecessary_lazy_eval.rs:47:13
    |
 LL |     let _ = Some(10).unwrap_or_else(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `Some(10).unwrap_or(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:47:13
+  --> $DIR/unnecessary_lazy_eval.rs:48:13
    |
 LL |     let _ = Some(10).and_then(|_| ext_opt);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `Some(10).and(ext_opt)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:48:28
+  --> $DIR/unnecessary_lazy_eval.rs:49:28
    |
 LL |     let _: Option<usize> = None.or_else(|| ext_opt);
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(ext_opt)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:49:13
+  --> $DIR/unnecessary_lazy_eval.rs:50:13
    |
 LL |     let _ = None.get_or_insert_with(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `None.get_or_insert(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:50:35
+  --> $DIR/unnecessary_lazy_eval.rs:51:35
    |
 LL |     let _: Result<usize, usize> = None.ok_or_else(|| 2);
    |                                   ^^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `None.ok_or(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:51:28
+  --> $DIR/unnecessary_lazy_eval.rs:52:28
    |
 LL |     let _: Option<usize> = None.or_else(|| None);
    |                            ^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(None)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:54:13
+  --> $DIR/unnecessary_lazy_eval.rs:55:13
    |
 LL |     let _ = deep.0.unwrap_or_else(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `deep.0.unwrap_or(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:55:13
+  --> $DIR/unnecessary_lazy_eval.rs:56:13
    |
 LL |     let _ = deep.0.and_then(|_| ext_opt);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `deep.0.and(ext_opt)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:56:13
+  --> $DIR/unnecessary_lazy_eval.rs:57:13
    |
 LL |     let _ = deep.0.or_else(|| None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `deep.0.or(None)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:57:13
+  --> $DIR/unnecessary_lazy_eval.rs:58:13
    |
 LL |     let _ = deep.0.get_or_insert_with(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `get_or_insert` instead: `deep.0.get_or_insert(2)`
 
 error: unnecessary closure used to substitute value for `Option::None`
-  --> $DIR/unnecessary_lazy_eval.rs:58:13
+  --> $DIR/unnecessary_lazy_eval.rs:59:13
    |
 LL |     let _ = deep.0.ok_or_else(|| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `ok_or` instead: `deep.0.ok_or(2)`
 
+error: unnecessary closure used to substitute value for `Option::None`
+  --> $DIR/unnecessary_lazy_eval.rs:79:28
+   |
+LL |     let _: Option<usize> = None.or_else(|| Some(3));
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `None.or(Some(3))`
+
+error: unnecessary closure used to substitute value for `Option::None`
+  --> $DIR/unnecessary_lazy_eval.rs:80:13
+   |
+LL |     let _ = deep.0.or_else(|| Some(3));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `deep.0.or(Some(3))`
+
+error: unnecessary closure used to substitute value for `Option::None`
+  --> $DIR/unnecessary_lazy_eval.rs:81:13
+   |
+LL |     let _ = opt.or_else(|| Some(3));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `opt.or(Some(3))`
+
 error: unnecessary closure used to substitute value for `Result::Err`
-  --> $DIR/unnecessary_lazy_eval.rs:84:13
+  --> $DIR/unnecessary_lazy_eval.rs:87:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| 2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(2)`
 
 error: unnecessary closure used to substitute value for `Result::Err`
-  --> $DIR/unnecessary_lazy_eval.rs:85:13
+  --> $DIR/unnecessary_lazy_eval.rs:88:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| astronomers_pi);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(astronomers_pi)`
 
 error: unnecessary closure used to substitute value for `Result::Err`
-  --> $DIR/unnecessary_lazy_eval.rs:86:13
+  --> $DIR/unnecessary_lazy_eval.rs:89:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| ext_str.some_field);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `unwrap_or` instead: `res2.unwrap_or(ext_str.some_field)`
 
-error: aborting due to 24 previous errors
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:111:35
+   |
+LL |     let _: Result<usize, usize> = res.and_then(|_| Err(2));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(2))`
+
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:112:35
+   |
+LL |     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(astronomers_pi))`
+
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:113:35
+   |
+LL |     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `and` instead: `res.and(Err(ext_str.some_field))`
+
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:115:35
+   |
+LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(2));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(2))`
+
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:116:35
+   |
+LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(astronomers_pi))`
+
+error: unnecessary closure used to substitute value for `Result::Err`
+  --> $DIR/unnecessary_lazy_eval.rs:117:35
+   |
+LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Use `or` instead: `res.or(Ok(ext_str.some_field))`
+
+error: aborting due to 32 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index f1e880d2696..11c6efb25cc 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -1,4 +1,4 @@
-error: useless conversion to the same type
+error: useless conversion to the same type: `T`
   --> $DIR/useless_conversion.rs:6:13
    |
 LL |     let _ = T::from(val);
@@ -10,61 +10,61 @@ note: the lint level is defined here
 LL | #![deny(clippy::useless_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `T`
   --> $DIR/useless_conversion.rs:7:5
    |
 LL |     val.into()
    |     ^^^^^^^^^^ help: consider removing `.into()`: `val`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `i32`
   --> $DIR/useless_conversion.rs:19:22
    |
 LL |         let _: i32 = 0i32.into();
    |                      ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion.rs:60:21
    |
 LL |     let _: String = "foo".to_string().into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion.rs:61:21
    |
 LL |     let _: String = From::from("foo".to_string());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion.rs:62:13
    |
 LL |     let _ = String::from("foo".to_string());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion.rs:63:13
    |
 LL |     let _ = String::from(format!("A: {:04}", 123));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::str::Lines`
   --> $DIR/useless_conversion.rs:64:13
    |
 LL |     let _ = "".lines().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::vec::IntoIter<i32>`
   --> $DIR/useless_conversion.rs:65:13
    |
 LL |     let _ = vec![1, 2, 3].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion.rs:66:21
    |
 LL |     let _: String = format!("Hello {}", "world").into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `i32`
   --> $DIR/useless_conversion.rs:71:13
    |
 LL |     let _ = i32::from(a + b) * 3;
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
index b765727c168..2e0d9129bfb 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
@@ -1,4 +1,4 @@
-error: useless conversion to the same type
+error: useless conversion to the same type: `T`
   --> $DIR/useless_conversion_try.rs:6:13
    |
 LL |     let _ = T::try_from(val).unwrap();
@@ -11,7 +11,7 @@ LL | #![deny(clippy::useless_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: consider removing `T::try_from()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `T`
   --> $DIR/useless_conversion_try.rs:7:5
    |
 LL |     val.try_into().unwrap()
@@ -19,7 +19,7 @@ LL |     val.try_into().unwrap()
    |
    = help: consider removing `.try_into()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:29:21
    |
 LL |     let _: String = "foo".to_string().try_into().unwrap();
@@ -27,7 +27,7 @@ LL |     let _: String = "foo".to_string().try_into().unwrap();
    |
    = help: consider removing `.try_into()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:30:21
    |
 LL |     let _: String = TryFrom::try_from("foo".to_string()).unwrap();
@@ -35,7 +35,7 @@ LL |     let _: String = TryFrom::try_from("foo".to_string()).unwrap();
    |
    = help: consider removing `TryFrom::try_from()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:31:13
    |
 LL |     let _ = String::try_from("foo".to_string()).unwrap();
@@ -43,7 +43,7 @@ LL |     let _ = String::try_from("foo".to_string()).unwrap();
    |
    = help: consider removing `String::try_from()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:32:13
    |
 LL |     let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
@@ -51,7 +51,7 @@ LL |     let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
    |
    = help: consider removing `String::try_from()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:33:21
    |
 LL |     let _: String = format!("Hello {}", "world").try_into().unwrap();
@@ -59,7 +59,7 @@ LL |     let _: String = format!("Hello {}", "world").try_into().unwrap();
    |
    = help: consider removing `.try_into()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:34:21
    |
 LL |     let _: String = "".to_owned().try_into().unwrap();
@@ -67,7 +67,7 @@ LL |     let _: String = "".to_owned().try_into().unwrap();
    |
    = help: consider removing `.try_into()`
 
-error: useless conversion to the same type
+error: useless conversion to the same type: `std::string::String`
   --> $DIR/useless_conversion_try.rs:35:27
    |
 LL |     let _: String = match String::from("_").try_into() {
diff --git a/src/tools/clippy/tests/ui/write_with_newline.rs b/src/tools/clippy/tests/ui/write_with_newline.rs
index 93afd73d111..1c1b1b58402 100644
--- a/src/tools/clippy/tests/ui/write_with_newline.rs
+++ b/src/tools/clippy/tests/ui/write_with_newline.rs
@@ -14,6 +14,7 @@ fn main() {
     write!(&mut v, "Hello {}\n", "world");
     write!(&mut v, "Hello {} {}\n", "world", "#2");
     write!(&mut v, "{}\n", 1265);
+    write!(&mut v, "\n");
 
     // These should be fine
     write!(&mut v, "");
diff --git a/src/tools/clippy/tests/ui/write_with_newline.stderr b/src/tools/clippy/tests/ui/write_with_newline.stderr
index 2473329ca72..a14e86122ee 100644
--- a/src/tools/clippy/tests/ui/write_with_newline.stderr
+++ b/src/tools/clippy/tests/ui/write_with_newline.stderr
@@ -44,7 +44,18 @@ LL |     writeln!(&mut v, "{}", 1265);
    |     ^^^^^^^            --
 
 error: using `write!()` with a format string that ends in a single newline
-  --> $DIR/write_with_newline.rs:35:5
+  --> $DIR/write_with_newline.rs:17:5
+   |
+LL |     write!(&mut v, "/n");
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `writeln!()` instead
+   |
+LL |     writeln!(&mut v, );
+   |     ^^^^^^^         --
+
+error: using `write!()` with a format string that ends in a single newline
+  --> $DIR/write_with_newline.rs:36:5
    |
 LL |     write!(&mut v, "//n"); // should fail
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +66,7 @@ LL |     writeln!(&mut v, "/"); // should fail
    |     ^^^^^^^            --
 
 error: using `write!()` with a format string that ends in a single newline
-  --> $DIR/write_with_newline.rs:42:5
+  --> $DIR/write_with_newline.rs:43:5
    |
 LL | /     write!(
 LL | |         &mut v,
@@ -72,7 +83,7 @@ LL |         ""
    |
 
 error: using `write!()` with a format string that ends in a single newline
-  --> $DIR/write_with_newline.rs:47:5
+  --> $DIR/write_with_newline.rs:48:5
    |
 LL | /     write!(
 LL | |         &mut v,
@@ -89,7 +100,7 @@ LL |         r""
    |
 
 error: using `write!()` with a format string that ends in a single newline
-  --> $DIR/write_with_newline.rs:56:5
+  --> $DIR/write_with_newline.rs:57:5
    |
 LL |     write!(&mut v, "/r/n"); //~ ERROR
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +111,7 @@ LL |     writeln!(&mut v, "/r"); //~ ERROR
    |     ^^^^^^^             --
 
 error: using `write!()` with a format string that ends in a single newline
-  --> $DIR/write_with_newline.rs:57:5
+  --> $DIR/write_with_newline.rs:58:5
    |
 LL |     write!(&mut v, "foo/rbar/n");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,5 +121,5 @@ help: use `writeln!()` instead
 LL |     writeln!(&mut v, "foo/rbar");
    |     ^^^^^^^                  --
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors