<commit_before><commit_msg>bittwiddler: Test inverting bits and bits fixed to constant values<commit_after>use bittwiddler::*;

#[bitpattern(default = Self::Choice1)]
#[bitfragment(dimensions = 1)]
#[pat_bits("0" = 1, "1" = !2, "2" = true, "3" = false)]
#[derive(Debug, PartialEq, Eq)]
enum MyEnum {
    #[bits("0010")]
    Choice1,
    #[bits("0110")]
    Choice2,
    #[bits("1010")]
    Choice3,
    #[bits("1110")]
    Choice4,
}

#[test]
fn pat_invert_fixed_encode() {
    let mut out = [false; 3];

    let x = MyEnum::Choice2;
    BitFragment::encode(&x, &mut out[..], [0], [false]);
    assert_eq!(out, [false, false, false]);

    let x = MyEnum::Choice3;
    BitFragment::encode(&x, &mut out[..], [0], [false]);
    assert_eq!(out, [false, true, true]);

    // offset
    let mut out = [true; 5];

    let x = MyEnum::Choice2;
    BitFragment::encode(&x, &mut out[..], [1], [false]);
    assert_eq!(out, [true, true, false, false, true]);

    let x = MyEnum::Choice3;
    BitFragment::encode(&x, &mut out[..], [1], [false]);
    assert_eq!(out, [true, true, true, true, true]);

    // mirroring
    let mut out = [false; 3];
    let x = MyEnum::Choice2;
    BitFragment::encode(&x, &mut out[..], [2], [true]);
    assert_eq!(out, [false, false, false]);

    let mut out = [true; 5];
    let x = MyEnum::Choice3;
    BitFragment::encode(&x, &mut out[..], [3], [true]);
    assert_eq!(out, [true, true, true, true, true]);
}

#[test]
fn pat_invert_fixed_decode() {
    let x = [true, false, true];
    let out: MyEnum = BitFragment::decode(&x[..], [0], [false]).unwrap();
    assert_eq!(out, MyEnum::Choice1);

    let x = [false, true, false];
    let out: MyEnum = BitFragment::decode(&x[..], [0], [false]).unwrap();
    assert_eq!(out, MyEnum::Choice4);

    // offset
    let x = [false, false, false, true, false, true];
    let out: MyEnum = BitFragment::decode(&x[..], [3], [false]).unwrap();
    assert_eq!(out, MyEnum::Choice1);

    let x = [true, true, true, false, true, false];
    let out: MyEnum = BitFragment::decode(&x[..], [3], [false]).unwrap();
    assert_eq!(out, MyEnum::Choice4);

    // mirroring
    let x = [false, false, false];
    let out: MyEnum = BitFragment::decode(&x[..], [2], [true]).unwrap();
    assert_eq!(out, MyEnum::Choice2);

    let x = [true, true, true, true, true, true];
    let out: MyEnum = BitFragment::decode(&x[..], [5], [true]).unwrap();
    assert_eq!(out, MyEnum::Choice3);
}
<|endoftext|>


<commit_before><commit_msg>Fix Truncated Unit Names in GUI<commit_after><|endoftext|>


<commit_before>/**
use the taylor series to caculate tan^-1 (x) where |x| < 1
**/
fn taylor_atan (x: f64) -> f64 {
    let mut a: f64 = 0.0;
    let mut s: f64 = 1.0;
    let mut xpow: f64;

    // by definition
    if x == 0.0 {
        return 0.0;
    }

    // this is well known, and the taylor series we are using explictly assumes |x| < 1
    if x == 1.0 {
        return std::f64::consts::PI/4.0;
    }

    for ii in range(1i, 60) {
        if ii % 2 == 0 {
            continue;
        }
        xpow = 1.0;
        for jj in range(0i, ii) {
            xpow *= x;
        }
        a += s * xpow / (ii as f64);
        s = -1.0*s;
    }

    return a;
}

fn generate_table () {

    let pi: f64 = 3.1415926536897932384626;
    let k1: f64 = 0.6072529350088812561694; // 1/k
    let num_bits: uint = 32;
    let mul: uint = 1<<(num_bits-2);

    println!("Cordic sin in rust");
    println!("num bits {}", num_bits);
    println!("mul {}", mul);
    println!("1<<(num_bits-2) {}", ((1i << (num_bits-2)) as f64));
    println!("pi is {}", pi);
    println!("k1 is {}", k1);

    println!("let cordic_tab = [");

    let shift: f64 = 2.0;
    for ii in range(0, num_bits) {
        let ipow: f64 = 1f64/shift.powi(ii as i32);
        let cur: f64 = taylor_atan(ipow) * (mul as f64);

        if ii % 4 == 0 && ii > 0 {
            println!("");
        }
        if ii == 0 {
            print!("0x{}, ", std::f64::to_str_hex(cur.floor()));
        } else {
            print!("0x{}, ", std::f64::to_str_hex(cur.floor()));
        }
    }

    println!("];");
}

fn sin(theta: f64) -> f64 {

    let num_bits: uint = 32;

    let k1: f64 = 0.6072529350088812561694; // 1/k
    let muli: int = 1<<(num_bits-2);
    let mul: f64 = muli as f64;
    let cordic_k1: f64 = k1 * mul;
    let mut x: int = cordic_k1.floor() as int; //0x26DD3B6A;
    let mut y: int = 0;
    let mut z: int = (mul * theta).floor() as int;
    let mut tx: int;
    let mut ty: int;
    let mut tz: int;

    let mut d: int;

    let cordic_tab = [
        0x3243f6a8, 0x1dac6705, 0xfadbafc, 0x7f56ea6,
        0x3feab76, 0x1ffd55b, 0xfffaaa, 0x7fff55,
        0x3fffea, 0x1ffffd, 0xfffff, 0x7ffff,
        0x3ffff, 0x1ffff, 0xffff, 0x7fff,
        0x3fff, 0x1fff, 0xfff, 0x7ff,
        0x3ff, 0x1ff, 0xff, 0x7f,
        0x3f, 0x1f, 0xf, 0x8,
        0x4, 0x2, 0x1, 0x0, ];

    for k in range(0, num_bits) {
        if z >= 0 {
            d = 0;
        } else {
            d = -1;
        }

        tx = x - (((y>>k) ^ d) - d);
        ty = y + (((x>>k) ^ d) - d);
        tz = z - ((cordic_tab[k] ^ d) - d);
        x = tx; y = ty; z = tz;
    }

    let s: f64 = (y as f64)/(mul as f64);

    return s;

}

fn main() {
    generate_table();

    let frac_pi_2: f64 = std::f64::consts::FRAC_PI_2; //pi/2.0;

    for ii in range(0i, 50) {
        let cur: f64 = ii as f64;
        let theta: f64 = cur/50.0 * frac_pi_2;
        let s: f64 = sin(theta);
            println!("s {}", s);
    }
}
<commit_msg>fix comment<commit_after>/**
use the taylor series to caculate tan^-1 (x) where |x| <= 1, x >= 0
**/
fn taylor_atan (x: f64) -> f64 {
    let mut a: f64 = 0.0;
    let mut s: f64 = 1.0;
    let mut xpow: f64;

    // by definition
    if x == 0.0 {
        return 0.0;
    }

    // this is well known, and the taylor series we are using explictly assumes |x| < 1
    if x == 1.0 {
        return std::f64::consts::PI/4.0;
    }

    for ii in range(1i, 60) {
        if ii % 2 == 0 {
            continue;
        }
        xpow = 1.0;
        for jj in range(0i, ii) {
            xpow *= x;
        }
        a += s * xpow / (ii as f64);
        s = -1.0*s;
    }

    return a;
}

fn generate_table () {

    let pi: f64 = 3.1415926536897932384626;
    let k1: f64 = 0.6072529350088812561694; // 1/k
    let num_bits: uint = 32;
    let mul: uint = 1<<(num_bits-2);

    println!("Cordic sin in rust");
    println!("num bits {}", num_bits);
    println!("mul {}", mul);
    println!("1<<(num_bits-2) {}", ((1i << (num_bits-2)) as f64));
    println!("pi is {}", pi);
    println!("k1 is {}", k1);

    println!("let cordic_tab = [");

    let shift: f64 = 2.0;
    for ii in range(0, num_bits) {
        let ipow: f64 = 1f64/shift.powi(ii as i32);
        let cur: f64 = taylor_atan(ipow) * (mul as f64);

        if ii % 4 == 0 && ii > 0 {
            println!("");
        }
        if ii == 0 {
            print!("0x{}, ", std::f64::to_str_hex(cur.floor()));
        } else {
            print!("0x{}, ", std::f64::to_str_hex(cur.floor()));
        }
    }

    println!("];");
}

fn sin(theta: f64) -> f64 {

    let num_bits: uint = 32;

    let k1: f64 = 0.6072529350088812561694; // 1/k
    let muli: int = 1<<(num_bits-2);
    let mul: f64 = muli as f64;
    let cordic_k1: f64 = k1 * mul;
    let mut x: int = cordic_k1.floor() as int; //0x26DD3B6A;
    let mut y: int = 0;
    let mut z: int = (mul * theta).floor() as int;
    let mut tx: int;
    let mut ty: int;
    let mut tz: int;

    let mut d: int;

    let cordic_tab = [
        0x3243f6a8, 0x1dac6705, 0xfadbafc, 0x7f56ea6,
        0x3feab76, 0x1ffd55b, 0xfffaaa, 0x7fff55,
        0x3fffea, 0x1ffffd, 0xfffff, 0x7ffff,
        0x3ffff, 0x1ffff, 0xffff, 0x7fff,
        0x3fff, 0x1fff, 0xfff, 0x7ff,
        0x3ff, 0x1ff, 0xff, 0x7f,
        0x3f, 0x1f, 0xf, 0x8,
        0x4, 0x2, 0x1, 0x0, ];

    for k in range(0, num_bits) {
        if z >= 0 {
            d = 0;
        } else {
            d = -1;
        }

        tx = x - (((y>>k) ^ d) - d);
        ty = y + (((x>>k) ^ d) - d);
        tz = z - ((cordic_tab[k] ^ d) - d);
        x = tx; y = ty; z = tz;
    }

    let s: f64 = (y as f64)/(mul as f64);

    return s;

}

