<commit_before>// Copyright 2013 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.

//! Complex numbers.

use core::prelude::*;

use core::num::{Zero,One,ToStrRadix};

// FIXME #1284: handle complex NaN & infinity etc. This
// probably doesn't map to C's _Complex correctly.

// FIXME #5734:: Need generic sin/cos for .to/from_polar().
// FIXME #5735: Need generic sqrt to implement .norm().

/// A complex number in Cartesian form.
#[deriving(Eq,Clone)]
pub struct Cmplx<T> {
    /// Real portion of the complex number
    re: T,
    /// Imaginary portion of the complex number
    im: T
}

pub type Complex = Cmplx<float>;
pub type Complex32 = Cmplx<f32>;
pub type Complex64 = Cmplx<f64>;

impl<T: Copy + Num> Cmplx<T> {
    /// Create a new Cmplx
    #[inline]
    pub fn new(re: T, im: T) -> Cmplx<T> {
        Cmplx { re: re, im: im }
    }

    /**
    Returns the square of the norm (since `T` doesn't necessarily
    have a sqrt function), i.e. `re^2 + im^2`.
    */
    #[inline]
    pub fn norm_sqr(&self) -> T {
        self.re * self.re + self.im * self.im
    }

    /// Returns the complex conjugate. i.e. `re - i im`
    #[inline]
    pub fn conj(&self) -> Cmplx<T> {
        Cmplx::new(self.re, -self.im)
    }

    /// Multiplies `self` by the scalar `t`.
    #[inline]
    pub fn scale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re * t, self.im * t)
    }

    /// Divides `self` by the scalar `t`.
    #[inline]
    pub fn unscale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re / t, self.im / t)
    }

    /// Returns `1/self`
    #[inline]
    pub fn inv(&self) -> Cmplx<T> {
        let norm_sqr = self.norm_sqr();
        Cmplx::new(self.re / norm_sqr,
                    -self.im / norm_sqr)
    }
}

/* arithmetic */
// (a + i b) + (c + i d) == (a + c) + i (b + d)
impl<T: Copy + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn add(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re + other.re, self.im + other.im)
    }
}
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<T: Copy + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re - other.re, self.im - other.im)
    }
}
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<T: Copy + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn mul(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re*other.re - self.im*other.im,
                     self.re*other.im + self.im*other.re)
    }
}

// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
//   == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
impl<T: Copy + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
        let norm_sqr = other.norm_sqr();
        Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
                     (self.im*other.re - self.re*other.im) / norm_sqr)
    }
}

impl<T: Copy + Num> Neg<Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn neg(&self) -> Cmplx<T> {
        Cmplx::new(-self.re, -self.im)
    }
}

/* constants */
impl<T: Copy + Num> Zero for Cmplx<T> {
    #[inline]
    fn zero() -> Cmplx<T> {
        Cmplx::new(Zero::zero(), Zero::zero())
    }

    #[inline]
    fn is_zero(&self) -> bool {
        *self == Zero::zero()
    }
}

impl<T: Copy + Num> One for Cmplx<T> {
    #[inline]
    fn one() -> Cmplx<T> {
        Cmplx::new(One::one(), Zero::zero())
    }
}

/* string conversions */
impl<T: ToStr + Num + Ord> ToStr for Cmplx<T> {
    fn to_str(&self) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str(), (-self.im).to_str())
        } else {
            fmt!("%s+%si", self.re.to_str(), self.im.to_str())
        }
    }
}

impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
    fn to_str_radix(&self, radix: uint) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str_radix(radix), (-self.im).to_str_radix(radix))
        } else {
            fmt!("%s+%si", self.re.to_str_radix(radix), self.im.to_str_radix(radix))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use core::num::{Zero,One};

    pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
    pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
    pub static _1_1i : Complex = Cmplx { re: 1f, im: 1f };
    pub static _0_1i : Complex = Cmplx { re: 0f, im: 1f };
    pub static _neg1_1i : Complex = Cmplx { re: -1f, im: 1f };
    pub static _05_05i : Complex = Cmplx { re: 0.5f, im: 0.5f };
    pub static all_consts : [Complex, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];

    #[test]
    fn test_consts() {
        // check our constants are what Cmplx::new creates
        fn test(c : Complex, r : float, i: float) {
            assert_eq!(c, Cmplx::new(r,i));
        }
        test(_0_0i, 0f, 0f);
        test(_1_0i, 1f, 0f);
        test(_1_1i, 1f, 1f);
        test(_neg1_1i, -1f, 1f);
        test(_05_05i, 0.5f, 0.5f);

        assert_eq!(_0_0i, Zero::zero());
        assert_eq!(_1_0i, One::one());
    }

    #[test]
    fn test_norm_sqr() {
        fn test(c: Complex, ns: float) {
            assert_eq!(c.norm_sqr(), ns);
        }
        test(_0_0i, 0f);
        test(_1_0i, 1f);
        test(_1_1i, 2f);
        test(_neg1_1i, 2f);
        test(_05_05i, 0.5f);
    }

    #[test]
    fn test_scale_unscale() {
        assert_eq!(_05_05i.scale(2f), _1_1i);
        assert_eq!(_1_1i.unscale(2f), _05_05i);
        for all_consts.each |&c| {
            assert_eq!(c.scale(2f).unscale(2f), c);
        }
    }

    #[test]
    fn test_conj() {
        for all_consts.each |&c| {
            assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
            assert_eq!(c.conj().conj(), c);
        }
    }

    #[test]
    fn test_inv() {
        assert_eq!(_1_1i.inv(), _05_05i.conj());
        assert_eq!(_1_0i.inv(), _1_0i.inv());
    }

    #[test]
    #[should_fail]
    #[ignore]
    fn test_inv_zero() {
        // FIXME #5736: should this really fail, or just NaN?
        _0_0i.inv();
    }

    mod arith {
        use super::*;
        use core::num::Zero;

        #[test]
        fn test_add() {
            assert_eq!(_05_05i + _05_05i, _1_1i);
            assert_eq!(_0_1i + _1_0i, _1_1i);
            assert_eq!(_1_0i + _neg1_1i, _0_1i);

            for all_consts.each |&c| {
                assert_eq!(_0_0i + c, c);
                assert_eq!(c + _0_0i, c);
            }
        }

        #[test]
        fn test_sub() {
            assert_eq!(_05_05i - _05_05i, _0_0i);
            assert_eq!(_0_1i - _1_0i, _neg1_1i);
            assert_eq!(_0_1i - _neg1_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c - _0_0i, c);
                assert_eq!(c - c, _0_0i);
            }
        }

        #[test]
        fn test_mul() {
            assert_eq!(_05_05i * _05_05i, _0_1i.unscale(2f));
            assert_eq!(_1_1i * _0_1i, _neg1_1i);

            // i^2 & i^4
            assert_eq!(_0_1i * _0_1i, -_1_0i);
            assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c * _1_0i, c);
                assert_eq!(_1_0i * c, c);
            }
        }
        #[test]
        fn test_div() {
            assert_eq!(_neg1_1i / _0_1i, _1_1i);
            for all_consts.each |&c| {
                if c != Zero::zero() {
                    assert_eq!(c / c, _1_0i);
                }
            }
        }
        #[test]
        fn test_neg() {
            assert_eq!(-_1_0i + _0_1i, _neg1_1i);
            assert_eq!((-_0_1i) * _0_1i, _1_0i);
            for all_consts.each |&c| {
                assert_eq!(-(-c), c);
            }
        }
    }

    #[test]
    fn test_to_str() {
        fn test(c : Complex, s: ~str) {
            assert_eq!(c.to_str(), s);
        }
        test(_0_0i, ~"0+0i");
        test(_1_0i, ~"1+0i");
        test(_0_1i, ~"0+1i");
        test(_1_1i, ~"1+1i");
        test(_neg1_1i, ~"-1+1i");
        test(-_neg1_1i, ~"1-1i");
        test(_05_05i, ~"0.5+0.5i");
    }
}
<commit_msg>extra: implement .norm(), and Polar conversion functions for complex numbers.<commit_after>// Copyright 2013 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.

//! Complex numbers.

use core::prelude::*;

use core::num::{Zero,One,ToStrRadix};

