| #![deny(clippy::branches_sharing_code)] |
| #![allow(clippy::let_and_return)] |
| |
| enum Mode { |
| Kill, |
| Table, |
| List, |
| } |
| |
| fn kill() {} |
| fn table() {} |
| fn list() {} |
| |
| // Every arm ends in `Ok(())`: the shared tail can be hoisted out below the `match`. |
| fn shared_tail(mode: Mode) -> Result<(), ()> { |
| //~v branches_sharing_code |
| match mode { |
| Mode::Kill => { |
| kill(); |
| }, |
| Mode::Table => { |
| table(); |
| }, |
| Mode::List => { |
| list(); |
| }, |
| } |
| Ok(()) |
| } |
| |
| // Shared tail even though one arm has an early `return`. |
| fn shared_tail_with_return(mode: Mode, skip: bool) -> Result<(), ()> { |
| //~v branches_sharing_code |
| match mode { |
| Mode::Kill => { |
| if skip { |
| return Ok(()); |
| } |
| kill(); |
| }, |
| _ => { |
| table(); |
| }, |
| } |
| Ok(()) |
| } |
| |
| // No lint: the trailing expressions differ. |
| fn different_tail(mode: Mode) -> Result<u32, ()> { |
| match mode { |
| Mode::Kill => { |
| kill(); |
| Ok(1) |
| }, |
| Mode::Table => { |
| table(); |
| Ok(2) |
| }, |
| Mode::List => Ok(3), |
| } |
| } |
| |
| // No lint: the tail references a binding introduced inside the arm. |
| fn refs_local(x: Option<i32>) -> i32 { |
| match x { |
| Some(v) => { |
| kill(); |
| v |
| }, |
| None => { |
| table(); |
| 0 |
| }, |
| } |
| } |
| |
| // No lint: the `match` value is bound, so the tail cannot simply be moved after it. |
| fn value_used(mode: Mode) -> Result<(), ()> { |
| let res = match mode { |
| Mode::Kill => { |
| kill(); |
| Ok(()) |
| }, |
| _ => { |
| table(); |
| Ok(()) |
| }, |
| }; |
| res |
| } |
| |
| struct Guard; |
| |
| impl Drop for Guard { |
| fn drop(&mut self) {} |
| } |
| |
| // No lint: an arm-local binding has a non-trivial `Drop`. Hoisting the tail would drop the guard |
| // before the moved expression runs, changing observable drop order. |
| fn arm_local_drop(mode: Mode) -> Result<(), ()> { |
| match mode { |
| Mode::Kill => { |
| let _g = Guard; |
| kill(); |
| Ok(()) |
| }, |
| _ => { |
| table(); |
| Ok(()) |
| }, |
| } |
| } |
| |
| // Comments inside the arm bodies, including right before the shared tail. |
| fn comments_in_arm_body(mode: Mode) -> Result<(), ()> { |
| //~v branches_sharing_code |
| match mode { |
| Mode::Kill => { |
| // kill it |
| kill(); |
| }, |
| Mode::Table => { |
| // table it |
| table(); |
| }, |
| Mode::List => { |
| list(); |
| }, |
| } |
| Ok(()) |
| } |
| |
| // Comments before the `=>` of each arm. |
| fn comments_before_fat_arrow(mode: Mode) -> Result<(), ()> { |
| //~v branches_sharing_code |
| match mode { |
| // killing time |
| Mode::Kill => { |
| kill(); |
| }, |
| // table time |
| Mode::Table => { |
| table(); |
| }, |
| // list time |
| Mode::List => { |
| list(); |
| }, |
| } |
| Ok(()) |
| } |
| |
| fn main() {} |