fn main() {
    generate_table();

    let frac_pi_2: f64 = std::f64::consts::FRAC_PI_2; //pi/2.0;

    for ii in range(0i, 50) {
        let cur: f64 = ii as f64;
        let theta: f64 = cur/50.0 * frac_pi_2;
        let s: f64 = sin(theta);
            println!("s {}", s);
    }
}
<|endoftext|>


<commit_before>use gl;
use context;
use ToGlEnum;

/// Describes the parameters that must be used for the stencil operations when drawing.
#[derive(Copy, Clone, Debug)]
pub struct Stencil {
    /// A comparison against the existing value in the stencil buffer.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_test_counter_clockwise` instead.
    ///
    /// The default value is `AlwaysPass`.
    pub test_clockwise: StencilTest,

    /// Reference value that is used by `stencil_test_clockwise`, `stencil_fail_operation_clockwise`,
    /// `stencil_pass_depth_fail_operation_clockwise` and `stencil_depth_pass_operation_clockwise`.
    pub reference_value_clockwise: i32,

    /// Allows specifying a mask when writing data on the stencil buffer.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_write_mask_counter_clockwise` instead.
    ///
    /// The default value is `0xffffffff`.
    pub write_mask_clockwise: u32,

    /// Specifies the operation to do when a fragment fails the stencil test.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_fail_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub fail_operation_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes the stencil test but fails
    /// the depth test.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_pass_depth_fail_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub pass_depth_fail_operation_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes both the stencil and depth tests.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_depth_pass_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub depth_pass_operation_clockwise: StencilOperation,

    /// A comparaison against the existing value in the stencil buffer.
    ///
    /// Only relevant for points, lines and faces that are counter-clockwise on the target surface.
    /// Other faces use `stencil_test_counter_clockwise` instead.
    ///
    /// The default value is `AlwaysPass`.
    pub test_counter_clockwise: StencilTest,

    /// Reference value that is used by `stencil_test_counter_clockwise`,
    /// `stencil_fail_operation_counter_clockwise`,
    /// `stencil_pass_depth_fail_operation_counter_clockwise` and
    /// `stencil_depth_pass_operation_counter_clockwise`.
    pub reference_value_counter_clockwise: i32,

    /// Allows specifying a mask when writing data on the stencil buffer.
    ///
    /// Only relevant for points, lines and faces that are counter-clockwise on the target surface.
    /// Other faces use `stencil_write_mask_clockwise` instead.
    ///
    /// The default value is `0xffffffff`.
    pub write_mask_counter_clockwise: u32,

    /// Specifies the operation to do when a fragment fails the stencil test.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_fail_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub fail_operation_counter_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes the stencil test but fails
    /// the depth test.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_pass_depth_fail_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub pass_depth_fail_operation_counter_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes both the stencil and depth tests.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_depth_pass_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub depth_pass_operation_counter_clockwise: StencilOperation,
}

impl Default for Stencil {
    #[inline]
    fn default() -> Stencil {
        Stencil {
            test_clockwise: StencilTest::AlwaysPass,
            reference_value_clockwise: 0,
            write_mask_clockwise: 0xffffffff,
            fail_operation_clockwise: StencilOperation::Keep,
            pass_depth_fail_operation_clockwise: StencilOperation::Keep,
            depth_pass_operation_clockwise: StencilOperation::Keep,
            test_counter_clockwise: StencilTest::AlwaysPass,
            reference_value_counter_clockwise: 0,
            write_mask_counter_clockwise: 0xffffffff,
            fail_operation_counter_clockwise: StencilOperation::Keep,
            pass_depth_fail_operation_counter_clockwise: StencilOperation::Keep,
            depth_pass_operation_counter_clockwise: StencilOperation::Keep,
        }
    }
}

/// Specifies which comparison the GPU will do to determine whether a sample passes the stencil
/// test. The general equation is `(ref & mask) CMP (stencil & mask)`, where `ref` is the reference
/// value (`stencil_reference_value_clockwise` or `stencil_reference_value_counter_clockwise`),
/// `CMP` is the comparison chosen, and `stencil` is the current value in the stencil buffer.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StencilTest {
    /// The stencil test always passes.
    AlwaysPass,

    /// The stencil test always fails.
    AlwaysFail,

    /// `(ref & mask) < (stencil & mask)`
    IfLess {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32
    },

    /// `(ref & mask) <= (stencil & mask)`
    IfLessOrEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) > (stencil & mask)`
    IfMore {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) >= (stencil & mask)`
    IfMoreOrEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) == (stencil & mask)`
    IfEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) != (stencil & mask)`
    IfNotEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },
}

/// Specificies which operation the GPU will do depending on the result of the stencil test.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StencilOperation {
    /// Keeps the value currently in the stencil buffer.
    Keep,

    /// Writes zero in the stencil buffer.
    Zero,

    /// Writes the reference value (`stencil_reference_value_clockwise` or
    /// `stencil_reference_value_counter_clockwise`) in the stencil buffer.
    Replace,

    /// Increments the value currently in the stencil buffer. If the value is the
    /// maximum, don't do anything.
    Increment,

    /// Increments the value currently in the stencil buffer. If the value is the
    /// maximum, wrap to `0`.
    IncrementWrap,

    /// Decrements the value currently in the stencil buffer. If the value is `0`,
    /// don't do anything.
    Decrement,

    /// Decrements the value currently in the stencil buffer. If the value is `0`,
    /// wrap to `-1`.
    DecrementWrap,

    /// Inverts each bit of the value.
    Invert,
}

impl ToGlEnum for StencilOperation {
    #[inline]
    fn to_glenum(&self) -> gl::types::GLenum {
        match *self {
            StencilOperation::Keep => gl::KEEP,
            StencilOperation::Zero => gl::ZERO,
            StencilOperation::Replace => gl::REPLACE,
            StencilOperation::Increment => gl::INCR,
            StencilOperation::IncrementWrap => gl::INCR_WRAP,
            StencilOperation::Decrement => gl::DECR,
            StencilOperation::DecrementWrap => gl::DECR_WRAP,
            StencilOperation::Invert => gl::INVERT,
        }
    }
}

pub fn sync_stencil(ctxt: &mut context::CommandContext, params: &Stencil) {
    // checks if stencil operations can be disabled
    if params.test_clockwise == StencilTest::AlwaysPass &&
       params.test_counter_clockwise == StencilTest::AlwaysPass &&
       params.fail_operation_clockwise == StencilOperation::Keep &&
       params.pass_depth_fail_operation_clockwise == StencilOperation::Keep &&
       params.depth_pass_operation_clockwise == StencilOperation::Keep &&
       params.fail_operation_counter_clockwise == StencilOperation::Keep &&
       params.pass_depth_fail_operation_counter_clockwise == StencilOperation::Keep &&
       params.depth_pass_operation_counter_clockwise == StencilOperation::Keep
    {
        if ctxt.state.enabled_stencil_test != false {
            unsafe { ctxt.gl.Disable(gl::STENCIL_TEST) };
            ctxt.state.enabled_stencil_test = false;
        }

        return;
    }

    // we are now in "stencil enabled land"

    // enabling if necessary
    if ctxt.state.enabled_stencil_test != true {
        unsafe { ctxt.gl.Enable(gl::STENCIL_TEST) };
        ctxt.state.enabled_stencil_test = true;
    }

    // synchronizing the test and read masks
    let (test_cw, read_mask_cw) = match params.test_clockwise {
        StencilTest::AlwaysPass => (gl::ALWAYS, 0),
        StencilTest::AlwaysFail => (gl::NEVER, 0),
        StencilTest::IfLess { mask } => (gl::LESS, mask),
        StencilTest::IfLessOrEqual { mask } => (gl::LEQUAL, mask),
        StencilTest::IfMore { mask } => (gl::GREATER, mask),
        StencilTest::IfMoreOrEqual { mask } => (gl::GEQUAL, mask),
        StencilTest::IfEqual { mask } => (gl::EQUAL, mask),
        StencilTest::IfNotEqual { mask } => (gl::NOTEQUAL, mask),
    };

    let (test_ccw, read_mask_ccw) = match params.test_counter_clockwise {
        StencilTest::AlwaysPass => (gl::ALWAYS, 0),
        StencilTest::AlwaysFail => (gl::NEVER, 0),
        StencilTest::IfLess { mask } => (gl::LESS, mask),
        StencilTest::IfLessOrEqual { mask } => (gl::LEQUAL, mask),
        StencilTest::IfMore { mask } => (gl::GREATER, mask),
        StencilTest::IfMoreOrEqual { mask } => (gl::GEQUAL, mask),
        StencilTest::IfEqual { mask } => (gl::EQUAL, mask),
        StencilTest::IfNotEqual { mask } => (gl::NOTEQUAL, mask),
    };

    let ref_cw = params.reference_value_clockwise;
    let ref_ccw = params.reference_value_counter_clockwise;

    if (test_cw, ref_cw, read_mask_cw) == (test_ccw, ref_ccw, read_mask_ccw) {
        if ctxt.state.stencil_func_back != (test_cw, ref_cw, read_mask_cw) ||
           ctxt.state.stencil_func_front != (test_ccw, ref_ccw, read_mask_ccw)
        {
            unsafe { ctxt.gl.StencilFunc(test_cw, ref_cw, read_mask_cw) };
            ctxt.state.stencil_func_back = (test_cw, ref_cw, read_mask_cw);
            ctxt.state.stencil_func_front = (test_ccw, ref_ccw, read_mask_ccw);
        }

    } else {
        if ctxt.state.stencil_func_back != (test_cw, ref_cw, read_mask_cw) {
            unsafe { ctxt.gl.StencilFuncSeparate(gl::BACK, test_cw, ref_cw, read_mask_cw) };
            ctxt.state.stencil_func_back = (test_cw, ref_cw, read_mask_cw);
        }

        if ctxt.state.stencil_func_front != (test_ccw, ref_ccw, read_mask_ccw) {
            unsafe { ctxt.gl.StencilFuncSeparate(gl::FRONT, test_ccw, ref_ccw, read_mask_ccw) };
            ctxt.state.stencil_func_front = (test_ccw, ref_ccw, read_mask_ccw);
        }
    }

    // synchronizing the write mask
    if params.write_mask_clockwise == params.write_mask_counter_clockwise {
        if ctxt.state.stencil_mask_back != params.write_mask_clockwise ||
           ctxt.state.stencil_mask_front != params.write_mask_clockwise
        {
            unsafe { ctxt.gl.StencilMask(params.write_mask_clockwise) };
            ctxt.state.stencil_mask_back = params.write_mask_clockwise;
            ctxt.state.stencil_mask_front = params.write_mask_clockwise;
        }

    } else {
        if ctxt.state.stencil_mask_back != params.write_mask_clockwise {
            unsafe { ctxt.gl.StencilMaskSeparate(gl::BACK, params.write_mask_clockwise) };
            ctxt.state.stencil_mask_back = params.write_mask_clockwise;
        }

        if ctxt.state.stencil_mask_front != params.write_mask_clockwise {
            unsafe { ctxt.gl.StencilMaskSeparate(gl::FRONT, params.write_mask_clockwise) };
            ctxt.state.stencil_mask_front = params.write_mask_clockwise;
        }
    }

    // synchronizing the operation
    let op_back = (params.fail_operation_clockwise.to_glenum(),
                   params.pass_depth_fail_operation_clockwise.to_glenum(),
                   params.depth_pass_operation_clockwise.to_glenum());

    let op_front = (params.fail_operation_counter_clockwise.to_glenum(),
                    params.pass_depth_fail_operation_counter_clockwise.to_glenum(),
                    params.depth_pass_operation_counter_clockwise.to_glenum());

    if op_back == op_front {
        if ctxt.state.stencil_op_back != op_back || ctxt.state.stencil_op_front != op_front {
            unsafe { ctxt.gl.StencilOp(op_back.0, op_back.1, op_back.2) };
            ctxt.state.stencil_op_back = op_back;
            ctxt.state.stencil_op_front = op_front;
        }

    } else {
        if ctxt.state.stencil_op_back != op_back {
            unsafe { ctxt.gl.StencilOpSeparate(gl::BACK, op_back.0, op_back.1, op_back.2) };
            ctxt.state.stencil_op_back = op_back;
        }

        if ctxt.state.stencil_op_front != op_front {
            unsafe { ctxt.gl.StencilOpSeparate(gl::FRONT, op_front.0, op_front.1, op_front.2) };
            ctxt.state.stencil_op_front = op_front;
        }
    }
}
<commit_msg>Improve StencilOperation::to_glenum<commit_after>use gl;
use context;
use ToGlEnum;

