about summary refs log tree commit diff
path: root/tests/ui
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui')
-rw-r--r--tests/ui/auxiliary/proc_macro_derive.rs12
-rw-r--r--tests/ui/blocks_in_if_conditions_closure.rs11
-rw-r--r--tests/ui/collapsible_else_if.fixed9
-rw-r--r--tests/ui/collapsible_else_if.rs9
-rw-r--r--tests/ui/collapsible_if.fixed7
-rw-r--r--tests/ui/collapsible_if.rs7
-rw-r--r--tests/ui/collapsible_match.rs8
-rw-r--r--tests/ui/collapsible_match.stderr60
-rw-r--r--tests/ui/collapsible_match2.stderr30
-rw-r--r--tests/ui/crashes/ice-6179.rs21
-rw-r--r--tests/ui/default_numeric_fallback.rs135
-rw-r--r--tests/ui/default_numeric_fallback.stderr148
-rw-r--r--tests/ui/doc.rs12
-rw-r--r--tests/ui/doc.stderr44
-rw-r--r--tests/ui/doc_panics.rs27
-rw-r--r--tests/ui/doc_panics.stderr21
-rw-r--r--tests/ui/enum_variants.rs13
-rw-r--r--tests/ui/enum_variants.stderr26
-rw-r--r--tests/ui/from_str_radix_10.rs52
-rw-r--r--tests/ui/from_str_radix_10.stderr52
-rw-r--r--tests/ui/if_same_then_else2.rs6
-rw-r--r--tests/ui/if_same_then_else2.stderr4
-rw-r--r--tests/ui/inconsistent_struct_constructor.fixed61
-rw-r--r--tests/ui/inconsistent_struct_constructor.rs65
-rw-r--r--tests/ui/inconsistent_struct_constructor.stderr20
-rw-r--r--tests/ui/inherent_to_string.rs11
-rw-r--r--tests/ui/inherent_to_string.stderr4
-rw-r--r--tests/ui/manual_map_option.fixed70
-rw-r--r--tests/ui/manual_map_option.rs122
-rw-r--r--tests/ui/manual_map_option.stderr158
-rw-r--r--tests/ui/result_unit_error.rs23
-rw-r--r--tests/ui/result_unit_error.stderr18
-rw-r--r--tests/ui/temporary_assignment.rs1
-rw-r--r--tests/ui/temporary_assignment.stderr8
-rw-r--r--tests/ui/unnecessary_wraps.rs45
-rw-r--r--tests/ui/unnecessary_wraps.stderr64
-rw-r--r--tests/ui/use_self.fixed224
-rw-r--r--tests/ui/use_self.rs222
-rw-r--r--tests/ui/use_self.stderr118
-rw-r--r--tests/ui/use_self_trait.fixed3
-rw-r--r--tests/ui/use_self_trait.rs1
-rw-r--r--tests/ui/use_self_trait.stderr8
-rw-r--r--tests/ui/vec_init_then_push.rs25
-rw-r--r--tests/ui/vec_init_then_push.stderr2
44 files changed, 1813 insertions, 174 deletions
diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs
index 24891682d36..aebeaf34679 100644
--- a/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/tests/ui/auxiliary/proc_macro_derive.rs
@@ -41,3 +41,15 @@ pub fn derive_foo(_input: TokenStream) -> TokenStream {
         }
     }
 }
+
+#[proc_macro_derive(StructAUseSelf)]
+pub fn derive_use_self(_input: TokenStream) -> proc_macro::TokenStream {
+    quote! {
+        struct A;
+        impl A {
+            fn new() -> A {
+                A
+            }
+        }
+    }
+}
diff --git a/tests/ui/blocks_in_if_conditions_closure.rs b/tests/ui/blocks_in_if_conditions_closure.rs
index acbabfa20d7..2856943b9be 100644
--- a/tests/ui/blocks_in_if_conditions_closure.rs
+++ b/tests/ui/blocks_in_if_conditions_closure.rs
@@ -44,4 +44,13 @@ fn macro_in_closure() {
     }
 }
 
-fn main() {}
+#[rustfmt::skip]
+fn main() {
+    let mut range = 0..10;
+    range.all(|i| {i < 10} );
+
+    let v = vec![1, 2, 3];
+    if v.into_iter().any(|x| {x == 4}) {
+        println!("contains 4!");
+    }
+}
diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed
index fa4bc30e933..c69a46f0a77 100644
--- a/tests/ui/collapsible_else_if.fixed
+++ b/tests/ui/collapsible_else_if.fixed
@@ -65,4 +65,13 @@ fn main() {
     else {
         println!("!")
     }
+
+    if x == "hello" {
+        print!("Hello ");
+    } else {
+        #[cfg(not(roflol))]
+        if y == "world" {
+            println!("world!")
+        }
+    }
 }
diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs
index bf6c1d1f894..1359c7eb627 100644
--- a/tests/ui/collapsible_else_if.rs
+++ b/tests/ui/collapsible_else_if.rs
@@ -79,4 +79,13 @@ fn main() {
             println!("!")
         }
     }
+
+    if x == "hello" {
+        print!("Hello ");
+    } else {
+        #[cfg(not(roflol))]
+        if y == "world" {
+            println!("world!")
+        }
+    }
 }
diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed
index efd4187947b..e4c088bf6f0 100644
--- a/tests/ui/collapsible_if.fixed
+++ b/tests/ui/collapsible_if.fixed
@@ -138,4 +138,11 @@ fn main() {
 
     // Fix #5962
     if matches!(true, true) && matches!(true, true) {}
+
+    if true {
+        #[cfg(not(teehee))]
+        if true {
+            println!("Hello world!");
+        }
+    }
 }
diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs
index 657f32d38a3..d6cf01c8319 100644
--- a/tests/ui/collapsible_if.rs
+++ b/tests/ui/collapsible_if.rs
@@ -154,4 +154,11 @@ fn main() {
     if matches!(true, true) {
         if matches!(true, true) {}
     }
+
+    if true {
+        #[cfg(not(teehee))]
+        if true {
+            println!("Hello world!");
+        }
+    }
 }
diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs
index 3294da7e814..55467cf4229 100644
--- a/tests/ui/collapsible_match.rs
+++ b/tests/ui/collapsible_match.rs
@@ -232,6 +232,14 @@ fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u
             };
         }
     }
