diff --git a/tests/compile-test.rs b/tests/compile-test.rs
index 18099c45fee..3b599351016 100644
--- a/tests/compile-test.rs
+++ b/tests/compile-test.rs
@@ -1,5 +1,6 @@
 #![feature(test)] // compiletest_rs requires this attribute
 #![feature(once_cell)]
+#![feature(is_sorted)]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
@@ -166,7 +167,8 @@ fn base_config(test_dir: &str) -> compiletest::Config {
 }
 
 fn run_ui() {
-    let config = base_config("ui");
+    let mut config = base_config("ui");
+    config.rustfix_coverage = true;
     // use tests/clippy.toml
     let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
     let _threads = VarGuard::set(
@@ -179,6 +181,7 @@ fn run_ui() {
         }),
     );
     compiletest::run_tests(&config);
+    check_rustfix_coverage();
 }
 
 fn run_internal_tests() {
@@ -341,6 +344,87 @@ fn compile_test() {
     run_internal_tests();
 }
 
+const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
+    "assign_ops2.rs",
+    "cast_size_32bit.rs",
+    "char_lit_as_u8.rs",
+    "cmp_owned/without_suggestion.rs",
+    "dbg_macro.rs",
+    "deref_addrof_double_trigger.rs",
+    "doc/unbalanced_ticks.rs",
+    "eprint_with_newline.rs",
+    "explicit_counter_loop.rs",
+    "iter_skip_next_unfixable.rs",
+    "let_and_return.rs",
+    "literals.rs",
+    "map_flatten.rs",
+    "map_unwrap_or.rs",
+    "match_bool.rs",
+    "mem_replace_macro.rs",
+    "needless_arbitrary_self_type_unfixable.rs",
+    "needless_borrow_pat.rs",
+    "needless_for_each_unfixable.rs",
+    "nonminimal_bool.rs",
+    "print_literal.rs",
+    "print_with_newline.rs",
+    "redundant_static_lifetimes_multiple.rs",
+    "ref_binding_to_reference.rs",
+    "repl_uninit.rs",
+    "result_map_unit_fn_unfixable.rs",
+    "search_is_some.rs",
+    "single_component_path_imports_nested_first.rs",
+    "string_add.rs",
+    "toplevel_ref_arg_non_rustfix.rs",
+    "unit_arg.rs",
+    "unnecessary_clone.rs",
+    "unnecessary_lazy_eval_unfixable.rs",
+    "write_literal.rs",
+    "write_literal_2.rs",
+    "write_with_newline.rs",
+];
+
+fn check_rustfix_coverage() {
+    let missing_coverage_path = Path::new("target/debug/test/ui/rustfix_missing_coverage.txt");
+
+    if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
+        assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));
+
+        for rs_path in missing_coverage_contents.lines() {
+            if Path::new(rs_path).starts_with("tests/ui/crashes") {
+                continue;
+            }
+            let filename = Path::new(rs_path).strip_prefix("tests/ui/").unwrap();
+            assert!(
+                RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
+                    .binary_search_by_key(&filename, Path::new)
+                    .is_ok(),
+                "`{}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
+                Please either add `// run-rustfix` at the top of the file or add the file to \
+                `RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
+                rs_path,
+            );
+        }
+    }
+}
+
+#[test]
+fn rustfix_coverage_known_exceptions_accuracy() {
+    for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
+        let rs_path = Path::new("tests/ui").join(filename);
+        assert!(
+            rs_path.exists(),
+            "`{}` does not exists",
+            rs_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
+        );
+        let fixed_path = rs_path.with_extension("fixed");
+        assert!(
+            !fixed_path.exists(),
+            "`{}` exists",
+            fixed_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
+        );
+    }
+}
+
 /// Restores an env var on drop
 #[must_use]
 struct VarGuard {
diff --git a/tests/ui/bind_instead_of_map_multipart.fixed b/tests/ui/bind_instead_of_map_multipart.fixed
new file mode 100644
index 00000000000..e1589843226
--- /dev/null
+++ b/tests/ui/bind_instead_of_map_multipart.fixed
@@ -0,0 +1,62 @@
+// run-rustfix
+#![deny(clippy::bind_instead_of_map)]
+#![allow(clippy::blocks_in_if_conditions)]
+
+pub fn main() {
+    let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
+    let _ = Some("42").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) });
+
+    let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
+    let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) });
+
+    let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });
+    let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) });
+
+    hard_example();
+    macro_example();
+}
+
+fn hard_example() {
+    Some("42").map(|s| {
+        if {
+            if s == "43" {
+                return 43;
+            }
+            s == "42"
+        } {
+            return 45;
+        }
+        match s.len() {
+            10 => 2,
+            20 => {
+                if foo() {
+                    return {
+                        if foo() {
+                            return 20;
+                        }
+                        println!("foo");
+                        3
+                    };
+                }
+                20
+            },
+            40 => 30,
+            _ => 1,
+        }
+    });
+}
+
+fn foo() -> bool {
+    true
+}
+
+macro_rules! m {
+    () => {
+        Some(10)
+    };
+}
+
+fn macro_example() {
+    let _ = Some("").and_then(|s| if s.len() == 20 { m!() } else { Some(20) });
+    let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) });
+}
diff --git a/tests/ui/bind_instead_of_map_multipart.rs b/tests/ui/bind_instead_of_map_multipart.rs
index 91d9d11e3c1..49944403f6d 100644
--- a/tests/ui/bind_instead_of_map_multipart.rs
+++ b/tests/ui/bind_instead_of_map_multipart.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 #![deny(clippy::bind_instead_of_map)]
 #![allow(clippy::blocks_in_if_conditions)]
 
diff --git a/tests/ui/bind_instead_of_map_multipart.stderr b/tests/ui/bind_instead_of_map_multipart.stderr
index e4f605a4de3..f822b6f49fa 100644
--- a/tests/ui/bind_instead_of_map_multipart.stderr
+++ b/tests/ui/bind_instead_of_map_multipart.stderr
@@ -1,11 +1,11 @@
 error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
-  --> $DIR/bind_instead_of_map_multipart.rs:5:13
+  --> $DIR/bind_instead_of_map_multipart.rs:6:13
    |
 LL |     let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/bind_instead_of_map_multipart.rs:1:9
+  --> $DIR/bind_instead_of_map_multipart.rs:2:9
    |
 LL | #![deny(clippy::bind_instead_of_map)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |     let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
    |                        ~~~                       ~          ~~~~~~~
 
 error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`
-  --> $DIR/bind_instead_of_map_multipart.rs:8:13
+  --> $DIR/bind_instead_of_map_multipart.rs:9:13
    |
 LL |     let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len()
    |                               ~~~                       ~          ~~~~~~~
 
 error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`
-  --> $DIR/bind_instead_of_map_multipart.rs:11:13
+  --> $DIR/bind_instead_of_map_multipart.rs:12:13
    |
 LL |     let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL |     let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 }
    |                                ~~~~~~~                       ~~~~~~~~~~~~          ~~~~~~~
 
 error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
-  --> $DIR/bind_instead_of_map_multipart.rs:19:5
+  --> $DIR/bind_instead_of_map_multipart.rs:20:5
    |
 LL | /     Some("42").and_then(|s| {
 LL | |         if {
@@ -59,7 +59,7 @@ LL |             s == "42"
  ...
 
 error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
-  --> $DIR/bind_instead_of_map_multipart.rs:60:13
+  --> $DIR/bind_instead_of_map_multipart.rs:61:13
    |
 LL |     let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/implicit_clone.fixed b/tests/ui/implicit_clone.fixed
new file mode 100644
index 00000000000..33770fc2a2c
--- /dev/null
+++ b/tests/ui/implicit_clone.fixed
@@ -0,0 +1,118 @@
+// run-rustfix
+#![warn(clippy::implicit_clone)]
+#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
+use std::borrow::Borrow;
+use std::ffi::{OsStr, OsString};
+use std::path::PathBuf;
+
+fn return_owned_from_slice(slice: &[u32]) -> Vec<u32> {
+    slice.to_owned()
+}
+
+pub fn own_same<T>(v: T) -> T
+where
+    T: ToOwned<Owned = T>,
+{
+    v.to_owned()
+}
+
+pub fn own_same_from_ref<T>(v: &T) -> T
+where
+    T: ToOwned<Owned = T>,
+{
+    v.to_owned()
+}
+
+pub fn own_different<T, U>(v: T) -> U
+where
+    T: ToOwned<Owned = U>,
+{
+    v.to_owned()
+}
+
+#[derive(Copy, Clone)]
+struct Kitten;
+impl Kitten {
+    // badly named method
+    fn to_vec(self) -> Kitten {
+        Kitten {}
+    }
+}
+impl Borrow<BorrowedKitten> for Kitten {
+    fn borrow(&self) -> &BorrowedKitten {
+        static VALUE: BorrowedKitten = BorrowedKitten {};
+        &VALUE
+    }
+}
+
+struct BorrowedKitten;
+impl ToOwned for BorrowedKitten {
+    type Owned = Kitten;
+    fn to_owned(&self) -> Kitten {
+        Kitten {}
+    }
+}
+
+mod weird {
+    #[allow(clippy::ptr_arg)]
+    pub fn to_vec(v: &Vec<u32>) -> Vec<u32> {
+        v.clone()
+    }
+}
+
+fn main() {
+    let vec = vec![5];
+    let _ = return_owned_from_slice(&vec);
+    let _ = vec.clone();
+    let _ = vec.clone();
+
+    let vec_ref = &vec;
+    let _ = return_owned_from_slice(vec_ref);
+    let _ = vec_ref.clone();
+    let _ = vec_ref.clone();
+
+    // we expect no lint for this
+    let _ = weird::to_vec(&vec);
+
+    // we expect no lints for this
+    let slice: &[u32] = &[1, 2, 3, 4, 5];
+    let _ = return_owned_from_slice(slice);
+    let _ = slice.to_owned();
+    let _ = slice.to_vec();
+
+    let str = "hello world".to_string();
+    let _ = str.clone();
+
+    // testing w/ an arbitrary type
+    let kitten = Kitten {};
+    let _ = kitten.clone();
+    let _ = own_same_from_ref(&kitten);
+    // this shouln't lint
+    let _ = kitten.to_vec();
+
+    // we expect no lints for this
+    let borrowed = BorrowedKitten {};
+    let _ = borrowed.to_owned();
+
+    let pathbuf = PathBuf::new();
+    let _ = pathbuf.clone();
+    let _ = pathbuf.clone();
+
+    let os_string = OsString::from("foo");
+    let _ = os_string.clone();
+    let _ = os_string.clone();
+
+    // we expect no lints for this
+    let os_str = OsStr::new("foo");
+    let _ = os_str.to_owned();
+    let _ = os_str.to_os_string();
+
+    // issue #8227
+    let pathbuf_ref = &pathbuf;
+    let pathbuf_ref = &pathbuf_ref;
+    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf`
+    let _ = (*pathbuf_ref).clone();
+    let pathbuf_ref = &pathbuf_ref;
+    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf`
+    let _ = (**pathbuf_ref).clone();
+}
diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs
index 2549c9f32f9..fc896525bd2 100644
--- a/tests/ui/implicit_clone.rs
+++ b/tests/ui/implicit_clone.rs
@@ -1,5 +1,6 @@
+// run-rustfix
 #![warn(clippy::implicit_clone)]
-#![allow(clippy::redundant_clone)]
+#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
 use std::borrow::Borrow;
 use std::ffi::{OsStr, OsString};
 use std::path::PathBuf;
diff --git a/tests/ui/implicit_clone.stderr b/tests/ui/implicit_clone.stderr
index 0f412424190..92c1aa58aff 100644
--- a/tests/ui/implicit_clone.stderr
+++ b/tests/ui/implicit_clone.stderr
@@ -1,5 +1,5 @@
 error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:65:13
+  --> $DIR/implicit_clone.rs:66:13
    |
 LL |     let _ = vec.to_owned();
    |             ^^^^^^^^^^^^^^ help: consider using: `vec.clone()`
@@ -7,67 +7,67 @@ LL |     let _ = vec.to_owned();
    = note: `-D clippy::implicit-clone` implied by `-D warnings`
 
 error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
-  --> $DIR/implicit_clone.rs:66:13
+  --> $DIR/implicit_clone.rs:67:13
    |
 LL |     let _ = vec.to_vec();
    |             ^^^^^^^^^^^^ help: consider using: `vec.clone()`
 
 error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:70:13
+  --> $DIR/implicit_clone.rs:71:13
    |
 LL |     let _ = vec_ref.to_owned();
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
 
 error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
-  --> $DIR/implicit_clone.rs:71:13
+  --> $DIR/implicit_clone.rs:72:13
    |
 LL |     let _ = vec_ref.to_vec();
    |             ^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
 
 error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:83:13
+  --> $DIR/implicit_clone.rs:84:13
    |
 LL |     let _ = str.to_owned();
    |             ^^^^^^^^^^^^^^ help: consider using: `str.clone()`
 
 error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:87:13
+  --> $DIR/implicit_clone.rs:88:13
    |
 LL |     let _ = kitten.to_owned();
    |             ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()`
 
 error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:97:13
+  --> $DIR/implicit_clone.rs:98:13
    |
 LL |     let _ = pathbuf.to_owned();
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
 
 error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
-  --> $DIR/implicit_clone.rs:98:13
+  --> $DIR/implicit_clone.rs:99:13
    |
 LL |     let _ = pathbuf.to_path_buf();
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
 
 error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type
-  --> $DIR/implicit_clone.rs:101:13
+  --> $DIR/implicit_clone.rs:102:13
    |
 LL |     let _ = os_string.to_owned();
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
 
 error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type
-  --> $DIR/implicit_clone.rs:102:13
+  --> $DIR/implicit_clone.rs:103:13
    |
 LL |     let _ = os_string.to_os_string();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
 
 error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
-  --> $DIR/implicit_clone.rs:113:13
+  --> $DIR/implicit_clone.rs:114:13
    |
 LL |     let _ = pathbuf_ref.to_path_buf();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()`
 
 error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
-  --> $DIR/implicit_clone.rs:116:13
+  --> $DIR/implicit_clone.rs:117:13
    |
 LL |     let _ = pathbuf_ref.to_path_buf();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`
diff --git a/tests/ui/issue_2356.fixed b/tests/ui/issue_2356.fixed
new file mode 100644
index 00000000000..942e99fa878
--- /dev/null
+++ b/tests/ui/issue_2356.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+#![deny(clippy::while_let_on_iterator)]
+#![allow(unused_mut)]
+
+use std::iter::Iterator;
+
+struct Foo;
+
+impl Foo {
+    fn foo1<I: Iterator<Item = usize>>(mut it: I) {
+        while let Some(_) = it.next() {
+            println!("{:?}", it.size_hint());
+        }
+    }
+
+    fn foo2<I: Iterator<Item = usize>>(mut it: I) {
+        for e in it {
+            println!("{:?}", e);
+        }
+    }
+}
+
+fn main() {
+    Foo::foo1(vec![].into_iter());
+    Foo::foo2(vec![].into_iter());
+}
diff --git a/tests/ui/issue_2356.rs b/tests/ui/issue_2356.rs
index da580a1839a..b000234ea59 100644
--- a/tests/ui/issue_2356.rs
+++ b/tests/ui/issue_2356.rs
@@ -1,4 +1,6 @@
+// run-rustfix
 #![deny(clippy::while_let_on_iterator)]
+#![allow(unused_mut)]
 
 use std::iter::Iterator;
 
diff --git a/tests/ui/issue_2356.stderr b/tests/ui/issue_2356.stderr
index 51b872e21c0..4e3ff7522e0 100644
--- a/tests/ui/issue_2356.stderr
+++ b/tests/ui/issue_2356.stderr
@@ -1,11 +1,11 @@
 error: this loop could be written as a `for` loop
-  --> $DIR/issue_2356.rs:15:9
+  --> $DIR/issue_2356.rs:17:9
    |
 LL |         while let Some(e) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for e in it`
    |
 note: the lint level is defined here
-  --> $DIR/issue_2356.rs:1:9
+  --> $DIR/issue_2356.rs:2:9
    |
 LL | #![deny(clippy::while_let_on_iterator)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/match_ref_pats.fixed b/tests/ui/match_ref_pats.fixed
new file mode 100644
index 00000000000..1b6c2d92412
--- /dev/null
+++ b/tests/ui/match_ref_pats.fixed
@@ -0,0 +1,118 @@
+// run-rustfix
+#![warn(clippy::match_ref_pats)]
+#![allow(dead_code, unused_variables, clippy::equatable_if_let, clippy::enum_variant_names)]
+
+fn ref_pats() {
+    {
+        let v = &Some(0);
+        match *v {
+            Some(v) => println!("{:?}", v),
+            None => println!("none"),
+        }
+        match v {
+            // This doesn't trigger; we have a different pattern.
+            &Some(v) => println!("some"),
+            other => println!("other"),
+        }
+    }
+    let tup = &(1, 2);
+    match tup {
+        &(v, 1) => println!("{}", v),
+        _ => println!("none"),
+    }
+    // Special case: using `&` both in expr and pats.
+    let w = Some(0);
+    match w {
+        Some(v) => println!("{:?}", v),
+        None => println!("none"),
+    }
+    // False positive: only wildcard pattern.
+    let w = Some(0);
+    #[allow(clippy::match_single_binding)]
+    match w {
+        _ => println!("none"),
+    }
+
+    let a = &Some(0);
+    if a.is_none() {
+        println!("none");
+    }
+
+    let b = Some(0);
+    if b.is_none() {
+        println!("none");
+    }
+}
+
+mod ice_3719 {
+    macro_rules! foo_variant(
+        ($idx:expr) => (Foo::get($idx).unwrap())
+    );
+
+    enum Foo {
+        A,
+        B,
+    }
+
+    impl Foo {
+        fn get(idx: u8) -> Option<&'static Self> {
+            match idx {
+                0 => Some(&Foo::A),
+                1 => Some(&Foo::B),
+                _ => None,
+            }
+        }
+    }
+
+    fn ice_3719() {
+        // ICE #3719
+        match foo_variant!(0) {
+            &Foo::A => println!("A"),
+            _ => println!("Wild"),
+        }
+    }
+}
+
+mod issue_7740 {
+    macro_rules! foobar_variant(
+        ($idx:expr) => (FooBar::get($idx).unwrap())
+    );
+
+    enum FooBar {
+        Foo,
+        Bar,
+        FooBar,
+        BarFoo,
+    }
+
+    impl FooBar {
+        fn get(idx: u8) -> Option<&'static Self> {
+            match idx {
+                0 => Some(&FooBar::Foo),
+                1 => Some(&FooBar::Bar),
+                2 => Some(&FooBar::FooBar),
+                3 => Some(&FooBar::BarFoo),
+                _ => None,
+            }
+        }
+    }
+
+    fn issue_7740() {
+        // Issue #7740
+        match *foobar_variant!(0) {
+            FooBar::Foo => println!("Foo"),
+            FooBar::Bar => println!("Bar"),
+            FooBar::FooBar => println!("FooBar"),
+            _ => println!("Wild"),
+        }
+
+        // This shouldn't trigger
+        if let &FooBar::BarFoo = foobar_variant!(3) {
+            println!("BarFoo");
+        } else {
+            println!("Wild");
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/match_ref_pats.rs b/tests/ui/match_ref_pats.rs
index 7e3674ab8c9..68dfac4e2e9 100644
--- a/tests/ui/match_ref_pats.rs
+++ b/tests/ui/match_ref_pats.rs
@@ -1,5 +1,6 @@
+// run-rustfix
 #![warn(clippy::match_ref_pats)]
-#![allow(clippy::equatable_if_let, clippy::enum_variant_names)]
+#![allow(dead_code, unused_variables, clippy::equatable_if_let, clippy::enum_variant_names)]
 
 fn ref_pats() {
     {
diff --git a/tests/ui/match_ref_pats.stderr b/tests/ui/match_ref_pats.stderr
index 901820077e2..353f7399d9c 100644
--- a/tests/ui/match_ref_pats.stderr
+++ b/tests/ui/match_ref_pats.stderr
@@ -1,5 +1,5 @@
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:7:9
+  --> $DIR/match_ref_pats.rs:8:9
    |
 LL | /         match v {
 LL | |             &Some(v) => println!("{:?}", v),
@@ -16,7 +16,7 @@ LL ~             None => println!("none"),
    |
 
 error: you don't need to add `&` to both the expression and the patterns
-  --> $DIR/match_ref_pats.rs:24:5
+  --> $DIR/match_ref_pats.rs:25:5
    |
 LL | /     match &w {
 LL | |         &Some(v) => println!("{:?}", v),
@@ -32,7 +32,7 @@ LL ~         None => println!("none"),
    |
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/match_ref_pats.rs:36:12
+  --> $DIR/match_ref_pats.rs:37:12
    |
 LL |     if let &None = a {
    |     -------^^^^^---- help: try this: `if a.is_none()`
@@ -40,13 +40,13 @@ LL |     if let &None = a {
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/match_ref_pats.rs:41:12
+  --> $DIR/match_ref_pats.rs:42:12
    |
 LL |     if let &None = &b {
    |     -------^^^^^----- help: try this: `if b.is_none()`
 
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:101:9
+  --> $DIR/match_ref_pats.rs:102:9
    |
 LL | /         match foobar_variant!(0) {
 LL | |             &FooBar::Foo => println!("Foo"),
diff --git a/tests/ui/match_str_case_mismatch.fixed b/tests/ui/match_str_case_mismatch.fixed
new file mode 100644
index 00000000000..e436bcf495f
--- /dev/null
+++ b/tests/ui/match_str_case_mismatch.fixed
@@ -0,0 +1,186 @@
+// run-rustfix
+#![warn(clippy::match_str_case_mismatch)]
+#![allow(dead_code)]
+
+// Valid
+
+fn as_str_match() {
+    let var = "BAR";
+
+    match var.to_ascii_lowercase().as_str() {
+        "foo" => {},
+        "bar" => {},
+        _ => {},
+    }
+}
+
+fn non_alphabetic() {
+    let var = "~!@#$%^&*()-_=+FOO";
+
+    match var.to_ascii_lowercase().as_str() {
+        "1234567890" => {},
+        "~!@#$%^&*()-_=+foo" => {},
+        "\n\r\t\x7F" => {},
+        _ => {},
+    }
+}
+
+fn unicode_cased() {
+    let var = "ВОДЫ";
+
+    match var.to_lowercase().as_str() {
+        "水" => {},
+        "νερό" => {},
+        "воды" => {},
+        "물" => {},
+        _ => {},
+    }
+}
+
+fn titlecase() {
+    let var = "BarDz";
+
+    match var.to_lowercase().as_str() {
+        "foolj" => {},
+        "bardz" => {},
+        _ => {},
+    }
+}
+
+fn no_case_equivalent() {
+    let var = "barʁ";
+
+    match var.to_uppercase().as_str() {
+        "FOOɕ" => {},
+        "BARʁ" => {},
+        _ => {},
+    }
+}
+
+fn addrof_unary_match() {
+    let var = "BAR";
+
+    match &*var.to_ascii_lowercase() {
+        "foo" => {},
+        "bar" => {},
+        _ => {},
+    }
+}
+
+fn alternating_chain() {
+    let var = "BAR";
+
+    match &*var
+        .to_ascii_lowercase()
+        .to_uppercase()
+        .to_lowercase()
+        .to_ascii_uppercase()
+    {
+        "FOO" => {},
+        "BAR" => {},
+        _ => {},
+    }
+}
+
+fn unrelated_method() {
+    struct Item {
+        a: String,
+    }
+
+    impl Item {
+        #[allow(clippy::wrong_self_convention)]
+        fn to_lowercase(self) -> String {
+            self.a
+        }
+    }
+
+    let item = Item { a: String::from("BAR") };
+
+    match &*item.to_lowercase() {
+        "FOO" => {},
+        "BAR" => {},
+        _ => {},
+    }
+}
+
+// Invalid
+
+fn as_str_match_mismatch() {
+    let var = "BAR";
+
+    match var.to_ascii_lowercase().as_str() {
+        "foo" => {},
+        "bar" => {},
+        _ => {},
+    }
+}
+
+fn non_alphabetic_mismatch() {
+    let var = "~!@#$%^&*()-_=+FOO";
+
+    match var.to_ascii_lowercase().as_str() {
+        "1234567890" => {},
+        "~!@#$%^&*()-_=+foo" => {},
+        "\n\r\t\x7F" => {},
+        _ => {},
+    }
+}
+
+fn unicode_cased_mismatch() {
+    let var = "ВОДЫ";
+
+    match var.to_lowercase().as_str() {
+        "水" => {},
+        "νερό" => {},
+        "воды" => {},
+        "물" => {},
+        _ => {},
+    }
+}
+
+fn titlecase_mismatch() {
+    let var = "BarDz";
+
+    match var.to_lowercase().as_str() {
+        "foolj" => {},
+        "bardz" => {},
+        _ => {},
+    }
+}
+
+fn no_case_equivalent_mismatch() {
+    let var = "barʁ";
+
+    match var.to_uppercase().as_str() {
+        "FOOɕ" => {},
+        "BARʁ" => {},
+        _ => {},
+    }
+}
+
+fn addrof_unary_match_mismatch() {
+    let var = "BAR";
+
+    match &*var.to_ascii_lowercase() {
+        "foo" => {},
+        "bar" => {},
+        _ => {},
+    }
+}
+
+fn alternating_chain_mismatch() {
+    let var = "BAR";
+
+    match &*var
+        .to_ascii_lowercase()
+        .to_uppercase()
+        .to_lowercase()
+        .to_ascii_uppercase()
+    {
+        "FOO" => {},
+        "BAR" => {},
+        _ => {},
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/match_str_case_mismatch.rs b/tests/ui/match_str_case_mismatch.rs
index ac555c87d83..92e2a000ade 100644
--- a/tests/ui/match_str_case_mismatch.rs
+++ b/tests/ui/match_str_case_mismatch.rs
@@ -1,4 +1,6 @@
+// run-rustfix
 #![warn(clippy::match_str_case_mismatch)]
+#![allow(dead_code)]
 
 // Valid
 
diff --git a/tests/ui/match_str_case_mismatch.stderr b/tests/ui/match_str_case_mismatch.stderr
index 92baa40ef28..197520a3d60 100644
--- a/tests/ui/match_str_case_mismatch.stderr
+++ b/tests/ui/match_str_case_mismatch.stderr
@@ -1,5 +1,5 @@
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:111:9
+  --> $DIR/match_str_case_mismatch.rs:113:9
    |
 LL |         "Bar" => {},
    |         ^^^^^
@@ -11,7 +11,7 @@ LL |         "bar" => {},
    |         ~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:121:9
+  --> $DIR/match_str_case_mismatch.rs:123:9
    |
 LL |         "~!@#$%^&*()-_=+Foo" => {},
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +22,7 @@ LL |         "~!@#$%^&*()-_=+foo" => {},
    |         ~~~~~~~~~~~~~~~~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:133:9
+  --> $DIR/match_str_case_mismatch.rs:135:9
    |
 LL |         "Воды" => {},
    |         ^^^^^^
@@ -33,7 +33,7 @@ LL |         "воды" => {},
    |         ~~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:144:9
+  --> $DIR/match_str_case_mismatch.rs:146:9
    |
 LL |         "barDz" => {},
    |         ^^^^^^
@@ -44,7 +44,7 @@ LL |         "bardz" => {},
    |         ~~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:154:9
+  --> $DIR/match_str_case_mismatch.rs:156:9
    |
 LL |         "bARʁ" => {},
    |         ^^^^^^
@@ -55,7 +55,7 @@ LL |         "BARʁ" => {},
    |         ~~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:164:9
+  --> $DIR/match_str_case_mismatch.rs:166:9
    |
 LL |         "Bar" => {},
    |         ^^^^^
@@ -66,7 +66,7 @@ LL |         "bar" => {},
    |         ~~~~~
 
 error: this `match` arm has a differing case than its expression
-  --> $DIR/match_str_case_mismatch.rs:179:9
+  --> $DIR/match_str_case_mismatch.rs:181:9
    |
 LL |         "bAR" => {},
    |         ^^^^^
diff --git a/tests/ui/needless_late_init.fixed b/tests/ui/needless_late_init.fixed
new file mode 100644
index 00000000000..63ae6e389f3
--- /dev/null
+++ b/tests/ui/needless_late_init.fixed
@@ -0,0 +1,258 @@
+// run-rustfix
+#![feature(let_chains)]
+#![allow(
+    unused,
+    clippy::assign_op_pattern,
+    clippy::let_and_return,
+    clippy::let_unit_value,
+    clippy::nonminimal_bool
+)]
+
+use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
+use std::rc::Rc;
+
+struct SignificantDrop;
+impl std::ops::Drop for SignificantDrop {
+    fn drop(&mut self) {
+        println!("dropped");
+    }
+}
+
+fn main() {
+    
+    let n = 1;
+    let a = match n {
+        1 => "one",
+        _ => {
+            "two"
+        },
+    };
+
+    
+    let b = if n == 3 {
+        "four"
+    } else {
+        "five"
+    };
+
+    
+    let d = if true {
+        let temp = 5;
+        temp
+    } else {
+        15
+    };
+
+    
+    let e = if true {
+        format!("{} {}", a, b)
+    } else {
+        format!("{}", n)
+    };
+
+    
+    let f = match 1 {
+        1 => "three",
+        _ => return,
+    }; // has semi
+
+    
+    let g: usize = if true {
+        5
+    } else {
+        panic!();
+    };
+
+    // Drop order only matters if both are significant
+    
+    let y = SignificantDrop;
+    let x = 1;
+
+    
+    let y = 1;
+    let x = SignificantDrop;
+
+    
+    // types that should be considered insignificant
+    let y = 1;
+    let y = "2";
+    let y = String::new();
+    let y = vec![3.0];
+    let y = HashMap::<usize, usize>::new();
+    let y = BTreeMap::<usize, usize>::new();
+    let y = HashSet::<usize>::new();
+    let y = BTreeSet::<usize>::new();
+    let y = Box::new(4);
+    let x = SignificantDrop;
+}
+
+async fn in_async() -> &'static str {
+    async fn f() -> &'static str {
+        "one"
+    }
+
+    
+    let n = 1;
+    let a = match n {
+        1 => f().await,
+        _ => {
+            "two"
+        },
+    };
+
+    a
+}
+
+const fn in_const() -> &'static str {
+    const fn f() -> &'static str {
+        "one"
+    }
+
+    
+    let n = 1;
+    let a = match n {
+        1 => f(),
+        _ => {
+            "two"
+        },
+    };
+
+    a
+}
+
+fn does_not_lint() {
+    let z;
+    if false {
+        z = 1;
+    }
+
+    let x;
+    let y;
+    if true {
+        x = 1;
+    } else {
+        y = 1;
+    }
+
+    let mut x;
+    if true {
+        x = 5;
+        x = 10 / x;
+    } else {
+        x = 2;
+    }
+
+    let x;
+    let _ = match 1 {
+        1 => x = 10,
+        _ => x = 20,
+    };
+
+    // using tuples would be possible, but not always preferable
+    let x;
+    let y;
+    if true {
+        x = 1;
+        y = 2;
+    } else {
+        x = 3;
+        y = 4;
+    }
+
+    // could match with a smarter heuristic to avoid multiple assignments
+    let x;
+    if true {
+        let mut y = 5;
+        y = 6;
+        x = y;
+    } else {
+        x = 2;
+    }
+
+    let (x, y);
+    if true {
+        x = 1;
+    } else {
+        x = 2;
+    }
+    y = 3;
+
+    macro_rules! assign {
+        ($i:ident) => {
+            $i = 1;
+        };
+    }
+    let x;
+    assign!(x);
+
+    let x;
+    if true {
+        assign!(x);
+    } else {
+        x = 2;
+    }
+
+    macro_rules! in_macro {
+        () => {
+            let x;
+            x = 1;
+
+            let x;
+            if true {
+                x = 1;
+            } else {
+                x = 2;
+            }
+        };
+    }
+    in_macro!();
+
+    // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613
+    let x;
+    if let Some(n) = Some("v") {
+        x = 1;
+    } else {
+        x = 2;
+    }
+
+    let x;
+    if true && let Some(n) = Some("let chains too") {
+        x = 1;
+    } else {
+        x = 2;
+    }
+
+    // ignore mut bindings
+    // https://github.com/shepmaster/twox-hash/blob/b169c16d86eb8ea4a296b0acb9d00ca7e3c3005f/src/sixty_four.rs#L88-L93
+    // https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/tests/test_generics.rs#L91-L100
+    let mut x: usize;
+    x = 1;
+    x = 2;
+    x = 3;
+
+    // should not move the declaration if `x` has a significant drop, and there
+    // is another binding with a significant drop between it and the first usage
+    let x;
+    let y = SignificantDrop;
+    x = SignificantDrop;
+}
+
+mod fixable {
+    #![allow(dead_code)]
+
+    fn main() {
+        
+        let a = "zero";
+
+        
+        
+        let b = 1;
+        let c = 2;
+
+        
+        let d: usize = 1;
+
+        
+        let e = format!("{}", d);
+    }
+}
diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs
index 54e66b391b8..89a85c8e053 100644
--- a/tests/ui/needless_late_init.rs
+++ b/tests/ui/needless_late_init.rs
@@ -1,5 +1,12 @@
+// run-rustfix
 #![feature(let_chains)]
-#![allow(unused, clippy::nonminimal_bool, clippy::let_unit_value)]
+#![allow(
+    unused,
+    clippy::assign_op_pattern,
+    clippy::let_and_return,
+    clippy::let_unit_value,
+    clippy::nonminimal_bool
+)]
 
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
 use std::rc::Rc;
@@ -229,3 +236,23 @@ fn does_not_lint() {
     let y = SignificantDrop;
     x = SignificantDrop;
 }
+
+mod fixable {
+    #![allow(dead_code)]
+
+    fn main() {
+        let a;
+        a = "zero";
+
+        let b;
+        let c;
+        b = 1;
+        c = 2;
+
+        let d: usize;
+        d = 1;
+
+        let e;
+        e = format!("{}", d);
+    }
+}
diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr
index d33a117b288..d17666e03ed 100644
--- a/tests/ui/needless_late_init.stderr
+++ b/tests/ui/needless_late_init.stderr
@@ -1,5 +1,5 @@
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:15:5
+  --> $DIR/needless_late_init.rs:22:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -21,7 +21,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:24:5
+  --> $DIR/needless_late_init.rs:31:5
    |
 LL |     let b;
    |     ^^^^^^
@@ -42,7 +42,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:31:5
+  --> $DIR/needless_late_init.rs:38:5
    |
 LL |     let d;
    |     ^^^^^^
@@ -63,7 +63,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:39:5
+  --> $DIR/needless_late_init.rs:46:5
    |
 LL |     let e;
    |     ^^^^^^
@@ -84,7 +84,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:46:5
+  --> $DIR/needless_late_init.rs:53:5
    |
 LL |     let f;
    |     ^^^^^^
@@ -100,7 +100,7 @@ LL +         1 => "three",
    | 
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:52:5
+  --> $DIR/needless_late_init.rs:59:5
    |
 LL |     let g: usize;
    |     ^^^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:60:5
+  --> $DIR/needless_late_init.rs:67:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -134,7 +134,7 @@ LL |     let x = 1;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:64:5
+  --> $DIR/needless_late_init.rs:71:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -148,7 +148,7 @@ LL |     let x = SignificantDrop;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:68:5
+  --> $DIR/needless_late_init.rs:75:5
    |
 LL |     let x;
    |     ^^^^^^ created here
@@ -162,7 +162,7 @@ LL |     let x = SignificantDrop;
    |     ~~~~~
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:87:5
+  --> $DIR/needless_late_init.rs:94:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -183,7 +183,7 @@ LL |     };
    |      +
 
 error: unneeded late initialization
-  --> $DIR/needless_late_init.rs:104:5
+  --> $DIR/needless_late_init.rs:111:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -203,5 +203,72 @@ help: add a semicolon after the `match` expression
 LL |     };
    |      +
 
-error: aborting due to 11 previous errors
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:244:9
+   |
+LL |         let a;
+   |         ^^^^^^ created here
+LL |         a = "zero";
+   |         ^^^^^^^^^^ initialised here
+   |
+help: declare `a` here
+   |
+LL |         let a = "zero";
+   |         ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:247:9
+   |
+LL |         let b;
+   |         ^^^^^^ created here
+LL |         let c;
+LL |         b = 1;
+   |         ^^^^^ initialised here
+   |
+help: declare `b` here
+   |
+LL |         let b = 1;
+   |         ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:248:9
+   |
+LL |         let c;
+   |         ^^^^^^ created here
+LL |         b = 1;
+LL |         c = 2;
+   |         ^^^^^ initialised here
+   |
+help: declare `c` here
+   |
+LL |         let c = 2;
+   |         ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:252:9
+   |
+LL |         let d: usize;
+   |         ^^^^^^^^^^^^^ created here
+LL |         d = 1;
+   |         ^^^^^ initialised here
+   |
+help: declare `d` here
+   |
+LL |         let d: usize = 1;
+   |         ~~~~~~~~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:255:9
+   |
+LL |         let e;
+   |         ^^^^^^ created here
+LL |         e = format!("{}", d);
+   |         ^^^^^^^^^^^^^^^^^^^^ initialised here
+   |
+help: declare `e` here
+   |
+LL |         let e = format!("{}", d);
+   |         ~~~~~
+
+error: aborting due to 16 previous errors
 
diff --git a/tests/ui/needless_late_init_fixable.fixed b/tests/ui/needless_late_init_fixable.fixed
deleted file mode 100644
index 724477e8691..00000000000
--- a/tests/ui/needless_late_init_fixable.fixed
+++ /dev/null
@@ -1,19 +0,0 @@
-// run-rustfix
-
-#![allow(unused, clippy::assign_op_pattern)]
-
-fn main() {
-    
-    let a = "zero";
-
-    
-    
-    let b = 1;
-    let c = 2;
-
-    
-    let d: usize = 1;
-
-    
-    let e = format!("{}", d);
-}
diff --git a/tests/ui/needless_late_init_fixable.rs b/tests/ui/needless_late_init_fixable.rs
deleted file mode 100644
index 3e6bd363672..00000000000
--- a/tests/ui/needless_late_init_fixable.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// run-rustfix
-
-#![allow(unused, clippy::assign_op_pattern)]
-
-fn main() {
-    let a;
-    a = "zero";
-
-    let b;
-    let c;
-    b = 1;
-    c = 2;
-
-    let d: usize;
-    d = 1;
-
-    let e;
-    e = format!("{}", d);
-}
diff --git a/tests/ui/needless_late_init_fixable.stderr b/tests/ui/needless_late_init_fixable.stderr
deleted file mode 100644
index 8c664309e3e..00000000000
--- a/tests/ui/needless_late_init_fixable.stderr
+++ /dev/null
@@ -1,70 +0,0 @@
-error: unneeded late initialization
-  --> $DIR/needless_late_init_fixable.rs:6:5
-   |
-LL |     let a;
-   |     ^^^^^^ created here
-LL |     a = "zero";
-   |     ^^^^^^^^^^ initialised here
-   |
-   = note: `-D clippy::needless-late-init` implied by `-D warnings`
-help: declare `a` here
-   |
-LL |     let a = "zero";
-   |     ~~~~~
-
-error: unneeded late initialization
-  --> $DIR/needless_late_init_fixable.rs:9:5
-   |
-LL |     let b;
-   |     ^^^^^^ created here
-LL |     let c;
-LL |     b = 1;
-   |     ^^^^^ initialised here
-   |
-help: declare `b` here
-   |
-LL |     let b = 1;
-   |     ~~~~~
-
-error: unneeded late initialization
-  --> $DIR/needless_late_init_fixable.rs:10:5
-   |
-LL |     let c;
-   |     ^^^^^^ created here
-LL |     b = 1;
-LL |     c = 2;
-   |     ^^^^^ initialised here
-   |
-help: declare `c` here
-   |
-LL |     let c = 2;
-   |     ~~~~~
-
-error: unneeded late initialization
-  --> $DIR/needless_late_init_fixable.rs:14:5
-   |
-LL |     let d: usize;
-   |     ^^^^^^^^^^^^^ created here
-LL |     d = 1;
-   |     ^^^^^ initialised here
-   |
-help: declare `d` here
-   |
-LL |     let d: usize = 1;
-   |     ~~~~~~~~~~~~
-
-error: unneeded late initialization
-  --> $DIR/needless_late_init_fixable.rs:17:5
-   |
-LL |     let e;
-   |     ^^^^^^ created here
-LL |     e = format!("{}", d);
-   |     ^^^^^^^^^^^^^^^^^^^^ initialised here
-   |
-help: declare `e` here
-   |
-LL |     let e = format!("{}", d);
-   |     ~~~~~
-
-error: aborting due to 5 previous errors
-
diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed
new file mode 100644
index 00000000000..aad44089de4
--- /dev/null
+++ b/tests/ui/nonminimal_bool_methods.fixed
@@ -0,0 +1,111 @@
+// run-rustfix
+#![allow(unused, clippy::diverging_sub_expression)]
+#![warn(clippy::nonminimal_bool)]
+
+fn methods_with_negation() {
+    let a: Option<i32> = unimplemented!();
+    let b: Result<i32, i32> = unimplemented!();
+    let _ = a.is_some();
+    let _ = a.is_none();
+    let _ = a.is_none();
+    let _ = a.is_some();
+    let _ = b.is_err();
+    let _ = b.is_ok();
+    let _ = b.is_ok();
+    let _ = b.is_err();
+    let c = false;
+    let _ = a.is_none() || c;
+    let _ = a.is_none() && c;
+    let _ = !(!c ^ c) || a.is_none();
+    let _ = (!c ^ c) || a.is_none();
+    let _ = !c ^ c || a.is_none();
+}
+
+// Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638
+// clippy::nonminimal_bool should only check the built-in Result and Some type, not
+// any other types like the following.
+enum CustomResultOk<E> {
+    Ok,
+    Err(E),
+}
+enum CustomResultErr<E> {
+    Ok,
+    Err(E),
+}
+enum CustomSomeSome<T> {
+    Some(T),
+    None,
+}
+enum CustomSomeNone<T> {
+    Some(T),
+    None,
+}
+
+impl<E> CustomResultOk<E> {
+    pub fn is_ok(&self) -> bool {
+        true
+    }
+}
+
+impl<E> CustomResultErr<E> {
+    pub fn is_err(&self) -> bool {
+        true
+    }
+}
+
+impl<T> CustomSomeSome<T> {
+    pub fn is_some(&self) -> bool {
+        true
+    }
+}
+
+impl<T> CustomSomeNone<T> {
+    pub fn is_none(&self) -> bool {
+        true
+    }
+}
+
+fn dont_warn_for_custom_methods_with_negation() {
+    let res = CustomResultOk::Err("Error");
+    // Should not warn and suggest 'is_err()' because the type does not
+    // implement is_err().
+    if !res.is_ok() {}
+
+    let res = CustomResultErr::Err("Error");
+    // Should not warn and suggest 'is_ok()' because the type does not
+    // implement is_ok().
+    if !res.is_err() {}
+
+    let res = CustomSomeSome::Some("thing");
+    // Should not warn and suggest 'is_none()' because the type does not
+    // implement is_none().
+    if !res.is_some() {}
+
+    let res = CustomSomeNone::Some("thing");
+    // Should not warn and suggest 'is_some()' because the type does not
+    // implement is_some().
+    if !res.is_none() {}
+}
+
+// Only Built-in Result and Some types should suggest the negated alternative
+fn warn_for_built_in_methods_with_negation() {
+    let res: Result<usize, usize> = Ok(1);
+    if res.is_err() {}
+    if res.is_ok() {}
+
+    let res = Some(1);
+    if res.is_none() {}
+    if res.is_some() {}
+}
+
+#[allow(clippy::neg_cmp_op_on_partial_ord)]
+fn dont_warn_for_negated_partial_ord_comparison() {
+    let a: f64 = unimplemented!();
+    let b: f64 = unimplemented!();
+    let _ = !(a < b);
+    let _ = !(a <= b);
+    let _ = !(a > b);
+    let _ = !(a >= b);
+}
+
+fn main() {}
diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs
index d0a289b7ea4..b9074da8427 100644
--- a/tests/ui/nonminimal_bool_methods.rs
+++ b/tests/ui/nonminimal_bool_methods.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 #![allow(unused, clippy::diverging_sub_expression)]
 #![warn(clippy::nonminimal_bool)]
 
diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr
index a2df889d623..21b84db8589 100644
--- a/tests/ui/nonminimal_bool_methods.stderr
+++ b/tests/ui/nonminimal_bool_methods.stderr
@@ -1,5 +1,5 @@
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:8:13
+  --> $DIR/nonminimal_bool_methods.rs:9:13
    |
 LL |     let _ = !a.is_some();
    |             ^^^^^^^^^^^^ help: try: `a.is_none()`
@@ -7,73 +7,73 @@ LL |     let _ = !a.is_some();
    = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:10:13
+  --> $DIR/nonminimal_bool_methods.rs:11:13
    |
 LL |     let _ = !a.is_none();
    |             ^^^^^^^^^^^^ help: try: `a.is_some()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:12:13
+  --> $DIR/nonminimal_bool_methods.rs:13:13
    |
 LL |     let _ = !b.is_err();
    |             ^^^^^^^^^^^ help: try: `b.is_ok()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:14:13
+  --> $DIR/nonminimal_bool_methods.rs:15:13
    |
 LL |     let _ = !b.is_ok();
    |             ^^^^^^^^^^ help: try: `b.is_err()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:16:13
+  --> $DIR/nonminimal_bool_methods.rs:17:13
    |
 LL |     let _ = !(a.is_some() && !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:17:13
+  --> $DIR/nonminimal_bool_methods.rs:18:13
    |
 LL |     let _ = !(a.is_some() || !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:18:26
+  --> $DIR/nonminimal_bool_methods.rs:19:26
    |
 LL |     let _ = !(!c ^ c) || !a.is_some();
    |                          ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:19:25
+  --> $DIR/nonminimal_bool_methods.rs:20:25
    |
 LL |     let _ = (!c ^ c) || !a.is_some();
    |                         ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:20:23
+  --> $DIR/nonminimal_bool_methods.rs:21:23
    |
 LL |     let _ = !c ^ c || !a.is_some();
    |                       ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:92:8
+  --> $DIR/nonminimal_bool_methods.rs:93:8
    |
 LL |     if !res.is_ok() {}
    |        ^^^^^^^^^^^^ help: try: `res.is_err()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:93:8
+  --> $DIR/nonminimal_bool_methods.rs:94:8
    |
 LL |     if !res.is_err() {}
    |        ^^^^^^^^^^^^^ help: try: `res.is_ok()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:96:8
+  --> $DIR/nonminimal_bool_methods.rs:97:8
    |
 LL |     if !res.is_some() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_none()`
 
 error: this boolean expression can be simplified
-  --> $DIR/nonminimal_bool_methods.rs:97:8
+  --> $DIR/nonminimal_bool_methods.rs:98:8
    |
 LL |     if !res.is_none() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_some()`
diff --git a/tests/ui/rc_buffer.fixed b/tests/ui/rc_buffer.fixed
new file mode 100644
index 00000000000..8910c01b1fc
--- /dev/null
+++ b/tests/ui/rc_buffer.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+#![warn(clippy::rc_buffer)]
+#![allow(dead_code, unused_imports)]
+
+use std::cell::RefCell;
+use std::ffi::OsString;
+use std::path::PathBuf;
+use std::rc::Rc;
+
+struct S {
+    // triggers lint
+    bad1: Rc<str>,
+    bad2: Rc<std::path::Path>,
+    bad3: Rc<[u8]>,
+    bad4: Rc<std::ffi::OsStr>,
+    // does not trigger lint
+    good1: Rc<RefCell<String>>,
+}
+
+// triggers lint
+fn func_bad1(_: Rc<str>) {}
+fn func_bad2(_: Rc<std::path::Path>) {}
+fn func_bad3(_: Rc<[u8]>) {}
+fn func_bad4(_: Rc<std::ffi::OsStr>) {}
+// does not trigger lint
+fn func_good1(_: Rc<RefCell<String>>) {}
+
+fn main() {}
diff --git a/tests/ui/rc_buffer.rs b/tests/ui/rc_buffer.rs
index 1fa98643936..1e63a43262e 100644
--- a/tests/ui/rc_buffer.rs
+++ b/tests/ui/rc_buffer.rs
@@ -1,4 +1,6 @@
+// run-rustfix
 #![warn(clippy::rc_buffer)]
+#![allow(dead_code, unused_imports)]
 
 use std::cell::RefCell;
 use std::ffi::OsString;
diff --git a/tests/ui/rc_buffer.stderr b/tests/ui/rc_buffer.stderr
index e4cc169af07..9ed028e3df4 100644
--- a/tests/ui/rc_buffer.stderr
+++ b/tests/ui/rc_buffer.stderr
@@ -1,5 +1,5 @@
 error: usage of `Rc<T>` when T is a buffer type
-  --> $DIR/rc_buffer.rs:10:11
+  --> $DIR/rc_buffer.rs:12:11
    |
 LL |     bad1: Rc<String>,
    |           ^^^^^^^^^^ help: try: `Rc<str>`
@@ -7,43 +7,43 @@ LL |     bad1: Rc<String>,
    = 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
+  --> $DIR/rc_buffer.rs:13: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
+  --> $DIR/rc_buffer.rs:14: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
+  --> $DIR/rc_buffer.rs:15: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
+  --> $DIR/rc_buffer.rs:21: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
+  --> $DIR/rc_buffer.rs:22: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
+  --> $DIR/rc_buffer.rs:23: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
+  --> $DIR/rc_buffer.rs:24:17
    |
 LL | fn func_bad4(_: Rc<OsString>) {}
    |                 ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
diff --git a/tests/ui/rc_buffer_arc.fixed b/tests/ui/rc_buffer_arc.fixed
new file mode 100644
index 00000000000..13dd6f5fcd1
--- /dev/null
+++ b/tests/ui/rc_buffer_arc.fixed
@@ -0,0 +1,27 @@
+// run-rustfix
+#![warn(clippy::rc_buffer)]
+#![allow(dead_code, unused_imports)]
+
+use std::ffi::OsString;
+use std::path::PathBuf;
+use std::sync::{Arc, Mutex};
+
+struct S {
+    // triggers lint
+    bad1: Arc<str>,
+    bad2: Arc<std::path::Path>,
+    bad3: Arc<[u8]>,
+    bad4: Arc<std::ffi::OsStr>,
+    // does not trigger lint
+    good1: Arc<Mutex<String>>,
+}
+
+// triggers lint
+fn func_bad1(_: Arc<str>) {}
+fn func_bad2(_: Arc<std::path::Path>) {}
+fn func_bad3(_: Arc<[u8]>) {}
+fn func_bad4(_: Arc<std::ffi::OsStr>) {}
+// does not trigger lint
+fn func_good1(_: Arc<Mutex<String>>) {}
+
+fn main() {}
diff --git a/tests/ui/rc_buffer_arc.rs b/tests/ui/rc_buffer_arc.rs
index 5d586584817..1a521bfeb7c 100644
--- a/tests/ui/rc_buffer_arc.rs
+++ b/tests/ui/rc_buffer_arc.rs
@@ -1,4 +1,6 @@
+// run-rustfix
 #![warn(clippy::rc_buffer)]
+#![allow(dead_code, unused_imports)]
 
 use std::ffi::OsString;
 use std::path::PathBuf;
diff --git a/tests/ui/rc_buffer_arc.stderr b/tests/ui/rc_buffer_arc.stderr
index 8252270d2ac..911feea7352 100644
--- a/tests/ui/rc_buffer_arc.stderr
+++ b/tests/ui/rc_buffer_arc.stderr
@@ -1,5 +1,5 @@
 error: usage of `Arc<T>` when T is a buffer type
-  --> $DIR/rc_buffer_arc.rs:9:11
+  --> $DIR/rc_buffer_arc.rs:11:11
    |
 LL |     bad1: Arc<String>,
    |           ^^^^^^^^^^^ help: try: `Arc<str>`
@@ -7,43 +7,43 @@ LL |     bad1: Arc<String>,
    = 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
+  --> $DIR/rc_buffer_arc.rs:12: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
+  --> $DIR/rc_buffer_arc.rs:13: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
+  --> $DIR/rc_buffer_arc.rs:14: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
+  --> $DIR/rc_buffer_arc.rs:20: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
+  --> $DIR/rc_buffer_arc.rs:21: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
+  --> $DIR/rc_buffer_arc.rs:22: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
+  --> $DIR/rc_buffer_arc.rs:23:17
    |
 LL | fn func_bad4(_: Arc<OsString>) {}
    |                 ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
diff --git a/tests/ui/suspicious_operation_groupings.fixed b/tests/ui/suspicious_operation_groupings.fixed
new file mode 100644
index 00000000000..ede8a39fed7
--- /dev/null
+++ b/tests/ui/suspicious_operation_groupings.fixed
@@ -0,0 +1,209 @@
+// run-rustfix
+#![warn(clippy::suspicious_operation_groupings)]
+#![allow(dead_code, unused_parens, clippy::eq_op)]
+
+struct Vec3 {
+    x: f64,
+    y: f64,
+    z: f64,
+}
+
+impl Eq for Vec3 {}
+
+impl PartialEq for Vec3 {
+    fn eq(&self, other: &Self) -> bool {
+        // This should trigger the lint because `self.x` is compared to `other.y`
+        self.x == other.x && self.y == other.y && self.z == other.z
+    }
+}
+
+struct S {
+    a: i32,
+    b: i32,
+    c: i32,
+    d: i32,
+}
+
+fn buggy_ab_cmp(s1: &S, s2: &S) -> bool {
+    // There's no `s1.b`
+    s1.a < s2.a && s1.b < s2.b
+}
+
+struct SaOnly {
+    a: i32,
+}
+
+impl S {
+    fn a(&self) -> i32 {
+        0
+    }
+}
+
+fn do_not_give_bad_suggestions_for_this_unusual_expr(s1: &S, s2: &SaOnly) -> bool {
+    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest
+    // `s2.b` since that is invalid.
+    s1.a < s2.a && s1.a() < s1.b
+}
+
+fn do_not_give_bad_suggestions_for_this_macro_expr(s1: &S, s2: &SaOnly) -> bool {
+    macro_rules! s1 {
+        () => {
+            S {
+                a: 1,
+                b: 1,
+                c: 1,
+                d: 1,
+            }
+        };
+    }
+
+    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest
+    // `s2.b` since that is invalid.
+    s1.a < s2.a && s1!().a < s1.b
+}
+
+fn do_not_give_bad_suggestions_for_this_incorrect_expr(s1: &S, s2: &SaOnly) -> bool {
+    // There's two `s1.b`, but we should not suggest `s2.b` since that is invalid
+    s1.a < s2.a && s1.b < s1.b
+}
+
+fn permissable(s1: &S, s2: &S) -> bool {
+    // Something like this seems like it might actually be what is desired.
+    s1.a == s2.b
+}
+
+fn non_boolean_operators(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d
+}
+
+fn odd_number_of_pairs(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.b`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
+}
+
+fn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 {
+    // There's no `s1.b`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
+}
+
+fn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.b`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
+}
+
+fn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.a`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
+}
+
+fn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c
+}
+
+fn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) {
+    (
+        s1.b * s2.c - s1.c * s2.b,
+        s1.c * s2.a - s1.a * s2.c,
+        s1.a * s2.b - s1.b * s2.a,
+    )
+}
+
+fn outer_parens_simple(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.b`
+    (s1.a * s2.a + s1.b * s2.b)
+}
+
+fn outer_parens(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    (s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d)
+}
+
+fn inner_parens(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)
+}
+
+fn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d))
+}
+
+fn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.c) + (s1.d * s2.d)))
+}
+
+fn all_parens_left_tree(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c)) + (s1.d * s2.d))
+}
+
+fn all_parens_right_tree(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)))
+}
+
+fn inside_other_binop_expression(s1: &S, s2: &S) -> i32 {
+    // There's no `s1.b`
+    (s1.a * s2.a + s1.b * s2.b) / 2
+}
+
+fn inside_function_call(s1: &S, s2: &S) -> i32 {
+    // There's no `s1.b`
+    i32::swap_bytes(s1.a * s2.a + s1.b * s2.b)
+}
+
+fn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool {
+    // There's no `s1.c`
+    s1.a > 0 && s1.b > 0 && s1.c == s2.c && s1.d == s2.d
+}
+
+fn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool {
+    // There's no `s1.c`
+    s1.a > 0 && s1.c == s2.c && s1.b > 0 && s1.d == s2.d
+}
+
+struct Nested {
+    inner: ((i32,), (i32,), (i32,)),
+}
+
+fn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool {
+    // There's no `n2.inner.2.0`
+    (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
+}
+
+// `eq_op` should catch this one.
+fn changed_initial_ident(n1: &Nested, n2: &Nested) -> bool {
+    // There's no `n2.inner.0.0`
+    (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
+}
+
+fn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool {
+    if strict {
+        s1.a < s2.a && s1.b < s2.b
+    } else {
+        // There's no `s1.b` in this subexpression
+        s1.a <= s2.a && s1.b <= s2.b
+    }
+}
+
+fn inside_an_if_statement(s1: &mut S, s2: &S) {
+    // There's no `s1.b`
+    if s1.a < s2.a && s1.b < s2.b {
+        s1.c = s2.c;
+    }
+}
+
+fn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 {
+    // There's no `s2.c`
+    -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.c) + -(-s1.d * -s2.d)))
+}
+
+fn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 {
+    // There's no `s1.b`
+    -(if -s1.a < -s2.a && -s1.b < -s2.b { s1.c } else { s2.a })
+}
+
+fn main() {}
diff --git a/tests/ui/suspicious_operation_groupings.rs b/tests/ui/suspicious_operation_groupings.rs
index 3201d5de0f3..26ce97bb37f 100644
--- a/tests/ui/suspicious_operation_groupings.rs
+++ b/tests/ui/suspicious_operation_groupings.rs
@@ -1,5 +1,6 @@
+// run-rustfix
 #![warn(clippy::suspicious_operation_groupings)]
