about summary refs log tree commit diff
path: root/tests/ui/branches_sharing_code
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/branches_sharing_code')
-rw-r--r--tests/ui/branches_sharing_code/shared_at_bottom.rs209
-rw-r--r--tests/ui/branches_sharing_code/shared_at_bottom.stderr143
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top.rs103
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top.stderr121
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs119
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr154
-rw-r--r--tests/ui/branches_sharing_code/valid_if_blocks.rs155
-rw-r--r--tests/ui/branches_sharing_code/valid_if_blocks.stderr101
8 files changed, 1105 insertions, 0 deletions
diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs
new file mode 100644
index 00000000000..c389c243d44
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs
@@ -0,0 +1,209 @@
+#![allow(dead_code)]
+#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+
+// This tests the branches_sharing_code lint at the end of blocks
+
+fn simple_examples() {
+    let x = 1;
+
+    let _ = if x == 7 {
+        println!("Branch I");
+        let start_value = 0;
+        println!("=^.^=");
+
+        // Same but not moveable due to `start_value`
+        let _ = start_value;
+
+        // The rest is self contained and moveable => Only lint the rest
+        let result = false;
+        println!("Block end!");
+        result
+    } else {
+        println!("Branch II");
+        let start_value = 8;
+        println!("xD");
+
+        // Same but not moveable due to `start_value`
+        let _ = start_value;
+
+        // The rest is self contained and moveable => Only lint the rest
+        let result = false;
+        println!("Block end!");
+        result
+    };
+
+    // Else if block
+    if x == 9 {
+        println!("The index is: 6");
+
+        println!("Same end of block");
+    } else if x == 8 {
+        println!("The index is: 4");
+
+        // We should only get a lint trigger for the last statement
+        println!("This is also eq with the else block");
+        println!("Same end of block");
+    } else {
+        println!("This is also eq with the else block");
+        println!("Same end of block");
+    }
+
+    // Use of outer scope value
+    let outer_scope_value = "I'm outside the if block";
+    if x < 99 {
+        let z = "How are you";
+        println!("I'm a local because I use the value `z`: `{}`", z);
+
+        println!(
+            "I'm moveable because I know: `outer_scope_value`: '{}'",
+            outer_scope_value
+        );
+    } else {
+        let z = 45678000;
+        println!("I'm a local because I use the value `z`: `{}`", z);
+
+        println!(
+            "I'm moveable because I know: `outer_scope_value`: '{}'",
+            outer_scope_value
+        );
+    }
+
+    if x == 9 {
+        if x == 8 {
+            // No parent!!
+            println!("---");
+            println!("Hello World");
+        } else {
+            println!("Hello World");
+        }
+    }
+}
+
+/// Simple examples where the move can cause some problems due to moved values
+fn simple_but_suggestion_is_invalid() {
+    let x = 16;
+
+    // Local value
+    let later_used_value = 17;
+    if x == 9 {
+        let _ = 9;
+        let later_used_value = "A string value";
+        println!("{}", later_used_value);
+    } else {
+        let later_used_value = "A string value";
+        println!("{}", later_used_value);
+        // I'm expecting a note about this
+    }
+    println!("{}", later_used_value);
+
+    // outer function
+    if x == 78 {
+        let simple_examples = "I now identify as a &str :)";
+        println!("This is the new simple_example: {}", simple_examples);
+    } else {
+        println!("Separator print statement");
+
+        let simple_examples = "I now identify as a &str :)";
+        println!("This is the new simple_example: {}", simple_examples);
+    }
+    simple_examples();
+}
+
+/// Tests where the blocks are not linted due to the used value scope
+fn not_moveable_due_to_value_scope() {
+    let x = 18;
+
+    // Using a local value in the moved code
+    if x == 9 {
+        let y = 18;
+        println!("y is: `{}`", y);
+    } else {
+        let y = "A string";
+        println!("y is: `{}`", y);
+    }
+
+    // Using a local value in the expression
+    let _ = if x == 0 {
+        let mut result = x + 1;
+
+        println!("1. Doing some calculations");
+        println!("2. Some more calculations");
+        println!("3. Setting result");
+
+        result
+    } else {
+        let mut result = x - 1;
+
+        println!("1. Doing some calculations");
+        println!("2. Some more calculations");
+        println!("3. Setting result");
+
+        result
+    };
+
+    let _ = if x == 7 {
+        let z1 = 100;
+        println!("z1: {}", z1);
+
+        let z2 = z1;
+        println!("z2: {}", z2);
+
+        z2
+    } else {
+        let z1 = 300;
+        println!("z1: {}", z1);
+
+        let z2 = z1;
+        println!("z2: {}", z2);
+
+        z2
+    };
+}
+
+/// This should add a note to the lint msg since the moved expression is not `()`
+fn added_note_for_expression_use() -> u32 {
+    let x = 9;
+
+    let _ = if x == 7 {
+        x << 2
+    } else {
+        let _ = 6;
+        x << 2
+    };
+
+    if x == 9 {
+        x * 4
+    } else {
+        let _ = 17;
+        x * 4
+    }
+}
+
+#[rustfmt::skip]
+fn test_suggestion_with_weird_formatting() {
+    let x = 9;
+    let mut a = 0;
+    let mut b = 0;
+
+    // The error message still looks weird tbh but this is the best I can do
+    // for weird formatting
+    if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }
+}
+
+fn fp_test() {
+    let x = 17;
+
+    if x == 18 {
+        let y = 19;
+        if y < x {
+            println!("Trigger")
+        }
+    } else {
+        let z = 166;
+        if z < x {
+            println!("Trigger")
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_bottom.stderr
new file mode 100644
index 00000000000..271fcd8b6c1
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_bottom.stderr
@@ -0,0 +1,143 @@
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:30:5
+   |
+LL | /         let result = false;
+LL | |         println!("Block end!");
+LL | |         result
+LL | |     };
+   | |_____^
+   |
+note: the lint level is defined here
+  --> $DIR/shared_at_bottom.rs:2:36
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: The end suggestion probably needs some adjustments to use the expression result correctly
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     let result = false;
+LL |     println!("Block end!");
+LL |     result;
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:48:5
+   |
+LL | /         println!("Same end of block");
+LL | |     }
+   | |_____^
+   |
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     println!("Same end of block");
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:65:5
+   |
+LL | /         println!(
+LL | |             "I'm moveable because I know: `outer_scope_value`: '{}'",
+LL | |             outer_scope_value
+LL | |         );
+LL | |     }
+   | |_____^
+   |
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     println!(
+LL |         "I'm moveable because I know: `outer_scope_value`: '{}'",
+LL |         outer_scope_value
+LL |     );
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:77:9
+   |
+LL | /             println!("Hello World");
+LL | |         }
+   | |_________^
+   |
+help: consider moving the end statements out like this
+   |
+LL |         }
+LL |         println!("Hello World");
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:93:5
+   |
+LL | /         let later_used_value = "A string value";
+LL | |         println!("{}", later_used_value);
+LL | |         // I'm expecting a note about this
+LL | |     }
+   | |_____^
+   |
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     let later_used_value = "A string value";
+LL |     println!("{}", later_used_value);
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:106:5
+   |
+LL | /         let simple_examples = "I now identify as a &str :)";
+LL | |         println!("This is the new simple_example: {}", simple_examples);
+LL | |     }
+   | |_____^
+   |
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     let simple_examples = "I now identify as a &str :)";
+LL |     println!("This is the new simple_example: {}", simple_examples);
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:171:5
+   |
+LL | /         x << 2
+LL | |     };
+   | |_____^
+   |
+   = note: The end suggestion probably needs some adjustments to use the expression result correctly
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     x << 2;
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:178:5
+   |
+LL | /         x * 4
+LL | |     }
+   | |_____^
+   |
+   = note: The end suggestion probably needs some adjustments to use the expression result correctly
+help: consider moving the end statements out like this
+   |
+LL |     }
+LL |     x * 4
+   |
+
+error: all if blocks contain the same code at the end
+  --> $DIR/shared_at_bottom.rs:190:44
+   |
+LL |     if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }
+   |                                            ^^^^^^^^^^^
+   |
+help: consider moving the end statements out like this
+   |
+LL |     if x == 17 { b = 1; a = 0x99; } else { }
+LL |     a = 0x99;
+   |
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/branches_sharing_code/shared_at_top.rs b/tests/ui/branches_sharing_code/shared_at_top.rs
new file mode 100644
index 00000000000..e65bcfd7873
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_top.rs
@@ -0,0 +1,103 @@
+#![allow(dead_code, clippy::eval_order_dependence)]
+#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+
+// This tests the branches_sharing_code lint at the start of blocks
+
+fn simple_examples() {
+    let x = 0;
+
+    // Simple
+    if true {
+        println!("Hello World!");
+        println!("I'm branch nr: 1");
+    } else {
+        println!("Hello World!");
+        println!("I'm branch nr: 2");
+    }
+
+    // Else if
+    if x == 0 {
+        let y = 9;
+        println!("The value y was set to: `{}`", y);
+        let _z = y;
+
+        println!("I'm the true start index of arrays");
+    } else if x == 1 {
+        let y = 9;
+        println!("The value y was set to: `{}`", y);
+        let _z = y;
+
+        println!("I start counting from 1 so my array starts from `1`");
+    } else {
+        let y = 9;
+        println!("The value y was set to: `{}`", y);
+        let _z = y;
+
+        println!("Ha, Pascal allows you to start the array where you want")
+    }
+
+    // Return a value
+    let _ = if x == 7 {
+        let y = 16;
+        println!("What can I say except: \"you're welcome?\"");
+        let _ = y;
+        x
+    } else {
+        let y = 16;
+        println!("Thank you");
+        y
+    };
+}
+
+/// Simple examples where the move can cause some problems due to moved values
+fn simple_but_suggestion_is_invalid() {
+    let x = 10;
+
+    // Can't be automatically moved because used_value_name is getting used again
+    let used_value_name = 19;
+    if x == 10 {
+        let used_value_name = "Different type";
+        println!("Str: {}", used_value_name);
+        let _ = 1;
+    } else {
+        let used_value_name = "Different type";
+        println!("Str: {}", used_value_name);
+        let _ = 2;
+    }
+    let _ = used_value_name;
+
+    // This can be automatically moved as `can_be_overridden` is not used again
+    let can_be_overridden = 8;
+    let _ = can_be_overridden;
+    if x == 11 {
+        let can_be_overridden = "Move me";
+        println!("I'm also moveable");
+        let _ = 111;
+    } else {
+        let can_be_overridden = "Move me";
+        println!("I'm also moveable");
+        let _ = 222;
+    }
+}
+
+/// This function tests that the `IS_SAME_THAN_ELSE` only covers the lint if it's enabled.
+fn check_if_same_than_else_mask() {
+    let x = 2021;
+
+    #[allow(clippy::if_same_then_else)]
+    if x == 2020 {
+        println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
+        println!("Because `IF_SAME_THEN_ELSE` is allowed here");
+    } else {
+        println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
+        println!("Because `IF_SAME_THEN_ELSE` is allowed here");
+    }
+
+    if x == 2019 {
+        println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
+    } else {
+        println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/branches_sharing_code/shared_at_top.stderr b/tests/ui/branches_sharing_code/shared_at_top.stderr
new file mode 100644
index 00000000000..15867e9ea02
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_top.stderr
@@ -0,0 +1,121 @@
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:10:5
+   |
+LL | /     if true {
+LL | |         println!("Hello World!");
+   | |_________________________________^
+   |
+note: the lint level is defined here
+  --> $DIR/shared_at_top.rs:2:36
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider moving the start statements out like this
+   |
+LL |     println!("Hello World!");
+LL |     if true {
+   |
+
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:19:5
+   |
+LL | /     if x == 0 {
+LL | |         let y = 9;
+LL | |         println!("The value y was set to: `{}`", y);
+LL | |         let _z = y;
+   | |___________________^
+   |
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the start statements out like this
+   |
+LL |     let y = 9;
+LL |     println!("The value y was set to: `{}`", y);
+LL |     let _z = y;
+LL |     if x == 0 {
+   |
+
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:40:5
+   |
+LL | /     let _ = if x == 7 {
+LL | |         let y = 16;
+   | |___________________^
+   |
+help: consider moving the start statements out like this
+   |
+LL |     let y = 16;
+LL |     let _ = if x == 7 {
+   |
+
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:58:5
+   |
+LL | /     if x == 10 {
+LL | |         let used_value_name = "Different type";
+LL | |         println!("Str: {}", used_value_name);
+   | |_____________________________________________^
+   |
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the start statements out like this
+   |
+LL |     let used_value_name = "Different type";
+LL |     println!("Str: {}", used_value_name);
+LL |     if x == 10 {
+   |
+
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:72:5
+   |
+LL | /     if x == 11 {
+LL | |         let can_be_overridden = "Move me";
+LL | |         println!("I'm also moveable");
+   | |______________________________________^
+   |
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the start statements out like this
+   |
+LL |     let can_be_overridden = "Move me";
+LL |     println!("I'm also moveable");
+LL |     if x == 11 {
+   |
+
+error: all if blocks contain the same code at the start
+  --> $DIR/shared_at_top.rs:88:5
+   |
+LL | /     if x == 2020 {
+LL | |         println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
+LL | |         println!("Because `IF_SAME_THEN_ELSE` is allowed here");
+   | |________________________________________________________________^
+   |
+help: consider moving the start statements out like this
+   |
+LL |     println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
+LL |     println!("Because `IF_SAME_THEN_ELSE` is allowed here");
+LL |     if x == 2020 {
+   |
+
+error: this `if` has identical blocks
+  --> $DIR/shared_at_top.rs:96:18
+   |
+LL |       if x == 2019 {
+   |  __________________^
+LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
+LL | |     } else {
+   | |_____^
+   |
+note: the lint level is defined here
+  --> $DIR/shared_at_top.rs:2:9
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: same as this
+  --> $DIR/shared_at_top.rs:98:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
+LL | |     }
+   | |_____^
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs
new file mode 100644
index 00000000000..deefdad32c9
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs
@@ -0,0 +1,119 @@
+#![allow(dead_code)]
+#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+
+// branches_sharing_code at the top and bottom of the if blocks
+
+struct DataPack {
+    id: u32,
+    name: String,
+    some_data: Vec<u8>,
+}
+
+fn overlapping_eq_regions() {
+    let x = 9;
+
+    // Overlap with separator
+    if x == 7 {
+        let t = 7;
+        let _overlap_start = t * 2;
+        let _overlap_end = 2 * t;
+        let _u = 9;
+    } else {
+        let t = 7;
+        let _overlap_start = t * 2;
+        let _overlap_end = 2 * t;
+        println!("Overlap separator");
+        let _overlap_start = t * 2;
+        let _overlap_end = 2 * t;
+        let _u = 9;
+    }
+
+    // Overlap with separator
+    if x == 99 {
+        let r = 7;
+        let _overlap_start = r;
+        let _overlap_middle = r * r;
+        let _overlap_end = r * r * r;
+        let z = "end";
+    } else {
+        let r = 7;
+        let _overlap_start = r;
+        let _overlap_middle = r * r;
+        let _overlap_middle = r * r;
+        let _overlap_end = r * r * r;
+        let z = "end";
+    }
+}
+
+fn complexer_example() {
+    fn gen_id(x: u32, y: u32) -> u32 {
+        let x = x & 0x0000_ffff;
+        let y = (y & 0xffff_0000) << 16;
+        x | y
+    }
+
+    fn process_data(data: DataPack) {
+        let _ = data;
+    }
+
+    let x = 8;
+    let y = 9;
+    if (x > 7 && y < 13) || (x + y) % 2 == 1 {
+        let a = 0xcafe;
+        let b = 0xffff00ff;
+        let e_id = gen_id(a, b);
+
+        println!("From the a `{}` to the b `{}`", a, b);
+
+        let pack = DataPack {
+            id: e_id,
+            name: "Player 1".to_string(),
+            some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],
+        };
+        process_data(pack);
+    } else {
+        let a = 0xcafe;
+        let b = 0xffff00ff;
+        let e_id = gen_id(a, b);
+
+        println!("The new ID is '{}'", e_id);
+
+        let pack = DataPack {
+            id: e_id,
+            name: "Player 1".to_string(),
+            some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],
+        };
+        process_data(pack);
+    }
+}
+
+/// This should add a note to the lint msg since the moved expression is not `()`
+fn added_note_for_expression_use() -> u32 {
+    let x = 9;
+
+    let _ = if x == 7 {
+        let _ = 19;
+
+        let _splitter = 6;
+
+        x << 2
+    } else {
+        let _ = 19;
+
+        x << 2
+    };
+
+    if x == 9 {
+        let _ = 17;
+
+        let _splitter = 6;
+
+        x * 4
+    } else {
+        let _ = 17;
+
+        x * 4
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
new file mode 100644
index 00000000000..212cfb2f1d1
--- /dev/null
+++ b/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
@@ -0,0 +1,154 @@
+error: all if blocks contain the same code at the start and the end. Here at the start
+  --> $DIR/shared_at_top_and_bottom.rs:16:5
+   |
+LL | /     if x == 7 {
+LL | |         let t = 7;
+LL | |         let _overlap_start = t * 2;
+LL | |         let _overlap_end = 2 * t;
+   | |_________________________________^
+   |
+note: the lint level is defined here
+  --> $DIR/shared_at_top_and_bottom.rs:2:36
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: and here at the end
+  --> $DIR/shared_at_top_and_bottom.rs:28:5
+   |
+LL | /         let _u = 9;
+LL | |     }
+   | |_____^
+help: consider moving the start statements out like this
+   |
+LL |     let t = 7;
+LL |     let _overlap_start = t * 2;
+LL |     let _overlap_end = 2 * t;
+LL |     if x == 7 {
+   |
+help: and consider moving the end statements out like this
+   |
+LL |     }
+LL |     let _u = 9;
+   |
+
+error: all if blocks contain the same code at the start and the end. Here at the start
+  --> $DIR/shared_at_top_and_bottom.rs:32:5
+   |
+LL | /     if x == 99 {
+LL | |         let r = 7;
+LL | |         let _overlap_start = r;
+LL | |         let _overlap_middle = r * r;
+   | |____________________________________^
+   |
+note: and here at the end
+  --> $DIR/shared_at_top_and_bottom.rs:43:5
+   |
+LL | /         let _overlap_end = r * r * r;
+LL | |         let z = "end";
+LL | |     }
+   | |_____^
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the start statements out like this
+   |
+LL |     let r = 7;
+LL |     let _overlap_start = r;
+LL |     let _overlap_middle = r * r;
+LL |     if x == 99 {
+   |
+help: and consider moving the end statements out like this
+   |
+LL |     }
+LL |     let _overlap_end = r * r * r;
+LL |     let z = "end";
+   |
+
+error: all if blocks contain the same code at the start and the end. Here at the start
+  --> $DIR/shared_at_top_and_bottom.rs:61:5
+   |
+LL | /     if (x > 7 && y < 13) || (x + y) % 2 == 1 {
+LL | |         let a = 0xcafe;
+LL | |         let b = 0xffff00ff;
+LL | |         let e_id = gen_id(a, b);
+   | |________________________________^
+   |
+note: and here at the end
+  --> $DIR/shared_at_top_and_bottom.rs:81:5
+   |
+LL | /         let pack = DataPack {
+LL | |             id: e_id,
+LL | |             name: "Player 1".to_string(),
+LL | |             some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],
+LL | |         };
+LL | |         process_data(pack);
+LL | |     }
+   | |_____^
+   = warning: Some moved values might need to be renamed to avoid wrong references
+help: consider moving the start statements out like this
+   |
+LL |     let a = 0xcafe;
+LL |     let b = 0xffff00ff;
+LL |     let e_id = gen_id(a, b);
+LL |     if (x > 7 && y < 13) || (x + y) % 2 == 1 {
+   |
+help: and consider moving the end statements out like this
+   |
+LL |     }
+LL |     let pack = DataPack {
+LL |         id: e_id,
+LL |         name: "Player 1".to_string(),
+LL |         some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],
+LL |     };
+ ...
+
+error: all if blocks contain the same code at the start and the end. Here at the start
+  --> $DIR/shared_at_top_and_bottom.rs:94:5
+   |
+LL | /     let _ = if x == 7 {
+LL | |         let _ = 19;
+   | |___________________^
+   |
+note: and here at the end
+  --> $DIR/shared_at_top_and_bottom.rs:103:5
+   |
+LL | /         x << 2
+LL | |     };
+   | |_____^
+   = note: The end suggestion probably needs some adjustments to use the expression result correctly
+help: consider moving the start statements out like this
+   |
+LL |     let _ = 19;
+LL |     let _ = if x == 7 {
+   |
+help: and consider moving the end statements out like this
+   |
+LL |     }
+LL |     x << 2;
+   |
+
+error: all if blocks contain the same code at the start and the end. Here at the start
+  --> $DIR/shared_at_top_and_bottom.rs:106:5
+   |
+LL | /     if x == 9 {
+LL | |         let _ = 17;
+   | |___________________^
+   |
+note: and here at the end
+  --> $DIR/shared_at_top_and_bottom.rs:115:5
+   |
+LL | /         x * 4
+LL | |     }
+   | |_____^
+   = note: The end suggestion probably needs some adjustments to use the expression result correctly
+help: consider moving the start statements out like this
+   |
+LL |     let _ = 17;
+LL |     if x == 9 {
+   |
+help: and consider moving the end statements out like this
+   |
+LL |     }
+LL |     x * 4
+   |
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs
new file mode 100644
index 00000000000..0c70e3748ec
--- /dev/null
+++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs
@@ -0,0 +1,155 @@
+#![allow(dead_code, clippy::eval_order_dependence)]
+#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+
+// This tests valid if blocks that shouldn't trigger the lint
+
+// Tests with value references are includes in "shared_code_at_bottom.rs"
+
+fn valid_examples() {
+    let x = 2;
+
+    // The edge statements are different
+    if x == 9 {
+        let y = 1 << 5;
+
+        println!("This is the same: vvv");
+        let _z = y;
+        println!("The block expression is different");
+
+        println!("Different end 1");
+    } else {
+        let y = 1 << 7;
+
+        println!("This is the same: vvv");
+        let _z = y;
+        println!("The block expression is different");
+
+        println!("Different end 2");
+    }
+
+    // No else
+    if x == 2 {
+        println!("Hello world!");
+        println!("Hello back, how are you?");
+
+        // This is different vvvv
+        println!("Howdy stranger =^.^=");
+
+        println!("Bye Bye World");
+    } else if x == 9 {
+        println!("Hello world!");
+        println!("Hello back, how are you?");
+
+        // This is different vvvv
+        println!("Hello reviewer :D");
+
+        println!("Bye Bye World");
+    }
+
+    // Overlapping statements only in else if blocks -> Don't lint
+    if x == 0 {
+        println!("I'm important!")
+    } else if x == 17 {
+        println!("I share code in else if");
+
+        println!("x is 17");
+    } else {
+        println!("I share code in else if");
+
+        println!("x is nether x nor 17");
+    }
+
+    // Mutability is different
+    if x == 13 {
+        let mut y = 9;
+        println!("Value y is: {}", y);
+        y += 16;
+        let _z1 = y;
+    } else {
+        let y = 9;
+        println!("Value y is: {}", y);
+        let _z2 = y;
+    }
+
+    // Same blocks but at start and bottom so no `if_same_then_else` lint
+    if x == 418 {
+        let y = 9;
+        let z = 8;
+        let _ = (x, y, z);
+        // Don't tell the programmer, my code is also in the else block
+    } else if x == 419 {
+        println!("+-----------+");
+        println!("|           |");
+        println!("|  O     O  |");
+        println!("|     °     |");
+        println!("|  \\_____/  |");
+        println!("|           |");
+        println!("+-----------+");
+    } else {
+        let y = 9;
+        let z = 8;
+        let _ = (x, y, z);
+        // I'm so much better than the x == 418 block. Trust me
+    }
+
+    let x = 1;
+    if true {
+        println!("{}", x);
+    } else {
+        let x = 2;
+        println!("{}", x);
+    }
+
+    // Let's test empty blocks
+    if false {
+    } else {
+    }
+}
+
+/// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint
+fn trigger_other_lint() {
+    let x = 0;
+    let y = 1;
+
+    // Same block
+    if x == 0 {
+        let u = 19;
+        println!("How are u today?");
+        let _ = "This is a string";
+    } else {
+        let u = 19;
+        println!("How are u today?");
+        let _ = "This is a string";
+    }
+
+    // Only same expression
+    let _ = if x == 6 { 7 } else { 7 };
+
+    // Same in else if block
+    let _ = if x == 67 {
+        println!("Well I'm the most important block");
+        "I'm a pretty string"
+    } else if x == 68 {
+        println!("I'm a doppelgänger");
+        // Don't listen to my clone below
+
+        if y == 90 { "=^.^=" } else { ":D" }
+    } else {
+        // Don't listen to my clone above
+        println!("I'm a doppelgänger");
+
+        if y == 90 { "=^.^=" } else { ":D" }
+    };
+
+    if x == 0 {
+        println!("I'm single");
+    } else if x == 68 {
+        println!("I'm a doppelgänger");
+        // Don't listen to my clone below
+    } else {
+        // Don't listen to my clone above
+        println!("I'm a doppelgänger");
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/tests/ui/branches_sharing_code/valid_if_blocks.stderr
new file mode 100644
index 00000000000..a815995e717
--- /dev/null
+++ b/tests/ui/branches_sharing_code/valid_if_blocks.stderr
@@ -0,0 +1,101 @@
+error: this `if` has identical blocks
+  --> $DIR/valid_if_blocks.rs:104:14
+   |
+LL |       if false {
+   |  ______________^
+LL | |     } else {
+   | |_____^
+   |
+note: the lint level is defined here
+  --> $DIR/valid_if_blocks.rs:2:9
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: same as this
+  --> $DIR/valid_if_blocks.rs:105:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |     }
+   | |_____^
+
+error: this `if` has identical blocks
+  --> $DIR/valid_if_blocks.rs:115:15
+   |
+LL |       if x == 0 {
+   |  _______________^
+LL | |         let u = 19;
+LL | |         println!("How are u today?");
+LL | |         let _ = "This is a string";
+LL | |     } else {
+   | |_____^
+   |
+note: same as this
+  --> $DIR/valid_if_blocks.rs:119:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         let u = 19;
+LL | |         println!("How are u today?");
+LL | |         let _ = "This is a string";
+LL | |     }
+   | |_____^
+
+error: this `if` has identical blocks
+  --> $DIR/valid_if_blocks.rs:126:23
+   |
+LL |     let _ = if x == 6 { 7 } else { 7 };
+   |                       ^^^^^
+   |
+note: same as this
+  --> $DIR/valid_if_blocks.rs:126:34
+   |
+LL |     let _ = if x == 6 { 7 } else { 7 };
+   |                                  ^^^^^
+
+error: this `if` has identical blocks
+  --> $DIR/valid_if_blocks.rs:132:23
+   |
+LL |       } else if x == 68 {
+   |  _______________________^
+LL | |         println!("I'm a doppelgänger");
+LL | |         // Don't listen to my clone below
+LL | |
+LL | |         if y == 90 { "=^.^=" } else { ":D" }
+LL | |     } else {
+   | |_____^
+   |
+note: same as this
+  --> $DIR/valid_if_blocks.rs:137:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         // Don't listen to my clone above
+LL | |         println!("I'm a doppelgänger");
+LL | |
+LL | |         if y == 90 { "=^.^=" } else { ":D" }
+LL | |     };
+   | |_____^
+
+error: this `if` has identical blocks
+  --> $DIR/valid_if_blocks.rs:146:23
+   |
+LL |       } else if x == 68 {
+   |  _______________________^
+LL | |         println!("I'm a doppelgänger");
+LL | |         // Don't listen to my clone below
+LL | |     } else {
+   | |_____^
+   |
+note: same as this
+  --> $DIR/valid_if_blocks.rs:149:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         // Don't listen to my clone above
+LL | |         println!("I'm a doppelgänger");
+LL | |     }
+   | |_____^
+
+error: aborting due to 5 previous errors
+