+    let _: &dyn std::any::Any = match &Some(Some(1)) {
+        Some(e) => match e {
+            Some(e) => e,
+            e => e,
+        },
+        // else branch looks the same but the binding is different
+        e => e,
+    };
 }
 
 fn make<T>() -> T {
diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr
index 63ac6a1613d..77978884900 100644
--- a/tests/ui/collapsible_match.stderr
+++ b/tests/ui/collapsible_match.stderr
@@ -1,4 +1,4 @@
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:7:20
    |
 LL |           Ok(val) => match val {
@@ -9,15 +9,15 @@ LL | |         },
    | |_________^
    |
    = note: `-D clippy::collapsible-match` implied by `-D warnings`
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:7:12
    |
 LL |         Ok(val) => match val {
-   |            ^^^ Replace this binding
+   |            ^^^ replace this binding
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:16:20
    |
 LL |           Ok(val) => match val {
@@ -27,15 +27,15 @@ LL | |             _ => return,
 LL | |         },
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:16:12
    |
 LL |         Ok(val) => match val {
-   |            ^^^ Replace this binding
+   |            ^^^ replace this binding
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:25:9
    |
 LL | /         if let Some(n) = val {
@@ -43,15 +43,15 @@ LL | |             take(n);
 LL | |         }
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:24:15
    |
 LL |     if let Ok(val) = res_opt {
-   |               ^^^ Replace this binding
+   |               ^^^ replace this binding
 LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:32:9
    |
 LL | /         if let Some(n) = val {
@@ -61,15 +61,15 @@ LL | |             return;
 LL | |         }
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:31:15
    |
 LL |     if let Ok(val) = res_opt {
-   |               ^^^ Replace this binding
+   |               ^^^ replace this binding
 LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:43:9
    |
 LL | /         match val {
@@ -78,16 +78,16 @@ LL | |             _ => (),
 LL | |         }
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:42:15
    |
 LL |     if let Ok(val) = res_opt {
-   |               ^^^ Replace this binding
+   |               ^^^ replace this binding
 LL |         match val {
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:52:13
    |
 LL | /             if let Some(n) = val {
@@ -95,15 +95,15 @@ LL | |                 take(n);
 LL | |             }
    | |_____________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:51:12
    |
 LL |         Ok(val) => {
-   |            ^^^ Replace this binding
+   |            ^^^ replace this binding
 LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:61:9
    |
 LL | /         match val {
@@ -112,16 +112,16 @@ LL | |             _ => return,
 LL | |         }
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:60:15
    |
 LL |     if let Ok(val) = res_opt {
-   |               ^^^ Replace this binding
+   |               ^^^ replace this binding
 LL |         match val {
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:72:13
    |
 LL | /             if let Some(n) = val {
@@ -131,15 +131,15 @@ LL | |                 return;
 LL | |             }
    | |_____________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:71:12
    |
 LL |         Ok(val) => {
-   |            ^^^ Replace this binding
+   |            ^^^ replace this binding
 LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:83:20
    |
 LL |           Ok(val) => match val {
@@ -149,15 +149,15 @@ LL | |             None => return,
 LL | |         },
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:83:12
    |
 LL |         Ok(val) => match val {
-   |            ^^^ Replace this binding
+   |            ^^^ replace this binding
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match.rs:92:22
    |
 LL |           Some(val) => match val {
@@ -167,11 +167,11 @@ LL | |             _ => return,
 LL | |         },
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:92:14
    |
 LL |         Some(val) => match val {
-   |              ^^^ Replace this binding
+   |              ^^^ replace this binding
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
diff --git a/tests/ui/collapsible_match2.stderr b/tests/ui/collapsible_match2.stderr
index b2eb457d173..c8a445ef369 100644
--- a/tests/ui/collapsible_match2.stderr
+++ b/tests/ui/collapsible_match2.stderr
@@ -1,4 +1,4 @@
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match2.rs:8:34
    |
 LL |               Ok(val) if make() => match val {
@@ -9,15 +9,15 @@ LL | |             },
    | |_____________^
    |
    = note: `-D clippy::collapsible-match` implied by `-D warnings`
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:8:16
    |
 LL |             Ok(val) if make() => match val {
-   |                ^^^ Replace this binding
+   |                ^^^ replace this binding
 LL |                 Some(n) => foo(n),
    |                 ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match2.rs:15:24
    |
 LL |               Ok(val) => match val {
@@ -27,15 +27,15 @@ LL | |                 _ => return,
 LL | |             },
    | |_____________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:15:16
    |
 LL |             Ok(val) => match val {
-   |                ^^^ Replace this binding
+   |                ^^^ replace this binding
 LL |                 Some(n) => foo(n),
    |                 ^^^^^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match2.rs:29:29
    |
 LL |                       $pat => match $e {
@@ -48,16 +48,16 @@ LL | |                     },
 LL |           mac!(res_opt => Ok(val), val => Some(n), foo(n));
    |           ------------------------------------------------- in this macro invocation
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:41:28
    |
 LL |         mac!(res_opt => Ok(val), val => Some(n), foo(n));
    |                            ^^^          ^^^^^^^ with this pattern
    |                            |
-   |                            Replace this binding
+   |                            replace this binding
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match2.rs:46:20
    |
 LL |           Some(s) => match *s {
@@ -67,15 +67,15 @@ LL | |             _ => (),
 LL | |         },
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:46:14
    |
 LL |         Some(s) => match *s {
-   |              ^ Replace this binding
+   |              ^ replace this binding
 LL |             [n] => foo(n),
    |             ^^^ with this pattern
 
-error: Unnecessary nested match
+error: unnecessary nested match
   --> $DIR/collapsible_match2.rs:55:24
    |
 LL |           Some(ref s) => match &*s {
@@ -85,11 +85,11 @@ LL | |             _ => (),
 LL | |         },
    | |_________^
    |
-help: The outer pattern can be modified to include the inner pattern.
+help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:55:14
    |
 LL |         Some(ref s) => match &*s {
-   |              ^^^^^ Replace this binding
+   |              ^^^^^ replace this binding
 LL |             [n] => foo(n),
    |             ^^^ with this pattern
 
diff --git a/tests/ui/crashes/ice-6179.rs b/tests/ui/crashes/ice-6179.rs
new file mode 100644
index 00000000000..f8c866a49aa
--- /dev/null
+++ b/tests/ui/crashes/ice-6179.rs
@@ -0,0 +1,21 @@
+//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.
+//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details.
+
+#![warn(clippy::use_self)]
+#![allow(dead_code)]
+
+struct Foo {}
+
+impl Foo {
+    fn foo() -> Self {
+        impl Foo {
+            fn bar() {}
+        }
+
+        let _: _ = 1;
+
+        Self {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/default_numeric_fallback.rs b/tests/ui/default_numeric_fallback.rs
new file mode 100644
index 00000000000..0b3758952ac
--- /dev/null
+++ b/tests/ui/default_numeric_fallback.rs
@@ -0,0 +1,135 @@
+#![warn(clippy::default_numeric_fallback)]
+#![allow(unused)]
+#![allow(clippy::never_loop)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::unnecessary_operation)]
+
+mod basic_expr {
+    fn test() {
+        // Should lint unsuffixed literals typed `i32`.
+        let x = 22;
+        let x = [1, 2, 3];
+        let x = if true { (1, 2) } else { (3, 4) };
+        let x = match 1 {
+            1 => 1,
+            _ => 2,
+        };
+
+        // Should lint unsuffixed literals typed `f64`.
+        let x = 0.12;
+
+        // Should NOT lint suffixed literals.
+        let x = 22_i32;
+        let x = 0.12_f64;
+
+        // Should NOT lint literals in init expr if `Local` has a type annotation.
+        let x: f64 = 0.1;
+        let x: [i32; 3] = [1, 2, 3];
+        let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };
+        let x: _ = 1;
+    }
+}
+
+mod nested_local {
+    fn test() {
+        let x: _ = {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1
+        };
+
+        let x: _ = if true {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1
+        } else {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            2
+        };
+    }
+}
+
+mod function_def {
+    fn ret_i32() -> i32 {
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        1
+    }
+
+    fn test() {
+        // Should lint this because return type is inferred to `i32` and NOT bound to a concrete
+        // type.
+        let f = || -> _ { 1 };
+
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        let f = || -> i32 { 1 };
+    }
+}
+
+mod function_calls {
+    fn concrete_arg(x: i32) {}
+
+    fn generic_arg<T>(t: T) {}
+
+    fn test() {
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        concrete_arg(1);
+
+        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
+        generic_arg(1);
+
+        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
+        let x: _ = generic_arg(1);
+    }
+}
+
+mod struct_ctor {
+    struct ConcreteStruct {
+        x: i32,
+    }
+
+    struct GenericStruct<T> {
+        x: T,
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteStruct { x: 1 };
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        GenericStruct { x: 1 };
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        let _ = GenericStruct { x: 1 };
+    }
+}
+
+mod method_calls {
+    struct StructForMethodCallTest {}
+
+    impl StructForMethodCallTest {
+        fn concrete_arg(&self, x: i32) {}
+
+        fn generic_arg<T>(&self, t: T) {}
+    }
+
+    fn test() {
+        let s = StructForMethodCallTest {};
+
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        s.concrete_arg(1);
+
+        // Should lint this because the argument type is bound to a concrete type.
+        s.generic_arg(1);
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/default_numeric_fallback.stderr b/tests/ui/default_numeric_fallback.stderr
new file mode 100644
index 00000000000..b31aa4ebcf8
--- /dev/null
+++ b/tests/ui/default_numeric_fallback.stderr
@@ -0,0 +1,148 @@
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:10:17
+   |
+LL |         let x = 22;
+   |                 ^^ help: consider adding suffix: `22_i32`
+   |
+   = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:11:18
+   |
+LL |         let x = [1, 2, 3];
+   |                  ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:11:21
+   |
+LL |         let x = [1, 2, 3];
+   |                     ^ help: consider adding suffix: `2_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:11:24
+   |
+LL |         let x = [1, 2, 3];
+   |                        ^ help: consider adding suffix: `3_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:12:28
+   |
+LL |         let x = if true { (1, 2) } else { (3, 4) };
+   |                            ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:12:31
+   |
+LL |         let x = if true { (1, 2) } else { (3, 4) };
+   |                               ^ help: consider adding suffix: `2_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:12:44
+   |
+LL |         let x = if true { (1, 2) } else { (3, 4) };
+   |                                            ^ help: consider adding suffix: `3_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:12:47
+   |
+LL |         let x = if true { (1, 2) } else { (3, 4) };
+   |                                               ^ help: consider adding suffix: `4_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:13:23
+   |
+LL |         let x = match 1 {
+   |                       ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:14:13
+   |
+LL |             1 => 1,
+   |             ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:14:18
+   |
+LL |             1 => 1,
+   |                  ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:15:18
+   |
+LL |             _ => 2,
+   |                  ^ help: consider adding suffix: `2_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:19:17
+   |
+LL |         let x = 0.12;
+   |                 ^^^^ help: consider adding suffix: `0.12_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:37:21
+   |
+LL |             let y = 1;
+   |                     ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:45:21
+   |
+LL |             let y = 1;
+   |                     ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:51:21
+   |
+LL |             let y = 1;
+   |                     ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:63:9
+   |
+LL |         1
+   |         ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:69:27
+   |
+LL |         let f = || -> _ { 1 };
+   |                           ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:73:29
+   |
+LL |         let f = || -> i32 { 1 };
+   |                             ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:87:21
+   |
+LL |         generic_arg(1);
+   |                     ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:90:32
+   |
+LL |         let x: _ = generic_arg(1);
+   |                                ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:108:28
+   |
+LL |         GenericStruct { x: 1 };
+   |                            ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:111:36
+   |
+LL |         let _ = GenericStruct { x: 1 };
+   |                                    ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:131:23
+   |
+LL |         s.generic_arg(1);
+   |                       ^ help: consider adding suffix: `1_i32`
+
+error: aborting due to 24 previous errors
+
diff --git a/tests/ui/doc.rs b/tests/ui/doc.rs
index e30970ed952..d2c666bd290 100644
--- a/tests/ui/doc.rs
+++ b/tests/ui/doc.rs
@@ -50,11 +50,23 @@ fn test_units() {
 }
 
 /// This tests allowed identifiers.
+/// KiB MiB GiB TiB PiB EiB
 /// DirectX
 /// ECMAScript
+/// GPLv2 GPLv3
+/// GitHub GitLab
+/// IPv4 IPv6
+/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
+/// NaN NaNs
 /// OAuth GraphQL
+/// OCaml
+/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
 /// WebGL
+/// TensorFlow
+/// TrueType
+/// iOS macOS
 /// TeX LaTeX BibTeX BibLaTeX
+/// MinGW
 /// CamelCase (see also #2395)
 /// be_sure_we_got_to_the_end_of_it
 fn test_allowed() {
diff --git a/tests/ui/doc.stderr b/tests/ui/doc.stderr
index e1c1aa85a60..7eab8a85f09 100644
--- a/tests/ui/doc.stderr
+++ b/tests/ui/doc.stderr
@@ -55,133 +55,133 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:59:5
+  --> $DIR/doc.rs:71:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `link_with_underscores` between ticks in the documentation
-  --> $DIR/doc.rs:63:22
+  --> $DIR/doc.rs:75:22
    |
 LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823.
    |                      ^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `inline_link2` between ticks in the documentation
-  --> $DIR/doc.rs:66:21
+  --> $DIR/doc.rs:78:21
    |
 LL | /// It can also be [inline_link2].
    |                     ^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:76:5
+  --> $DIR/doc.rs:88:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:84:8
+  --> $DIR/doc.rs:96:8
    |
 LL | /// ## CamelCaseThing
    |        ^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:87:7
+  --> $DIR/doc.rs:99:7
    |
 LL | /// # CamelCaseThing
    |       ^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:89:22
+  --> $DIR/doc.rs:101:22
    |
 LL | /// Not a title #897 CamelCaseThing
    |                      ^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:90:5
+  --> $DIR/doc.rs:102:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:97:5
+  --> $DIR/doc.rs:109:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:110:5
+  --> $DIR/doc.rs:122:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:121:43
+  --> $DIR/doc.rs:133:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
 
 error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:126:5
+  --> $DIR/doc.rs:138:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:127:1
+  --> $DIR/doc.rs:139:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:132:43
+  --> $DIR/doc.rs:144:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
 
 error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:137:5
+  --> $DIR/doc.rs:149:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:138:1
+  --> $DIR/doc.rs:150:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:149:5
+  --> $DIR/doc.rs:161:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:176:13
+  --> $DIR/doc.rs:188:13
    |
 LL | /// Not ok: http://www.unicode.org
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:177:13
+  --> $DIR/doc.rs:189:13
    |
 LL | /// Not ok: https://www.unicode.org
    |             ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:178:13
+  --> $DIR/doc.rs:190:13
    |
 LL | /// Not ok: http://www.unicode.org/
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:179:13
+  --> $DIR/doc.rs:191:13
    |
 LL | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `mycrate::Collection` between ticks in the documentation
-  --> $DIR/doc.rs:182:22
+  --> $DIR/doc.rs:194:22
    |
 LL | /// An iterator over mycrate::Collection's values.
    |                      ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/doc_panics.rs b/tests/ui/doc_panics.rs
index 7ef932f367b..3008c2d5b85 100644
--- a/tests/ui/doc_panics.rs
+++ b/tests/ui/doc_panics.rs
@@ -28,6 +28,15 @@ pub fn inner_body(opt: Option<u32>) {
     });
 }
 
+/// This needs to be documented
+pub fn unreachable_and_panic() {
+    if true {
+        unreachable!()
+    } else {
+        panic!()
+    }
+}
+
 /// This is documented
 ///
 /// # Panics
@@ -69,6 +78,19 @@ pub fn todo_documented() {
     todo!()
 }
 
+/// This is documented
+///
+/// # Panics
+///
+/// We still need to do this part
+pub fn unreachable_amd_panic_documented() {
+    if true {
+        unreachable!()
+    } else {
+        panic!()
+    }
+}
+
 /// This is okay because it is private
 fn unwrap_private() {
     let result = Err("Hi");
@@ -93,3 +115,8 @@ fn inner_body_private(opt: Option<u32>) {
         }
     });
 }
+
+/// This is okay because unreachable
+pub fn unreachable() {
+    unreachable!("This function panics")
+}
diff --git a/tests/ui/doc_panics.stderr b/tests/ui/doc_panics.stderr
index c0c4e9e4fa7..287148690d2 100644
--- a/tests/ui/doc_panics.stderr
+++ b/tests/ui/doc_panics.stderr
@@ -63,5 +63,24 @@ LL |             panic!()
    |             ^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error: docs for function which may panic missing `# Panics` section
+  --> $DIR/doc_panics.rs:32:1
+   |
+LL | / pub fn unreachable_and_panic() {
+LL | |     if true {
+LL | |         unreachable!()
+LL | |     } else {
+LL | |         panic!()
+LL | |     }
+LL | | }
+   | |_^
+   |
+note: first possible panic found here
+  --> $DIR/doc_panics.rs:36:9
+   |
+LL |         panic!()
+   |         ^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/enum_variants.rs b/tests/ui/enum_variants.rs
index 89d99dcf0c8..4fefc0b43f1 100644
--- a/tests/ui/enum_variants.rs
+++ b/tests/ui/enum_variants.rs
@@ -133,4 +133,17 @@ pub enum NetworkLayer {
     Layer3,
 }
 
+// should lint suggesting `IData`, not only `Data` (see #4639)
+enum IDataRequest {
+    PutIData(String),
+    GetIData(String),
+    DeleteUnpubIData(String),
+}
+
+enum HIDataRequest {
+    PutHIData(String),
+    GetHIData(String),
+    DeleteUnpubHIData(String),
+}
+
 fn main() {}
diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr
index b1d481190ff..ab7fff4507a 100644
--- a/tests/ui/enum_variants.stderr
+++ b/tests/ui/enum_variants.stderr
@@ -97,5 +97,29 @@ LL | | }
    = note: `-D clippy::pub-enum-variant-names` implied by `-D warnings`
    = help: remove the prefixes and use full paths to the variants instead of glob imports
 
-error: aborting due to 10 previous errors
+error: all variants have the same postfix: `IData`
+  --> $DIR/enum_variants.rs:137:1
+   |
+LL | / enum IDataRequest {
+LL | |     PutIData(String),
+LL | |     GetIData(String),
+LL | |     DeleteUnpubIData(String),
+LL | | }
+   | |_^
+   |
+   = help: remove the postfixes and use full paths to the variants instead of glob imports
+
+error: all variants have the same postfix: `HIData`
+  --> $DIR/enum_variants.rs:143:1
+   |
+LL | / enum HIDataRequest {
+LL | |     PutHIData(String),
+LL | |     GetHIData(String),
+LL | |     DeleteUnpubHIData(String),
+LL | | }
+   | |_^
+   |
+   = help: remove the postfixes and use full paths to the variants instead of glob imports
+
+error: aborting due to 12 previous errors
 
diff --git a/tests/ui/from_str_radix_10.rs b/tests/ui/from_str_radix_10.rs
new file mode 100644
index 00000000000..2f2ea04847a
--- /dev/null
+++ b/tests/ui/from_str_radix_10.rs
@@ -0,0 +1,52 @@
+#![warn(clippy::from_str_radix_10)]
+
+mod some_mod {
+    // fake function that shouldn't trigger the lint
+    pub fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {
+        unimplemented!()
+    }
+}
+
+// fake function that shouldn't trigger the lint
+fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {
+    unimplemented!()
+}
+
+// to test parenthesis addition
+struct Test;
+
+impl std::ops::Add<Test> for Test {
+    type Output = &'static str;
+
+    fn add(self, _: Self) -> Self::Output {
+        "304"
+    }
+}
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // all of these should trigger the lint
+    u32::from_str_radix("30", 10)?;
+    i64::from_str_radix("24", 10)?;
+    isize::from_str_radix("100", 10)?;
+    u8::from_str_radix("7", 10)?;
+    u16::from_str_radix(&("10".to_owned() + "5"), 10)?;
+    i128::from_str_radix(Test + Test, 10)?;
+
+    let string = "300";
+    i32::from_str_radix(string, 10)?;
+
+    let stringier = "400".to_string();
+    i32::from_str_radix(&stringier, 10)?;
+
+    // none of these should trigger the lint
+    u16::from_str_radix("20", 3)?;
+    i32::from_str_radix("45", 12)?;
+    usize::from_str_radix("10", 16)?;
+    i128::from_str_radix("10", 13)?;
+    some_mod::from_str_radix("50", 10)?;
+    some_mod::from_str_radix("50", 6)?;
+    from_str_radix("50", 10)?;
+    from_str_radix("50", 6)?;
+
+    Ok(())
+}
diff --git a/tests/ui/from_str_radix_10.stderr b/tests/ui/from_str_radix_10.stderr
new file mode 100644
index 00000000000..471bf52a9a7
--- /dev/null
+++ b/tests/ui/from_str_radix_10.stderr
@@ -0,0 +1,52 @@
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:28:5
+   |
+LL |     u32::from_str_radix("30", 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"30".parse::<u32>()`
+   |
+   = note: `-D clippy::from-str-radix-10` implied by `-D warnings`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:29:5
+   |
+LL |     i64::from_str_radix("24", 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"24".parse::<i64>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:30:5
+   |
+LL |     isize::from_str_radix("100", 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"100".parse::<isize>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:31:5
+   |
+LL |     u8::from_str_radix("7", 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"7".parse::<u8>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:32:5
+   |
+LL |     u16::from_str_radix(&("10".to_owned() + "5"), 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(("10".to_owned() + "5")).parse::<u16>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:33:5
+   |
+LL |     i128::from_str_radix(Test + Test, 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::<i128>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:36:5
+   |
+LL |     i32::from_str_radix(string, 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::<i32>()`
+
+error: this call to `from_str_radix` can be replaced with a call to `str::parse`
+  --> $DIR/from_str_radix_10.rs:39:5
+   |
+LL |     i32::from_str_radix(&stringier, 10)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::<i32>()`
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs
index e83ce47e563..a2ff1b741ca 100644
--- a/tests/ui/if_same_then_else2.rs
+++ b/tests/ui/if_same_then_else2.rs
@@ -12,7 +12,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     if true {
         for _ in &[42] {
             let foo: &Option<_> = &Some::<u8>(42);
-            if true {
+            if foo.is_some() {
                 break;
             } else {
                 continue;
@@ -21,8 +21,8 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     } else {
         //~ ERROR same body as `if` block
         for _ in &[42] {
-            let foo: &Option<_> = &Some::<u8>(42);
-            if true {
+            let bar: &Option<_> = &Some::<u8>(42);
+            if bar.is_some() {
                 break;
             } else {
                 continue;
diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr
index f98e30fa376..454322d8aac 100644
--- a/tests/ui/if_same_then_else2.stderr
+++ b/tests/ui/if_same_then_else2.stderr
@@ -5,7 +5,7 @@ LL |       } else {
    |  ____________^
 LL | |         //~ ERROR same body as `if` block
 LL | |         for _ in &[42] {
-LL | |             let foo: &Option<_> = &Some::<u8>(42);
+LL | |             let bar: &Option<_> = &Some::<u8>(42);
 ...  |
 LL | |         }
 LL | |     }
@@ -19,7 +19,7 @@ LL |       if true {
    |  _____________^
 LL | |         for _ in &[42] {
 LL | |             let foo: &Option<_> = &Some::<u8>(42);
-LL | |             if true {
+LL | |             if foo.is_some() {
 ...  |
 LL | |         }
 LL | |     } else {
diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed
new file mode 100644
index 00000000000..8d9c3110035
--- /dev/null
+++ b/tests/ui/inconsistent_struct_constructor.fixed
@@ -0,0 +1,61 @@
+// run-rustfix
+// edition:2018
+#![warn(clippy::inconsistent_struct_constructor)]
+#![allow(clippy::redundant_field_names)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::no_effect)]
+#![allow(dead_code)]
+
+#[derive(Default)]
+struct Foo {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
+mod without_base {
+    use super::Foo;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should lint.
+        Foo { x, y, z };
+
+        // Shoule NOT lint because the order is the same as in the definition.
+        Foo { x, y, z };
+
+        // Should NOT lint because z is not a shorthand init.
+        Foo { y, x, z: z };
+    }
+}
+
+mod with_base {
+    use super::Foo;
+
+    fn test() {
+        let x = 1;
+        let z = 1;
+
+        // Should lint.
+        Foo { x, z, ..Default::default() };
+
+        // Should NOT lint because the order is consistent with the definition.
+        Foo {
+            x,
+            z,
+            ..Default::default()
+        };
+
+        // Should NOT lint because z is not a shorthand init.
+        Foo {
+            z: z,
+            x,
+            ..Default::default()
+        };
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs
new file mode 100644
index 00000000000..63fac910501
--- /dev/null
+++ b/tests/ui/inconsistent_struct_constructor.rs
@@ -0,0 +1,65 @@
+// run-rustfix
+// edition:2018
+#![warn(clippy::inconsistent_struct_constructor)]
+#![allow(clippy::redundant_field_names)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::no_effect)]
+#![allow(dead_code)]
+
+#[derive(Default)]
+struct Foo {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
+mod without_base {
+    use super::Foo;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should lint.
+        Foo { y, x, z };
+
+        // Shoule NOT lint because the order is the same as in the definition.
+        Foo { x, y, z };
+
+        // Should NOT lint because z is not a shorthand init.
+        Foo { y, x, z: z };
+    }
+}
+
+mod with_base {
+    use super::Foo;
+
+    fn test() {
+        let x = 1;
+        let z = 1;
+
+        // Should lint.
+        Foo {
+            z,
+            x,
+            ..Default::default()
+        };
+
+        // Should NOT lint because the order is consistent with the definition.
+        Foo {
+            x,
+            z,
+            ..Default::default()
+        };
+
+        // Should NOT lint because z is not a shorthand init.
+        Foo {
+            z: z,
+            x,
+            ..Default::default()
+        };
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/inconsistent_struct_constructor.stderr b/tests/ui/inconsistent_struct_constructor.stderr
new file mode 100644
index 00000000000..d7abe44f254
--- /dev/null
+++ b/tests/ui/inconsistent_struct_constructor.stderr
@@ -0,0 +1,20 @@
+error: inconsistent struct constructor
+  --> $DIR/inconsistent_struct_constructor.rs:25:9
+   |
+LL |         Foo { y, x, z };
+   |         ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
+   |
+   = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`
+
+error: inconsistent struct constructor
+  --> $DIR/inconsistent_struct_constructor.rs:43:9
+   |
+LL | /         Foo {
+LL | |             z,
+LL | |             x,
+LL | |             ..Default::default()
+LL | |         };
+   | |_________^ help: try: `Foo { x, z, ..Default::default() }`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/inherent_to_string.rs b/tests/ui/inherent_to_string.rs
index e6cf337d1bb..6e65fdbd04e 100644
--- a/tests/ui/inherent_to_string.rs
+++ b/tests/ui/inherent_to_string.rs
@@ -14,6 +14,7 @@ struct C;
 struct D;
 struct E;
 struct F;
+struct G;
 
 impl A {
     // Should be detected; emit warning
@@ -73,6 +74,13 @@ impl F {
     }
 }
 
+impl G {
+    // Should not be detected, as it does not match the function signature
+    fn to_string<const _N: usize>(&self) -> String {
+        "G.to_string()".to_string()
+    }
+}
+
 fn main() {
     let a = A;
     a.to_string();
@@ -93,4 +101,7 @@ fn main() {
 
     let f = F;
     f.to_string(1);
+
+    let g = G;
+    g.to_string::<1>();
 }
diff --git a/tests/ui/inherent_to_string.stderr b/tests/ui/inherent_to_string.stderr
index 4f331f5bec9..f5fcc193b4d 100644
--- a/tests/ui/inherent_to_string.stderr
+++ b/tests/ui/inherent_to_string.stderr
@@ -1,5 +1,5 @@
 error: implementation of inherent method `to_string(&self) -> String` for type `A`
-  --> $DIR/inherent_to_string.rs:20:5
+  --> $DIR/inherent_to_string.rs:21:5
    |
 LL | /     fn to_string(&self) -> String {
 LL | |         "A.to_string()".to_string()
@@ -10,7 +10,7 @@ LL | |     }
    = help: implement trait `Display` for type `A` instead
 
 error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`
-  --> $DIR/inherent_to_string.rs:44:5
+  --> $DIR/inherent_to_string.rs:45:5
    |
 LL | /     fn to_string(&self) -> String {
 LL | |         "C.to_string()".to_string()
diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed
new file mode 100644
index 00000000000..19350906758
--- /dev/null
+++ b/tests/ui/manual_map_option.fixed
@@ -0,0 +1,70 @@
+// run-rustfix
+
+#![warn(clippy::manual_map)]
+#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)]
+
+fn main() {
+    Some(0).map(|_| 2);
+
+    Some(0).map(|x| x + 1);
+
+    Some("").map(|x| x.is_empty());
+
+    Some(0).map(|x| !x);
+
+    #[rustfmt::skip]
+    Some(0).map(std::convert::identity);
+
+    Some(&String::new()).map(|x| str::len(x));
+
+    match Some(0) {
+        Some(x) if false => Some(x + 1),
+        _ => None,
+    };
+
+    Some([0, 1]).as_ref().map(|x| x[0]);
+
+    Some(0).map(|x| x * 2);
+
+    Some(String::new()).as_ref().map(|x| x.is_empty());
+
+    Some(String::new()).as_ref().map(|x| x.len());
+
+    Some(0).map(|x| x + x);
+
+    #[warn(clippy::option_map_unit_fn)]
+    match &mut Some(String::new()) {
+        Some(x) => Some(x.push_str("")),
+        None => None,
+    };
+
+    #[allow(clippy::option_map_unit_fn)]
+    {
+        Some(String::new()).as_mut().map(|x| x.push_str(""));
+    }
+
+    Some(String::new()).as_ref().map(|x| x.len());
+
+    Some(String::new()).as_ref().map(|x| x.is_empty());
+
+    Some((0, 1, 2)).map(|(x, y, z)| x + y + z);
+
+    Some([1, 2, 3]).map(|[first, ..]| first);
+
+    Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x));
+
+    match Some((String::new(), 0)) {
+        Some((ref x, y)) => Some((y, x)),
+        None => None,
+    };
+
+    match Some(Some(0)) {
+        Some(Some(_)) | Some(None) => Some(0),
+        None => None,
+    };
+
+    match Some(Some((0, 1))) {
+        Some(Some((x, 1))) => Some(x),
+        _ => None,
+    };
+}
diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs
new file mode 100644
index 00000000000..8b8187db0a9
--- /dev/null
+++ b/tests/ui/manual_map_option.rs
@@ -0,0 +1,122 @@
+// run-rustfix
+
+#![warn(clippy::manual_map)]
+#![allow(clippy::no_effect, clippy::map_identity, clippy::unit_arg, clippy::match_ref_pats)]
+
+fn main() {
+    match Some(0) {
+        Some(_) => Some(2),
+        None::<u32> => None,
+    };
+
+    match Some(0) {
+        Some(x) => Some(x + 1),
+        _ => None,
+    };
+
+    match Some("") {
+        Some(x) => Some(x.is_empty()),
+        None => None,
+    };
+
+    if let Some(x) = Some(0) {
+        Some(!x)
+    } else {
+        None
+    };
+
+    #[rustfmt::skip]
+    match Some(0) {
+        Some(x) => { Some(std::convert::identity(x)) }
+        None => { None }
+    };
+
+    match Some(&String::new()) {
+        Some(x) => Some(str::len(x)),
+        None => None,
+    };
+
+    match Some(0) {
+        Some(x) if false => Some(x + 1),
+        _ => None,
+    };
+
+    match &Some([0, 1]) {
+        Some(x) => Some(x[0]),
+        &None => None,
+    };
+
+    match &Some(0) {
+        &Some(x) => Some(x * 2),
+        None => None,
+    };
+
+    match Some(String::new()) {
+        Some(ref x) => Some(x.is_empty()),
+        _ => None,
+    };
+
+    match &&Some(String::new()) {
+        Some(x) => Some(x.len()),
+        _ => None,
+    };
+
+    match &&Some(0) {
+        &&Some(x) => Some(x + x),
+        &&_ => None,
+    };
+
+    #[warn(clippy::option_map_unit_fn)]
+    match &mut Some(String::new()) {
+        Some(x) => Some(x.push_str("")),
+        None => None,
+    };
+
+    #[allow(clippy::option_map_unit_fn)]
+    {
+        match &mut Some(String::new()) {
+            Some(x) => Some(x.push_str("")),
+            None => None,
+        };
+    }
+
+    match &mut Some(String::new()) {
+        Some(ref x) => Some(x.len()),
+        None => None,
+    };
+
+    match &mut &Some(String::new()) {
+        Some(x) => Some(x.is_empty()),
+        &mut _ => None,
+    };
+
+    match Some((0, 1, 2)) {
+        Some((x, y, z)) => Some(x + y + z),
+        None => None,
+    };
+
+    match Some([1, 2, 3]) {
+        Some([first, ..]) => Some(first),
+        None => None,
+    };
+
+    match &Some((String::new(), "test")) {
+        Some((x, y)) => Some((y, x)),
+        None => None,
+    };
+
+    match Some((String::new(), 0)) {
+        Some((ref x, y)) => Some((y, x)),
+        None => None,
+    };
+
+    match Some(Some(0)) {
+        Some(Some(_)) | Some(None) => Some(0),
+        None => None,
+    };
+
+    match Some(Some((0, 1))) {
+        Some(Some((x, 1))) => Some(x),
+        _ => None,
+    };
+}
diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr
new file mode 100644
index 00000000000..210a30d05d4
--- /dev/null
+++ b/tests/ui/manual_map_option.stderr
@@ -0,0 +1,158 @@
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:7:5
+   |
+LL | /     match Some(0) {
+LL | |         Some(_) => Some(2),
+LL | |         None::<u32> => None,
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(|_| 2)`
+   |
+   = note: `-D clippy::manual-map` implied by `-D warnings`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:12:5
+   |
+LL | /     match Some(0) {
+LL | |         Some(x) => Some(x + 1),
+LL | |         _ => None,
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(|x| x + 1)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:17:5
+   |
+LL | /     match Some("") {
+LL | |         Some(x) => Some(x.is_empty()),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some("").map(|x| x.is_empty())`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:22:5
+   |
+LL | /     if let Some(x) = Some(0) {
+LL | |         Some(!x)
+LL | |     } else {
+LL | |         None
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(|x| !x)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:29:5
+   |
+LL | /     match Some(0) {
+LL | |         Some(x) => { Some(std::convert::identity(x)) }
+LL | |         None => { None }
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(std::convert::identity)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:34:5
+   |
+LL | /     match Some(&String::new()) {
+LL | |         Some(x) => Some(str::len(x)),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:44:5
+   |
+LL | /     match &Some([0, 1]) {
+LL | |         Some(x) => Some(x[0]),
+LL | |         &None => None,
+LL | |     };
+   | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:49:5
+   |
+LL | /     match &Some(0) {
+LL | |         &Some(x) => Some(x * 2),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(|x| x * 2)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:54:5
+   |
+LL | /     match Some(String::new()) {
+LL | |         Some(ref x) => Some(x.is_empty()),
+LL | |         _ => None,
+LL | |     };
+   | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:59:5
+   |
+LL | /     match &&Some(String::new()) {
+LL | |         Some(x) => Some(x.len()),
+LL | |         _ => None,
+LL | |     };
+   | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:64:5
+   |
+LL | /     match &&Some(0) {
+LL | |         &&Some(x) => Some(x + x),
+LL | |         &&_ => None,
+LL | |     };
+   | |_____^ help: try this: `Some(0).map(|x| x + x)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:77:9
+   |
+LL | /         match &mut Some(String::new()) {
+LL | |             Some(x) => Some(x.push_str("")),
+LL | |             None => None,
+LL | |         };
+   | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:83:5
+   |
+LL | /     match &mut Some(String::new()) {
+LL | |         Some(ref x) => Some(x.len()),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:88:5
+   |
+LL | /     match &mut &Some(String::new()) {
+LL | |         Some(x) => Some(x.is_empty()),
+LL | |         &mut _ => None,
+LL | |     };
+   | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:93:5
+   |
+LL | /     match Some((0, 1, 2)) {
+LL | |         Some((x, y, z)) => Some(x + y + z),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:98:5
+   |
+LL | /     match Some([1, 2, 3]) {
+LL | |         Some([first, ..]) => Some(first),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)`
+
+error: manual implementation of `Option::map`
+  --> $DIR/manual_map_option.rs:103:5
+   |
+LL | /     match &Some((String::new(), "test")) {
+LL | |         Some((x, y)) => Some((y, x)),
+LL | |         None => None,
+LL | |     };
+   | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))`
+
+error: aborting due to 17 previous errors
+
diff --git a/tests/ui/result_unit_error.rs b/tests/ui/result_unit_error.rs
index 5e57c752b5a..a4ec803024e 100644
--- a/tests/ui/result_unit_error.rs
+++ b/tests/ui/result_unit_error.rs
@@ -1,6 +1,4 @@
-#![allow(clippy::unnecessary_wraps)]
-#[warn(clippy::result_unit_err)]
-#[allow(unused)]
+#![warn(clippy::result_unit_err)]
 
 pub fn returns_unit_error() -> Result<u32, ()> {
     Err(())
@@ -36,4 +34,23 @@ impl UnitErrorHolder {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/6546
+pub mod issue_6546 {
+    type ResInv<A, B> = Result<B, A>;
+
+    pub fn should_lint() -> ResInv<(), usize> {
+        Ok(0)
+    }
+
+    pub fn should_not_lint() -> ResInv<usize, ()> {
+        Ok(())
+    }
+
+    type MyRes<A, B> = Result<(A, B), Box<dyn std::error::Error>>;
+
+    pub fn should_not_lint2(x: i32) -> MyRes<i32, ()> {
+        Ok((x, ()))
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/result_unit_error.stderr b/tests/ui/result_unit_error.stderr
index 12901b354f9..41d8b0a7cb7 100644
--- a/tests/ui/result_unit_error.stderr
+++ b/tests/ui/result_unit_error.stderr
@@ -1,5 +1,5 @@
 error: this returns a `Result<_, ()>
-  --> $DIR/result_unit_error.rs:5:1
+  --> $DIR/result_unit_error.rs:3:1
    |
 LL | pub fn returns_unit_error() -> Result<u32, ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | pub fn returns_unit_error() -> Result<u32, ()> {
    = help: use a custom Error type instead
 
 error: this returns a `Result<_, ()>
-  --> $DIR/result_unit_error.rs:14:5
+  --> $DIR/result_unit_error.rs:12:5
    |
 LL |     fn get_that_error(&self) -> Result<bool, ()>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     fn get_that_error(&self) -> Result<bool, ()>;
    = help: use a custom Error type instead
 
 error: this returns a `Result<_, ()>
-  --> $DIR/result_unit_error.rs:16:5
+  --> $DIR/result_unit_error.rs:14:5
    |
 LL |     fn get_this_one_too(&self) -> Result<bool, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,12 +24,20 @@ LL |     fn get_this_one_too(&self) -> Result<bool, ()> {
    = help: use a custom Error type instead
 
 error: this returns a `Result<_, ()>
-  --> $DIR/result_unit_error.rs:34:5
+  --> $DIR/result_unit_error.rs:32:5
    |
 LL |     pub fn unit_error(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a custom Error type instead
 
-error: aborting due to 4 previous errors
+error: this returns a `Result<_, ()>
+  --> $DIR/result_unit_error.rs:41:5
+   |
+LL |     pub fn should_lint() -> ResInv<(), usize> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use a custom Error type instead
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/temporary_assignment.rs b/tests/ui/temporary_assignment.rs
index b4a931043b0..ac4c1bc6597 100644
--- a/tests/ui/temporary_assignment.rs
+++ b/tests/ui/temporary_assignment.rs
@@ -1,5 +1,4 @@
 #![warn(clippy::temporary_assignment)]
-#![allow(const_item_mutation)]
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/tests/ui/temporary_assignment.stderr b/tests/ui/temporary_assignment.stderr
index 4cc32c79f05..7d79901a28d 100644
--- a/tests/ui/temporary_assignment.stderr
+++ b/tests/ui/temporary_assignment.stderr
@@ -1,5 +1,5 @@
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:48:5
+  --> $DIR/temporary_assignment.rs:47:5
    |
 LL |     Struct { field: 0 }.field = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     Struct { field: 0 }.field = 1;
    = note: `-D clippy::temporary-assignment` implied by `-D warnings`
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:49:5
+  --> $DIR/temporary_assignment.rs:48:5
    |
 LL | /     MultiStruct {
 LL | |         structure: Struct { field: 0 },
@@ -17,13 +17,13 @@ LL | |     .field = 1;
    | |______________^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:54:5
+  --> $DIR/temporary_assignment.rs:53:5
    |
 LL |     ArrayStruct { array: [0] }.array[0] = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:55:5
+  --> $DIR/temporary_assignment.rs:54:5
    |
 LL |     (0, 0).0 = 1;
    |     ^^^^^^^^^^^^
diff --git a/tests/ui/unnecessary_wraps.rs b/tests/ui/unnecessary_wraps.rs
index a4570098d71..a510263e67d 100644
--- a/tests/ui/unnecessary_wraps.rs
+++ b/tests/ui/unnecessary_wraps.rs
@@ -116,8 +116,53 @@ fn issue_6384(s: &str) -> Option<&str> {
     })
 }
 
+// should be linted
+fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+    if a && b {
+        return Some(());
+    }
+    if a {
+        Some(());
+        Some(())
+    } else {
+        return Some(());
+    }
+}
+
+// should be linted
+fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+    if a && b {
+        return Ok(());
+    }
+    if a {
+        Ok(())
+    } else {
+        return Ok(());
+    }
+}
+
+// should not be linted
+fn issue_6640_3() -> Option<()> {
+    if true {
+        Some(())
+    } else {
+        None
+    }
+}
+
+// should not be linted
+fn issue_6640_4() -> Result<(), ()> {
+    if true {
+        Ok(())
+    } else {
+        Err(())
+    }
+}
+
 fn main() {
     // method calls are not linted
     func1(true, true);
     func2(true, true);
+    issue_6640_1(true, true);
+    issue_6640_2(true, true);
 }
diff --git a/tests/ui/unnecessary_wraps.stderr b/tests/ui/unnecessary_wraps.stderr
index 410f054b8ef..9a861c61a46 100644
--- a/tests/ui/unnecessary_wraps.stderr
+++ b/tests/ui/unnecessary_wraps.stderr
@@ -15,7 +15,7 @@ help: remove `Option` from the return type...
    |
 LL | fn func1(a: bool, b: bool) -> i32 {
    |                               ^^^
-help: ...and change the returning expressions
+help: ...and then change returning expressions
    |
 LL |         return 42;
 LL |     }
@@ -41,7 +41,7 @@ help: remove `Option` from the return type...
    |
 LL | fn func2(a: bool, b: bool) -> i32 {
    |                               ^^^
-help: ...and change the returning expressions
+help: ...and then change returning expressions
    |
 LL |         return 10;
 LL |     }
@@ -63,7 +63,7 @@ help: remove `Option` from the return type...
    |
 LL | fn func5() -> i32 {
    |               ^^^
-help: ...and change the returning expressions
+help: ...and then change returning expressions
    |
 LL |     1
    |
@@ -80,7 +80,7 @@ help: remove `Result` from the return type...
    |
 LL | fn func7() -> i32 {
    |               ^^^
-help: ...and change the returning expressions
+help: ...and then change returning expressions
    |
 LL |     1
    |
@@ -97,10 +97,62 @@ help: remove `Option` from the return type...
    |
 LL |     fn func12() -> i32 {
    |                    ^^^
-help: ...and change the returning expressions
+help: ...and then change returning expressions
    |
 LL |         1
    |
 
-error: aborting due to 5 previous errors
+error: this function's return value is unnecessary
+  --> $DIR/unnecessary_wraps.rs:120:1
+   |
+LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+LL | |     if a && b {
+LL | |         return Some(());
+LL | |     }
+...  |
+LL | |     }
+LL | | }
+   | |_^
+   |
+help: remove the return type...
+   |
+LL | fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+   |                                      ^^^^^^^^^^
+help: ...and then remove returned values
+   |
+LL |         return ;
+LL |     }
+LL |     if a {
+LL |         Some(());
+LL |         
+LL |     } else {
+ ...
+
+error: this function's return value is unnecessary
+  --> $DIR/unnecessary_wraps.rs:133:1
+   |
+LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+LL | |     if a && b {
+LL | |         return Ok(());
+LL | |     }
+...  |
+LL | |     }
+LL | | }
+   | |_^
+   |
+help: remove the return type...
+   |
+LL | fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+   |                                      ^^^^^^^^^^^^^^^
+help: ...and then remove returned values
+   |
+LL |         return ;
+LL |     }
+LL |     if a {
+LL |         
+LL |     } else {
+LL |         return ;
+   |
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed
index bb2012441d9..95e7bc75431 100644
--- a/tests/ui/use_self.fixed
+++ b/tests/ui/use_self.fixed
@@ -1,9 +1,13 @@
 // run-rustfix
 // edition:2018
+// aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)]
+#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+
+#[macro_use]
+extern crate proc_macro_derive;
 
 fn main() {}
 
@@ -71,13 +75,12 @@ mod lifetimes {
 
 mod issue2894 {
     trait IntoBytes {
-        #[allow(clippy::wrong_self_convention)]
-        fn into_bytes(&self) -> Vec<u8>;
+        fn to_bytes(&self) -> Vec<u8>;
     }
 
     // This should not be linted
     impl IntoBytes for u8 {
-        fn into_bytes(&self) -> Vec<u8> {
+        fn to_bytes(&self) -> Vec<u8> {
             vec![*self]
         }
     }
@@ -110,8 +113,8 @@ mod tuple_structs {
 mod macros {
     macro_rules! use_self_expand {
         () => {
-            fn new() -> Self {
-                Self {}
+            fn new() -> Foo {
+                Foo {}
             }
         };
     }
@@ -119,8 +122,11 @@ mod macros {
     struct Foo {}
 
     impl Foo {
-        use_self_expand!(); // Should lint in local macros
+        use_self_expand!(); // Should not lint in local macros
     }
+
+    #[derive(StructAUseSelf)] // Should not lint in derives
+    struct A;
 }
 
 mod nesting {
@@ -177,11 +183,22 @@ mod issue3410 {
     struct B;
 
     trait Trait<T> {
-        fn a(v: T);
+        fn a(v: T) -> Self;
     }
 
     impl Trait<Vec<A>> for Vec<B> {
-        fn a(_: Vec<A>) {}
+        fn a(_: Vec<A>) -> Self {
+            unimplemented!()
+        }
+    }
+
+    impl<T> Trait<Vec<A>> for Vec<T>
+    where
+        T: Trait<B>,
+    {
+        fn a(v: Vec<A>) -> Self {
+            <Vec<B>>::a(v).into_iter().map(Trait::a).collect()
+        }
     }
 }
 
@@ -252,3 +269,192 @@ mod paths_created_by_lowering {
         }
     }
 }
+
+// reused from #1997
+mod generics {
+    struct Foo<T> {
+        value: T,
+    }
+
+    impl<T> Foo<T> {
+        // `Self` is applicable here
+        fn foo(value: T) -> Self {
+            Self { value }
+        }
+
+        // `Cannot` use `Self` as a return type as the generic types are different
+        fn bar(value: i32) -> Foo<i32> {
+            Foo { value }
+        }
+    }
+}
+
+mod issue4140 {
+    pub struct Error<From, To> {
+        _from: From,
+        _too: To,
+    }
+
+    pub trait From<T> {
+        type From;
+        type To;
+
+        fn from(value: T) -> Self;
+    }
+
+    pub trait TryFrom<T>
+    where
+        Self: Sized,
+    {
+        type From;
+        type To;
+
+        fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
+    }
+
+    impl<F, T> TryFrom<F> for T
+    where
+        T: From<F>,
+    {
+        type From = Self;
+        type To = Self;
+
+        fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
+            Ok(From::from(value))
+        }
+    }
+
+    impl From<bool> for i64 {
+        type From = bool;
+        type To = Self;
+
+        fn from(value: bool) -> Self {
+            if value {
+                100
+            } else {
+                0
+            }
+        }
+    }
+}
+
+mod issue2843 {
+    trait Foo {
+        type Bar;
+    }
+
+    impl Foo for usize {
+        type Bar = u8;
+    }
+
+    impl<T: Foo> Foo for Option<T> {
+        type Bar = Option<T::Bar>;
+    }
+}
+
+mod issue3859 {
+    pub struct Foo;
+    pub struct Bar([usize; 3]);
+
+    impl Foo {
+        pub const BAR: usize = 3;
+
+        pub fn foo() {
+            const _X: usize = Foo::BAR;
+            // const _Y: usize = Self::BAR;
+        }
+    }
+}
+
+mod issue4305 {
+    trait Foo: 'static {}
+
+    struct Bar;
+
+    impl Foo for Bar {}
+
+    impl<T: Foo> From<T> for Box<dyn Foo> {
+        fn from(t: T) -> Self {
+            Box::new(t)
+        }
+    }
+}
+
+mod lint_at_item_level {
+    struct Foo {}
+
+    #[allow(clippy::use_self)]
+    impl Foo {
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    #[allow(clippy::use_self)]
+    impl Default for Foo {
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod lint_at_impl_item_level {
+    struct Foo {}
+
+    impl Foo {
+        #[allow(clippy::use_self)]
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    impl Default for Foo {
+        #[allow(clippy::use_self)]
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod issue4734 {
+    #[repr(C, packed)]
+    pub struct X {
+        pub x: u32,
+    }
+
+    impl From<X> for u32 {
+        fn from(c: X) -> Self {
+            unsafe { core::mem::transmute(c) }
+        }
+    }
+}
+
+mod nested_paths {
+    use std::convert::Into;
+    mod submod {
+        pub struct B {}
+        pub struct C {}
+
+        impl Into<C> for B {
+            fn into(self) -> C {
+                C {}
+            }
+        }
+    }
+
+    struct A<T> {
+        t: T,
+    }
+
+    impl<T> A<T> {
+        fn new<V: Into<T>>(v: V) -> Self {
+            Self { t: Into::into(v) }
+        }
+    }
+
+    impl A<submod::C> {
+        fn test() -> Self {
+            Self::new::<submod::B>(submod::B {})
+        }
+    }
+}
diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs
index ddfd2beba31..75424f34159 100644
--- a/tests/ui/use_self.rs
+++ b/tests/ui/use_self.rs
@@ -1,9 +1,13 @@
 // run-rustfix
 // edition:2018
+// aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)]
+#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+
+#[macro_use]
+extern crate proc_macro_derive;
 
 fn main() {}
 
@@ -71,13 +75,12 @@ mod lifetimes {
 
 mod issue2894 {
     trait IntoBytes {
-        #[allow(clippy::wrong_self_convention)]
-        fn into_bytes(&self) -> Vec<u8>;
+        fn to_bytes(&self) -> Vec<u8>;
     }
 
     // This should not be linted
     impl IntoBytes for u8 {
-        fn into_bytes(&self) -> Vec<u8> {
+        fn to_bytes(&self) -> Vec<u8> {
             vec![*self]
         }
     }
@@ -87,7 +90,7 @@ mod existential {
     struct Foo;
 
     impl Foo {
-        fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
+        fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
             foos.iter()
         }
 
@@ -119,8 +122,11 @@ mod macros {
     struct Foo {}
 
     impl Foo {
-        use_self_expand!(); // Should lint in local macros
+        use_self_expand!(); // Should not lint in local macros
     }
+
+    #[derive(StructAUseSelf)] // Should not lint in derives
+    struct A;
 }
 
 mod nesting {
@@ -177,11 +183,22 @@ mod issue3410 {
     struct B;
 
     trait Trait<T> {
-        fn a(v: T);
+        fn a(v: T) -> Self;
     }
 
     impl Trait<Vec<A>> for Vec<B> {
-        fn a(_: Vec<A>) {}
+        fn a(_: Vec<A>) -> Self {
+            unimplemented!()
+        }
+    }
+
+    impl<T> Trait<Vec<A>> for Vec<T>
+    where
+        T: Trait<B>,
+    {
+        fn a(v: Vec<A>) -> Self {
+            <Vec<B>>::a(v).into_iter().map(Trait::a).collect()
+        }
     }
 }
 
@@ -252,3 +269,192 @@ mod paths_created_by_lowering {
         }
     }
 }
+
+// reused from #1997
+mod generics {
+    struct Foo<T> {
+        value: T,
+    }
+
+    impl<T> Foo<T> {
+        // `Self` is applicable here
+        fn foo(value: T) -> Foo<T> {
+            Foo { value }
+        }
+
+        // `Cannot` use `Self` as a return type as the generic types are different
+        fn bar(value: i32) -> Foo<i32> {
+            Foo { value }
+        }
+    }
+}
+
+mod issue4140 {
+    pub struct Error<From, To> {
+        _from: From,
+        _too: To,
+    }
+
+    pub trait From<T> {
+        type From;
+        type To;
+
+        fn from(value: T) -> Self;
+    }
+
+    pub trait TryFrom<T>
+    where
+        Self: Sized,
+    {
+        type From;
+        type To;
+
+        fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
+    }
+
+    impl<F, T> TryFrom<F> for T
+    where
+        T: From<F>,
+    {
+        type From = T::From;
+        type To = T::To;
+
+        fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
+            Ok(From::from(value))
+        }
+    }
+
+    impl From<bool> for i64 {
+        type From = bool;
+        type To = Self;
+
+        fn from(value: bool) -> Self {
+            if value {
+                100
+            } else {
+                0
+            }
+        }
+    }
+}
+
+mod issue2843 {
+    trait Foo {
+        type Bar;
+    }
+
+    impl Foo for usize {
+        type Bar = u8;
+    }
+
+    impl<T: Foo> Foo for Option<T> {
+        type Bar = Option<T::Bar>;
+    }
+}
+
+mod issue3859 {
+    pub struct Foo;
+    pub struct Bar([usize; 3]);
+
+    impl Foo {
+        pub const BAR: usize = 3;
+
+        pub fn foo() {
+            const _X: usize = Foo::BAR;
+            // const _Y: usize = Self::BAR;
+        }
+    }
+}
+
+mod issue4305 {
+    trait Foo: 'static {}
+
+    struct Bar;
+
+    impl Foo for Bar {}
+
+    impl<T: Foo> From<T> for Box<dyn Foo> {
+        fn from(t: T) -> Self {
+            Box::new(t)
+        }
+    }
+}
+
+mod lint_at_item_level {
+    struct Foo {}
+
+    #[allow(clippy::use_self)]
+    impl Foo {
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    #[allow(clippy::use_self)]
+    impl Default for Foo {
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod lint_at_impl_item_level {
+    struct Foo {}
+
+    impl Foo {
+        #[allow(clippy::use_self)]
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    impl Default for Foo {
+        #[allow(clippy::use_self)]
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod issue4734 {
+    #[repr(C, packed)]
+    pub struct X {
+        pub x: u32,
+    }
+
+    impl From<X> for u32 {
+        fn from(c: X) -> Self {
+            unsafe { core::mem::transmute(c) }
+        }
+    }
+}
+
+mod nested_paths {
+    use std::convert::Into;
+    mod submod {
+        pub struct B {}
+        pub struct C {}
+
+        impl Into<C> for B {
+            fn into(self) -> C {
+                C {}
+            }
+        }
+    }
+
+    struct A<T> {
+        t: T,
+    }
+
+    impl<T> A<T> {
+        fn new<V: Into<T>>(v: V) -> Self {
+            Self { t: Into::into(v) }
+        }
+    }
+
+    impl A<submod::C> {
+        fn test() -> Self {
+            A::new::<submod::B>(submod::B {})
+        }
+    }
+}
diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr
index 80e1bfc75e8..37dfef7cfe0 100644
--- a/tests/ui/use_self.stderr
+++ b/tests/ui/use_self.stderr
@@ -1,5 +1,5 @@
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:14:21
+  --> $DIR/use_self.rs:18:21
    |
 LL |         fn new() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
@@ -7,158 +7,172 @@ LL |         fn new() -> Foo {
    = note: `-D clippy::use-self` implied by `-D warnings`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:15:13
+  --> $DIR/use_self.rs:19:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:17:22
+  --> $DIR/use_self.rs:21:22
    |
 LL |         fn test() -> Foo {
    |                      ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:18:13
+  --> $DIR/use_self.rs:22:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:23:25
+  --> $DIR/use_self.rs:27:25
    |
 LL |         fn default() -> Foo {
    |                         ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:24:13
+  --> $DIR/use_self.rs:28:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:90:56
+  --> $DIR/use_self.rs:93:24
    |
-LL |         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
-   |                                                        ^^^ help: use the applicable keyword: `Self`
+LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
+   |                        ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:105:13
+  --> $DIR/use_self.rs:93:55
+   |
+LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
+   |                                                       ^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:108:13
    |
 LL |             TS(0)
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:113:25
-   |
-LL |             fn new() -> Foo {
-   |                         ^^^ help: use the applicable keyword: `Self`
-...
-LL |         use_self_expand!(); // Should lint in local macros
-   |         ------------------- in this macro invocation
+  --> $DIR/use_self.rs:143:29
    |
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL |                 fn bar() -> Bar {
+   |                             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:114:17
-   |
-LL |                 Foo {}
-   |                 ^^^ help: use the applicable keyword: `Self`
-...
-LL |         use_self_expand!(); // Should lint in local macros
-   |         ------------------- in this macro invocation
+  --> $DIR/use_self.rs:144:21
    |
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL |                     Bar { foo: Foo {} }
+   |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:149:21
+  --> $DIR/use_self.rs:155:21
    |
 LL |         fn baz() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:150:13
+  --> $DIR/use_self.rs:156:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:137:29
-   |
-LL |                 fn bar() -> Bar {
-   |                             ^^^ help: use the applicable keyword: `Self`
-
-error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:138:21
-   |
-LL |                     Bar { foo: Foo {} }
-   |                     ^^^ help: use the applicable keyword: `Self`
-
-error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:167:21
+  --> $DIR/use_self.rs:173:21
    |
 LL |             let _ = Enum::B(42);
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:168:21
+  --> $DIR/use_self.rs:174:21
    |
 LL |             let _ = Enum::C { field: true };
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:169:21
+  --> $DIR/use_self.rs:175:21
    |
 LL |             let _ = Enum::A;
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:200:13
+  --> $DIR/use_self.rs:217:13
    |
 LL |             nested::A::fun_1();
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:201:13
+  --> $DIR/use_self.rs:218:13
    |
 LL |             nested::A::A;
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:203:13
+  --> $DIR/use_self.rs:220:13
    |
 LL |             nested::A {};
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:222:13
+  --> $DIR/use_self.rs:239:13
    |
 LL |             TestStruct::from_something()
    |             ^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:236:25
+  --> $DIR/use_self.rs:253:25
    |
 LL |         async fn g() -> S {
    |                         ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:237:13
+  --> $DIR/use_self.rs:254:13
    |
 LL |             S {}
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:241:16
+  --> $DIR/use_self.rs:258:16
    |
 LL |             &p[S::A..S::B]
    |                ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:241:22
+  --> $DIR/use_self.rs:258:22
    |
 LL |             &p[S::A..S::B]
    |                      ^ help: use the applicable keyword: `Self`
 
-error: aborting due to 25 previous errors
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:281:29
+   |
+LL |         fn foo(value: T) -> Foo<T> {
+   |                             ^^^^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:282:13
+   |
+LL |             Foo { value }
+   |             ^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:319:21
+   |
+LL |         type From = T::From;
+   |                     ^^^^^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:320:19
+   |
+LL |         type To = T::To;
+   |                   ^^^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:457:13
+   |
+LL |             A::new::<submod::B>(submod::B {})
+   |             ^ help: use the applicable keyword: `Self`
+
+error: aborting due to 29 previous errors
 
diff --git a/tests/ui/use_self_trait.fixed b/tests/ui/use_self_trait.fixed
index 1582ae114bf..9bcd692fb35 100644
--- a/tests/ui/use_self_trait.fixed
+++ b/tests/ui/use_self_trait.fixed
@@ -47,7 +47,8 @@ impl Mul for Bad {
 
 impl Clone for Bad {
     fn clone(&self) -> Self {
-        Self
+        // FIXME: applicable here
+        Bad
     }
 }
 
diff --git a/tests/ui/use_self_trait.rs b/tests/ui/use_self_trait.rs
index 70667b9797e..de305d40f33 100644
--- a/tests/ui/use_self_trait.rs
+++ b/tests/ui/use_self_trait.rs
@@ -47,6 +47,7 @@ impl Mul for Bad {
 
 impl Clone for Bad {
     fn clone(&self) -> Self {
+        // FIXME: applicable here
         Bad
     }
 }
diff --git a/tests/ui/use_self_trait.stderr b/tests/ui/use_self_trait.stderr
index 4f2506cc119..55af3ff2a93 100644
--- a/tests/ui/use_self_trait.stderr
+++ b/tests/ui/use_self_trait.stderr
@@ -84,11 +84,5 @@ error: unnecessary structure name repetition
 LL |     fn mul(self, rhs: Bad) -> Bad {
    |                               ^^^ help: use the applicable keyword: `Self`
 
-error: unnecessary structure name repetition
-  --> $DIR/use_self_trait.rs:50:9
-   |
-LL |         Bad
-   |         ^^^ help: use the applicable keyword: `Self`
-
-error: aborting due to 15 previous errors
+error: aborting due to 14 previous errors
 
diff --git a/tests/ui/vec_init_then_push.rs b/tests/ui/vec_init_then_push.rs
index 642ce504009..5099aad83bc 100644
--- a/tests/ui/vec_init_then_push.rs
+++ b/tests/ui/vec_init_then_push.rs
@@ -12,10 +12,35 @@ fn main() {
     cap_err.push(0);
     cap_err.push(1);
     cap_err.push(2);
+    if true {
+        // don't include this one
+        cap_err.push(3);
+    }
 
     let mut cap_ok = Vec::with_capacity(10);
     cap_ok.push(0);
 
     new_err = Vec::new();
     new_err.push(0);
+
+    let mut vec = Vec::new();
+    // control flow at block final expression
+    if true {
+        // no lint
+        vec.push(1);
+    }
+}
+
+pub fn no_lint() -> Vec<i32> {
+    let mut p = Some(1);
+    let mut vec = Vec::new();
+    loop {
+        match p {
+            None => return vec,
+            Some(i) => {
+                vec.push(i);
+                p = None;
+            },
+        }
+    }
 }
diff --git a/tests/ui/vec_init_then_push.stderr b/tests/ui/vec_init_then_push.stderr
index 819ed47d099..9ec3e10e624 100644
--- a/tests/ui/vec_init_then_push.stderr
+++ b/tests/ui/vec_init_then_push.stderr
@@ -24,7 +24,7 @@ LL | |     cap_err.push(2);
    | |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];`
 
 error: calls to `push` immediately after creation
-  --> $DIR/vec_init_then_push.rs:19:5
+  --> $DIR/vec_init_then_push.rs:23:5
    |
 LL | /     new_err = Vec::new();
 LL | |     new_err.push(0);