// FIXME #1284: handle complex NaN & infinity etc. This
// probably doesn't map to C's _Complex correctly.

// FIXME #5734:: Need generic sin/cos for .to/from_polar().
// FIXME #5735: Need generic sqrt to implement .norm().

/// A complex number in Cartesian form.
#[deriving(Eq,Clone)]
pub struct Cmplx<T> {
    /// Real portion of the complex number
    re: T,
    /// Imaginary portion of the complex number
    im: T
}

pub type Complex = Cmplx<float>;
pub type Complex32 = Cmplx<f32>;
pub type Complex64 = Cmplx<f64>;

impl<T: Clone + Num> Cmplx<T> {
    /// Create a new Cmplx
    #[inline]
    pub fn new(re: T, im: T) -> Cmplx<T> {
        Cmplx { re: re, im: im }
    }

    /**
    Returns the square of the norm (since `T` doesn't necessarily
    have a sqrt function), i.e. `re^2 + im^2`.
    */
    #[inline]
    pub fn norm_sqr(&self) -> T {
        self.re * self.re + self.im * self.im
    }

    /// Returns the complex conjugate. i.e. `re - i im`
    #[inline]
    pub fn conj(&self) -> Cmplx<T> {
        Cmplx::new(self.re.clone(), -self.im)
    }

    /// Multiplies `self` by the scalar `t`.
    #[inline]
    pub fn scale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re * t, self.im * t)
    }

    /// Divides `self` by the scalar `t`.
    #[inline]
    pub fn unscale(&self, t: T) -> Cmplx<T> {
        Cmplx::new(self.re / t, self.im / t)
    }

    /// Returns `1/self`
    #[inline]
    pub fn inv(&self) -> Cmplx<T> {
        let norm_sqr = self.norm_sqr();
        Cmplx::new(self.re / norm_sqr,
                    -self.im / norm_sqr)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Algebraic + Num> Cmplx<T> {
    /// Calculate |self|
    #[inline(always)]
    pub fn norm(&self) -> T {
        self.re.hypot(&self.im)
    }
}

#[cfg(not(stage0))] // Fixed by #4228
impl<T: Clone + Trigonometric + Algebraic + Num> Cmplx<T> {
    /// Calculate the principal Arg of self.
    #[inline(always)]
    pub fn arg(&self) -> T {
        self.im.atan2(&self.re)
    }
    /// Convert to polar form (r, theta), such that `self = r * exp(i
    /// * theta)`
    #[inline]
    pub fn to_polar(&self) -> (T, T) {
        (self.norm(), self.arg())
    }
    /// Convert a polar representation into a complex number.
    #[inline]
    pub fn from_polar(r: &T, theta: &T) -> Cmplx<T> {
        Cmplx::new(r * theta.cos(), r * theta.sin())
    }
}

/* arithmetic */
// (a + i b) + (c + i d) == (a + c) + i (b + d)
impl<T: Clone + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn add(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re + other.re, self.im + other.im)
    }
}
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<T: Clone + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re - other.re, self.im - other.im)
    }
}
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn mul(&self, other: &Cmplx<T>) -> Cmplx<T> {
        Cmplx::new(self.re*other.re - self.im*other.im,
                   self.re*other.im + self.im*other.re)
    }
}

// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
//   == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
impl<T: Clone + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
        let norm_sqr = other.norm_sqr();
        Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
                   (self.im*other.re - self.re*other.im) / norm_sqr)
    }
}

impl<T: Clone + Num> Neg<Cmplx<T>> for Cmplx<T> {
    #[inline]
    fn neg(&self) -> Cmplx<T> {
        Cmplx::new(-self.re, -self.im)
    }
}

/* constants */
impl<T: Clone + Num> Zero for Cmplx<T> {
    #[inline]
    fn zero() -> Cmplx<T> {
        Cmplx::new(Zero::zero(), Zero::zero())
    }

    #[inline]
    fn is_zero(&self) -> bool {
        self.re.is_zero() && self.im.is_zero()
    }
}

impl<T: Clone + Num> One for Cmplx<T> {
    #[inline]
    fn one() -> Cmplx<T> {
        Cmplx::new(One::one(), Zero::zero())
    }
}

/* string conversions */
impl<T: ToStr + Num + Ord> ToStr for Cmplx<T> {
    fn to_str(&self) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str(), (-self.im).to_str())
        } else {
            fmt!("%s+%si", self.re.to_str(), self.im.to_str())
        }
    }
}

impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
    fn to_str_radix(&self, radix: uint) -> ~str {
        if self.im < Zero::zero() {
            fmt!("%s-%si", self.re.to_str_radix(radix), (-self.im).to_str_radix(radix))
        } else {
            fmt!("%s+%si", self.re.to_str_radix(radix), self.im.to_str_radix(radix))
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use core::num::{Zero,One,Real};

    pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
    pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
    pub static _1_1i : Complex = Cmplx { re: 1f, im: 1f };
    pub static _0_1i : Complex = Cmplx { re: 0f, im: 1f };
    pub static _neg1_1i : Complex = Cmplx { re: -1f, im: 1f };
    pub static _05_05i : Complex = Cmplx { re: 0.5f, im: 0.5f };
    pub static all_consts : [Complex, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];

    #[test]
    fn test_consts() {
        // check our constants are what Cmplx::new creates
        fn test(c : Complex, r : float, i: float) {
            assert_eq!(c, Cmplx::new(r,i));
        }
        test(_0_0i, 0f, 0f);
        test(_1_0i, 1f, 0f);
        test(_1_1i, 1f, 1f);
        test(_neg1_1i, -1f, 1f);
        test(_05_05i, 0.5f, 0.5f);

        assert_eq!(_0_0i, Zero::zero());
        assert_eq!(_1_0i, One::one());
    }

    #[test]
    fn test_norm() {
        fn test(c: Complex, ns: float) {
            assert_eq!(c.norm_sqr(), ns);
            assert_eq!(c.norm(), ns.sqrt())
        }
        test(_0_0i, 0f);
        test(_1_0i, 1f);
        test(_1_1i, 2f);
        test(_neg1_1i, 2f);
        test(_05_05i, 0.5f);
    }

    #[test]
    fn test_scale_unscale() {
        assert_eq!(_05_05i.scale(2f), _1_1i);
        assert_eq!(_1_1i.unscale(2f), _05_05i);
        for all_consts.each |&c| {
            assert_eq!(c.scale(2f).unscale(2f), c);
        }
    }

    #[test]
    fn test_conj() {
        for all_consts.each |&c| {
            assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
            assert_eq!(c.conj().conj(), c);
        }
    }

    #[test]
    fn test_inv() {
        assert_eq!(_1_1i.inv(), _05_05i.conj());
        assert_eq!(_1_0i.inv(), _1_0i.inv());
    }

    #[test]
    #[should_fail]
    #[ignore]
    fn test_inv_zero() {
        // FIXME #5736: should this really fail, or just NaN?
        _0_0i.inv();
    }

    #[test]
    fn test_arg() {
        fn test(c: Complex, arg: float) {
            assert!(c.arg().approx_eq(&arg))
        }
        test(_1_0i, 0f);
        test(_1_1i, 0.25f * Real::pi());
        test(_neg1_1i, 0.75f * Real::pi());
        test(_05_05i, 0.25f * Real::pi());
    }

    #[test]
    fn test_polar_conv() {
        fn test(c: Complex) {
            let (r, theta) = c.to_polar();
            assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
        }
        for all_consts.each |&c| { test(c); }
    }

    mod arith {
        use super::*;
        use core::num::Zero;

        #[test]
        fn test_add() {
            assert_eq!(_05_05i + _05_05i, _1_1i);
            assert_eq!(_0_1i + _1_0i, _1_1i);
            assert_eq!(_1_0i + _neg1_1i, _0_1i);

            for all_consts.each |&c| {
                assert_eq!(_0_0i + c, c);
                assert_eq!(c + _0_0i, c);
            }
        }

        #[test]
        fn test_sub() {
            assert_eq!(_05_05i - _05_05i, _0_0i);
            assert_eq!(_0_1i - _1_0i, _neg1_1i);
            assert_eq!(_0_1i - _neg1_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c - _0_0i, c);
                assert_eq!(c - c, _0_0i);
            }
        }

        #[test]
        fn test_mul() {
            assert_eq!(_05_05i * _05_05i, _0_1i.unscale(2f));
            assert_eq!(_1_1i * _0_1i, _neg1_1i);

            // i^2 & i^4
            assert_eq!(_0_1i * _0_1i, -_1_0i);
            assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);

            for all_consts.each |&c| {
                assert_eq!(c * _1_0i, c);
                assert_eq!(_1_0i * c, c);
            }
        }
        #[test]
        fn test_div() {
            assert_eq!(_neg1_1i / _0_1i, _1_1i);
            for all_consts.each |&c| {
                if c != Zero::zero() {
                    assert_eq!(c / c, _1_0i);
                }
            }
        }
        #[test]
        fn test_neg() {
            assert_eq!(-_1_0i + _0_1i, _neg1_1i);
            assert_eq!((-_0_1i) * _0_1i, _1_0i);
            for all_consts.each |&c| {
                assert_eq!(-(-c), c);
            }
        }
    }

    #[test]
    fn test_to_str() {
        fn test(c : Complex, s: ~str) {
            assert_eq!(c.to_str(), s);
        }
        test(_0_0i, ~"0+0i");
        test(_1_0i, ~"1+0i");
        test(_0_1i, ~"0+1i");
        test(_1_1i, ~"1+1i");
        test(_neg1_1i, ~"-1+1i");
        test(-_neg1_1i, ~"1-1i");
        test(_05_05i, ~"0.5+0.5i");
    }
}
<|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.

