use inner::{self as inner_mod};
mod inner {}

pub mod ops {
    #[lang = "fn_once"]
    pub trait FnOnce<Args> {}

    #[lang = "fn_mut"]
    pub trait FnMut<Args>: FnOnce<Args> {}

    #[lang = "fn"]
    pub trait Fn<Args>: FnMut<Args> {}
}

struct Foo {
    x: u32,
}

trait Bar {
    fn bar(&self) -> i32;
}

impl Bar for Foo {
    fn bar(&self) -> i32 {
        self.x
    }
}

impl Foo {
    fn baz(mut self, f: Foo) -> i32 {
        f.baz(self)
    }

    fn qux(&mut self) {
        self.x = 0;
    }

    fn quop(&self) -> i32 {
        self.x
    }
}

use self::FooCopy::{self as BarCopy};

#[derive(Copy)]
struct FooCopy {
    x: u32,
}

impl FooCopy {
    fn baz(self, f: FooCopy) -> u32 {
        f.baz(self)
    }

    fn qux(&mut self) {
        self.x = 0;
    }

    fn quop(&self) -> u32 {
        self.x
    }
}

fn str() {
    str();
}

fn foo<'a, T>() -> T {
    foo::<'a, i32>()
}

fn never() -> ! {
    loop {}
}

fn const_param<const FOO: usize>() -> usize {
    const_param::<{ FOO }>();
    FOO
}

use ops::Fn;
fn baz<F: Fn() -> ()>(f: F) {
    f()
}

fn foobar() -> impl Copy {}

fn foo() {
    let bar = foobar();
}

// comment
fn main() {
    let mut x = 42;
    x += 1;
    let y = &mut x;
    let z = &y;

    let Foo { x: z, y } = Foo { x: z, y };

    y;

    let mut foo = Foo { x, y: x };
    let foo2 = Foo { x, y: x };
    foo.quop();
    foo.qux();
    foo.baz(foo2);

    let mut copy = FooCopy { x };
    copy.quop();
    copy.qux();
    copy.baz(copy);

    let a = |x| x;
    let bar = Foo::baz;

    let baz = (-42,);
    let baz = -baz.0;

    let _ = !true;

    'foo: loop {
        break 'foo;
        continue 'foo;
    }
}

enum Option<T> {
    Some(T),
    None,
}
use Option::*;

impl<T> Option<T> {
    fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
        match other {
            None => unimplemented!(),
            Nope => Nope,
        }
    }
}

async fn learn_and_sing() {
    let song = learn_song().await;
    sing_song(song).await;
}

async fn async_main() {
    let f1 = learn_and_sing();
    let f2 = dance();
    futures::join!(f1, f2);
}

fn use_foo_items() {
    let bob = foo::Person {
        name: "Bob",
        age: foo::consts::NUMBER,
    };

    let control_flow = foo::identity(foo::ControlFlow::Continue);

    if control_flow.should_die() {
        foo::die!();
    }
}

pub enum Bool { True, False }

impl Bool {
    pub const fn to_primitive(self) -> bool {
        true
    }
}
const USAGE_OF_BOOL: bool = Bool::True.to_primitive();

trait Baz {
    type Qux;
}

fn baz<T>(t: T)
where
    T: Baz,
    <T as Baz>::Qux: Bar {}

fn gp_shadows_trait<Baz: Bar>() {
    Baz::bar;
}