// run-pass

#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
#![allow(unreachable_code)]

// Test various cases where we permit an unconstrained variable
// to fallback based on control-flow.
//
// These represent current behavior, but are pretty dubious.  I would
// like to revisit these and potentially change them. --nmatsakis

#![feature(never_type_fallback)]

trait BadDefault {
    fn default() -> Self;
}

impl BadDefault for u32 {
    fn default() -> Self {
        0
    }
}

impl BadDefault for ! {
    fn default() -> ! {
        panic!()
    }
}

fn assignment() {
    let x;

    if true {
        x = BadDefault::default();
    } else {
        x = return;
    }
}

fn assignment_rev() {
    let x;

    if true {
        x = return;
    } else {
        x = BadDefault::default();
    }
}

fn if_then_else() {
    let _x = if true {
        BadDefault::default()
    } else {
        return;
    };
}

fn if_then_else_rev() {
    let _x = if true {
        return;
    } else {
        BadDefault::default()
    };
}

fn match_arm() {
    let _x = match Ok(BadDefault::default()) {
        Ok(v) => v,
        Err(()) => return,
    };
}

fn match_arm_rev() {
    let _x = match Ok(BadDefault::default()) {
        Err(()) => return,
        Ok(v) => v,
    };
}

fn loop_break() {
    let _x = loop {
        if false {
            break return;
        } else {
            break BadDefault::default();
        }
    };
}

fn loop_break_rev() {
    let _x = loop {
        if false {
            break return;
        } else {
            break BadDefault::default();
        }
    };
}

fn main() { }