use rustc::hir::pat_util;
use rustc::ty;
use rustc::ty::adjustment;
use util::nodemap::FnvHashMap;
use lint::{LateContext, EarlyContext, LintContext, LintArray};
use lint::{LintPass, EarlyLintPass, LateLintPass};

use std::collections::hash_map::Entry::{Occupied, Vacant};

use syntax::ast;
use syntax::attr::{self, AttrMetaMethods};
use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
use syntax::ptr::P;
use syntax_pos::Span;

use rustc_back::slice;
use rustc::hir;
use rustc::hir::intravisit::FnKind;

declare_lint! {
    pub UNUSED_MUT,
    Warn,
    "detect mut variables which don't need to be mutable"
}

#[derive(Copy, Clone)]
pub struct UnusedMut;

impl UnusedMut {
    fn check_unused_mut_pat(&self, cx: &LateContext, pats: &[P<hir::Pat>]) {
        // collect all mutable pattern and group their NodeIDs by their Identifier to
        // avoid false warnings in match arms with multiple patterns

        let mut mutables = FnvHashMap();
        for p in pats {
            pat_util::pat_bindings(p, |mode, id, _, path1| {
                let name = path1.node;
                if let hir::BindByValue(hir::MutMutable) = mode {
                    if !name.as_str().starts_with("_") {
                        match mutables.entry(name.0 as usize) {
                            Vacant(entry) => { entry.insert(vec![id]); },
                            Occupied(mut entry) => { entry.get_mut().push(id); },
                        }
                    }
                }
            });
        }

        let used_mutables = cx.tcx.used_mut_nodes.borrow();
        for (_, v) in &mutables {
            if !v.iter().any(|e| used_mutables.contains(e)) {
                cx.span_lint(UNUSED_MUT, cx.tcx.map.span(v[0]),
                             "variable does not need to be mutable");
            }
        }
    }
}

impl LintPass for UnusedMut {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_MUT)
    }
}

impl LateLintPass for UnusedMut {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        if let hir::ExprMatch(_, ref arms, _) = e.node {
            for a in arms {
                self.check_unused_mut_pat(cx, &a.pats)
            }
        }
    }

    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        if let hir::StmtDecl(ref d, _) = s.node {
            if let hir::DeclLocal(ref l) = d.node {
                self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat));
            }
        }
    }

    fn check_fn(&mut self, cx: &LateContext,
                _: FnKind, decl: &hir::FnDecl,
                _: &hir::Block, _: Span, _: ast::NodeId) {
        for a in &decl.inputs {
            self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
        }
    }
}

declare_lint! {
    pub UNUSED_MUST_USE,
    Warn,
    "unused result of a type flagged as #[must_use]"
}

declare_lint! {
    pub UNUSED_RESULTS,
    Allow,
    "unused result of an expression in a statement"
}

#[derive(Copy, Clone)]
pub struct UnusedResults;

impl LintPass for UnusedResults {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
    }
}

impl LateLintPass for UnusedResults {
    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        let expr = match s.node {
            hir::StmtSemi(ref expr, _) => &**expr,
            _ => return
        };

        if let hir::ExprRet(..) = expr.node {
            return;
        }

        let t = cx.tcx.expr_ty(&expr);
        let warned = match t.sty {
            ty::TyTuple(ref tys) if tys.is_empty() => return,
            ty::TyBool => return,
            ty::TyStruct(def, _) |
            ty::TyEnum(def, _) => {
                let attrs = cx.tcx.get_attrs(def.did);
                check_must_use(cx, &attrs[..], s.span)
            }
            _ => false,
        };
        if !warned {
            cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
        }

        fn check_must_use(cx: &LateContext, attrs: &[ast::Attribute], sp: Span) -> bool {
            for attr in attrs {
                if attr.check_name("must_use") {
                    let mut msg = "unused result which must be used".to_string();
                    // check for #[must_use="..."]
                    if let Some(s) = attr.value_str() {
                        msg.push_str(": ");
                        msg.push_str(&s);
                    }
                    cx.span_lint(UNUSED_MUST_USE, sp, &msg);
                    return true;
                }
            }
            false
        }
    }
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

#[derive(Copy, Clone)]
pub struct UnusedUnsafe;

impl LintPass for UnusedUnsafe {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_UNSAFE)
    }
}

impl LateLintPass for UnusedUnsafe {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        if let hir::ExprBlock(ref blk) = e.node {
            // Don't warn about generated blocks, that'll just pollute the output.
            if blk.rules == hir::UnsafeBlock(hir::UserProvided) &&
                !cx.tcx.used_unsafe.borrow().contains(&blk.id) {
                    cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
            }
        }
    }
}

declare_lint! {
    pub PATH_STATEMENTS,
    Warn,
    "path statements with no effect"
}

#[derive(Copy, Clone)]
pub struct PathStatements;

impl LintPass for PathStatements {
    fn get_lints(&self) -> LintArray {
        lint_array!(PATH_STATEMENTS)
    }
}

impl LateLintPass for PathStatements {
    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        if let hir::StmtSemi(ref expr, _) = s.node {
            if let hir::ExprPath(..) = expr.node {
                cx.span_lint(PATH_STATEMENTS, s.span,
                             "path statement with no effect");
            }
        }
    }
}

declare_lint! {
    pub UNUSED_ATTRIBUTES,
    Warn,
    "detects attributes that were not used by the compiler"
}

#[derive(Copy, Clone)]
pub struct UnusedAttributes;

impl LintPass for UnusedAttributes {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_ATTRIBUTES)
    }
}

impl LateLintPass for UnusedAttributes {
    fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
        // Note that check_name() marks the attribute as used if it matches.
        for &(ref name, ty, _) in KNOWN_ATTRIBUTES {
            match ty {
                AttributeType::Whitelisted if attr.check_name(name) => {
                    break;
                },
                _ => ()
            }
        }

        let plugin_attributes = cx.sess().plugin_attributes.borrow_mut();
        for &(ref name, ty) in plugin_attributes.iter() {
            if ty == AttributeType::Whitelisted && attr.check_name(&name) {
                break;
            }
        }

        if !attr::is_used(attr) {
            cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
            // Is it a builtin attribute that must be used at the crate level?
            let known_crate = KNOWN_ATTRIBUTES.iter().find(|&&(name, ty, _)| {
                attr.name() == name &&
                ty == AttributeType::CrateLevel
            }).is_some();

            // Has a plugin registered this attribute as one which must be used at
            // the crate level?
            let plugin_crate = plugin_attributes.iter()
                                                .find(|&&(ref x, t)| {
                                                        &*attr.name() == x &&
                                                        AttributeType::CrateLevel == t
                                                    }).is_some();
            if  known_crate || plugin_crate {
                let msg = match attr.node.style {
                    ast::AttrStyle::Outer => "crate-level attribute should be an inner \
                                              attribute: add an exclamation mark: #![foo]",
                    ast::AttrStyle::Inner => "crate-level attribute should be in the \
                                              root module",
                };
                cx.span_lint(UNUSED_ATTRIBUTES, attr.span, msg);
            }
        }
    }
}