/// Describes the parameters that must be used for the stencil operations when drawing.
#[derive(Copy, Clone, Debug)]
pub struct Stencil {
    /// A comparison against the existing value in the stencil buffer.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_test_counter_clockwise` instead.
    ///
    /// The default value is `AlwaysPass`.
    pub test_clockwise: StencilTest,

    /// Reference value that is used by `stencil_test_clockwise`, `stencil_fail_operation_clockwise`,
    /// `stencil_pass_depth_fail_operation_clockwise` and `stencil_depth_pass_operation_clockwise`.
    pub reference_value_clockwise: i32,

    /// Allows specifying a mask when writing data on the stencil buffer.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_write_mask_counter_clockwise` instead.
    ///
    /// The default value is `0xffffffff`.
    pub write_mask_clockwise: u32,

    /// Specifies the operation to do when a fragment fails the stencil test.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_fail_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub fail_operation_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes the stencil test but fails
    /// the depth test.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_pass_depth_fail_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub pass_depth_fail_operation_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes both the stencil and depth tests.
    ///
    /// The stencil test is the test specified by `stencil_test_clockwise`.
    ///
    /// Only relevant for faces that are clockwise on the target surface. Other faces, points and
    /// lines use `stencil_depth_pass_operation_counter_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub depth_pass_operation_clockwise: StencilOperation,

    /// A comparaison against the existing value in the stencil buffer.
    ///
    /// Only relevant for points, lines and faces that are counter-clockwise on the target surface.
    /// Other faces use `stencil_test_counter_clockwise` instead.
    ///
    /// The default value is `AlwaysPass`.
    pub test_counter_clockwise: StencilTest,

    /// Reference value that is used by `stencil_test_counter_clockwise`,
    /// `stencil_fail_operation_counter_clockwise`,
    /// `stencil_pass_depth_fail_operation_counter_clockwise` and
    /// `stencil_depth_pass_operation_counter_clockwise`.
    pub reference_value_counter_clockwise: i32,

    /// Allows specifying a mask when writing data on the stencil buffer.
    ///
    /// Only relevant for points, lines and faces that are counter-clockwise on the target surface.
    /// Other faces use `stencil_write_mask_clockwise` instead.
    ///
    /// The default value is `0xffffffff`.
    pub write_mask_counter_clockwise: u32,

    /// Specifies the operation to do when a fragment fails the stencil test.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_fail_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub fail_operation_counter_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes the stencil test but fails
    /// the depth test.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_pass_depth_fail_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub pass_depth_fail_operation_counter_clockwise: StencilOperation,

    /// Specifies the operation to do when a fragment passes both the stencil and depth tests.
    ///
    /// The stencil test is the test specified by `stencil_test_counter_clockwise`.
    ///
    /// Only relevant for faces that are counter-clockwise on the target surface. Other faces
    /// use `stencil_depth_pass_operation_clockwise` instead.
    ///
    /// The default value is `Keep`.
    pub depth_pass_operation_counter_clockwise: StencilOperation,
}

impl Default for Stencil {
    #[inline]
    fn default() -> Stencil {
        Stencil {
            test_clockwise: StencilTest::AlwaysPass,
            reference_value_clockwise: 0,
            write_mask_clockwise: 0xffffffff,
            fail_operation_clockwise: StencilOperation::Keep,
            pass_depth_fail_operation_clockwise: StencilOperation::Keep,
            depth_pass_operation_clockwise: StencilOperation::Keep,
            test_counter_clockwise: StencilTest::AlwaysPass,
            reference_value_counter_clockwise: 0,
            write_mask_counter_clockwise: 0xffffffff,
            fail_operation_counter_clockwise: StencilOperation::Keep,
            pass_depth_fail_operation_counter_clockwise: StencilOperation::Keep,
            depth_pass_operation_counter_clockwise: StencilOperation::Keep,
        }
    }
}

