//! returns: 0

/// Aggregate metadata must remain distinct from scalar metadata.
record Pair: Copy {
    /// First field.
    first: u32,
    /// Full-width field.
    second: u64,
}

/// Mutate an addressed full-width local.
fn increment(value: &mut u64) {
    set *value += 1;
}

/// Exercise reused lexical slots with different types and address modes.
fn check(seed: u32) -> u32 {
    let value = seed;
    let mut result: u32 = 0;
    {
        let mut value: u64 = 0x100000000 + seed as u64;
        increment(&mut value);
        assert value == 0x100000001 + seed as u64;
        set result += value as u32;
    }
    assert value == seed;
    {
        let value = Pair { first: seed + 2, second: 0x200000000 + seed as u64 };
        assert value.second == 0x200000000 + seed as u64;
        set result += value.first;
    }
    {
        let mut value = seed % 2 == 0;
        set value = not value;
        assert value == (seed % 2 == 1);
    }
    {
        let mut value = seed + 3;
        set value += 1;
        set result += value;
    }
    assert value == seed;
    return result;
}

/// Check repeated invocations and slot initialization in an empty function.
fn empty() {}

/// Keep local metadata live across multiple slice growth boundaries.
fn wide(seed: u64) -> u64 {
    let a = seed + 1;
    let b = seed + 2;
    let c = seed + 3;
    let d = seed + 4;
    let e = seed + 5;
    let f = seed + 6;
    let g = seed + 7;
    let h = seed + 8;
    let i = seed + 9;
    let j = seed + 10;
    let k = seed + 11;
    let l = seed + 12;
    let m = seed + 13;
    let n = seed + 14;
    let o = seed + 15;
    let mut p = seed + 16;
    increment(&mut p);
    return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p;
}

/// Verify scoped metadata over several argument values.
@default fn main() -> u32 {
    empty();
    for seed in 0..16 {
        assert check(seed) == seed * 3 + 7;
        let value = 0x100000000 + seed as u64;
        assert wide(value) == value * 16 + 137;
    }
    empty();
    return 0;
}