declare_lint! {
    UNUSED_PARENS,
    Warn,
    "`if`, `match`, `while` and `return` do not need parentheses"
}

#[derive(Copy, Clone)]
pub struct UnusedParens;

impl UnusedParens {
    fn check_unused_parens_core(&self, cx: &EarlyContext, value: &ast::Expr, msg: &str,
                                struct_lit_needs_parens: bool) {
        if let ast::ExprKind::Paren(ref inner) = value.node {
            let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&inner);
            if !necessary {
                cx.span_lint(UNUSED_PARENS, value.span,
                             &format!("unnecessary parentheses around {}", msg))
            }
        }

        /// Expressions that syntactically contain an "exterior" struct
        /// literal i.e. not surrounded by any parens or other
        /// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
        /// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
        /// y: 1 }) == foo` does not.
        fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
            match value.node {
                ast::ExprKind::Struct(..) => true,

                ast::ExprKind::Assign(ref lhs, ref rhs) |
                ast::ExprKind::AssignOp(_, ref lhs, ref rhs) |
                ast::ExprKind::Binary(_, ref lhs, ref rhs) => {
                    // X { y: 1 } + X { y: 2 }
                    contains_exterior_struct_lit(&lhs) ||
                        contains_exterior_struct_lit(&rhs)
                }
                ast::ExprKind::Unary(_, ref x) |
                ast::ExprKind::Cast(ref x, _) |
                ast::ExprKind::Type(ref x, _) |
                ast::ExprKind::Field(ref x, _) |
                ast::ExprKind::TupField(ref x, _) |
                ast::ExprKind::Index(ref x, _) => {
                    // &X { y: 1 }, X { y: 1 }.y
                    contains_exterior_struct_lit(&x)
                }

                ast::ExprKind::MethodCall(_, _, ref exprs) => {
                    // X { y: 1 }.bar(...)
                    contains_exterior_struct_lit(&exprs[0])
                }

                _ => false
            }
        }
    }
}

impl LintPass for UnusedParens {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_PARENS)
    }
}

impl EarlyLintPass for UnusedParens {
    fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
        use syntax::ast::ExprKind::*;
        let (value, msg, struct_lit_needs_parens) = match e.node {
            If(ref cond, _, _) => (cond, "`if` condition", true),
            While(ref cond, _, _) => (cond, "`while` condition", true),
            IfLet(_, ref cond, _, _) => (cond, "`if let` head expression", true),
            WhileLet(_, ref cond, _, _) => (cond, "`while let` head expression", true),
            ForLoop(_, ref cond, _, _) => (cond, "`for` head expression", true),
            Match(ref head, _) => (head, "`match` head expression", true),
            Ret(Some(ref value)) => (value, "`return` value", false),
            Assign(_, ref value) => (value, "assigned value", false),
            AssignOp(_, _, ref value) => (value, "assigned value", false),
            InPlace(_, ref value) => (value, "emplacement value", false),
            _ => return
        };
        self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
    }

    fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
        let (value, msg) = match s.node {
            ast::StmtKind::Local(ref local) => match local.init {
                Some(ref value) => (value, "assigned value"),
                None => return
            },
            _ => return
        };
        self.check_unused_parens_core(cx, &value, msg, false);
    }
}

declare_lint! {
    UNUSED_IMPORT_BRACES,
    Allow,
    "unnecessary braces around an imported item"
}

#[derive(Copy, Clone)]
pub struct UnusedImportBraces;

impl LintPass for UnusedImportBraces {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_IMPORT_BRACES)
    }
}

impl LateLintPass for UnusedImportBraces {
    fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
        if let hir::ItemUse(ref view_path) = item.node {
            if let hir::ViewPathList(_, ref items) = view_path.node {
                if items.len() == 1 {
                    if let hir::PathListIdent {ref name, ..} = items[0].node {
                        let m = format!("braces around {} is unnecessary",
                                        name);
                        cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
                                     &m[..]);
                    }
                }
            }
        }
    }
}

declare_lint! {
    UNUSED_ALLOCATION,
    Warn,
    "detects unnecessary allocations that can be eliminated"
}

#[derive(Copy, Clone)]
pub struct UnusedAllocation;

impl LintPass for UnusedAllocation {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_ALLOCATION)
    }
}

impl LateLintPass for UnusedAllocation {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        match e.node {
            hir::ExprBox(_) => {}
            _ => return
        }

        if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
            if let adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
                ref autoref, ..
            }) = *adjustment {
                match autoref {
                    &Some(adjustment::AutoPtr(_, hir::MutImmutable)) => {
                        cx.span_lint(UNUSED_ALLOCATION, e.span,
                                     "unnecessary allocation, use & instead");
                    }
                    &Some(adjustment::AutoPtr(_, hir::MutMutable)) => {
                        cx.span_lint(UNUSED_ALLOCATION, e.span,
                                     "unnecessary allocation, use &mut instead");
                    }
                    _ => ()
                }
            }
        }
    }
}
<commit_msg>Make unused lint ignore unused `!`<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.

use rustc::hir::pat_util;
use rustc::ty;
use rustc::ty::adjustment;
use util::nodemap::FnvHashMap;
use lint::{LateContext, EarlyContext, LintContext, LintArray};
use lint::{LintPass, EarlyLintPass, LateLintPass};

use std::collections::hash_map::Entry::{Occupied, Vacant};

use syntax::ast;
use syntax::attr::{self, AttrMetaMethods};
use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
use syntax::ptr::P;
use syntax_pos::Span;

use rustc_back::slice;
use rustc::hir;
use rustc::hir::intravisit::FnKind;

declare_lint! {
    pub UNUSED_MUT,
    Warn,
    "detect mut variables which don't need to be mutable"
}

#[derive(Copy, Clone)]
pub struct UnusedMut;

impl UnusedMut {
    fn check_unused_mut_pat(&self, cx: &LateContext, pats: &[P<hir::Pat>]) {
        // collect all mutable pattern and group their NodeIDs by their Identifier to
        // avoid false warnings in match arms with multiple patterns

        let mut mutables = FnvHashMap();
        for p in pats {
            pat_util::pat_bindings(p, |mode, id, _, path1| {
                let name = path1.node;
                if let hir::BindByValue(hir::MutMutable) = mode {
                    if !name.as_str().starts_with("_") {
                        match mutables.entry(name.0 as usize) {
                            Vacant(entry) => { entry.insert(vec![id]); },
                            Occupied(mut entry) => { entry.get_mut().push(id); },
                        }
                    }
                }
            });
        }

        let used_mutables = cx.tcx.used_mut_nodes.borrow();
        for (_, v) in &mutables {
            if !v.iter().any(|e| used_mutables.contains(e)) {
                cx.span_lint(UNUSED_MUT, cx.tcx.map.span(v[0]),
                             "variable does not need to be mutable");
            }
        }
    }
}

impl LintPass for UnusedMut {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_MUT)
    }
}

impl LateLintPass for UnusedMut {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        if let hir::ExprMatch(_, ref arms, _) = e.node {
            for a in arms {
                self.check_unused_mut_pat(cx, &a.pats)
            }
        }
    }

    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        if let hir::StmtDecl(ref d, _) = s.node {
            if let hir::DeclLocal(ref l) = d.node {
                self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat));
            }
        }
    }

    fn check_fn(&mut self, cx: &LateContext,
                _: FnKind, decl: &hir::FnDecl,
                _: &hir::Block, _: Span, _: ast::NodeId) {
        for a in &decl.inputs {
            self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
        }
    }
}

declare_lint! {
    pub UNUSED_MUST_USE,
    Warn,
    "unused result of a type flagged as #[must_use]"
}

declare_lint! {
    pub UNUSED_RESULTS,
    Allow,
    "unused result of an expression in a statement"
}

#[derive(Copy, Clone)]
pub struct UnusedResults;