/// Specifies which comparison the GPU will do to determine whether a sample passes the stencil
/// test. The general equation is `(ref & mask) CMP (stencil & mask)`, where `ref` is the reference
/// value (`stencil_reference_value_clockwise` or `stencil_reference_value_counter_clockwise`),
/// `CMP` is the comparison chosen, and `stencil` is the current value in the stencil buffer.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StencilTest {
    /// The stencil test always passes.
    AlwaysPass,

    /// The stencil test always fails.
    AlwaysFail,

    /// `(ref & mask) < (stencil & mask)`
    IfLess {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32
    },

    /// `(ref & mask) <= (stencil & mask)`
    IfLessOrEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) > (stencil & mask)`
    IfMore {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) >= (stencil & mask)`
    IfMoreOrEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) == (stencil & mask)`
    IfEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },

    /// `(ref & mask) != (stencil & mask)`
    IfNotEqual {
        /// The mask that is and'ed with the reference value and stencil buffer.
        mask: u32,
    },
}

/// Specificies which operation the GPU will do depending on the result of the stencil test.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]    // GLenum
pub enum StencilOperation {
    /// Keeps the value currently in the stencil buffer.
    Keep = gl::KEEP,

    /// Writes zero in the stencil buffer.
    Zero = gl::ZERO,

    /// Writes the reference value (`stencil_reference_value_clockwise` or
    /// `stencil_reference_value_counter_clockwise`) in the stencil buffer.
    Replace = gl::REPLACE,

    /// Increments the value currently in the stencil buffer. If the value is the
    /// maximum, don't do anything.
    Increment = gl::INCR,

    /// Increments the value currently in the stencil buffer. If the value is the
    /// maximum, wrap to `0`.
    IncrementWrap = gl::INCR_WRAP,

    /// Decrements the value currently in the stencil buffer. If the value is `0`,
    /// don't do anything.
    Decrement = gl::DECR,

    /// Decrements the value currently in the stencil buffer. If the value is `0`,
    /// wrap to `-1`.
    DecrementWrap = gl::DECR_WRAP,

    /// Inverts each bit of the value.
    Invert = gl::INVERT,
}

impl ToGlEnum for StencilOperation {
    #[inline]
    fn to_glenum(&self) -> gl::types::GLenum {
        *self as gl::types::GLenum
    }
}

pub fn sync_stencil(ctxt: &mut context::CommandContext, params: &Stencil) {
    // checks if stencil operations can be disabled
    if params.test_clockwise == StencilTest::AlwaysPass &&
       params.test_counter_clockwise == StencilTest::AlwaysPass &&
       params.fail_operation_clockwise == StencilOperation::Keep &&
       params.pass_depth_fail_operation_clockwise == StencilOperation::Keep &&
       params.depth_pass_operation_clockwise == StencilOperation::Keep &&
       params.fail_operation_counter_clockwise == StencilOperation::Keep &&
       params.pass_depth_fail_operation_counter_clockwise == StencilOperation::Keep &&
       params.depth_pass_operation_counter_clockwise == StencilOperation::Keep
    {
        if ctxt.state.enabled_stencil_test != false {
            unsafe { ctxt.gl.Disable(gl::STENCIL_TEST) };
            ctxt.state.enabled_stencil_test = false;
        }

        return;
    }

    // we are now in "stencil enabled land"

    // enabling if necessary
    if ctxt.state.enabled_stencil_test != true {
        unsafe { ctxt.gl.Enable(gl::STENCIL_TEST) };
        ctxt.state.enabled_stencil_test = true;
    }

    // synchronizing the test and read masks
    let (test_cw, read_mask_cw) = match params.test_clockwise {
        StencilTest::AlwaysPass => (gl::ALWAYS, 0),
        StencilTest::AlwaysFail => (gl::NEVER, 0),
        StencilTest::IfLess { mask } => (gl::LESS, mask),
        StencilTest::IfLessOrEqual { mask } => (gl::LEQUAL, mask),
        StencilTest::IfMore { mask } => (gl::GREATER, mask),
        StencilTest::IfMoreOrEqual { mask } => (gl::GEQUAL, mask),
        StencilTest::IfEqual { mask } => (gl::EQUAL, mask),
        StencilTest::IfNotEqual { mask } => (gl::NOTEQUAL, mask),
    };

    let (test_ccw, read_mask_ccw) = match params.test_counter_clockwise {
        StencilTest::AlwaysPass => (gl::ALWAYS, 0),
        StencilTest::AlwaysFail => (gl::NEVER, 0),
        StencilTest::IfLess { mask } => (gl::LESS, mask),
        StencilTest::IfLessOrEqual { mask } => (gl::LEQUAL, mask),
        StencilTest::IfMore { mask } => (gl::GREATER, mask),
        StencilTest::IfMoreOrEqual { mask } => (gl::GEQUAL, mask),
        StencilTest::IfEqual { mask } => (gl::EQUAL, mask),
        StencilTest::IfNotEqual { mask } => (gl::NOTEQUAL, mask),
    };

    let ref_cw = params.reference_value_clockwise;
    let ref_ccw = params.reference_value_counter_clockwise;

    if (test_cw, ref_cw, read_mask_cw) == (test_ccw, ref_ccw, read_mask_ccw) {
        if ctxt.state.stencil_func_back != (test_cw, ref_cw, read_mask_cw) ||
           ctxt.state.stencil_func_front != (test_ccw, ref_ccw, read_mask_ccw)
        {
            unsafe { ctxt.gl.StencilFunc(test_cw, ref_cw, read_mask_cw) };
            ctxt.state.stencil_func_back = (test_cw, ref_cw, read_mask_cw);
            ctxt.state.stencil_func_front = (test_ccw, ref_ccw, read_mask_ccw);
        }

    } else {
        if ctxt.state.stencil_func_back != (test_cw, ref_cw, read_mask_cw) {
            unsafe { ctxt.gl.StencilFuncSeparate(gl::BACK, test_cw, ref_cw, read_mask_cw) };
            ctxt.state.stencil_func_back = (test_cw, ref_cw, read_mask_cw);
        }

        if ctxt.state.stencil_func_front != (test_ccw, ref_ccw, read_mask_ccw) {
            unsafe { ctxt.gl.StencilFuncSeparate(gl::FRONT, test_ccw, ref_ccw, read_mask_ccw) };
            ctxt.state.stencil_func_front = (test_ccw, ref_ccw, read_mask_ccw);
        }
    }

    // synchronizing the write mask
    if params.write_mask_clockwise == params.write_mask_counter_clockwise {
        if ctxt.state.stencil_mask_back != params.write_mask_clockwise ||
           ctxt.state.stencil_mask_front != params.write_mask_clockwise
        {
            unsafe { ctxt.gl.StencilMask(params.write_mask_clockwise) };
            ctxt.state.stencil_mask_back = params.write_mask_clockwise;
            ctxt.state.stencil_mask_front = params.write_mask_clockwise;
        }

    } else {
        if ctxt.state.stencil_mask_back != params.write_mask_clockwise {
            unsafe { ctxt.gl.StencilMaskSeparate(gl::BACK, params.write_mask_clockwise) };
            ctxt.state.stencil_mask_back = params.write_mask_clockwise;
        }

        if ctxt.state.stencil_mask_front != params.write_mask_clockwise {
            unsafe { ctxt.gl.StencilMaskSeparate(gl::FRONT, params.write_mask_clockwise) };
            ctxt.state.stencil_mask_front = params.write_mask_clockwise;
        }
    }

    // synchronizing the operation
    let op_back = (params.fail_operation_clockwise.to_glenum(),
                   params.pass_depth_fail_operation_clockwise.to_glenum(),
                   params.depth_pass_operation_clockwise.to_glenum());

    let op_front = (params.fail_operation_counter_clockwise.to_glenum(),
                    params.pass_depth_fail_operation_counter_clockwise.to_glenum(),
                    params.depth_pass_operation_counter_clockwise.to_glenum());

    if op_back == op_front {
        if ctxt.state.stencil_op_back != op_back || ctxt.state.stencil_op_front != op_front {
            unsafe { ctxt.gl.StencilOp(op_back.0, op_back.1, op_back.2) };
            ctxt.state.stencil_op_back = op_back;
            ctxt.state.stencil_op_front = op_front;
        }

    } else {
        if ctxt.state.stencil_op_back != op_back {
            unsafe { ctxt.gl.StencilOpSeparate(gl::BACK, op_back.0, op_back.1, op_back.2) };
            ctxt.state.stencil_op_back = op_back;
        }

        if ctxt.state.stencil_op_front != op_front {
            unsafe { ctxt.gl.StencilOpSeparate(gl::FRONT, op_front.0, op_front.1, op_front.2) };
            ctxt.state.stencil_op_front = op_front;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a test for #71202<commit_after>// check-pass

#![feature(const_generics)]
#![allow(incomplete_features, const_evaluatable_unchecked)]

use std::marker::PhantomData;

struct DataHolder<T> {
    item: T,
}

impl<T: Copy> DataHolder<T> {
    const ITEM_IS_COPY: [(); 1 - {
        trait NotCopy {
            const VALUE: bool = false;
        }

        impl<__Type: ?Sized> NotCopy for __Type {}

        struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);

        impl<__Type> IsCopy<__Type>
        where
            __Type: Sized + Copy,
        {
            const VALUE: bool = true;
        }

        <IsCopy<T>>::VALUE
    } as usize] = [];
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Problem: pedantic rustfmt fails cause it wants types alphabetically<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags:-g
// ignore-pretty as this critically relies on line numbers

use std::io;
use std::io::prelude::*;
use std::env;

#[path = "backtrace-debuginfo-aux.rs"] mod aux;

macro_rules! pos {
    () => ((file!(), line!()))
}

#[cfg(all(unix,
          not(target_os = "macos"),
          not(target_os = "ios"),
          not(target_os = "android"),
          not(all(target_os = "linux", target_arch = "arm"))))]
macro_rules! dump_and_die {
    ($($pos:expr),*) => ({
        // FIXME(#18285): we cannot include the current position because
        // the macro span takes over the last frame's file/line.
        dump_filelines(&[$($pos),*]);
        panic!();
    })
}

// this does not work on Windows, Android, OSX or iOS
#[cfg(any(not(unix),
          target_os = "macos",
          target_os = "ios",
          target_os = "android",
          all(target_os = "linux", target_arch = "arm")))]
macro_rules! dump_and_die {
    ($($pos:expr),*) => ({ let _ = [$($pos),*]; })
}

// we can't use a function as it will alter the backtrace
macro_rules! check {
    ($counter:expr; $($pos:expr),*) => ({
        if *$counter == 0 {
            dump_and_die!($($pos),*)
        } else {
            *$counter -= 1;
        }
    })
}

type Pos = (&'static str, u32);

// this goes to stdout and each line has to be occurred
// in the following backtrace to stderr with a correct order.
fn dump_filelines(filelines: &[Pos]) {
    for &(file, line) in filelines.iter().rev() {
        // extract a basename
        let basename = file.split(&['/', '\\'][..]).last().unwrap();
        println!("{}:{}", basename, line);
    }
}

#[inline(never)]
fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);
    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
}

#[inline(always)]
fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);

    #[inline(always)]
    fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
        check!(counter; main_pos, outer_pos, inner_pos);
    }
    inner_further_inlined(counter, main_pos, outer_pos, pos!());

    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
}

#[inline(never)]
fn outer(mut counter: i32, main_pos: Pos) {
    inner(&mut counter, main_pos, pos!());
    inner_inlined(&mut counter, main_pos, pos!());
}

fn check_trace(output: &str, error: &str) {
    // reverse the position list so we can start with the last item (which was the first line)
    let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();

    assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error);
    for line in error.lines() {
        if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
            remaining.pop();
        }
    }
    assert!(remaining.is_empty(),
            "trace does not match position list: {}\n---\n{}", error, output);
}

fn run_test(me: &str) {
    use std::str;
    use std::process::Command;

    let mut template = Command::new(me);
    template.env("RUST_BACKTRACE", "1");

    let mut i = 0;
    loop {
        let out = Command::new(me)
                          .env("RUST_BACKTRACE", "1")
                          .arg(i.to_string()).output().unwrap();
        let output = str::from_utf8(&out.stdout).unwrap();
        let error = str::from_utf8(&out.stderr).unwrap();
        if out.status.success() {
            assert!(output.contains("done."), "bad output for successful run: {}", output);
            break;
        } else {
            check_trace(output, error);
        }
        i += 1;
    }
}

#[inline(never)]
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let case = args[1].parse().unwrap();
        writeln!(&mut io::stderr(), "test case {}", case).unwrap();
        outer(case, pos!());
        println!("done.");
    } else {
        run_test(&args[0]);
    }
}
<commit_msg>Make the backtrace-debuginfo test less error prone<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// We disable tail merging here because it can't preserve debuginfo and thus
// potentially breaks the backtraces. Also, subtle changes can decide whether
// tail merging suceeds, so the test might work today but fail tomorrow due to a
// seemingly completely unrelated change.
// Unfortunately, LLVM has no "disable" option for this, so we have to set
// "enable" to 0 instead.
// compile-flags:-g -Cllvm-args=-enable-tail-merge=0
// ignore-pretty as this critically relies on line numbers

use std::io;
use std::io::prelude::*;
use std::env;

#[path = "backtrace-debuginfo-aux.rs"] mod aux;

macro_rules! pos {
    () => ((file!(), line!()))
}

#[cfg(all(unix,
          not(target_os = "macos"),
          not(target_os = "ios"),
          not(target_os = "android"),
          not(all(target_os = "linux", target_arch = "arm"))))]
macro_rules! dump_and_die {
    ($($pos:expr),*) => ({
        // FIXME(#18285): we cannot include the current position because
        // the macro span takes over the last frame's file/line.
        dump_filelines(&[$($pos),*]);
        panic!();
    })
}

// this does not work on Windows, Android, OSX or iOS
#[cfg(any(not(unix),
          target_os = "macos",
          target_os = "ios",
          target_os = "android",
          all(target_os = "linux", target_arch = "arm")))]
macro_rules! dump_and_die {
    ($($pos:expr),*) => ({ let _ = [$($pos),*]; })
}

// we can't use a function as it will alter the backtrace
macro_rules! check {
    ($counter:expr; $($pos:expr),*) => ({
        if *$counter == 0 {
            dump_and_die!($($pos),*)
        } else {
            *$counter -= 1;
        }
    })
}

type Pos = (&'static str, u32);

// this goes to stdout and each line has to be occurred
// in the following backtrace to stderr with a correct order.
fn dump_filelines(filelines: &[Pos]) {
    for &(file, line) in filelines.iter().rev() {
        // extract a basename
        let basename = file.split(&['/', '\\'][..]).last().unwrap();
        println!("{}:{}", basename, line);
    }
}

#[inline(never)]
fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);
    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
}

#[inline(always)]
fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);

    #[inline(always)]
    fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
        check!(counter; main_pos, outer_pos, inner_pos);
    }
    inner_further_inlined(counter, main_pos, outer_pos, pos!());

    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });

    // this tests a distinction between two independent calls to the inlined function.
    // (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
    inner_further_inlined(counter, main_pos, outer_pos, pos!());
}

#[inline(never)]
fn outer(mut counter: i32, main_pos: Pos) {
    inner(&mut counter, main_pos, pos!());
    inner_inlined(&mut counter, main_pos, pos!());
}

fn check_trace(output: &str, error: &str) {
    // reverse the position list so we can start with the last item (which was the first line)
    let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();

    assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error);
    for line in error.lines() {
        if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
            remaining.pop();
        }
    }
    assert!(remaining.is_empty(),
            "trace does not match position list: {}\n---\n{}", error, output);
}

fn run_test(me: &str) {
    use std::str;
    use std::process::Command;

    let mut template = Command::new(me);
    template.env("RUST_BACKTRACE", "1");

    let mut i = 0;
    loop {
        let out = Command::new(me)
                          .env("RUST_BACKTRACE", "1")
                          .arg(i.to_string()).output().unwrap();
        let output = str::from_utf8(&out.stdout).unwrap();
        let error = str::from_utf8(&out.stderr).unwrap();
        if out.status.success() {
            assert!(output.contains("done."), "bad output for successful run: {}", output);
            break;
        } else {
            check_trace(output, error);
        }
        i += 1;
    }
}

#[inline(never)]
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let case = args[1].parse().unwrap();
        writeln!(&mut io::stderr(), "test case {}", case).unwrap();
        outer(case, pos!());
        println!("done.");
    } else {
        run_test(&args[0]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #1430 - RalfJung:unsize, r=RalfJung<commit_after>// Taken from the rustc test suite; this triggers an interesting case in unsizing.

#![allow(non_upper_case_globals, incomplete_features)]
#![feature(associated_type_bounds)]
#![feature(impl_trait_in_bindings)]

use std::ops::Add;

trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
trait Tr2<'a> { fn tr2(self) -> &'a Self; }

fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
fn assert_static<T: 'static>(_: T) {}
fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}

#[derive(Copy, Clone)]
struct S1;
#[derive(Copy, Clone)]
struct S2;
impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }

const cdef_et1: &dyn Tr1<As1: Copy> = &S1;
const sdef_et1: &dyn Tr1<As1: Copy> = &S1;
pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); }

const cdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
static sdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); }

const cdef_et3: &dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = {
    struct A;
    impl Tr1 for A {
        type As1 = core::ops::Range<u8>;
        fn mk(&self) -> Self::As1 { 0..10 }
    };
    &A
};
pub fn use_et3() {
    let _0 = cdef_et3.mk().clone();
    let mut s = 0u8;
    for _1 in _0 {
        let _2 = _1 + 1u8;
        s += _2.into();
    }
    assert_eq!(s, (0..10).map(|x| x + 1).sum());
}

const cdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = {
    #[derive(Copy, Clone)]
    struct A;
    impl Tr1 for A {
        type As1 = A;
        fn mk(&self) -> A { A }
    }
    impl<'a> Tr2<'a> for A {
        fn tr2(self) -> &'a Self { &A }
    }
    &A
};
static sdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = cdef_et4;
pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); }

fn main() {
    let _ = use_et1();
    let _ = use_et2();
    let _ = use_et3();
    let _ = use_et4();
}
<|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before><commit_msg>Comment fix<commit_after><|endoftext|>


<commit_before><commit_msg>Added the feature 'nightly' flag<commit_after><|endoftext|>


<commit_before><commit_msg>added run-pass test for issue #9049<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

enum Foo {
    B { b1: int, bb1: int},
}

macro_rules! match_inside_expansion(
    () => (
        match B { b1:29 , bb1: 100} {
            B { b1:b2 , bb1:bb2 } => b2+bb2
        }
    )
)

fn main() {
    assert_eq!(match_inside_expansion!(),129);
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for Issue 19811.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
    let mut escaped = String::from_str("");
    for c in '\u{10401}'.escape_unicode() {
        escaped.push(c);
    }
    assert_eq!("\\u{10401}", escaped);
}
<|endoftext|>


<commit_before><commit_msg>chore: update actix-web<commit_after><|endoftext|>


<commit_before>import std::map::hashmap;
import middle::ty;
import middle::ty::*;
import metadata::encoder;
import syntax::codemap;
import syntax::print::pprust;
import syntax::print::pprust::{path_to_str, constr_args_to_str, proto_to_str,
                               mode_to_str};
import syntax::{ast, ast_util};
import middle::ast_map;
import driver::session::session;

fn bound_region_to_str(_cx: ctxt, br: bound_region) -> str {
    alt br {
      br_anon          { "&" }
      br_named(str)    { #fmt["&%s", str] }
      br_self          { "&self" }
    }
}

fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> str {
    alt cx.items.get(node_id) {
      ast_map::node_block(blk) {
        #fmt("<block at %s>",
             codemap::span_to_str(blk.span, cx.sess.codemap))
      }
      ast_map::node_expr(expr) {
        alt expr.node {
          ast::expr_call(_, _, _) {
            #fmt("<call at %s>",
                 codemap::span_to_str(expr.span, cx.sess.codemap))
          }
          ast::expr_alt(_, _, _) {
            #fmt("<alt at %s>",
                 codemap::span_to_str(expr.span, cx.sess.codemap))
          }
          _ { cx.sess.bug(
              #fmt["re_scope refers to %s",
                   ast_map::node_id_to_str(cx.items, node_id)]) }
        }
      }
      _ { cx.sess.bug(
          #fmt["re_scope refers to %s",
               ast_map::node_id_to_str(cx.items, node_id)]) }
    }
}

fn region_to_str(cx: ctxt, region: region) -> str {
    alt region {
      re_scope(node_id) { #fmt["&%s", re_scope_id_to_str(cx, node_id)] }
      re_bound(br) { bound_region_to_str(cx, br) }
      re_free(id, br) { #fmt["{%d} %s", id, bound_region_to_str(cx, br)] }

      // These two should not be seen by end-users (very often, anyhow):
      re_var(id)    { #fmt("&%s", id.to_str()) }
      re_static     { "&static" }
    }
}

fn mt_to_str(cx: ctxt, m: mt) -> str {
    let mstr = alt m.mutbl {
      ast::m_mutbl { "mut " }
      ast::m_imm { "" }
      ast::m_const { "const " }
    };
    ret mstr + ty_to_str(cx, m.ty);
}

fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> str {
    alt vs {
      ty::vstore_fixed(n) { #fmt["%u", n] }
      ty::vstore_uniq { "~" }
      ty::vstore_box { "@" }
      ty::vstore_slice(r) { region_to_str(cx, r) }
    }
}

fn ty_to_str(cx: ctxt, typ: t) -> str {
    fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) ->
       str {
        let {mode, ty} = input;
        let modestr = alt canon_mode(cx, mode) {
          ast::infer(_) { "" }
          ast::expl(m) {
            if !ty::type_has_vars(ty) &&
                m == ty::default_arg_mode_for_ty(ty) {
                ""
            } else {
                mode_to_str(ast::expl(m))
            }
          }
        };
        modestr + ty_to_str(cx, ty)
    }
    fn fn_to_str(cx: ctxt, proto: ast::proto, ident: option<ast::ident>,
                 inputs: [arg], output: t, cf: ast::ret_style,
                 constrs: [@constr]) -> str {
        let mut s = proto_to_str(proto);
        alt ident { some(i) { s += " "; s += i; } _ { } }
        s += "(";
        let mut strs = [];
        for inputs.each {|a| strs += [fn_input_to_str(cx, a)]; }
        s += str::connect(strs, ", ");
        s += ")";
        if ty::get(output).struct != ty_nil {
            s += " -> ";
            alt cf {
              ast::noreturn { s += "!"; }
              ast::return_val { s += ty_to_str(cx, output); }
            }
        }
        s += constrs_str(constrs);
        ret s;
    }
    fn method_to_str(cx: ctxt, m: method) -> str {
        ret fn_to_str(cx, m.fty.proto, some(m.ident), m.fty.inputs,
                      m.fty.output, m.fty.ret_style, m.fty.constraints) + ";";
    }
    fn field_to_str(cx: ctxt, f: field) -> str {
        ret f.ident + ": " + mt_to_str(cx, f.mt);
    }
    fn parameterized(cx: ctxt, base: str, tps: [ty::t]) -> str {
        if vec::len(tps) > 0u {
            let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
            #fmt["%s<%s>", base, str::connect(strs, ",")]
        } else {
            base
        }
    }

    // if there is an id, print that instead of the structural type:
    alt ty::type_def_id(typ) {
      some(def_id) {
        let cs = ast_map::path_to_str(ty::item_path(cx, def_id));
        ret alt ty::get(typ).struct {
          ty_enum(_, tps) | ty_res(_, _, tps) | ty_iface(_, tps) |
          ty_class(_, tps) {
            parameterized(cx, cs, tps)
          }
          _ { cs }
        };
      }
      none { /* fallthrough */}
    }

    // pretty print the structural type representation:
    ret alt ty::get(typ).struct {
      ty_nil { "()" }
      ty_bot { "_|_" }
      ty_bool { "bool" }
      ty_int(ast::ty_i) { "int" }
      ty_int(ast::ty_char) { "char" }
      ty_int(t) { ast_util::int_ty_to_str(t) }
      ty_uint(ast::ty_u) { "uint" }
      ty_uint(t) { ast_util::uint_ty_to_str(t) }
      ty_float(ast::ty_f) { "float" }
      ty_float(t) { ast_util::float_ty_to_str(t) }
      ty_str { "str" }
      ty_self(ts) { parameterized(cx, "self", ts) }
      ty_box(tm) { "@" + mt_to_str(cx, tm) }
      ty_uniq(tm) { "~" + mt_to_str(cx, tm) }
      ty_ptr(tm) { "*" + mt_to_str(cx, tm) }
      ty_rptr(r, tm) {
        let rs = region_to_str(cx, r);
        if str::len(rs) == 1u {
            rs + mt_to_str(cx, tm)
        } else {
            rs + "." + mt_to_str(cx, tm)
        }
      }
      ty_vec(tm) { "[" + mt_to_str(cx, tm) + "]" }
      ty_type { "type" }
      ty_rec(elems) {
        let mut strs: [str] = [];
        for elems.each {|fld| strs += [field_to_str(cx, fld)]; }
        "{" + str::connect(strs, ",") + "}"
      }
      ty_tup(elems) {
        let mut strs = [];
        for elems.each {|elem| strs += [ty_to_str(cx, elem)]; }
        "(" + str::connect(strs, ",") + ")"
      }
      ty_fn(f) {
        fn_to_str(cx, f.proto, none, f.inputs, f.output, f.ret_style,
                  f.constraints)
      }
      ty_var(v) { v.to_str() }
      ty_param(id, _) {
        "'" + str::from_bytes([('a' as u8) + (id as u8)])
      }
      ty_enum(did, tps) | ty_res(did, _, tps) | ty_iface(did, tps) |
      ty_class(did, tps) {
        let path = ty::item_path(cx, did);
        let base = ast_map::path_to_str(path);
        parameterized(cx, base, tps)
      }
      ty_evec(mt, vs) {
        #fmt["[%s]/%s", mt_to_str(cx, mt),
             vstore_to_str(cx, vs)]
      }
      ty_estr(vs) { #fmt["str/%s", vstore_to_str(cx, vs)] }
      ty_opaque_box { "@?" }
      ty_constr(t, _) { "@?" }
      ty_opaque_closure_ptr(ck_block) { "closure&" }
      ty_opaque_closure_ptr(ck_box) { "closure@" }
      ty_opaque_closure_ptr(ck_uniq) { "closure~" }
    }
}

fn ty_to_short_str(cx: ctxt, typ: t) -> str {
    let mut s = encoder::encoded_ty(cx, typ);
    if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); }
    ret s;
}

fn constr_to_str(c: @constr) -> str {
    ret path_to_str(c.node.path) +
            pprust::constr_args_to_str(pprust::uint_to_str, c.node.args);
}

fn constrs_str(constrs: [@constr]) -> str {
    let mut s = "";
    let mut colon = true;
    for constrs.each {|c|
        if colon { s += " : "; colon = false; } else { s += ", "; }
        s += constr_to_str(c);
    }
    ret s;
}

fn ty_constr_to_str<Q>(c: @ast::spanned<ast::constr_general_<@ast::path, Q>>)
   -> str {
    ret path_to_str(c.node.path) +
            constr_args_to_str::<@ast::path>(path_to_str, c.node.args);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>change printout to be what users will expect<commit_after>import std::map::hashmap;
import middle::ty;
import middle::ty::*;
import metadata::encoder;
import syntax::codemap;
import syntax::print::pprust;
import syntax::print::pprust::{path_to_str, constr_args_to_str, proto_to_str,
                               mode_to_str};
import syntax::{ast, ast_util};
import middle::ast_map;
import driver::session::session;

fn bound_region_to_str(_cx: ctxt, br: bound_region) -> str {
    alt br {
      br_anon          { "&" }
      br_named(str)    { #fmt["&%s", str] }
      br_self          { "&self" }
    }
}

fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> str {
    alt cx.items.get(node_id) {
      ast_map::node_block(blk) {
        #fmt("<block at %s>",
             codemap::span_to_str(blk.span, cx.sess.codemap))
      }
      ast_map::node_expr(expr) {
        alt expr.node {
          ast::expr_call(_, _, _) {
            #fmt("<call at %s>",
                 codemap::span_to_str(expr.span, cx.sess.codemap))
          }
          ast::expr_alt(_, _, _) {
            #fmt("<alt at %s>",
                 codemap::span_to_str(expr.span, cx.sess.codemap))
          }
          _ { cx.sess.bug(
              #fmt["re_scope refers to %s",
                   ast_map::node_id_to_str(cx.items, node_id)]) }
        }
      }
      _ { cx.sess.bug(
          #fmt["re_scope refers to %s",
               ast_map::node_id_to_str(cx.items, node_id)]) }
    }
}

fn region_to_str(cx: ctxt, region: region) -> str {
    alt region {
      re_scope(node_id) { #fmt["&%s", re_scope_id_to_str(cx, node_id)] }
      re_bound(br) { bound_region_to_str(cx, br) }
      re_free(id, br) {
        // For debugging, this version is sometimes helpful:
        //  #fmt["{%d} %s", id, bound_region_to_str(cx, br)]

        // But this version is what the user expects to see:
        bound_region_to_str(cx, br)
      }

      // These two should not be seen by end-users (very often, anyhow):
      re_var(id)    { #fmt("&%s", id.to_str()) }
      re_static     { "&static" }
    }
}

fn mt_to_str(cx: ctxt, m: mt) -> str {
    let mstr = alt m.mutbl {
      ast::m_mutbl { "mut " }
      ast::m_imm { "" }
      ast::m_const { "const " }
    };
    ret mstr + ty_to_str(cx, m.ty);
}

fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> str {
    alt vs {
      ty::vstore_fixed(n) { #fmt["%u", n] }
      ty::vstore_uniq { "~" }
      ty::vstore_box { "@" }
      ty::vstore_slice(r) { region_to_str(cx, r) }
    }
}

fn ty_to_str(cx: ctxt, typ: t) -> str {
    fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) ->
       str {
        let {mode, ty} = input;
        let modestr = alt canon_mode(cx, mode) {
          ast::infer(_) { "" }
          ast::expl(m) {
            if !ty::type_has_vars(ty) &&
                m == ty::default_arg_mode_for_ty(ty) {
                ""
            } else {
                mode_to_str(ast::expl(m))
            }
          }
        };
        modestr + ty_to_str(cx, ty)
    }
    fn fn_to_str(cx: ctxt, proto: ast::proto, ident: option<ast::ident>,
                 inputs: [arg], output: t, cf: ast::ret_style,
                 constrs: [@constr]) -> str {
        let mut s = proto_to_str(proto);
        alt ident { some(i) { s += " "; s += i; } _ { } }
        s += "(";
        let mut strs = [];
        for inputs.each {|a| strs += [fn_input_to_str(cx, a)]; }
        s += str::connect(strs, ", ");
        s += ")";
        if ty::get(output).struct != ty_nil {
            s += " -> ";
            alt cf {
              ast::noreturn { s += "!"; }
              ast::return_val { s += ty_to_str(cx, output); }
            }
        }
        s += constrs_str(constrs);
        ret s;
    }
    fn method_to_str(cx: ctxt, m: method) -> str {
        ret fn_to_str(cx, m.fty.proto, some(m.ident), m.fty.inputs,
                      m.fty.output, m.fty.ret_style, m.fty.constraints) + ";";
    }
    fn field_to_str(cx: ctxt, f: field) -> str {
        ret f.ident + ": " + mt_to_str(cx, f.mt);
    }
    fn parameterized(cx: ctxt, base: str, tps: [ty::t]) -> str {
        if vec::len(tps) > 0u {
            let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
            #fmt["%s<%s>", base, str::connect(strs, ",")]
        } else {
            base
        }
    }

    // if there is an id, print that instead of the structural type:
    alt ty::type_def_id(typ) {
      some(def_id) {
        let cs = ast_map::path_to_str(ty::item_path(cx, def_id));
        ret alt ty::get(typ).struct {
          ty_enum(_, tps) | ty_res(_, _, tps) | ty_iface(_, tps) |
          ty_class(_, tps) {
            parameterized(cx, cs, tps)
          }
          _ { cs }
        };
      }
      none { /* fallthrough */}
    }

    // pretty print the structural type representation:
    ret alt ty::get(typ).struct {
      ty_nil { "()" }
      ty_bot { "_|_" }
      ty_bool { "bool" }
      ty_int(ast::ty_i) { "int" }
      ty_int(ast::ty_char) { "char" }
      ty_int(t) { ast_util::int_ty_to_str(t) }
      ty_uint(ast::ty_u) { "uint" }
      ty_uint(t) { ast_util::uint_ty_to_str(t) }
      ty_float(ast::ty_f) { "float" }
      ty_float(t) { ast_util::float_ty_to_str(t) }
      ty_str { "str" }
      ty_self(ts) { parameterized(cx, "self", ts) }
      ty_box(tm) { "@" + mt_to_str(cx, tm) }
      ty_uniq(tm) { "~" + mt_to_str(cx, tm) }
      ty_ptr(tm) { "*" + mt_to_str(cx, tm) }
      ty_rptr(r, tm) {
        let rs = region_to_str(cx, r);
        if str::len(rs) == 1u {
            rs + mt_to_str(cx, tm)
        } else {
            rs + "." + mt_to_str(cx, tm)
        }
      }
      ty_vec(tm) { "[" + mt_to_str(cx, tm) + "]" }
      ty_type { "type" }
      ty_rec(elems) {
        let mut strs: [str] = [];
        for elems.each {|fld| strs += [field_to_str(cx, fld)]; }
        "{" + str::connect(strs, ",") + "}"
      }
      ty_tup(elems) {
        let mut strs = [];
        for elems.each {|elem| strs += [ty_to_str(cx, elem)]; }
        "(" + str::connect(strs, ",") + ")"
      }
      ty_fn(f) {
        fn_to_str(cx, f.proto, none, f.inputs, f.output, f.ret_style,
                  f.constraints)
      }
      ty_var(v) { v.to_str() }
      ty_param(id, _) {
        "'" + str::from_bytes([('a' as u8) + (id as u8)])
      }
      ty_enum(did, tps) | ty_res(did, _, tps) | ty_iface(did, tps) |
      ty_class(did, tps) {
        let path = ty::item_path(cx, did);
        let base = ast_map::path_to_str(path);
        parameterized(cx, base, tps)
      }
      ty_evec(mt, vs) {
        #fmt["[%s]/%s", mt_to_str(cx, mt),
             vstore_to_str(cx, vs)]
      }
      ty_estr(vs) { #fmt["str/%s", vstore_to_str(cx, vs)] }
      ty_opaque_box { "@?" }
      ty_constr(t, _) { "@?" }
      ty_opaque_closure_ptr(ck_block) { "closure&" }
      ty_opaque_closure_ptr(ck_box) { "closure@" }
      ty_opaque_closure_ptr(ck_uniq) { "closure~" }
    }
}

fn ty_to_short_str(cx: ctxt, typ: t) -> str {
    let mut s = encoder::encoded_ty(cx, typ);
    if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); }
    ret s;
}

fn constr_to_str(c: @constr) -> str {
    ret path_to_str(c.node.path) +
            pprust::constr_args_to_str(pprust::uint_to_str, c.node.args);
}

fn constrs_str(constrs: [@constr]) -> str {
    let mut s = "";
    let mut colon = true;
    for constrs.each {|c|
        if colon { s += " : "; colon = false; } else { s += ", "; }
        s += constr_to_str(c);
    }
    ret s;
}

fn ty_constr_to_str<Q>(c: @ast::spanned<ast::constr_general_<@ast::path, Q>>)
   -> str {
    ret path_to_str(c.node.path) +
            constr_args_to_str::<@ast::path>(path_to_str, c.node.args);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! An implementation of SipHash 2-4.

use prelude::v1::*;

use ptr;
use super::Hasher;

/// An implementation of SipHash 2-4.
///
/// See: http://131002.net/siphash/
///
/// This is the default hashing function used by standard library (eg.
/// `collections::HashMap` uses it by default).
///
/// SipHash is a general-purpose hashing function: it runs at a good
/// speed (competitive with Spooky and City) and permits strong _keyed_
/// hashing. This lets you key your hashtables from a strong RNG, such
/// as [`rand::Rng`](https://doc.rust-lang.org/rand/rand/trait.Rng.html).
///
/// Although the SipHash algorithm is considered to be cryptographically
/// strong, this implementation has not been reviewed for such purposes.
/// As such, all cryptographic uses of this implementation are _strongly
/// discouraged_.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct SipHasher {
    k0: u64,
    k1: u64,
    length: usize, // how many bytes we've processed
    // v0, v2 and v1, v3 show up in pairs in the algorithm,
    // and simd implementations of SipHash will use vectors
    // of v02 and v13. By placing them in this order in the struct,
    // the compiler can pick up on just a few simd optimizations by itself.
    v0: u64, // hash state
    v2: u64,
    v1: u64,
    v3: u64,
    tail: u64, // unprocessed bytes le
    ntail: usize, // how many bytes in tail are valid
}

// sadly, these macro definitions can't appear later,
// because they're needed in the following defs;
// this design could be improved.

macro_rules! u8to64_le {
    ($buf:expr, $i:expr) =>
    ($buf[0+$i] as u64 |
     ($buf[1+$i] as u64) << 8 |
     ($buf[2+$i] as u64) << 16 |
     ($buf[3+$i] as u64) << 24 |
     ($buf[4+$i] as u64) << 32 |
     ($buf[5+$i] as u64) << 40 |
     ($buf[6+$i] as u64) << 48 |
     ($buf[7+$i] as u64) << 56);
    ($buf:expr, $i:expr, $len:expr) =>
    ({
        let mut t = 0;
        let mut out = 0;
        while t < $len {
            out |= ($buf[t+$i] as u64) << t*8;
            t += 1;
        }
        out
    });
}

/// Load a full u64 word from a byte stream, in LE order. Use
/// `copy_nonoverlapping` to let the compiler generate the most efficient way
/// to load u64 from a possibly unaligned address.
///
/// Unsafe because: unchecked indexing at i..i+8
#[inline]
unsafe fn load_u64_le(buf: &[u8], i: usize) -> u64 {
    debug_assert!(i + 8 <= buf.len());
    let mut data = 0u64;
    ptr::copy_nonoverlapping(buf.get_unchecked(i), &mut data as *mut _ as *mut u8, 8);
    data.to_le()
}

macro_rules! rotl {
    ($x:expr, $b:expr) =>
    (($x << $b) | ($x >> (64_i32.wrapping_sub($b))))
}

macro_rules! compress {
    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
    ({
        $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
        $v0 = rotl!($v0, 32);
        $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2;
        $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
        $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
        $v2 = rotl!($v2, 32);
    })
}

impl SipHasher {
    /// Creates a new `SipHasher` with the two initial keys set to 0.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> SipHasher {
        SipHasher::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher` that is keyed off the provided keys.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
        let mut state = SipHasher {
            k0: key0,
            k1: key1,
            length: 0,
            v0: 0,
            v1: 0,
            v2: 0,
            v3: 0,
            tail: 0,
            ntail: 0,
        };
        state.reset();
        state
    }

    #[inline]
    fn reset(&mut self) {
        self.length = 0;
        self.v0 = self.k0 ^ 0x736f6d6570736575;
        self.v1 = self.k1 ^ 0x646f72616e646f6d;
        self.v2 = self.k0 ^ 0x6c7967656e657261;
        self.v3 = self.k1 ^ 0x7465646279746573;
        self.ntail = 0;
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hasher for SipHasher {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        let length = msg.len();
        self.length += length;

        let mut needed = 0;

        if self.ntail != 0 {
            needed = 8 - self.ntail;
            if length < needed {
                self.tail |= u8to64_le!(msg, 0, length) << 8 * self.ntail;
                self.ntail += length;
                return
            }

            let m = self.tail | u8to64_le!(msg, 0, needed) << 8 * self.ntail;

            self.v3 ^= m;
            compress!(self.v0, self.v1, self.v2, self.v3);
            compress!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= m;

            self.ntail = 0;
        }

        // Buffered tail is now flushed, process new input.
        let len = length - needed;
        let left = len & 0x7;

        let mut i = needed;
        while i < len - left {
            let mi = unsafe { load_u64_le(msg, i) };

            self.v3 ^= mi;
            compress!(self.v0, self.v1, self.v2, self.v3);
            compress!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= mi;

            i += 8;
        }

        self.tail = u8to64_le!(msg, i, left);
        self.ntail = left;
    }

    #[inline]
    fn finish(&self) -> u64 {
        let mut v0 = self.v0;
        let mut v1 = self.v1;
        let mut v2 = self.v2;
        let mut v3 = self.v3;

        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;

        v3 ^= b;
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        v0 ^= b;

        v2 ^= 0xff;
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);

        v0 ^ v1 ^ v2 ^ v3
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for SipHasher {
    #[inline]
    fn clone(&self) -> SipHasher {
        SipHasher {
            k0: self.k0,
            k1: self.k1,
            length: self.length,
            v0: self.v0,
            v1: self.v1,
            v2: self.v2,
            v3: self.v3,
            tail: self.tail,
            ntail: self.ntail,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Default for SipHasher {
    fn default() -> SipHasher {
        SipHasher::new()
    }
}
<commit_msg>Amend `hash::SipHasher` docs to more strongly discourage cryptographic uses<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! An implementation of SipHash 2-4.

use prelude::v1::*;

use ptr;
use super::Hasher;

/// An implementation of SipHash 2-4.
///
/// See: http://131002.net/siphash/
///
/// This is the default hashing function used by standard library (eg.
/// `collections::HashMap` uses it by default).
///
/// SipHash is a general-purpose hashing function: it runs at a good
/// speed (competitive with Spooky and City) and permits strong _keyed_
/// hashing. This lets you key your hashtables from a strong RNG, such
/// as [`rand::Rng`](https://doc.rust-lang.org/rand/rand/trait.Rng.html).
///
/// Although the SipHash algorithm is considered to be generally strong,
/// it is not intended for cryptographic purposes. As such, all
/// cryptographic uses of this implementation are _strongly discouraged_.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct SipHasher {
    k0: u64,
    k1: u64,
    length: usize, // how many bytes we've processed
    // v0, v2 and v1, v3 show up in pairs in the algorithm,
    // and simd implementations of SipHash will use vectors
    // of v02 and v13. By placing them in this order in the struct,
    // the compiler can pick up on just a few simd optimizations by itself.
    v0: u64, // hash state
    v2: u64,
    v1: u64,
    v3: u64,
    tail: u64, // unprocessed bytes le
    ntail: usize, // how many bytes in tail are valid
}

// sadly, these macro definitions can't appear later,
// because they're needed in the following defs;
// this design could be improved.

macro_rules! u8to64_le {
    ($buf:expr, $i:expr) =>
    ($buf[0+$i] as u64 |
     ($buf[1+$i] as u64) << 8 |
     ($buf[2+$i] as u64) << 16 |
     ($buf[3+$i] as u64) << 24 |
     ($buf[4+$i] as u64) << 32 |
     ($buf[5+$i] as u64) << 40 |
     ($buf[6+$i] as u64) << 48 |
     ($buf[7+$i] as u64) << 56);
    ($buf:expr, $i:expr, $len:expr) =>
    ({
        let mut t = 0;
        let mut out = 0;
        while t < $len {
            out |= ($buf[t+$i] as u64) << t*8;
            t += 1;
        }
        out
    });
}

/// Load a full u64 word from a byte stream, in LE order. Use
/// `copy_nonoverlapping` to let the compiler generate the most efficient way
/// to load u64 from a possibly unaligned address.
///
/// Unsafe because: unchecked indexing at i..i+8
#[inline]
unsafe fn load_u64_le(buf: &[u8], i: usize) -> u64 {
    debug_assert!(i + 8 <= buf.len());
    let mut data = 0u64;
    ptr::copy_nonoverlapping(buf.get_unchecked(i), &mut data as *mut _ as *mut u8, 8);
    data.to_le()
}

macro_rules! rotl {
    ($x:expr, $b:expr) =>
    (($x << $b) | ($x >> (64_i32.wrapping_sub($b))))
}

macro_rules! compress {
    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
    ({
        $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
        $v0 = rotl!($v0, 32);
        $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2;
        $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
        $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
        $v2 = rotl!($v2, 32);
    })
}

impl SipHasher {
    /// Creates a new `SipHasher` with the two initial keys set to 0.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> SipHasher {
        SipHasher::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher` that is keyed off the provided keys.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
        let mut state = SipHasher {
            k0: key0,
            k1: key1,
            length: 0,
            v0: 0,
            v1: 0,
            v2: 0,
            v3: 0,
            tail: 0,
            ntail: 0,
        };
        state.reset();
        state
    }

    #[inline]
    fn reset(&mut self) {
        self.length = 0;
        self.v0 = self.k0 ^ 0x736f6d6570736575;
        self.v1 = self.k1 ^ 0x646f72616e646f6d;
        self.v2 = self.k0 ^ 0x6c7967656e657261;
        self.v3 = self.k1 ^ 0x7465646279746573;
        self.ntail = 0;
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hasher for SipHasher {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        let length = msg.len();
        self.length += length;

        let mut needed = 0;

        if self.ntail != 0 {
            needed = 8 - self.ntail;
            if length < needed {
                self.tail |= u8to64_le!(msg, 0, length) << 8 * self.ntail;
                self.ntail += length;
                return
            }

            let m = self.tail | u8to64_le!(msg, 0, needed) << 8 * self.ntail;

            self.v3 ^= m;
            compress!(self.v0, self.v1, self.v2, self.v3);
            compress!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= m;

            self.ntail = 0;
        }

        // Buffered tail is now flushed, process new input.
        let len = length - needed;
        let left = len & 0x7;

        let mut i = needed;
        while i < len - left {
            let mi = unsafe { load_u64_le(msg, i) };

            self.v3 ^= mi;
            compress!(self.v0, self.v1, self.v2, self.v3);
            compress!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= mi;

            i += 8;
        }

        self.tail = u8to64_le!(msg, i, left);
        self.ntail = left;
    }

    #[inline]
    fn finish(&self) -> u64 {
        let mut v0 = self.v0;
        let mut v1 = self.v1;
        let mut v2 = self.v2;
        let mut v3 = self.v3;

        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;

        v3 ^= b;
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        v0 ^= b;

        v2 ^= 0xff;
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);
        compress!(v0, v1, v2, v3);

        v0 ^ v1 ^ v2 ^ v3
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for SipHasher {
    #[inline]
    fn clone(&self) -> SipHasher {
        SipHasher {
            k0: self.k0,
            k1: self.k1,
            length: self.length,
            v0: self.v0,
            v1: self.v1,
            v2: self.v2,
            v3: self.v3,
            tail: self.tail,
            ntail: self.ntail,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Default for SipHasher {
    fn default() -> SipHasher {
        SipHasher::new()
    }
}
<|endoftext|>


<commit_before><commit_msg>Add owner tx tests<commit_after>use actix::prelude::*;
use godcoin::prelude::*;

mod common;
pub use common::*;

#[test]
fn owner_tx_minter_key_change() {
    System::run(|| {
        let minter = TestMinter::new();

        let minter_key = KeyPair::gen();
        let wallet_key = KeyPair::gen();

        let tx = {
            let mut tx = OwnerTx {
                base: create_tx_header(TxType::OWNER, "0.0000 GRAEL"),
                minter: minter_key.0,
                wallet: wallet_key.0.into(),
                script: minter.genesis_info().script.clone(),
            };
            tx.append_sign(&minter.genesis_info().wallet_keys[3]);
            tx.append_sign(&minter.genesis_info().wallet_keys[0]);
            TxVariant::OwnerTx(tx)
        };

        let fut = minter.request(MsgRequest::Broadcast(tx.clone()));
        System::current().arbiter().send(
            fut.and_then(move |res| {
                assert!(!res.is_err(), format!("{:?}", res));
                assert_eq!(res, MsgResponse::Broadcast());

                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let owner = minter.chain().get_owner();
                assert_eq!(tx, TxVariant::OwnerTx(owner));

                minter.produce_block()
            })
            .and_then(|res| {
                // Minter key changed, should fail
                assert_eq!(res.unwrap_err(), verify::BlockErr::InvalidSignature);

                System::current().stop();
                Ok(())
            }),
        );
    })
    .unwrap();
}

#[test]
fn owner_tx_deny_mint_tokens() {
    System::run(|| {
        let minter = TestMinter::new();

        let wallet_key = KeyPair::gen();

        let tx = {
            let mut tx = OwnerTx {
                base: create_tx_header(TxType::OWNER, "0.0000 GRAEL"),
                minter: minter.genesis_info().minter_key.0.clone(),
                wallet: (&wallet_key.0).into(),
                script: minter.genesis_info().script.clone(),
            };
            tx.append_sign(&minter.genesis_info().wallet_keys[3]);
            tx.append_sign(&minter.genesis_info().wallet_keys[0]);
            TxVariant::OwnerTx(tx)
        };

        let fut = minter.request(MsgRequest::Broadcast(tx.clone()));
        System::current().arbiter().send(
            fut.and_then(move |res| {
                assert!(!res.is_err(), format!("{:?}", res));
                assert_eq!(res, MsgResponse::Broadcast());

                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let owner = minter.chain().get_owner();
                assert_eq!(tx, TxVariant::OwnerTx(owner));

                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let mut tx = MintTx {
                    base: create_tx_header(TxType::MINT, "0.0000 GRAEL"),
                    to: (&minter.genesis_info().script).into(),
                    amount: get_asset("10.0000 GRAEL"),
                    // This is the old owner script, validation should fail
                    script: minter.genesis_info().script.clone(),
                };
                tx.append_sign(&wallet_key);

                minter.request(MsgRequest::Broadcast(TxVariant::MintTx(tx)))
            })
            .and_then(|res| {
                assert_eq!(
                    res,
                    MsgResponse::Error(net::ErrorKind::TxValidation(
                        verify::TxErr::ScriptHashMismatch
                    ))
                );

                System::current().stop();
                Ok(())
            }),
        );
    })
    .unwrap();
}

#[test]
fn owner_tx_accept_mint_tokens() {
    System::run(|| {
        let minter = TestMinter::new();

        let wallet_key = KeyPair::gen();

        let tx = {
            let mut tx = OwnerTx {
                base: create_tx_header(TxType::OWNER, "0.0000 GRAEL"),
                minter: minter.genesis_info().minter_key.0.clone(),
                wallet: (&wallet_key.0).into(),
                script: minter.genesis_info().script.clone(),
            };
            tx.append_sign(&minter.genesis_info().wallet_keys[3]);
            tx.append_sign(&minter.genesis_info().wallet_keys[0]);
            TxVariant::OwnerTx(tx)
        };

        let fut = minter.request(MsgRequest::Broadcast(tx.clone()));
        System::current().arbiter().send(
            fut.and_then(move |res| {
                assert!(!res.is_err(), format!("{:?}", res));
                assert_eq!(res, MsgResponse::Broadcast());

                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let owner = minter.chain().get_owner();
                assert_eq!(tx, TxVariant::OwnerTx(owner));

                minter.produce_block().map(|_| minter)
            })
            .and_then({
                let wallet_key = wallet_key.clone();
                move |minter| {
                    let mut tx = MintTx {
                        base: create_tx_header(TxType::MINT, "0.0000 GRAEL"),
                        to: wallet_key.0.clone().into(),
                        amount: get_asset("1000.0000 GRAEL"),
                        script: wallet_key.0.clone().into(),
                    };
                    tx.append_sign(&wallet_key);
                    let tx = TxVariant::MintTx(tx);

                    minter
                        .request(MsgRequest::Broadcast(tx))
                        .map(|res| (res, minter))
                }
            })
            .and_then(|(res, minter)| {
                assert_eq!(res, MsgResponse::Broadcast());
                minter.produce_block().map(|_| minter)
            })
            .and_then(move |minter| {
                let chain = minter.chain();
                let props = chain.get_properties();
                let expected_bal = get_asset("2000.0000 GRAEL");
                assert_eq!(props.token_supply, expected_bal);

                let bal = chain.get_balance(&wallet_key.0.clone().into());
                assert_eq!(bal, get_asset("1000.0000 GRAEL"));

                System::current().stop();
                Ok(())
            }),
        );
    })
    .unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Fix tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add empty action test case.<commit_after><|endoftext|>


<commit_before><commit_msg>todo rewrite<commit_after><|endoftext|>