-#![allow(clippy::eq_op)]
+#![allow(dead_code, unused_parens, clippy::eq_op)]
 
 struct Vec3 {
     x: f64,
diff --git a/tests/ui/suspicious_operation_groupings.stderr b/tests/ui/suspicious_operation_groupings.stderr
index baf9bc74b00..29f229245fe 100644
--- a/tests/ui/suspicious_operation_groupings.stderr
+++ b/tests/ui/suspicious_operation_groupings.stderr
@@ -1,5 +1,5 @@
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:15:9
+  --> $DIR/suspicious_operation_groupings.rs:16:9
    |
 LL |         self.x == other.y && self.y == other.y && self.z == other.z
    |         ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`
@@ -7,151 +7,151 @@ LL |         self.x == other.y && self.y == other.y && self.z == other.z
    = note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:28:20
+  --> $DIR/suspicious_operation_groupings.rs:29:20
    |
 LL |     s1.a < s2.a && s1.a < s2.b
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:76:33
+  --> $DIR/suspicious_operation_groupings.rs:77:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:81:19
+  --> $DIR/suspicious_operation_groupings.rs:82:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:81:19
+  --> $DIR/suspicious_operation_groupings.rs:82:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:86:19
+  --> $DIR/suspicious_operation_groupings.rs:87:19
    |
 LL |     s1.a * s2.a + s2.b * s2.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:91:19
+  --> $DIR/suspicious_operation_groupings.rs:92:19
    |
 LL |     s1.a * s2.a + s1.b * s1.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:96:5
+  --> $DIR/suspicious_operation_groupings.rs:97:5
    |
 LL |     s1.a * s1.a + s1.b * s2.b + s1.c * s2.c
    |     ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:101:33
+  --> $DIR/suspicious_operation_groupings.rs:102:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s1.c
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:114:20
+  --> $DIR/suspicious_operation_groupings.rs:115:20
    |
 LL |     (s1.a * s2.a + s1.b * s1.b)
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:119:34
+  --> $DIR/suspicious_operation_groupings.rs:120:34
    |
 LL |     (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)
    |                                  ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:124:38
+  --> $DIR/suspicious_operation_groupings.rs:125:38
    |
 LL |     (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)
    |                                      ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:129:39
+  --> $DIR/suspicious_operation_groupings.rs:130:39
    |
 LL |     ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))
    |                                       ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:134:42
+  --> $DIR/suspicious_operation_groupings.rs:135:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:134:42
+  --> $DIR/suspicious_operation_groupings.rs:135:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:139:40
+  --> $DIR/suspicious_operation_groupings.rs:140:40
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:144:40
+  --> $DIR/suspicious_operation_groupings.rs:145:40
    |
 LL |     ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:149:20
+  --> $DIR/suspicious_operation_groupings.rs:150:20
    |
 LL |     (s1.a * s2.a + s2.b * s2.b) / 2
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:154:35
+  --> $DIR/suspicious_operation_groupings.rs:155:35
    |
 LL |     i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)
    |                                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:159:29
+  --> $DIR/suspicious_operation_groupings.rs:160:29
    |
 LL |     s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d
    |                             ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:164:17
+  --> $DIR/suspicious_operation_groupings.rs:165:17
    |
 LL |     s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d
    |                 ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:173:77
+  --> $DIR/suspicious_operation_groupings.rs:174:77
    |
 LL |     (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0
    |                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:187:25
+  --> $DIR/suspicious_operation_groupings.rs:188:25
    |
 LL |         s1.a <= s2.a && s1.a <= s2.b
    |                         ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:193:23
+  --> $DIR/suspicious_operation_groupings.rs:194:23
    |
 LL |     if s1.a < s2.a && s1.a < s2.b {
    |                       ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:200:48
+  --> $DIR/suspicious_operation_groupings.rs:201:48
    |
 LL |     -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))
    |                                                ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> $DIR/suspicious_operation_groupings.rs:205:27
+  --> $DIR/suspicious_operation_groupings.rs:206:27
    |
 LL |     -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })
    |                           ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`
diff --git a/tests/ui/unicode.fixed b/tests/ui/unicode.fixed
new file mode 100644
index 00000000000..328cda369e1
--- /dev/null
+++ b/tests/ui/unicode.fixed
@@ -0,0 +1,36 @@
+// run-rustfix
+#[warn(clippy::invisible_characters)]
+fn zero() {
+    print!("Here >\u{200B}< is a ZWS, and \u{200B}another");
+    print!("This\u{200B}is\u{200B}fine");
+    print!("Here >\u{AD}< is a SHY, and \u{AD}another");
+    print!("This\u{ad}is\u{ad}fine");
+    print!("Here >\u{2060}< is a WJ, and \u{2060}another");
+    print!("This\u{2060}is\u{2060}fine");
+}
+
+#[warn(clippy::unicode_not_nfc)]
+fn canon() {
+    print!("̀àh?");
+    print!("a\u{0300}h?"); // also ok
+}
+
+#[warn(clippy::non_ascii_literal)]
+fn uni() {
+    print!("\u{dc}ben!");
+    print!("\u{DC}ben!"); // this is ok
+}
+
+// issue 8013
+#[warn(clippy::non_ascii_literal)]
+fn single_quote() {
+    const _EMPTY_BLOCK: char = '\u{25b1}';
+    const _FULL_BLOCK: char = '\u{25b0}';
+}
+
+fn main() {
+    zero();
+    uni();
+    canon();
+    single_quote();
+}
diff --git a/tests/ui/unicode.rs b/tests/ui/unicode.rs
index e0a4eadce33..7828d6bcbea 100644
--- a/tests/ui/unicode.rs
+++ b/tests/ui/unicode.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 #[warn(clippy::invisible_characters)]
 fn zero() {
     print!("Here >​< is a ZWS, and ​another");
diff --git a/tests/ui/unicode.stderr b/tests/ui/unicode.stderr
index 3f54e3880e7..01d3f3c0296 100644
--- a/tests/ui/unicode.stderr
+++ b/tests/ui/unicode.stderr
@@ -1,5 +1,5 @@
 error: invisible character detected
-  --> $DIR/unicode.rs:3:12
+  --> $DIR/unicode.rs:4:12
    |
 LL |     print!("Here >​< is a ZWS, and ​another");
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"`
@@ -7,19 +7,19 @@ LL |     print!("Here >​< is a ZWS, and ​another");
    = note: `-D clippy::invisible-characters` implied by `-D warnings`
 
 error: invisible character detected
-  --> $DIR/unicode.rs:5:12
+  --> $DIR/unicode.rs:6:12
    |
 LL |     print!("Here >­< is a SHY, and ­another");
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"`
 
 error: invisible character detected
-  --> $DIR/unicode.rs:7:12
+  --> $DIR/unicode.rs:8:12
    |
 LL |     print!("Here >⁠< is a WJ, and ⁠another");
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"`
 
 error: non-NFC Unicode sequence detected
-  --> $DIR/unicode.rs:13:12
+  --> $DIR/unicode.rs:14:12
    |
 LL |     print!("̀àh?");
    |            ^^^^^ help: consider replacing the string with: `"̀àh?"`
@@ -27,7 +27,7 @@ LL |     print!("̀àh?");
    = note: `-D clippy::unicode-not-nfc` implied by `-D warnings`
 
 error: literal non-ASCII character detected
-  --> $DIR/unicode.rs:19:12
+  --> $DIR/unicode.rs:20:12
    |
 LL |     print!("Üben!");
    |            ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
@@ -35,13 +35,13 @@ LL |     print!("Üben!");
    = note: `-D clippy::non-ascii-literal` implied by `-D warnings`
 
 error: literal non-ASCII character detected
-  --> $DIR/unicode.rs:26:32
+  --> $DIR/unicode.rs:27:32
    |
 LL |     const _EMPTY_BLOCK: char = '▱';
    |                                ^^^ help: consider replacing the string with: `'/u{25b1}'`
 
 error: literal non-ASCII character detected
-  --> $DIR/unicode.rs:27:31
+  --> $DIR/unicode.rs:28:31
    |
 LL |     const _FULL_BLOCK: char = '▰';
    |                               ^^^ help: consider replacing the string with: `'/u{25b0}'`
diff --git a/tests/ui/unit_arg_empty_blocks.fixed b/tests/ui/unit_arg_empty_blocks.fixed
new file mode 100644
index 00000000000..9400e93cac8
--- /dev/null
+++ b/tests/ui/unit_arg_empty_blocks.fixed
@@ -0,0 +1,30 @@
+// run-rustfix
+#![warn(clippy::unit_arg)]
+#![allow(clippy::no_effect, unused_must_use, unused_variables)]
+
+use std::fmt::Debug;
+
+fn foo<T: Debug>(t: T) {
+    println!("{:?}", t);
+}
+
+fn foo3<T1: Debug, T2: Debug, T3: Debug>(t1: T1, t2: T2, t3: T3) {
+    println!("{:?}, {:?}, {:?}", t1, t2, t3);
+}
+
+fn bad() {
+    foo(());
+    foo3((), 2, 2);
+    foo(0);
+    taking_two_units((), ());
+    foo(0);
+    foo(1);
+    taking_three_units((), (), ());
+}
+
+fn taking_two_units(a: (), b: ()) {}
+fn taking_three_units(a: (), b: (), c: ()) {}
+
+fn main() {
+    bad();
+}
diff --git a/tests/ui/unit_arg_empty_blocks.rs b/tests/ui/unit_arg_empty_blocks.rs
index 18a31eb3dee..5f52b6c5315 100644
--- a/tests/ui/unit_arg_empty_blocks.rs
+++ b/tests/ui/unit_arg_empty_blocks.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 #![warn(clippy::unit_arg)]
 #![allow(clippy::no_effect, unused_must_use, unused_variables)]
 
diff --git a/tests/ui/unit_arg_empty_blocks.stderr b/tests/ui/unit_arg_empty_blocks.stderr
index 39072c9a8cc..d35e931697d 100644
--- a/tests/ui/unit_arg_empty_blocks.stderr
+++ b/tests/ui/unit_arg_empty_blocks.stderr
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg_empty_blocks.rs:15:5
+  --> $DIR/unit_arg_empty_blocks.rs:16:5
    |
 LL |     foo({});
    |     ^^^^--^
@@ -9,7 +9,7 @@ LL |     foo({});
    = note: `-D clippy::unit-arg` implied by `-D warnings`
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg_empty_blocks.rs:16:5
+  --> $DIR/unit_arg_empty_blocks.rs:17:5
    |
 LL |     foo3({}, 2, 2);
    |     ^^^^^--^^^^^^^
@@ -17,7 +17,7 @@ LL |     foo3({}, 2, 2);
    |          help: use a unit literal instead: `()`
 
 error: passing unit values to a function
-  --> $DIR/unit_arg_empty_blocks.rs:17:5
+  --> $DIR/unit_arg_empty_blocks.rs:18:5
    |
 LL |     taking_two_units({}, foo(0));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL ~     taking_two_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg_empty_blocks.rs:18:5
+  --> $DIR/unit_arg_empty_blocks.rs:19:5
    |
 LL |     taking_three_units({}, foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed
new file mode 100644
index 00000000000..b352b285c86
--- /dev/null
+++ b/tests/ui/unnecessary_cast.fixed
@@ -0,0 +1,91 @@
+// run-rustfix
+#![warn(clippy::unnecessary_cast)]
+#![allow(
+    unused_must_use,
+    clippy::borrow_as_ptr,
+    clippy::no_effect,
+    clippy::nonstandard_macro_braces,
+    clippy::unnecessary_operation
+)]
+
+#[rustfmt::skip]
+fn main() {
+    // Test cast_unnecessary
+    1_i32;
+    1_f32;
+    false;
+    &1i32 as &i32;
+
+    -1_i32;
+    - 1_i32;
+    -1_f32;
+    1_i32;
+    1_f32;
+
+    // macro version
+    macro_rules! foo {
+        ($a:ident, $b:ident) => {
+            #[allow(unused)]
+            pub fn $a() -> $b {
+                1 as $b
+            }
+        };
+    }
+    foo!(a, i32);
+    foo!(b, f32);
+    foo!(c, f64);
+
+    // do not lint cast to cfg-dependant type
+    1 as std::os::raw::c_char;
+
+    // do not lint cast to alias type
+    1 as I32Alias;
+    &1 as &I32Alias;
+}
+
+type I32Alias = i32;
+
+mod fixable {
+    #![allow(dead_code)]
+
+    fn main() {
+        // casting integer literal to float is unnecessary
+        100_f32;
+        100_f64;
+        100_f64;
+        let _ = -100_f32;
+        let _ = -100_f64;
+        let _ = -100_f64;
+        100_f32;
+        100_f64;
+        // Should not trigger
+        #[rustfmt::skip]
+        let v = vec!(1);
+        &v as &[i32];
+        0x10 as f32;
+        0o10 as f32;
+        0b10 as f32;
+        0x11 as f64;
+        0o11 as f64;
+        0b11 as f64;
+
+        1_u32;
+        0x10_i32;
+        0b10_usize;
+        0o73_u16;
+        1_000_000_000_u32;
+
+        1.0_f64;
+        0.5_f32;
+
+        1.0 as u16;
+
+        let _ = -1_i32;
+        let _ = -1.0_f32;
+
+        let _ = 1 as I32Alias;
+        let _ = &1 as &I32Alias;
+    }
+
+    type I32Alias = i32;
+}
diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs
index 62c3e963686..6c8cc3effe8 100644
--- a/tests/ui/unnecessary_cast.rs
+++ b/tests/ui/unnecessary_cast.rs
@@ -1,5 +1,12 @@
+// run-rustfix
 #![warn(clippy::unnecessary_cast)]
-#![allow(clippy::no_effect)]
+#![allow(
+    unused_must_use,
+    clippy::borrow_as_ptr,
+    clippy::no_effect,
+    clippy::nonstandard_macro_braces,
+    clippy::unnecessary_operation
+)]
 
 #[rustfmt::skip]
 fn main() {
@@ -37,3 +44,48 @@ fn main() {
 }
 
 type I32Alias = i32;
+
+mod fixable {
+    #![allow(dead_code)]
+
+    fn main() {
+        // casting integer literal to float is unnecessary
+        100 as f32;
+        100 as f64;
+        100_i32 as f64;
+        let _ = -100 as f32;
+        let _ = -100 as f64;
+        let _ = -100_i32 as f64;
+        100. as f32;
+        100. as f64;
+        // Should not trigger
+        #[rustfmt::skip]
+        let v = vec!(1);
+        &v as &[i32];
+        0x10 as f32;
+        0o10 as f32;
+        0b10 as f32;
+        0x11 as f64;
+        0o11 as f64;
+        0b11 as f64;
+
+        1 as u32;
+        0x10 as i32;
+        0b10 as usize;
+        0o73 as u16;
+        1_000_000_000 as u32;
+
+        1.0 as f64;
+        0.5 as f32;
+
+        1.0 as u16;
+
+        let _ = -1 as i32;
+        let _ = -1.0 as f32;
+
+        let _ = 1 as I32Alias;
+        let _ = &1 as &I32Alias;
+    }
+
+    type I32Alias = i32;
+}
diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr
index a5a93c6110c..bad45f0025b 100644
--- a/tests/ui/unnecessary_cast.stderr
+++ b/tests/ui/unnecessary_cast.stderr
@@ -1,5 +1,5 @@
 error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:7:5
+  --> $DIR/unnecessary_cast.rs:14:5
    |
 LL |     1i32 as i32;
    |     ^^^^^^^^^^^ help: try: `1_i32`
@@ -7,46 +7,148 @@ LL |     1i32 as i32;
    = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
 
 error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:8:5
+  --> $DIR/unnecessary_cast.rs:15:5
    |
 LL |     1f32 as f32;
    |     ^^^^^^^^^^^ help: try: `1_f32`
 
 error: casting to the same type is unnecessary (`bool` -> `bool`)
-  --> $DIR/unnecessary_cast.rs:9:5
+  --> $DIR/unnecessary_cast.rs:16:5
    |
 LL |     false as bool;
    |     ^^^^^^^^^^^^^ help: try: `false`
 
 error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:12:5
+  --> $DIR/unnecessary_cast.rs:19:5
    |
 LL |     -1_i32 as i32;
    |     ^^^^^^^^^^^^^ help: try: `-1_i32`
 
 error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:13:5
+  --> $DIR/unnecessary_cast.rs:20:5
    |
 LL |     - 1_i32 as i32;
    |     ^^^^^^^^^^^^^^ help: try: `- 1_i32`
 
 error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:14:5
+  --> $DIR/unnecessary_cast.rs:21:5
    |
 LL |     -1f32 as f32;
    |     ^^^^^^^^^^^^ help: try: `-1_f32`
 
 error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:15:5
+  --> $DIR/unnecessary_cast.rs:22:5
    |
 LL |     1_i32 as i32;
    |     ^^^^^^^^^^^^ help: try: `1_i32`
 
 error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast.rs:16:5
+  --> $DIR/unnecessary_cast.rs:23:5
    |
 LL |     1_f32 as f32;
    |     ^^^^^^^^^^^^ help: try: `1_f32`
 
-error: aborting due to 8 previous errors
+error: casting integer literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:53:9
+   |
+LL |         100 as f32;
+   |         ^^^^^^^^^^ help: try: `100_f32`
+
+error: casting integer literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:54:9
+   |
+LL |         100 as f64;
+   |         ^^^^^^^^^^ help: try: `100_f64`
+
+error: casting integer literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:55:9
+   |
+LL |         100_i32 as f64;
+   |         ^^^^^^^^^^^^^^ help: try: `100_f64`
+
+error: casting integer literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:56:17
+   |
+LL |         let _ = -100 as f32;
+   |                 ^^^^^^^^^^^ help: try: `-100_f32`
+
+error: casting integer literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:57:17
+   |
+LL |         let _ = -100 as f64;
+   |                 ^^^^^^^^^^^ help: try: `-100_f64`
+
+error: casting integer literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:58:17
+   |
+LL |         let _ = -100_i32 as f64;
+   |                 ^^^^^^^^^^^^^^^ help: try: `-100_f64`
+
+error: casting float literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:59:9
+   |
+LL |         100. as f32;
+   |         ^^^^^^^^^^^ help: try: `100_f32`
+
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:60:9
+   |
+LL |         100. as f64;
+   |         ^^^^^^^^^^^ help: try: `100_f64`
+
+error: casting integer literal to `u32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:72:9
+   |
+LL |         1 as u32;
+   |         ^^^^^^^^ help: try: `1_u32`
+
+error: casting integer literal to `i32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:73:9
+   |
+LL |         0x10 as i32;
+   |         ^^^^^^^^^^^ help: try: `0x10_i32`
+
+error: casting integer literal to `usize` is unnecessary
+  --> $DIR/unnecessary_cast.rs:74:9
+   |
+LL |         0b10 as usize;
+   |         ^^^^^^^^^^^^^ help: try: `0b10_usize`
+
+error: casting integer literal to `u16` is unnecessary
+  --> $DIR/unnecessary_cast.rs:75:9
+   |
+LL |         0o73 as u16;
+   |         ^^^^^^^^^^^ help: try: `0o73_u16`
+
+error: casting integer literal to `u32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:76:9
+   |
+LL |         1_000_000_000 as u32;
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32`
+
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:78:9
+   |
+LL |         1.0 as f64;
+   |         ^^^^^^^^^^ help: try: `1.0_f64`
+
+error: casting float literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:79:9
+   |
+LL |         0.5 as f32;
+   |         ^^^^^^^^^^ help: try: `0.5_f32`
+
+error: casting integer literal to `i32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:83:17
+   |
+LL |         let _ = -1 as i32;
+   |                 ^^^^^^^^^ help: try: `-1_i32`
+
+error: casting float literal to `f32` is unnecessary
+  --> $DIR/unnecessary_cast.rs:84:17
+   |
+LL |         let _ = -1.0 as f32;
+   |                 ^^^^^^^^^^^ help: try: `-1.0_f32`
+
+error: aborting due to 25 previous errors
 
diff --git a/tests/ui/unnecessary_cast_fixable.fixed b/tests/ui/unnecessary_cast_fixable.fixed
deleted file mode 100644
index 36800c5340d..00000000000
--- a/tests/ui/unnecessary_cast_fixable.fixed
+++ /dev/null
@@ -1,50 +0,0 @@
-// run-rustfix
-
-#![warn(clippy::unnecessary_cast)]
-#![allow(
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::nonstandard_macro_braces,
-    clippy::borrow_as_ptr
-)]
-
-fn main() {
-    // casting integer literal to float is unnecessary
-    100_f32;
-    100_f64;
-    100_f64;
-    let _ = -100_f32;
-    let _ = -100_f64;
-    let _ = -100_f64;
-    100_f32;
-    100_f64;
-    // Should not trigger
-    #[rustfmt::skip]
-    let v = vec!(1);
-    &v as &[i32];
-    0x10 as f32;
-    0o10 as f32;
-    0b10 as f32;
-    0x11 as f64;
-    0o11 as f64;
-    0b11 as f64;
-
-    1_u32;
-    0x10_i32;
-    0b10_usize;
-    0o73_u16;
-    1_000_000_000_u32;
-
-    1.0_f64;
-    0.5_f32;
-
-    1.0 as u16;
-
-    let _ = -1_i32;
-    let _ = -1.0_f32;
-
-    let _ = 1 as I32Alias;
-    let _ = &1 as &I32Alias;
-}
-
-type I32Alias = i32;
diff --git a/tests/ui/unnecessary_cast_fixable.rs b/tests/ui/unnecessary_cast_fixable.rs
deleted file mode 100644
index d4b6bb952ab..00000000000
--- a/tests/ui/unnecessary_cast_fixable.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// run-rustfix
-
-#![warn(clippy::unnecessary_cast)]
-#![allow(
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::nonstandard_macro_braces,
-    clippy::borrow_as_ptr
-)]
-
-fn main() {
-    // casting integer literal to float is unnecessary
-    100 as f32;
-    100 as f64;
-    100_i32 as f64;
-    let _ = -100 as f32;
-    let _ = -100 as f64;
-    let _ = -100_i32 as f64;
-    100. as f32;
-    100. as f64;
-    // Should not trigger
-    #[rustfmt::skip]
-    let v = vec!(1);
-    &v as &[i32];
-    0x10 as f32;
-    0o10 as f32;
-    0b10 as f32;
-    0x11 as f64;
-    0o11 as f64;
-    0b11 as f64;
-
-    1 as u32;
-    0x10 as i32;
-    0b10 as usize;
-    0o73 as u16;
-    1_000_000_000 as u32;
-
-    1.0 as f64;
-    0.5 as f32;
-
-    1.0 as u16;
-
-    let _ = -1 as i32;
-    let _ = -1.0 as f32;
-
-    let _ = 1 as I32Alias;
-    let _ = &1 as &I32Alias;
-}
-
-type I32Alias = i32;
diff --git a/tests/ui/unnecessary_cast_fixable.stderr b/tests/ui/unnecessary_cast_fixable.stderr
deleted file mode 100644
index a281143281b..00000000000
--- a/tests/ui/unnecessary_cast_fixable.stderr
+++ /dev/null
@@ -1,106 +0,0 @@
-error: casting integer literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:13:5
-   |
-LL |     100 as f32;
-   |     ^^^^^^^^^^ help: try: `100_f32`
-   |
-   = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
-
-error: casting integer literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:14:5
-   |
-LL |     100 as f64;
-   |     ^^^^^^^^^^ help: try: `100_f64`
-
-error: casting integer literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:15:5
-   |
-LL |     100_i32 as f64;
-   |     ^^^^^^^^^^^^^^ help: try: `100_f64`
-
-error: casting integer literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:16:13
-   |
-LL |     let _ = -100 as f32;
-   |             ^^^^^^^^^^^ help: try: `-100_f32`
-
-error: casting integer literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:17:13
-   |
-LL |     let _ = -100 as f64;
-   |             ^^^^^^^^^^^ help: try: `-100_f64`
-
-error: casting integer literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:18:13
-   |
-LL |     let _ = -100_i32 as f64;
-   |             ^^^^^^^^^^^^^^^ help: try: `-100_f64`
-
-error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:19:5
-   |
-LL |     100. as f32;
-   |     ^^^^^^^^^^^ help: try: `100_f32`
-
-error: casting float literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:20:5
-   |
-LL |     100. as f64;
-   |     ^^^^^^^^^^^ help: try: `100_f64`
-
-error: casting integer literal to `u32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:32:5
-   |
-LL |     1 as u32;
-   |     ^^^^^^^^ help: try: `1_u32`
-
-error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:33:5
-   |
-LL |     0x10 as i32;
-   |     ^^^^^^^^^^^ help: try: `0x10_i32`
-
-error: casting integer literal to `usize` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:34:5
-   |
-LL |     0b10 as usize;
-   |     ^^^^^^^^^^^^^ help: try: `0b10_usize`
-
-error: casting integer literal to `u16` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:35:5
-   |
-LL |     0o73 as u16;
-   |     ^^^^^^^^^^^ help: try: `0o73_u16`
-
-error: casting integer literal to `u32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:36:5
-   |
-LL |     1_000_000_000 as u32;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32`
-
-error: casting float literal to `f64` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:38:5
-   |
-LL |     1.0 as f64;
-   |     ^^^^^^^^^^ help: try: `1.0_f64`
-
-error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:39:5
-   |
-LL |     0.5 as f32;
-   |     ^^^^^^^^^^ help: try: `0.5_f32`
-
-error: casting integer literal to `i32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:43:13
-   |
-LL |     let _ = -1 as i32;
-   |             ^^^^^^^^^ help: try: `-1_i32`
-
-error: casting float literal to `f32` is unnecessary
-  --> $DIR/unnecessary_cast_fixable.rs:44:13
-   |
-LL |     let _ = -1.0 as f32;
-   |             ^^^^^^^^^^^ help: try: `-1.0_f32`
-
-error: aborting due to 17 previous errors
-