impl LintPass for UnusedResults {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
    }
}

impl LateLintPass for UnusedResults {
    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        let expr = match s.node {
            hir::StmtSemi(ref expr, _) => &**expr,
            _ => return
        };

        if let hir::ExprRet(..) = expr.node {
            return;
        }

        let t = cx.tcx.expr_ty(&expr);
        let warned = match t.sty {
            ty::TyTuple(ref tys) if tys.is_empty() => return,
            ty::TyEmpty => return,
            ty::TyBool => return,
            ty::TyStruct(def, _) |
            ty::TyEnum(def, _) => {
                let attrs = cx.tcx.get_attrs(def.did);
                check_must_use(cx, &attrs[..], s.span)
            }
            _ => false,
        };
        if !warned {
            cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
        }

        fn check_must_use(cx: &LateContext, attrs: &[ast::Attribute], sp: Span) -> bool {
            for attr in attrs {
                if attr.check_name("must_use") {
                    let mut msg = "unused result which must be used".to_string();
                    // check for #[must_use="..."]
                    if let Some(s) = attr.value_str() {
                        msg.push_str(": ");
                        msg.push_str(&s);
                    }
                    cx.span_lint(UNUSED_MUST_USE, sp, &msg);
                    return true;
                }
            }
            false
        }
    }
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

#[derive(Copy, Clone)]
pub struct UnusedUnsafe;

impl LintPass for UnusedUnsafe {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_UNSAFE)
    }
}

impl LateLintPass for UnusedUnsafe {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        if let hir::ExprBlock(ref blk) = e.node {
            // Don't warn about generated blocks, that'll just pollute the output.
            if blk.rules == hir::UnsafeBlock(hir::UserProvided) &&
                !cx.tcx.used_unsafe.borrow().contains(&blk.id) {
                    cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
            }
        }
    }
}

declare_lint! {
    pub PATH_STATEMENTS,
    Warn,
    "path statements with no effect"
}

#[derive(Copy, Clone)]
pub struct PathStatements;

impl LintPass for PathStatements {
    fn get_lints(&self) -> LintArray {
        lint_array!(PATH_STATEMENTS)
    }
}

impl LateLintPass for PathStatements {
    fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
        if let hir::StmtSemi(ref expr, _) = s.node {
            if let hir::ExprPath(..) = expr.node {
                cx.span_lint(PATH_STATEMENTS, s.span,
                             "path statement with no effect");
            }
        }
    }
}

declare_lint! {
    pub UNUSED_ATTRIBUTES,
    Warn,
    "detects attributes that were not used by the compiler"
}

#[derive(Copy, Clone)]
pub struct UnusedAttributes;

impl LintPass for UnusedAttributes {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_ATTRIBUTES)
    }
}

impl LateLintPass for UnusedAttributes {
    fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
        // Note that check_name() marks the attribute as used if it matches.
        for &(ref name, ty, _) in KNOWN_ATTRIBUTES {
            match ty {
                AttributeType::Whitelisted if attr.check_name(name) => {
                    break;
                },
                _ => ()
            }
        }

        let plugin_attributes = cx.sess().plugin_attributes.borrow_mut();
        for &(ref name, ty) in plugin_attributes.iter() {
            if ty == AttributeType::Whitelisted && attr.check_name(&name) {
                break;
            }
        }

        if !attr::is_used(attr) {
            cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
            // Is it a builtin attribute that must be used at the crate level?
            let known_crate = KNOWN_ATTRIBUTES.iter().find(|&&(name, ty, _)| {
                attr.name() == name &&
                ty == AttributeType::CrateLevel
            }).is_some();

            // Has a plugin registered this attribute as one which must be used at
            // the crate level?
            let plugin_crate = plugin_attributes.iter()
                                                .find(|&&(ref x, t)| {
                                                        &*attr.name() == x &&
                                                        AttributeType::CrateLevel == t
                                                    }).is_some();
            if  known_crate || plugin_crate {
                let msg = match attr.node.style {
                    ast::AttrStyle::Outer => "crate-level attribute should be an inner \
                                              attribute: add an exclamation mark: #![foo]",
                    ast::AttrStyle::Inner => "crate-level attribute should be in the \
                                              root module",
                };
                cx.span_lint(UNUSED_ATTRIBUTES, attr.span, msg);
            }
        }
    }
}

declare_lint! {
    UNUSED_PARENS,
    Warn,
    "`if`, `match`, `while` and `return` do not need parentheses"
}

#[derive(Copy, Clone)]
pub struct UnusedParens;

impl UnusedParens {
    fn check_unused_parens_core(&self, cx: &EarlyContext, value: &ast::Expr, msg: &str,
                                struct_lit_needs_parens: bool) {
        if let ast::ExprKind::Paren(ref inner) = value.node {
            let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&inner);
            if !necessary {
                cx.span_lint(UNUSED_PARENS, value.span,
                             &format!("unnecessary parentheses around {}", msg))
            }
        }

        /// Expressions that syntactically contain an "exterior" struct
        /// literal i.e. not surrounded by any parens or other
        /// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
        /// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
        /// y: 1 }) == foo` does not.
        fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
            match value.node {
                ast::ExprKind::Struct(..) => true,

                ast::ExprKind::Assign(ref lhs, ref rhs) |
                ast::ExprKind::AssignOp(_, ref lhs, ref rhs) |
                ast::ExprKind::Binary(_, ref lhs, ref rhs) => {
                    // X { y: 1 } + X { y: 2 }
                    contains_exterior_struct_lit(&lhs) ||
                        contains_exterior_struct_lit(&rhs)
                }
                ast::ExprKind::Unary(_, ref x) |
                ast::ExprKind::Cast(ref x, _) |
                ast::ExprKind::Type(ref x, _) |
                ast::ExprKind::Field(ref x, _) |
                ast::ExprKind::TupField(ref x, _) |
                ast::ExprKind::Index(ref x, _) => {
                    // &X { y: 1 }, X { y: 1 }.y
                    contains_exterior_struct_lit(&x)
                }

                ast::ExprKind::MethodCall(_, _, ref exprs) => {
                    // X { y: 1 }.bar(...)
                    contains_exterior_struct_lit(&exprs[0])
                }

                _ => false
            }
        }
    }
}

impl LintPass for UnusedParens {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_PARENS)
    }
}

impl EarlyLintPass for UnusedParens {
    fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
        use syntax::ast::ExprKind::*;
        let (value, msg, struct_lit_needs_parens) = match e.node {
            If(ref cond, _, _) => (cond, "`if` condition", true),
            While(ref cond, _, _) => (cond, "`while` condition", true),
            IfLet(_, ref cond, _, _) => (cond, "`if let` head expression", true),
            WhileLet(_, ref cond, _, _) => (cond, "`while let` head expression", true),
            ForLoop(_, ref cond, _, _) => (cond, "`for` head expression", true),
            Match(ref head, _) => (head, "`match` head expression", true),
            Ret(Some(ref value)) => (value, "`return` value", false),
            Assign(_, ref value) => (value, "assigned value", false),
            AssignOp(_, _, ref value) => (value, "assigned value", false),
            InPlace(_, ref value) => (value, "emplacement value", false),
            _ => return
        };
        self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
    }

    fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
        let (value, msg) = match s.node {
            ast::StmtKind::Local(ref local) => match local.init {
                Some(ref value) => (value, "assigned value"),
                None => return
            },
            _ => return
        };
        self.check_unused_parens_core(cx, &value, msg, false);
    }
}

declare_lint! {
    UNUSED_IMPORT_BRACES,
    Allow,
    "unnecessary braces around an imported item"
}

#[derive(Copy, Clone)]
pub struct UnusedImportBraces;

impl LintPass for UnusedImportBraces {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_IMPORT_BRACES)
    }
}

impl LateLintPass for UnusedImportBraces {
    fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
        if let hir::ItemUse(ref view_path) = item.node {
            if let hir::ViewPathList(_, ref items) = view_path.node {
                if items.len() == 1 {
                    if let hir::PathListIdent {ref name, ..} = items[0].node {
                        let m = format!("braces around {} is unnecessary",
                                        name);
                        cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
                                     &m[..]);
                    }
                }
            }
        }
    }
}

