//@run-rustfix

#![feature(lint_reasons)]
#![feature(yeet_expr)]
#![allow(unused)]
#![allow(
    clippy::if_same_then_else,
    clippy::single_match,
    clippy::needless_bool,
    clippy::equatable_if_let,
    clippy::needless_else
)]
#![warn(clippy::needless_return)]

use std::cell::RefCell;

macro_rules! the_answer {
    () => {
        42
    };
}

fn test_end_of_fn() -> bool {
    if true {
        // no error!
        return true;
    }
    true
}

fn test_no_semicolon() -> bool {
    true
}

#[rustfmt::skip]
fn test_multiple_semicolon() -> bool {
    true
}

#[rustfmt::skip]
fn test_multiple_semicolon_with_spaces() -> bool {
    true
}

fn test_if_block() -> bool {
    if true {
        true
    } else {
        false
    }
}

fn test_match(x: bool) -> bool {
    match x {
        true => false,
        false => {
            true
        },
    }
}

fn test_closure() {
    let _ = || {
        true
    };
    let _ = || true;
}

fn test_macro_call() -> i32 {
    the_answer!()
}

fn test_void_fun() {
}

fn test_void_if_fun(b: bool) {
    if b {
    } else {
    }
}

fn test_void_match(x: u32) {
    match x {
        0 => (),
        _ => (),
    }
}

fn test_nested_match(x: u32) {
    match x {
        0 => (),
        1 => {
            let _ = 42;
        },
        _ => (),
    }
}

fn temporary_outlives_local() -> String {
    let x = RefCell::<String>::default();
    return x.borrow().clone();
}

fn borrows_but_not_last(value: bool) -> String {
    if value {
        let x = RefCell::<String>::default();
        let _a = x.borrow().clone();
        String::from("test")
    } else {
        String::new()
    }
}

macro_rules! needed_return {
    ($e:expr) => {
        if $e > 3 {
            return;
        }
    };
}

fn test_return_in_macro() {
    // This will return and the macro below won't be executed. Removing the `return` from the macro
    // will change semantics.
    needed_return!(10);
    needed_return!(0);
}

mod issue6501 {
    #[allow(clippy::unnecessary_lazy_evaluations)]
    fn foo(bar: Result<(), ()>) {
        bar.unwrap_or_else(|_| {})
    }

    fn test_closure() {
        let _ = || {
        };
        let _ = || {};
    }

    struct Foo;
    #[allow(clippy::unnecessary_lazy_evaluations)]
    fn bar(res: Result<Foo, u8>) -> Foo {
        res.unwrap_or_else(|_| Foo)
    }
}

async fn async_test_end_of_fn() -> bool {
    if true {
        // no error!
        return true;
    }
    true
}

async fn async_test_no_semicolon() -> bool {
    true
}

async fn async_test_if_block() -> bool {
    if true {
        true
    } else {
        false
    }
}

async fn async_test_match(x: bool) -> bool {
    match x {
        true => false,
        false => {
            true
        },
    }
}

async fn async_test_closure() {
    let _ = || {
        true
    };
    let _ = || true;
}

async fn async_test_macro_call() -> i32 {
    the_answer!()
}

async fn async_test_void_fun() {
}

async fn async_test_void_if_fun(b: bool) {
    if b {
    } else {
    }
}

async fn async_test_void_match(x: u32) {
    match x {
        0 => (),
        _ => (),
    }
}

async fn async_temporary_outlives_local() -> String {
    let x = RefCell::<String>::default();
    return x.borrow().clone();
}

async fn async_borrows_but_not_last(value: bool) -> String {
    if value {
        let x = RefCell::<String>::default();
        let _a = x.borrow().clone();
        String::from("test")
    } else {
        String::new()
    }
}

async fn async_test_return_in_macro() {
    needed_return!(10);
    needed_return!(0);
}

fn let_else() {
    let Some(1) = Some(1) else { return };
}

fn needless_return_macro() -> String {
    let _ = "foo";
    let _ = "bar";
    format!("Hello {}", "world!")
}

fn issue_9361() -> i32 {
    let n = 1;
    #[allow(clippy::arithmetic_side_effects)]
    return n + n;
}

fn issue8336(x: i32) -> bool {
    if x > 0 {
        println!("something");
        true
    } else {
        false
    }
}

fn issue8156(x: u8) -> u64 {
    match x {
        80 => {
            10
        },
        _ => {
            100
        },
    }
}

// Ideally the compiler should throw `unused_braces` in this case
fn issue9192() -> i32 {
    {
        0
    }
}

fn issue9503(x: usize) -> isize {
    unsafe {
        if x > 12 {
            *(x as *const isize)
        } else {
            !*(x as *const isize)
        }
    }
}

mod issue9416 {
    pub fn with_newline() {
        let _ = 42;
    }

    #[rustfmt::skip]
    pub fn oneline() {
        let _ = 42;
    }
}

fn issue9947() -> Result<(), String> {
    do yeet "hello";
}

// without anyhow, but triggers the same bug I believe
#[expect(clippy::useless_format)]
fn issue10051() -> Result<String, String> {
    if true {
        Ok(format!("ok!"))
    } else {
        Err(format!("err!"))
    }
}

mod issue10049 {
    fn single() -> u32 {
        if true { 1 } else { 2 }
    }

    fn multiple(b1: bool, b2: bool, b3: bool) -> u32 {
        (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })
    }
}

fn test_match_as_stmt() {
    let x = 9;
    match x {
        1 => 2,
        2 => return,
        _ => 0,
    };
}

fn main() {}