declare_lint! {
    UNUSED_ALLOCATION,
    Warn,
    "detects unnecessary allocations that can be eliminated"
}

#[derive(Copy, Clone)]
pub struct UnusedAllocation;

impl LintPass for UnusedAllocation {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNUSED_ALLOCATION)
    }
}

impl LateLintPass for UnusedAllocation {
    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
        match e.node {
            hir::ExprBox(_) => {}
            _ => return
        }

        if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
            if let adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
                ref autoref, ..
            }) = *adjustment {
                match autoref {
                    &Some(adjustment::AutoPtr(_, hir::MutImmutable)) => {
                        cx.span_lint(UNUSED_ALLOCATION, e.span,
                                     "unnecessary allocation, use & instead");
                    }
                    &Some(adjustment::AutoPtr(_, hir::MutMutable)) => {
                        cx.span_lint(UNUSED_ALLOCATION, e.span,
                                     "unnecessary allocation, use &mut instead");
                    }
                    _ => ()
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-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.

use ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};

const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
const MILLIS_PER_SEC: u64 = 1_000;

/// A duration type to represent a span of time, typically used for system
/// timeouts.
///
/// Each duration is composed of a number of seconds and nanosecond precision.
/// APIs binding a system timeout will typically round up the nanosecond
/// precision if the underlying system does not support that level of precision.
///
/// Durations implement many common traits, including `Add`, `Sub`, and other
/// ops traits. Currently a duration may only be inspected for its number of
/// seconds and its nanosecond precision.
///
/// # Examples
///
/// ```
/// use std::time::Duration;
///
/// let five_seconds = Duration::new(5, 0);
/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
///
/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
///
/// let ten_millis = Duration::from_millis(10);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Duration {
    secs: u64,
    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
}

impl Duration {
    /// Creates a new `Duration` from the specified number of seconds and
    /// additional nanosecond precision.
    ///
    /// If the nanoseconds is greater than 1 billion (the number of nanoseconds
    /// in a second), then it will carry over into the seconds provided.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn new(secs: u64, nanos: u32) -> Duration {
        let secs = secs + (nanos / NANOS_PER_SEC) as u64;
        let nanos = nanos % NANOS_PER_SEC;
        Duration { secs: secs, nanos: nanos }
    }

    /// Creates a new `Duration` from the specified number of seconds.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn from_secs(secs: u64) -> Duration {
        Duration { secs: secs, nanos: 0 }
    }

    /// Creates a new `Duration` from the specified number of milliseconds.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn from_millis(millis: u64) -> Duration {
        let secs = millis / MILLIS_PER_SEC;
        let nanos = ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI;
        Duration { secs: secs, nanos: nanos }
    }

    /// Returns the number of whole seconds represented by this duration.
    ///
    /// The extra precision represented by this duration is ignored (e.g. extra
    /// nanoseconds are not represented in the returned value).
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn as_secs(&self) -> u64 { self.secs }

    /// Returns the nanosecond precision represented by this duration.
    ///
    /// This method does **not** return the length of the duration when
    /// represented by nanoseconds. The returned number always represents a
    /// fractional portion of a second (e.g. it is less than one billion).
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn subsec_nanos(&self) -> u32 { self.nanos }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Add for Duration {
    type Output = Duration;

    fn add(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_add(rhs.secs)
                           .expect("overflow when adding durations");
        let mut nanos = self.nanos + rhs.nanos;
        if nanos >= NANOS_PER_SEC {
            nanos -= NANOS_PER_SEC;
            secs = secs.checked_add(1).expect("overflow when adding durations");
        }
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl AddAssign for Duration {
    fn add_assign(&mut self, rhs: Duration) {
        *self = *self + rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Sub for Duration {
    type Output = Duration;

    fn sub(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_sub(rhs.secs)
                           .expect("overflow when subtracting durations");
        let nanos = if self.nanos >= rhs.nanos {
            self.nanos - rhs.nanos
        } else {
            secs = secs.checked_sub(1)
                       .expect("overflow when subtracting durations");
            self.nanos + NANOS_PER_SEC - rhs.nanos
        };
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl SubAssign for Duration {
    fn sub_assign(&mut self, rhs: Duration) {
        *self = *self - rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Mul<u32> for Duration {
    type Output = Duration;

    fn mul(self, rhs: u32) -> Duration {
        // Multiply nanoseconds as u64, because it cannot overflow that way.
        let total_nanos = self.nanos as u64 * rhs as u64;
        let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
        let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
        let secs = self.secs.checked_mul(rhs as u64)
                       .and_then(|s| s.checked_add(extra_secs))
                       .expect("overflow when multiplying duration");
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl MulAssign<u32> for Duration {
    fn mul_assign(&mut self, rhs: u32) {
        *self = *self * rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Div<u32> for Duration {
    type Output = Duration;

    fn div(self, rhs: u32) -> Duration {
        let secs = self.secs / (rhs as u64);
        let carry = self.secs - secs * (rhs as u64);
        let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
        let nanos = self.nanos / rhs + (extra_nanos as u32);
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl DivAssign<u32> for Duration {
    fn div_assign(&mut self, rhs: u32) {
        *self = *self / rhs;
    }
}

#[cfg(test)]
mod tests {
    use super::Duration;

    #[test]
    fn creation() {
        assert!(Duration::from_secs(1) != Duration::from_secs(0));
        assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
                   Duration::from_secs(3));
        assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
                   Duration::new(4, 10 * 1_000_000));
        assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
    }

    #[test]
    fn secs() {
        assert_eq!(Duration::new(0, 0).as_secs(), 0);
        assert_eq!(Duration::from_secs(1).as_secs(), 1);
        assert_eq!(Duration::from_millis(999).as_secs(), 0);
        assert_eq!(Duration::from_millis(1001).as_secs(), 1);
    }

    #[test]
    fn nanos() {
        assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
        assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
        assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
        assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
        assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
        assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
    }

    #[test]
    fn add() {
        assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
                   Duration::new(1, 1));
    }

    #[test]
    fn sub() {
        assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
                   Duration::new(0, 999_999_999));
    }

    #[test] #[should_panic]
    fn sub_bad1() {
        Duration::new(0, 0) - Duration::new(0, 1);
    }

    #[test] #[should_panic]
    fn sub_bad2() {
        Duration::new(0, 0) - Duration::new(1, 0);
    }

    #[test]
    fn mul() {
        assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
        assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
        assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
        assert_eq!(Duration::new(0, 500_000_001) * 4000,
                   Duration::new(2000, 4000));
    }

    #[test]
    fn div() {
        assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
        assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
        assert_eq!(Duration::new(99, 999_999_000) / 100,
                   Duration::new(0, 999_999_990));
    }
}
<commit_msg>Auto merge of #33072 - tbu-:pr_duration_new_overflow, r=alexcrichton<commit_after>// Copyright 2012-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.

use ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};

const NANOS_PER_SEC: u32 = 1_000_000_000;
const NANOS_PER_MILLI: u32 = 1_000_000;
const MILLIS_PER_SEC: u64 = 1_000;

/// A duration type to represent a span of time, typically used for system
/// timeouts.
///
/// Each duration is composed of a number of seconds and nanosecond precision.
/// APIs binding a system timeout will typically round up the nanosecond
/// precision if the underlying system does not support that level of precision.
///
/// Durations implement many common traits, including `Add`, `Sub`, and other
/// ops traits. Currently a duration may only be inspected for its number of
/// seconds and its nanosecond precision.
///
/// # Examples
///
/// ```
/// use std::time::Duration;
///
/// let five_seconds = Duration::new(5, 0);
/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
///
/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
///
/// let ten_millis = Duration::from_millis(10);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Duration {
    secs: u64,
    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
}

impl Duration {
    /// Creates a new `Duration` from the specified number of seconds and
    /// additional nanosecond precision.
    ///
    /// If the nanoseconds is greater than 1 billion (the number of nanoseconds
    /// in a second), then it will carry over into the seconds provided.
    ///
    /// # Panics
    ///
    /// This constructor will panic if the carry from the nanoseconds overflows
    /// the seconds counter.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn new(secs: u64, nanos: u32) -> Duration {
        let secs = secs.checked_add((nanos / NANOS_PER_SEC) as u64)
            .expect("overflow in Duration::new");
        let nanos = nanos % NANOS_PER_SEC;
        Duration { secs: secs, nanos: nanos }
    }

    /// Creates a new `Duration` from the specified number of seconds.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn from_secs(secs: u64) -> Duration {
        Duration { secs: secs, nanos: 0 }
    }

    /// Creates a new `Duration` from the specified number of milliseconds.
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn from_millis(millis: u64) -> Duration {
        let secs = millis / MILLIS_PER_SEC;
        let nanos = ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI;
        Duration { secs: secs, nanos: nanos }
    }

    /// Returns the number of whole seconds represented by this duration.
    ///
    /// The extra precision represented by this duration is ignored (e.g. extra
    /// nanoseconds are not represented in the returned value).
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn as_secs(&self) -> u64 { self.secs }

    /// Returns the nanosecond precision represented by this duration.
    ///
    /// This method does **not** return the length of the duration when
    /// represented by nanoseconds. The returned number always represents a
    /// fractional portion of a second (e.g. it is less than one billion).
    #[stable(feature = "duration", since = "1.3.0")]
    #[inline]
    pub fn subsec_nanos(&self) -> u32 { self.nanos }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Add for Duration {
    type Output = Duration;

    fn add(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_add(rhs.secs)
                           .expect("overflow when adding durations");
        let mut nanos = self.nanos + rhs.nanos;
        if nanos >= NANOS_PER_SEC {
            nanos -= NANOS_PER_SEC;
            secs = secs.checked_add(1).expect("overflow when adding durations");
        }
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl AddAssign for Duration {
    fn add_assign(&mut self, rhs: Duration) {
        *self = *self + rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Sub for Duration {
    type Output = Duration;

    fn sub(self, rhs: Duration) -> Duration {
        let mut secs = self.secs.checked_sub(rhs.secs)
                           .expect("overflow when subtracting durations");
        let nanos = if self.nanos >= rhs.nanos {
            self.nanos - rhs.nanos
        } else {
            secs = secs.checked_sub(1)
                       .expect("overflow when subtracting durations");
            self.nanos + NANOS_PER_SEC - rhs.nanos
        };
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl SubAssign for Duration {
    fn sub_assign(&mut self, rhs: Duration) {
        *self = *self - rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Mul<u32> for Duration {
    type Output = Duration;

    fn mul(self, rhs: u32) -> Duration {
        // Multiply nanoseconds as u64, because it cannot overflow that way.
        let total_nanos = self.nanos as u64 * rhs as u64;
        let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
        let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
        let secs = self.secs.checked_mul(rhs as u64)
                       .and_then(|s| s.checked_add(extra_secs))
                       .expect("overflow when multiplying duration");
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl MulAssign<u32> for Duration {
    fn mul_assign(&mut self, rhs: u32) {
        *self = *self * rhs;
    }
}

#[stable(feature = "duration", since = "1.3.0")]
impl Div<u32> for Duration {
    type Output = Duration;

    fn div(self, rhs: u32) -> Duration {
        let secs = self.secs / (rhs as u64);
        let carry = self.secs - secs * (rhs as u64);
        let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
        let nanos = self.nanos / rhs + (extra_nanos as u32);
        debug_assert!(nanos < NANOS_PER_SEC);
        Duration { secs: secs, nanos: nanos }
    }
}

#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl DivAssign<u32> for Duration {
    fn div_assign(&mut self, rhs: u32) {
        *self = *self / rhs;
    }
}

#[cfg(test)]
mod tests {
    use super::Duration;

    #[test]
    fn creation() {
        assert!(Duration::from_secs(1) != Duration::from_secs(0));
        assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
                   Duration::from_secs(3));
        assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
                   Duration::new(4, 10 * 1_000_000));
        assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
    }

    #[test]
    fn secs() {
        assert_eq!(Duration::new(0, 0).as_secs(), 0);
        assert_eq!(Duration::from_secs(1).as_secs(), 1);
        assert_eq!(Duration::from_millis(999).as_secs(), 0);
        assert_eq!(Duration::from_millis(1001).as_secs(), 1);
    }

    #[test]
    fn nanos() {
        assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
        assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
        assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
        assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
        assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
        assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
    }

    #[test]
    fn add() {
        assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
                   Duration::new(1, 1));
    }

    #[test]
    fn sub() {
        assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
                   Duration::new(0, 1));
        assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
                   Duration::new(0, 999_999_999));
    }

    #[test] #[should_panic]
    fn sub_bad1() {
        Duration::new(0, 0) - Duration::new(0, 1);
    }

    #[test] #[should_panic]
    fn sub_bad2() {
        Duration::new(0, 0) - Duration::new(1, 0);
    }

    #[test]
    fn mul() {
        assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
        assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
        assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
        assert_eq!(Duration::new(0, 500_000_001) * 4000,
                   Duration::new(2000, 4000));
    }

    #[test]
    fn div() {
        assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
        assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
        assert_eq!(Duration::new(99, 999_999_000) / 100,
                   Duration::new(0, 999_999_990));
    }
}
<|endoftext|>


<commit_before>extern crate loirc;

use std::env;

use loirc::{connect, Code, Event, Prefix, ReconnectionSettings};

/// Say "peekaboo" in a channel on freenode and then quit.
/// target/debug/examples/peekaboo "#mychannel"
fn main() {
    let args: Vec<String> = env::args().collect();

    let channel = args.get(1).unwrap_or_else(|| {
        println!("Channel must be given as an argument.");
        panic!();
    });

    // Connect to freenode and use no not reconnect.
    let (writer, reader) = connect("irc.freenode.net:6667",
                                   ReconnectionSettings::DoNotReconnect).unwrap();
    writer.raw(format!("USER {} 8 * :{}\n", "peekaboo", "peekaboo"));
    writer.raw(format!("NICK {}\n", "peekaboo"));

    // Receive events.
    for event in reader.iter() {
        println!("{:?}", event);
        match event {
            Event::Message(msg) => {
                if msg.code == Code::RplWelcome {
                    // join channel, no password
                    writer.raw(format!("JOIN {}\n", channel));
                }
                // JOIN is sent when you join a channel.
                if msg.code == Code::Join {
                    // If there is a prefix...
                    if let Some(prefix) = msg.prefix {
                        match prefix {
                            // And the prefix is a user...
                            Prefix::User(user) => {
                                // And that user's nick is peekaboo, we've joined the channel!
                                if user.nickname == "peekaboo" {
                                    writer.raw(format!("PRIVMSG {} :{}\n", channel, "peekaboo"));
                                    // Note that if the reconnection settings said to reconnect,
                                    // it would. Close would "really" stop it.
                                    writer.raw(format!("QUIT :{}\n", "peekaboo"));
                                    // writer.close();
                                }
                            }
                            _ => {}
                        }
                    }
                }
            }
            _ => {}
        }
    }
}
<commit_msg>Update the peekaboo example<commit_after>extern crate loirc;

use std::env;

use loirc::{connect, Code, Event, Prefix, ReconnectionSettings};

/// Say "peekaboo" in a channel on freenode and then quit.
/// target/debug/examples/peekaboo "#mychannel"
fn main() {
    let args: Vec<String> = env::args().collect();
    let channel = args.get(1).expect("Channel must be given as an argument.");

    // Connect to freenode and use no not reconnect.
    let (writer, reader) = connect("irc.freenode.net:6667",
                                   ReconnectionSettings::DoNotReconnect).unwrap();
    writer.raw(format!("USER {} 8 * :{}\n", "peekaboo", "peekaboo"));
    writer.raw(format!("NICK {}\n", "peekaboo"));

    // Receive events.
    for event in reader.iter() {
        println!("{:?}", event);
        match event {
            Event::Message(msg) => {
                if msg.code == Code::RplWelcome {
                    // join channel, no password
                    writer.raw(format!("JOIN {}\n", channel));
                }
                // JOIN is sent when you join a channel.
                if msg.code == Code::Join {
                    // If there is a prefix...
                    if let Some(prefix) = msg.prefix {
                        match prefix {
                            // And the prefix is a user...
                            Prefix::User(user) => {
                                // And that user's nick is peekaboo, we've joined the channel!
                                if user.nickname == "peekaboo" {
                                    writer.raw(format!("PRIVMSG {} :{}\n", channel, "peekaboo"));
                                    // Note that if the reconnection settings said to reconnect,
                                    // it would. Close would "really" stop it.
                                    writer.raw(format!("QUIT :{}\n", "peekaboo"));
                                    // writer.close();
                                }
                            }
                            _ => {}
                        }
                    }
                }
            }
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod elektra_examples {
    use crate::{KeyBuilder, ReadableKey, StringKey, WriteableKey};

    #[test]
    fn key_example() -> Result<(), Box<dyn std::error::Error>> {
        // This test should stay in sync with the example in the Readme
        // To create a simple key with a name and value
        let mut key = StringKey::new("user/test/language")?;
        key.set_value("rust");
        assert_eq!(key.name(), "user/test/language");
        assert_eq!(key.value(), "rust");

        // To iterate over the name
        for name in key.name_iter() {
            println!("Name: {}", name);
        }

        // Duplicate a key
        let key_duplicate = key.duplicate();

        // And compare them
        assert_eq!(key, key_duplicate);

        // To create a key with multiple meta values, use the KeyBuilder
        let mut key: StringKey = KeyBuilder::new("user/test/fruits")?
            .meta("banana", "🍌")?
            .meta("pineapple", "🍍")?
            .meta("strawberry", "🍓")?
            .build();
        assert_eq!(key.meta("pineapple")?.value(), "🍍");

        // We can iterate over the metakeys
        key.rewind_meta();
        for metakey in key.meta_iter() {
            println!("Key: {}, Value: {}", metakey.name(), metakey.value());
        }

        // Delete a metakey
        key.delete_meta("banana")?;

        // Check if key is in the user namespace
        assert!(key.is_user());

        Ok(())
    }

    use crate::{KeySet, LookupOption};

    #[test]
    fn keyset_example() -> Result<(), Box<dyn std::error::Error>> {
        // Create a new KeySet with enough preallocated space for 5 Keys
        let mut keyset = KeySet::with_capacity(5);

        // Append some keys
        keyset.append_key(
            KeyBuilder::<StringKey>::new("user/sw/app/#1/host")?
                .value("localhost")
                .build(),
        )?;
        keyset.append_key(
            KeyBuilder::<StringKey>::new("user/sw/app/#1/port")?
                .value("8080")
                .build(),
        )?;

        // Iterate the keyset
        keyset.rewind();
        for mut key in keyset.iter_mut() {
            // Add a metakey to each key
            key.set_meta("setby", "owner")?;
        }

        // Lookup a key by name and set a new value
        if let Some(mut found_key) =
            keyset.lookup_by_name("user/sw/app/#1/port", LookupOption::KDB_O_NONE)
        {
            found_key.set_value("5001");
        } else {
            panic!("Did not find the key!");
        }

        // Delete a key by passing the POP option
        keyset.lookup_by_name("user/sw/app/#1/host", LookupOption::KDB_O_POP);

        // Remove the last (and now only) key in the set
        let removed_key = keyset.pop().unwrap();

        assert_eq!(removed_key.value(), "5001");
        // Check that the meta information is set
        assert_eq!(removed_key.meta("setby")?.value(), "owner");

        // The keyset is now empty
        assert_eq!(keyset.size(), 0);

        Ok(())
    }
}
<commit_msg>Rust: Unify use statement<commit_after>#[cfg(test)]
mod elektra_examples {
    use crate::{KeyBuilder, KeySet, LookupOption, ReadableKey, StringKey, WriteableKey};

    #[test]
    fn key_example() -> Result<(), Box<dyn std::error::Error>> {
        // This test should stay in sync with the example in the Readme
        // To create a simple key with a name and value
        let mut key = StringKey::new("user/test/language")?;
        key.set_value("rust");
        assert_eq!(key.name(), "user/test/language");
        assert_eq!(key.value(), "rust");

        // To iterate over the name
        for name in key.name_iter() {
            println!("Name: {}", name);
        }

        // Duplicate a key
        let key_duplicate = key.duplicate();

        // And compare them
        assert_eq!(key, key_duplicate);

        // To create a key with multiple meta values, use the KeyBuilder
        let mut key: StringKey = KeyBuilder::new("user/test/fruits")?
            .meta("banana", "🍌")?
            .meta("pineapple", "🍍")?
            .meta("strawberry", "🍓")?
            .build();
        assert_eq!(key.meta("pineapple")?.value(), "🍍");

        // We can iterate over the metakeys
        key.rewind_meta();
        for metakey in key.meta_iter() {
            println!("Key: {}, Value: {}", metakey.name(), metakey.value());
        }

        // Delete a metakey
        key.delete_meta("banana")?;

        // Check if key is in the user namespace
        assert!(key.is_user());

        Ok(())
    }

    #[test]
    fn keyset_example() -> Result<(), Box<dyn std::error::Error>> {
        // Create a new KeySet with enough preallocated space for 5 Keys
        let mut keyset = KeySet::with_capacity(5);

        // Append some keys
        keyset.append_key(
            KeyBuilder::<StringKey>::new("user/sw/app/#1/host")?
                .value("localhost")
                .build(),
        )?;
        keyset.append_key(
            KeyBuilder::<StringKey>::new("user/sw/app/#1/port")?
                .value("8080")
                .build(),
        )?;

        // Iterate the keyset
        keyset.rewind();
        for mut key in keyset.iter_mut() {
            // Add a metakey to each key
            key.set_meta("setby", "owner")?;
        }

        // Lookup a key by name and set a new value
        if let Some(mut found_key) =
            keyset.lookup_by_name("user/sw/app/#1/port", LookupOption::KDB_O_NONE)
        {
            found_key.set_value("5001");
        } else {
            panic!("Did not find the key!");
        }

        // Delete a key by passing the POP option
        keyset.lookup_by_name("user/sw/app/#1/host", LookupOption::KDB_O_POP);

        // Remove the last (and now only) key in the set
        let removed_key = keyset.pop().unwrap();

        assert_eq!(removed_key.value(), "5001");
        // Check that the meta information is set
        assert_eq!(removed_key.meta("setby")?.value(), "owner");

        // The keyset is now empty
        assert_eq!(keyset.size(), 0);

        Ok(())
    }
}
<|endoftext|>


<commit_before>// 32-bit fixed point. Haven't decided on the fractional bits yet

use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;

// TODO: Typedef Int = i32 or something

pub const FRACTIONAL_BITS: i32 = 16;
pub const DENOMINATOR: i32 = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Eq, PartialEq)]
pub struct Fx32 {
	pub x: i32,
}

impl Fx32 {
	pub fn new (x: i32) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * (DENOMINATOR as f32)) as i32)
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a / 256) * (b) / 256)
		}
		else {
			Fx32::new ((a) * (b / 256) / 256)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) / 16384)
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as i64 * o.x as i64;
		Fx32::new ((c / 65536) as i32)
	}
}

impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}

impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x / 256) * (o.x / 256))
	}
}
<commit_msg>Removing more magic numbers<commit_after>// 32-bit fixed point. Haven't decided on the fractional bits yet

use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;

// TODO: Typedef Int = i32 or something

pub const HALF_FRACTIONAL_BITS: i32 = 8;
pub const FRACTIONAL_BITS: i32 = HALF_FRACTIONAL_BITS * 2;
pub const ROOT_DENOMINATOR: i32 = 1 << HALF_FRACTIONAL_BITS;
pub const DENOMINATOR: i32 = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Eq, PartialEq)]
pub struct Fx32 {
	pub x: i32,
}

impl Fx32 {
	pub fn new (x: i32) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * DENOMINATOR as f32) as i32)
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a / ROOT_DENOMINATOR) * (b) / ROOT_DENOMINATOR)
		}
		else {
			Fx32::new ((a) * (b / ROOT_DENOMINATOR) / ROOT_DENOMINATOR)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) / 16384)
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as i64 * o.x as i64;
		Fx32::new ((c / DENOMINATOR as i64) as i32)
	}
}

impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}

impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x / ROOT_DENOMINATOR) * (o.x / ROOT_DENOMINATOR))
	}
}
<|endoftext|>