<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use resource_task::{ProgressMsg, Payload, Done, LoaderTask};

use std::cell::Cell;
use std::vec;
use extra::url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
use std::rt::io::Reader;
use std::rt::io::net::ip::SocketAddr;

pub fn factory() -> LoaderTask {
	let f: LoaderTask = |url, progress_chan| {
        let url = Cell::new(url);
        let progress_chan = Cell::new(progress_chan);
        spawn(|| load(url.take(), progress_chan.take()))
	};
	f
}

fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
	assert!(url.scheme == ~"http");

    info!("requesting %s", url.to_str());

    let mut request = ~RequestWriter::new(Get, url.clone());
    request.remote_addr = Some(url_to_socket_addr(&url));
    let mut response = match request.read_response() {
        Ok(r) => r,
        Err(_) => {
            progress_chan.send(Done(Err(())));
            return;
        }
    };

    loop {
        for header in response.headers.iter() {
            info!(" - %s: %s", header.header_name(), header.header_value());
        }

        let mut buf = vec::with_capacity(1024);
        unsafe { vec::raw::set_len(&mut buf, 1024) };
        match response.read(buf) {
            Some(len) => {
                unsafe { vec::raw::set_len(&mut buf, len) };
            }
            None => {
                progress_chan.send(Done(Ok(())));
                return;
            }
        }
        progress_chan.send(Payload(buf));
    }
}

// FIXME: Quick hack to convert ip addresses to SocketAddr
fn url_to_socket_addr(url: &Url) -> SocketAddr {
    let host_and_port = fmt!("%s:%s", url.host, url.port.clone().unwrap_or_default(~"80"));
    FromStr::from_str(host_and_port).expect("couldn't parse host as IP address")
}
<commit_msg>Fix logic in http_loader<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use resource_task::{ProgressMsg, Payload, Done, LoaderTask};

use std::cell::Cell;
use std::vec;
use extra::url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
use std::rt::io::Reader;
use std::rt::io::net::ip::SocketAddr;

pub fn factory() -> LoaderTask {
	let f: LoaderTask = |url, progress_chan| {
        let url = Cell::new(url);
        let progress_chan = Cell::new(progress_chan);
        spawn(|| load(url.take(), progress_chan.take()))
	};
	f
}

fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
	assert!(url.scheme == ~"http");

    info!("requesting %s", url.to_str());

    let mut request = ~RequestWriter::new(Get, url.clone());
    request.remote_addr = Some(url_to_socket_addr(&url));
    let mut response = match request.read_response() {
        Ok(r) => r,
        Err(_) => {
            progress_chan.send(Done(Err(())));
            return;
        }
    };

    for header in response.headers.iter() {
        info!(" - %s: %s", header.header_name(), header.header_value());
    }

    loop {
        let mut buf = vec::with_capacity(1024);

        unsafe { vec::raw::set_len(&mut buf, 1024) };
        match response.read(buf) {
            Some(len) => {
                unsafe { vec::raw::set_len(&mut buf, len) };
            }
            None => {
                progress_chan.send(Done(Ok(())));
                return;
            }
        }
        progress_chan.send(Payload(buf));
    }
    progress_chan.send(Done(Ok(())));
}

// FIXME: Quick hack to convert ip addresses to SocketAddr
fn url_to_socket_addr(url: &Url) -> SocketAddr {
    let host_and_port = fmt!("%s:%s", url.host, url.port.clone().unwrap_or_default(~"80"));
    FromStr::from_str(host_and_port).expect("couldn't parse host as IP address")
}
<|endoftext|>


<commit_before>//! Watcher interface implementation for Habitat Supervisor.

use habitat_core::package::target::{PackageTarget,
                                    AARCH64_DARWIN};
use notify::{poll::PollWatcher,
             DebouncedEvent,
             RecommendedWatcher,
             RecursiveMode,
             Result,
             Watcher};
use std::{env,
          path::Path,
          str::FromStr,
          sync::mpsc::Sender,
          time::Duration};

pub enum SupWatcher {
    Native(RecommendedWatcher),
    Fallback(PollWatcher),
}

impl Watcher for SupWatcher {
    fn new_raw(tx: Sender<notify::RawEvent>) -> Result<Self> {
        let target = PackageTarget::from_str(&env::var("HAB_STUDIO_HOST_ARCH").
                                             unwrap_or_default()).
                                             unwrap_or(PackageTarget::active_target());
        if target == AARCH64_DARWIN {
            Ok(SupWatcher::Fallback(PollWatcher::new_raw(tx).unwrap()))
        } else {
            Ok(SupWatcher::Native(RecommendedWatcher::new_raw(tx).unwrap()))
        }
    }

    fn new(tx: Sender<DebouncedEvent>, delay: Duration) -> Result<Self> {
        let target = PackageTarget::from_str(&env::var("HAB_STUDIO_HOST_ARCH").
                                             unwrap_or_default()).
                                             unwrap_or(PackageTarget::active_target());
        if target == AARCH64_DARWIN {
            debug!("Using pollwatcher");
            Ok(SupWatcher::Fallback(PollWatcher::new(tx, delay).unwrap()))
        } else {
            debug!("Using native watcher");
            Ok(SupWatcher::Native(RecommendedWatcher::new(tx, delay).unwrap()))
        }
    }

    fn watch<P: AsRef<Path>>(&mut self, path: P, recursive_mode: RecursiveMode) -> Result<()> {
        match self {
            SupWatcher::Native(watcher) => watcher.watch(path, recursive_mode),
            SupWatcher::Fallback(watcher) => watcher.watch(path, recursive_mode),
        }
    }

    fn unwatch<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        match self {
            SupWatcher::Native(watcher) => watcher.unwatch(path),
            SupWatcher::Fallback(watcher) => watcher.unwatch(path),
        }
    }
}
<commit_msg>clippy<commit_after>//! Watcher interface implementation for Habitat Supervisor.

use habitat_core::package::target::{PackageTarget,
                                    AARCH64_DARWIN};
use notify::{poll::PollWatcher,
             DebouncedEvent,
             RecommendedWatcher,
             RecursiveMode,
             Result,
             Watcher};
use std::{env,
          path::Path,
          str::FromStr,
          sync::mpsc::Sender,
          time::Duration};

pub enum SupWatcher {
    Native(RecommendedWatcher),
    Fallback(PollWatcher),
}

impl Watcher for SupWatcher {
    fn new_raw(tx: Sender<notify::RawEvent>) -> Result<Self> {
        let target = PackageTarget::from_str(&env::var("HAB_STUDIO_HOST_ARCH").
                                             unwrap_or_default()).
                                             unwrap_or_else(|_| PackageTarget::active_target());
        if target == AARCH64_DARWIN {
            Ok(SupWatcher::Fallback(PollWatcher::new_raw(tx).unwrap()))
        } else {
            Ok(SupWatcher::Native(RecommendedWatcher::new_raw(tx).unwrap()))
        }
    }

    fn new(tx: Sender<DebouncedEvent>, delay: Duration) -> Result<Self> {
        let target = PackageTarget::from_str(&env::var("HAB_STUDIO_HOST_ARCH").
                                             unwrap_or_default()).
                                             unwrap_or_else(|_| PackageTarget::active_target());
        if target == AARCH64_DARWIN {
            debug!("Using pollwatcher");
            Ok(SupWatcher::Fallback(PollWatcher::new(tx, delay).unwrap()))
        } else {
            debug!("Using native watcher");
            Ok(SupWatcher::Native(RecommendedWatcher::new(tx, delay).unwrap()))
        }
    }

    fn watch<P: AsRef<Path>>(&mut self, path: P, recursive_mode: RecursiveMode) -> Result<()> {
        match self {
            SupWatcher::Native(watcher) => watcher.watch(path, recursive_mode),
            SupWatcher::Fallback(watcher) => watcher.watch(path, recursive_mode),
        }
    }

    fn unwatch<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        match self {
            SupWatcher::Native(watcher) => watcher.unwatch(path),
            SupWatcher::Fallback(watcher) => watcher.unwatch(path),
        }
    }
}
<|endoftext|>


<commit_before>/// A graph similarity score using neighbor matching according to [this paper][1].
///
/// [1]: http://arxiv.org/abs/1009.5290 "2010, Mladen Nikolic, Measuring Similarity of Graph Nodes by Neighbor Matching"

extern crate nalgebra;
extern crate munkres;

use nalgebra::{DMat, Shape, ApproxEq};
use munkres::{WeightMatrix, solve_assignment};
use std::cmp;
use std::mem;

// The Hungarian algorithm minimizes the sum of weights. For us, a high-score
// (1.0)
// means high similarity and we want to avoid matching a low score (0.0). That's
// why we reverse the value (1.0 - value).
fn max_weight(x: f32) -> f32 {
    assert!(x >= 0.0 && x <= 1.0);
    // 1.0 - x
    x
}

// n_i contains the neighborhood of i (either in or out neighbors, not both)
// n_j contains the neighborhood of j (either in or out neighbors, not both)
fn s_next(n_i: &[usize], n_j: &[usize], x: &DMat<f32>) -> f32 {
    let max_deg = cmp::max(n_i.len(), n_j.len());
    let min_deg = cmp::min(n_i.len(), n_j.len());

    if min_deg == 0 {
        // in the paper, 0/0 is defined as 1.0
        return 1.0;
    }

    // map indicies from 0..min(degree) to the node indices
    let mapidx = |(a, b)| (n_i[a], n_j[b]);

    let mut w = WeightMatrix::from_fn(min_deg, |ab| max_weight(x[mapidx(ab)]));

    let assignment = solve_assignment(&mut w);
    assert!(assignment.len() == min_deg);

    let sum: f32 = assignment.iter().fold(0.0, |acc, &ab| acc + max_weight(x[mapidx(ab)]));

    return sum / max_deg as f32;
}

// Calculates x[k+1]
fn next_x(x: &DMat<f32>,
          new_x: &mut DMat<f32>,
          in_a: &[Vec<usize>],
          in_b: &[Vec<usize>],
          out_a: &[Vec<usize>],
          out_b: &[Vec<usize>]) {
    let shape = x.shape();
    assert!(shape == new_x.shape());

    for i in 0..shape.0 {
        for j in 0..shape.1 {
            new_x[(i, j)] = (s_next(&in_a[i], &in_b[j], x) + s_next(&out_a[i], &out_b[j], x)) / 2.0;
        }
    }
}

/// in_a:  Incoming edge list for each node of graph A
/// in_b:  Incoming edge list for each node of graph B
/// out_a: Outgoing edge list for each node of graph A
/// out_b: Outgoing edge list for each node of graph B
/// eps:   When to stop the iteration
/// stop_after_iter: Stop after iteration (Calculate x(stop_after_iter))
///
/// Returns (number of iterations, similarity matrix `x`)
pub fn neighbor_matching_matrix(in_a: &[Vec<usize>],
                                in_b: &[Vec<usize>],
                                out_a: &[Vec<usize>],
                                out_b: &[Vec<usize>],
                                eps: f32,
                                stop_after_iter: usize)
                                -> (usize, DMat<f32>) {
    let (na, nb) = (in_a.len(), in_b.len());
    assert!((na, nb) == (out_a.len(), out_b.len()));

    // `x` is the node-similarity matrix.
    // we initialize `x`, so that x[i,j]=1 for all i in A.edges() and j in
    // B.edges().
    let mut x: DMat<f32> = DMat::from_fn(na, nb, |i, j| {
        // XXX: Is that correct?
        if in_a[i].len() + out_a[i].len() > 0 && in_b[j].len() + out_b[j].len() > 0 {
            1.0
        } else {
            0.0
        }
    });

    let mut iter = 0;
    let mut new_x: DMat<f32> = DMat::new_zeros(na, nb);

    loop {
        println!("---------------------------------");
        println!("iter: {}", iter);
        println!("mat: {:?}", x);
        println!("---------------------------------");
        if x.approx_eq_eps(&new_x, &eps) || iter >= stop_after_iter {
            break;
        }

        next_x(&x, &mut new_x, &in_a, &in_b, &out_a, &out_b);
        mem::swap(&mut new_x, &mut x);
        iter += 1;
    }

    (iter, x)
}

/// For parameters see `neighbor_matching_matrix`.
pub fn neighbor_matching_score(in_a: &[Vec<usize>],
                               in_b: &[Vec<usize>],
                               out_a: &[Vec<usize>],
                               out_b: &[Vec<usize>],
                               eps: f32,
                               stop_after_iter: usize)
                               -> (usize, f32) {
    let (na, nb) = (in_a.len(), in_b.len());
    assert!((na, nb) == (out_a.len(), out_b.len()));

    let (iter, mat) = if na >= nb {
        neighbor_matching_matrix(in_a, in_b, out_a, out_b, eps, stop_after_iter)
    } else {
        // reverse graph a and b.
        neighbor_matching_matrix(in_b, in_a, out_b, out_a, eps, stop_after_iter)
    };

    assert!(mat.nrows() >= mat.ncols());

    let n = cmp::min(mat.nrows(), mat.ncols());
    // let m = mat.nrows();

    let mut w = WeightMatrix::from_fn(n, |(i, j)| {
        // let weight = if j >= m { 0.0 }
        //             else { mat[(i,j)] };

        let weight = mat[(i, j)];
        max_weight(weight)
    });

    let assignment = solve_assignment(&mut w);
    // assert!(assignment.len() == m);
    assert!(assignment.len() == n);

    let mut score = 0.0;
    for &(i, j) in &assignment[0..n] {
        score += mat[(i, j)];
    }

    (iter, score / n as f32)
}

#[test]
fn test_matrix() {
    // A: 0 --> 1
    let in_a = vec![vec![], vec![0]];
    let out_a = vec![vec![1], vec![]];

    // B: 0 <-- 1
    let in_b = vec![vec![1], vec![]];
    let out_b = vec![vec![], vec![0]];

    let (iter, mat) = neighbor_matching_matrix(&in_a, &in_b, &out_a, &out_b, 0.1, 100);
    println!("{:?}", mat);
    assert_eq!(iter, 1);
    assert_eq!(2, mat.nrows());
    assert_eq!(2, mat.ncols());

    // A and B are isomorphic
    assert_eq!(1.0, mat[(0, 0)]);
    assert_eq!(1.0, mat[(0, 1)]);
    assert_eq!(1.0, mat[(1, 0)]);
    assert_eq!(1.0, mat[(1, 1)]);
    assert!(false);
}

#[test]
fn test_score() {
    // A: 0 --> 1
    let in_a = vec![vec![], vec![0]];
    let out_a = vec![vec![1], vec![]];

    // B: 0 <-- 1
    let in_b = vec![vec![1], vec![]];
    let out_b = vec![vec![], vec![0]];

    let (iter, score) = neighbor_matching_score(&in_a, &in_b, &out_a, &out_b, 0.1, 100);
    println!("{}", score);
    assert_eq!(iter, 1);

    // The score is 1.0 <=> A and B are isomorphic
    assert_eq!(1.0, score);
    assert!(false);
}
<commit_msg>Fix calculation<commit_after>/// A graph similarity score using neighbor matching according to [this paper][1].
///
/// [1]: http://arxiv.org/abs/1009.5290 "2010, Mladen Nikolic, Measuring Similarity of Graph Nodes by Neighbor Matching"

extern crate nalgebra;
extern crate munkres;

use nalgebra::{DMat, Shape, ApproxEq};
use munkres::{WeightMatrix, solve_assignment};
use std::cmp;
use std::mem;

// n_i contains the neighborhood of i (either in or out neighbors, not both)
// n_j contains the neighborhood of j (either in or out neighbors, not both)
fn s_next(n_i: &[usize], n_j: &[usize], x: &DMat<f32>) -> f32 {
    let max_deg = cmp::max(n_i.len(), n_j.len());
    let min_deg = cmp::min(n_i.len(), n_j.len());

    if min_deg == 0 {
        // in the paper, 0/0 is defined as 1.0
        return 1.0;
    }

    // map indicies from 0..min(degree) to the node indices
    let mapidx = |(a, b)| (n_i[a], n_j[b]);

    let mut w = WeightMatrix::from_fn(min_deg, |ab| x[mapidx(ab)]);

    let assignment = solve_assignment(&mut w);
    assert!(assignment.len() == min_deg);

    let sum: f32 = assignment.iter().fold(0.0, |acc, &ab| acc + x[mapidx(ab)]);

    return sum / max_deg as f32;
}

// Calculates x[k+1]
fn next_x(x: &DMat<f32>,
          new_x: &mut DMat<f32>,
          in_a: &[Vec<usize>],
          in_b: &[Vec<usize>],
          out_a: &[Vec<usize>],
          out_b: &[Vec<usize>]) {
    let shape = x.shape();
    assert!(shape == new_x.shape());

    for i in 0..shape.0 {
        for j in 0..shape.1 {
            new_x[(i, j)] = (s_next(&in_a[i], &in_b[j], x) + s_next(&out_a[i], &out_b[j], x)) / 2.0;
        }
    }
}

/// in_a:  Incoming edge list for each node of graph A
/// in_b:  Incoming edge list for each node of graph B
/// out_a: Outgoing edge list for each node of graph A
/// out_b: Outgoing edge list for each node of graph B
/// eps:   When to stop the iteration
/// stop_after_iter: Stop after iteration (Calculate x(stop_after_iter))
///
/// Returns (number of iterations, similarity matrix `x`)
pub fn neighbor_matching_matrix(in_a: &[Vec<usize>],
                                in_b: &[Vec<usize>],
                                out_a: &[Vec<usize>],
                                out_b: &[Vec<usize>],
                                eps: f32,
                                stop_after_iter: usize)
                                -> (usize, DMat<f32>) {
    let (na, nb) = (in_a.len(), in_b.len());
    assert!((na, nb) == (out_a.len(), out_b.len()));

    // `x` is the node-similarity matrix.
    // we initialize `x`, so that x[i,j]=1 for all i in A.edges() and j in
    // B.edges().
    let mut x: DMat<f32> = DMat::from_fn(na, nb, |i, j| {
        // XXX: Is that correct?
        if in_a[i].len() + out_a[i].len() > 0 && in_b[j].len() + out_b[j].len() > 0 {
            1.0
        } else {
            0.0
        }
    });

    let mut iter = 0;
    let mut new_x: DMat<f32> = DMat::new_zeros(na, nb);

    loop {
        if x.approx_eq_eps(&new_x, &eps) || iter >= stop_after_iter {
            break;
        }

        next_x(&x, &mut new_x, &in_a, &in_b, &out_a, &out_b);
        mem::swap(&mut new_x, &mut x);
        iter += 1;
    }

    (iter, x)
}

/// For parameters see `neighbor_matching_matrix`.
pub fn neighbor_matching_score(in_a: &[Vec<usize>],
                               in_b: &[Vec<usize>],
                               out_a: &[Vec<usize>],
                               out_b: &[Vec<usize>],
                               eps: f32,
                               stop_after_iter: usize)
                               -> (usize, f32) {

    let (iter, x) = neighbor_matching_matrix(in_a, in_b, out_a, out_b, eps, stop_after_iter);
    let n = cmp::min(x.nrows(), x.ncols());
    if n == 0 {
        return (iter, 0.0);
    }
    let mut w = WeightMatrix::from_fn(n, |ij| x[ij]);

    let assignment = solve_assignment(&mut w);
    assert!(assignment.len() == n);

    let score: f32 = assignment.iter().fold(0.0, |acc, &ab| acc + x[ab]);
    let score = score / n as f32;

    (iter, score)
}

#[test]
fn test_matrix() {
    // A: 0 --> 1
    let in_a = vec![vec![], vec![0]];
    let out_a = vec![vec![1], vec![]];

    // B: 0 <-- 1
    let in_b = vec![vec![1], vec![]];
    let out_b = vec![vec![], vec![0]];

    let (iter, mat) = neighbor_matching_matrix(&in_a, &in_b, &out_a, &out_b, 0.1, 100);
    println!("{:?}", mat);
    assert_eq!(iter, 1);
    assert_eq!(2, mat.nrows());
    assert_eq!(2, mat.ncols());

    // A and B are isomorphic
    assert_eq!(1.0, mat[(0, 0)]);
    assert_eq!(1.0, mat[(0, 1)]);
    assert_eq!(1.0, mat[(1, 0)]);
    assert_eq!(1.0, mat[(1, 1)]);
}

#[test]
fn test_matrix_iter1() {
    let in_a = vec![vec![0, 0, 0]];
    let out_a = vec![vec![0, 0, 0]];

    let in_b = vec![vec![0, 0, 0, 0, 0]];
    let out_b = vec![vec![0, 0, 0, 0, 0]];

    let (iter, mat) = neighbor_matching_matrix(&in_a, &in_b, &out_a, &out_b, 0.1, 1);
    assert_eq!(iter, 1);
    assert_eq!(3.0 / 5.0, mat[(0, 0)]);
}

#[test]
fn test_score() {
    // A: 0 --> 1
    let in_a = vec![vec![], vec![0]];
    let out_a = vec![vec![1], vec![]];

    // B: 0 <-- 1
    let in_b = vec![vec![1], vec![]];
    let out_b = vec![vec![], vec![0]];

    let (iter, score) = neighbor_matching_score(&in_a, &in_b, &out_a, &out_b, 0.1, 100);
    assert_eq!(iter, 1);

    // The score is 1.0 <=> A and B are isomorphic
    assert_eq!(1.0, score);
}
<|endoftext|>


<commit_before><commit_msg>Add non_exhaustive<commit_after><|endoftext|>


<commit_before><commit_msg>Wrapper: document time and memory complexity<commit_after><|endoftext|>


<commit_before><commit_msg>Use `CString::new`<commit_after><|endoftext|>


<commit_before><commit_msg>Updated to nightly for 2016-04-06.<commit_after><|endoftext|>


<commit_before><commit_msg>cargo fmt<commit_after><|endoftext|>


<commit_before><commit_msg>Fix typo and awkward sentences.<commit_after><|endoftext|>


<commit_before><commit_msg>Implement `Error` for `StrSimError` (#23)<commit_after><|endoftext|>


<commit_before>use crate::utils::{last_path_segment, span_help_and_lint};
use rustc::lint::in_external_macro;
use rustc::ty::subst::SubstsRef;
use rustc::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef};
use rustc_hir::{
    intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind,
    QPath, Stmt, StmtKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** Checks for patterns that aren't exact representations of the types
    /// they are applied to.
    ///
    /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable
    /// because it increases ownership hints in the code, and will guard against some changes
    /// in ownership.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust,ignore
    /// // Bad
    /// let value = &Some(Box::new(23));
    /// match value {
    ///     Some(inner) => println!("{}", inner),
    ///     None => println!("none"),
    /// }
    ///
    /// // Good
    /// let value = &Some(Box::new(23));
    /// match *value {
    ///     Some(ref inner) => println!("{}", inner),
    ///     None => println!("none"),
    /// }
    /// ```
    pub PATTERN_TYPE_MISMATCH,
    restriction,
    "type of pattern does not match the expression type"
}

declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch {
    fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) {
        if let StmtKind::Local(ref local) = stmt.kind {
            if let Some(init) = &local.init {
                if let Some(init_ty) = cx.tables.node_type_opt(init.hir_id) {
                    let pat = &local.pat;
                    if in_external_macro(cx.sess(), pat.span) {
                        return;
                    }
                    let deref_possible = match local.source {
                        LocalSource::Normal => DerefPossible::Possible,
                        _ => DerefPossible::Impossible,
                    };
                    apply_lint(cx, pat, init_ty, deref_possible);
                }
            }
        }
    }

    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
        if let ExprKind::Match(ref expr, arms, source) = expr.kind {
            match source {
                MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => {
                    if let Some(expr_ty) = cx.tables.node_type_opt(expr.hir_id) {
                        'pattern_checks: for arm in arms {
                            let pat = &arm.pat;
                            if in_external_macro(cx.sess(), pat.span) {
                                continue 'pattern_checks;
                            }
                            if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
                                break 'pattern_checks;
                            }
                        }
                    }
                },
                _ => (),
            }
        }
    }

    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        _: intravisit::FnKind<'tcx>,
        _: &'tcx FnDecl<'_>,
        body: &'tcx Body<'_>,
        _: Span,
        hir_id: HirId,
    ) {
        if let Some(fn_sig) = cx.tables.liberated_fn_sigs().get(hir_id) {
            for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) {
                apply_lint(cx, &param.pat, ty, DerefPossible::Impossible);
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
enum DerefPossible {
    Possible,
    Impossible,
}

fn apply_lint<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    pat: &Pat<'_>,
    expr_ty: Ty<'tcx>,
    deref_possible: DerefPossible,
) -> bool {
    let maybe_mismatch = find_first_mismatch(cx, pat, expr_ty, Level::Top);
    if let Some((span, mutability, level)) = maybe_mismatch {
        span_help_and_lint(
            cx,
            PATTERN_TYPE_MISMATCH,
            span,
            "type of pattern does not match the expression type",
            &format!(
                "{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings",
                match (deref_possible, level) {
                    (DerefPossible::Possible, Level::Top) => "use `*` to dereference the match expression or ",
                    _ => "",
                },
                match mutability {
                    Mutability::Mut => "&mut _",
                    Mutability::Not => "&_",
                },
            ),
        );
        true
    } else {
        false
    }
}

#[derive(Debug, Copy, Clone)]
enum Level {
    Top,
    Lower,
}

#[allow(rustc::usage_of_ty_tykind)]
fn find_first_mismatch<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    pat: &Pat<'_>,
    ty: Ty<'tcx>,
    level: Level,
) -> Option<(Span, Mutability, Level)> {
    if let PatKind::Ref(ref sub_pat, _) = pat.kind {
        if let TyKind::Ref(_, sub_ty, _) = ty.kind {
            return find_first_mismatch(cx, sub_pat, sub_ty, Level::Lower);
        }
    }

    if let TyKind::Ref(_, _, mutability) = ty.kind {
        if is_non_ref_pattern(&pat.kind) {
            return Some((pat.span, mutability, level));
        }
    }

    if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind {
        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind {
            if let Some(variant) = get_variant(adt_def, qpath) {
                let field_defs = &variant.fields;
                return find_first_mismatch_in_struct(cx, field_pats, field_defs, substs_ref);
            }
        }
    }

    if let PatKind::TupleStruct(ref qpath, ref pats, _) = pat.kind {
        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind {
            if let Some(variant) = get_variant(adt_def, qpath) {
                let field_defs = &variant.fields;
                let ty_iter = field_defs.iter().map(|field_def| field_def.ty(cx.tcx, substs_ref));
                return find_first_mismatch_in_tuple(cx, pats, ty_iter);
            }
        }
    }

    if let PatKind::Tuple(ref pats, _) = pat.kind {
        if let TyKind::Tuple(..) = ty.kind {
            return find_first_mismatch_in_tuple(cx, pats, ty.tuple_fields());
        }
    }

    if let PatKind::Or(sub_pats) = pat.kind {
        for pat in sub_pats {
            let maybe_mismatch = find_first_mismatch(cx, pat, ty, level);
            if let Some(mismatch) = maybe_mismatch {
                return Some(mismatch);
            }
        }
    }

    None
}

fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a VariantDef> {
    if adt_def.is_struct() {
        if let Some(variant) = adt_def.variants.iter().next() {
            return Some(variant);
        }
    }

    if adt_def.is_enum() {
        let pat_ident = last_path_segment(qpath).ident;
        for variant in &adt_def.variants {
            if variant.ident == pat_ident {
                return Some(variant);
            }
        }
    }

    None
}

fn find_first_mismatch_in_tuple<'a, 'tcx, I>(
    cx: &LateContext<'a, 'tcx>,
    pats: &[&Pat<'_>],
    ty_iter_src: I,
) -> Option<(Span, Mutability, Level)>
where
    I: IntoIterator<Item = Ty<'tcx>>,
{
    let mut field_tys = ty_iter_src.into_iter();
    'fields: for pat in pats {
        let field_ty = if let Some(ty) = field_tys.next() {
            ty
        } else {
            break 'fields;
        };

        let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower);
        if let Some(mismatch) = maybe_mismatch {
            return Some(mismatch);
        }
    }

    None
}

fn find_first_mismatch_in_struct<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    field_pats: &[FieldPat<'_>],
    field_defs: &[FieldDef],
    substs_ref: SubstsRef<'tcx>,
) -> Option<(Span, Mutability, Level)> {
    for field_pat in field_pats {
        'definitions: for field_def in field_defs {
            if field_pat.ident == field_def.ident {
                let field_ty = field_def.ty(cx.tcx, substs_ref);
                let pat = &field_pat.pat;
                let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower);
                if let Some(mismatch) = maybe_mismatch {
                    return Some(mismatch);
                }
                break 'definitions;
            }
        }
    }

    None
}

fn is_non_ref_pattern(pat_kind: &PatKind<'_>) -> bool {
    match pat_kind {
        PatKind::Struct(..) | PatKind::Tuple(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => true,
        PatKind::Or(sub_pats) => sub_pats.iter().any(|pat| is_non_ref_pattern(&pat.kind)),
        _ => false,
    }
}
<commit_msg>span_help_and_lint -> span_lint_and_help<commit_after>use crate::utils::{last_path_segment, span_lint_and_help};
use rustc::lint::in_external_macro;
use rustc::ty::subst::SubstsRef;
use rustc::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef};
use rustc_hir::{
    intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind,
    QPath, Stmt, StmtKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** Checks for patterns that aren't exact representations of the types
    /// they are applied to.
    ///
    /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable
    /// because it increases ownership hints in the code, and will guard against some changes
    /// in ownership.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust,ignore
    /// // Bad
    /// let value = &Some(Box::new(23));
    /// match value {
    ///     Some(inner) => println!("{}", inner),
    ///     None => println!("none"),
    /// }
    ///
    /// // Good
    /// let value = &Some(Box::new(23));
    /// match *value {
    ///     Some(ref inner) => println!("{}", inner),
    ///     None => println!("none"),
    /// }
    /// ```
    pub PATTERN_TYPE_MISMATCH,
    restriction,
    "type of pattern does not match the expression type"
}

declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PatternTypeMismatch {
    fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) {
        if let StmtKind::Local(ref local) = stmt.kind {
            if let Some(init) = &local.init {
                if let Some(init_ty) = cx.tables.node_type_opt(init.hir_id) {
                    let pat = &local.pat;
                    if in_external_macro(cx.sess(), pat.span) {
                        return;
                    }
                    let deref_possible = match local.source {
                        LocalSource::Normal => DerefPossible::Possible,
                        _ => DerefPossible::Impossible,
                    };
                    apply_lint(cx, pat, init_ty, deref_possible);
                }
            }
        }
    }

    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
        if let ExprKind::Match(ref expr, arms, source) = expr.kind {
            match source {
                MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => {
                    if let Some(expr_ty) = cx.tables.node_type_opt(expr.hir_id) {
                        'pattern_checks: for arm in arms {
                            let pat = &arm.pat;
                            if in_external_macro(cx.sess(), pat.span) {
                                continue 'pattern_checks;
                            }
                            if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
                                break 'pattern_checks;
                            }
                        }
                    }
                },
                _ => (),
            }
        }
    }

    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        _: intravisit::FnKind<'tcx>,
        _: &'tcx FnDecl<'_>,
        body: &'tcx Body<'_>,
        _: Span,
        hir_id: HirId,
    ) {
        if let Some(fn_sig) = cx.tables.liberated_fn_sigs().get(hir_id) {
            for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) {
                apply_lint(cx, &param.pat, ty, DerefPossible::Impossible);
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
enum DerefPossible {
    Possible,
    Impossible,
}

fn apply_lint<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    pat: &Pat<'_>,
    expr_ty: Ty<'tcx>,
    deref_possible: DerefPossible,
) -> bool {
    let maybe_mismatch = find_first_mismatch(cx, pat, expr_ty, Level::Top);
    if let Some((span, mutability, level)) = maybe_mismatch {
        span_lint_and_help(
            cx,
            PATTERN_TYPE_MISMATCH,
            span,
            "type of pattern does not match the expression type",
            &format!(
                "{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings",
                match (deref_possible, level) {
                    (DerefPossible::Possible, Level::Top) => "use `*` to dereference the match expression or ",
                    _ => "",
                },
                match mutability {
                    Mutability::Mut => "&mut _",
                    Mutability::Not => "&_",
                },
            ),
        );
        true
    } else {
        false
    }
}

#[derive(Debug, Copy, Clone)]
enum Level {
    Top,
    Lower,
}

#[allow(rustc::usage_of_ty_tykind)]
fn find_first_mismatch<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    pat: &Pat<'_>,
    ty: Ty<'tcx>,
    level: Level,
) -> Option<(Span, Mutability, Level)> {
    if let PatKind::Ref(ref sub_pat, _) = pat.kind {
        if let TyKind::Ref(_, sub_ty, _) = ty.kind {
            return find_first_mismatch(cx, sub_pat, sub_ty, Level::Lower);
        }
    }

    if let TyKind::Ref(_, _, mutability) = ty.kind {
        if is_non_ref_pattern(&pat.kind) {
            return Some((pat.span, mutability, level));
        }
    }

    if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind {
        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind {
            if let Some(variant) = get_variant(adt_def, qpath) {
                let field_defs = &variant.fields;
                return find_first_mismatch_in_struct(cx, field_pats, field_defs, substs_ref);
            }
        }
    }

    if let PatKind::TupleStruct(ref qpath, ref pats, _) = pat.kind {
        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind {
            if let Some(variant) = get_variant(adt_def, qpath) {
                let field_defs = &variant.fields;
                let ty_iter = field_defs.iter().map(|field_def| field_def.ty(cx.tcx, substs_ref));
                return find_first_mismatch_in_tuple(cx, pats, ty_iter);
            }
        }
    }

    if let PatKind::Tuple(ref pats, _) = pat.kind {
        if let TyKind::Tuple(..) = ty.kind {
            return find_first_mismatch_in_tuple(cx, pats, ty.tuple_fields());
        }
    }

    if let PatKind::Or(sub_pats) = pat.kind {
        for pat in sub_pats {
            let maybe_mismatch = find_first_mismatch(cx, pat, ty, level);
            if let Some(mismatch) = maybe_mismatch {
                return Some(mismatch);
            }
        }
    }

    None
}

fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a VariantDef> {
    if adt_def.is_struct() {
        if let Some(variant) = adt_def.variants.iter().next() {
            return Some(variant);
        }
    }

    if adt_def.is_enum() {
        let pat_ident = last_path_segment(qpath).ident;
        for variant in &adt_def.variants {
            if variant.ident == pat_ident {
                return Some(variant);
            }
        }
    }

    None
}

fn find_first_mismatch_in_tuple<'a, 'tcx, I>(
    cx: &LateContext<'a, 'tcx>,
    pats: &[&Pat<'_>],
    ty_iter_src: I,
) -> Option<(Span, Mutability, Level)>
where
    I: IntoIterator<Item = Ty<'tcx>>,
{
    let mut field_tys = ty_iter_src.into_iter();
    'fields: for pat in pats {
        let field_ty = if let Some(ty) = field_tys.next() {
            ty
        } else {
            break 'fields;
        };

        let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower);
        if let Some(mismatch) = maybe_mismatch {
            return Some(mismatch);
        }
    }

    None
}

fn find_first_mismatch_in_struct<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    field_pats: &[FieldPat<'_>],
    field_defs: &[FieldDef],
    substs_ref: SubstsRef<'tcx>,
) -> Option<(Span, Mutability, Level)> {
    for field_pat in field_pats {
        'definitions: for field_def in field_defs {
            if field_pat.ident == field_def.ident {
                let field_ty = field_def.ty(cx.tcx, substs_ref);
                let pat = &field_pat.pat;
                let maybe_mismatch = find_first_mismatch(cx, pat, field_ty, Level::Lower);
                if let Some(mismatch) = maybe_mismatch {
                    return Some(mismatch);
                }
                break 'definitions;
            }
        }
    }

    None
}

fn is_non_ref_pattern(pat_kind: &PatKind<'_>) -> bool {
    match pat_kind {
        PatKind::Struct(..) | PatKind::Tuple(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => true,
        PatKind::Or(sub_pats) => sub_pats.iter().any(|pat| is_non_ref_pattern(&pat.kind)),
        _ => false,
    }
}
<|endoftext|>


<commit_before>use byteorder::{BigEndian, ByteOrder};
use std;
use std::fmt;
use util::u128;
// Unneeded since 1.21
#[allow(unused_imports)]
use std::ascii::AsciiExt;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SpotifyId(u128);

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SpotifyIdError;

const BASE62_DIGITS: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const BASE16_DIGITS: &'static [u8] = b"0123456789abcdef";

impl SpotifyId {
    pub fn from_base16(id: &str) -> Result<SpotifyId, SpotifyIdError> {
        let data = id.as_bytes();

        let mut n: u128 = u128::zero();
        for c in data {
            let d = match BASE16_DIGITS.iter().position(|e| e == c) {
                None => return Err(SpotifyIdError),
                Some(x) => x as u8,
            };
            n = n * u128::from(16);
            n = n + u128::from(d);
        }

        Ok(SpotifyId(n))
    }

    pub fn from_base62(id: &str) -> Result<SpotifyId, SpotifyIdError> {
        let data = id.as_bytes();

        let mut n: u128 = u128::zero();
        for c in data {
            let d = match BASE62_DIGITS.iter().position(|e| e == c) {
                None => return Err(SpotifyIdError),
                Some(x) => x as u8,
            };
            n = n * u128::from(62);
            n = n + u128::from(d);
        }

        Ok(SpotifyId(n))
    }

    pub fn from_raw(data: &[u8]) -> Result<SpotifyId, SpotifyIdError> {
        if data.len() != 16 {
            return Err(SpotifyIdError)
        };

        let high = BigEndian::read_u64(&data[0..8]);
        let low = BigEndian::read_u64(&data[8..16]);

        Ok(SpotifyId(u128::from_parts(high, low)))
    }

    pub fn to_base16(&self) -> String {
        let &SpotifyId(ref n) = self;
        let (high, low) = n.parts();

        let mut data = [0u8; 32];
        for i in 0..16 {
            data[31 - i] = BASE16_DIGITS[(low.wrapping_shr(4 * i as u32) & 0xF) as usize];
        }
        for i in 0..16 {
            data[15 - i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
        }

        std::str::from_utf8(&data).unwrap().to_owned()
    }

    pub fn to_raw(&self) -> [u8; 16] {
        let &SpotifyId(ref n) = self;
        let (high, low) = n.parts();

        let mut data = [0u8; 16];

        BigEndian::write_u64(&mut data[0..8], high);
        BigEndian::write_u64(&mut data[8..16], low);

        data
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub [u8; 20]);

impl FileId {
    pub fn to_base16(&self) -> String {
        self.0
            .iter()
            .map(|b| format!("{:02x}", b))
            .collect::<Vec<String>>()
            .concat()
    }
}

impl fmt::Debug for FileId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("FileId").field(&self.to_base16()).finish()
    }
}

impl fmt::Display for FileId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.to_base16())
    }
}
<commit_msg>Fix formatting<commit_after>use byteorder::{BigEndian, ByteOrder};
use std;
use std::fmt;
use util::u128;
// Unneeded since 1.21
#[allow(unused_imports)]
use std::ascii::AsciiExt;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SpotifyId(u128);

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SpotifyIdError;

const BASE62_DIGITS: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const BASE16_DIGITS: &'static [u8] = b"0123456789abcdef";

impl SpotifyId {
    pub fn from_base16(id: &str) -> Result<SpotifyId, SpotifyIdError> {
        let data = id.as_bytes();

        let mut n: u128 = u128::zero();
        for c in data {
            let d = match BASE16_DIGITS.iter().position(|e| e == c) {
                None => return Err(SpotifyIdError),
                Some(x) => x as u8,
            };
            n = n * u128::from(16);
            n = n + u128::from(d);
        }

        Ok(SpotifyId(n))
    }

    pub fn from_base62(id: &str) -> Result<SpotifyId, SpotifyIdError> {
        let data = id.as_bytes();

        let mut n: u128 = u128::zero();
        for c in data {
            let d = match BASE62_DIGITS.iter().position(|e| e == c) {
                None => return Err(SpotifyIdError),
                Some(x) => x as u8,
            };
            n = n * u128::from(62);
            n = n + u128::from(d);
        }

        Ok(SpotifyId(n))
    }

    pub fn from_raw(data: &[u8]) -> Result<SpotifyId, SpotifyIdError> {
        if data.len() != 16 {
            return Err(SpotifyIdError);
        };

        let high = BigEndian::read_u64(&data[0..8]);
        let low = BigEndian::read_u64(&data[8..16]);

        Ok(SpotifyId(u128::from_parts(high, low)))
    }

    pub fn to_base16(&self) -> String {
        let &SpotifyId(ref n) = self;
        let (high, low) = n.parts();

        let mut data = [0u8; 32];
        for i in 0..16 {
            data[31 - i] = BASE16_DIGITS[(low.wrapping_shr(4 * i as u32) & 0xF) as usize];
        }
        for i in 0..16 {
            data[15 - i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
        }

        std::str::from_utf8(&data).unwrap().to_owned()
    }

    pub fn to_raw(&self) -> [u8; 16] {
        let &SpotifyId(ref n) = self;
        let (high, low) = n.parts();

        let mut data = [0u8; 16];

        BigEndian::write_u64(&mut data[0..8], high);
        BigEndian::write_u64(&mut data[8..16], low);

        data
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub [u8; 20]);

impl FileId {
    pub fn to_base16(&self) -> String {
        self.0
            .iter()
            .map(|b| format!("{:02x}", b))
            .collect::<Vec<String>>()
            .concat()
    }
}

impl fmt::Debug for FileId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("FileId").field(&self.to_base16()).finish()
    }
}

impl fmt::Display for FileId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.to_base16())
    }
}
<|endoftext|>


<commit_before>use card;
use std::fmt;

mod tests;

pub struct Hand {
    pub cards: Vec<card::Card>
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards
        }
    }

    pub fn has_flush(&self) -> bool {
        let suit: card::Suit = self.cards.get(0).unwrap().suit.clone();
        for card in &self.cards {
            if card.suit != suit {
                return false
            }
        }
        true
    }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq)]
pub enum PokerHand {
    HighCard((card::Card)),
    OnePair((card::Card, card::Card)),
    TwoPair((card::Card, card::Card), (card::Card, card::Card)),
    Trips((card::Card, card::Card, card::Card)),
    Straight((card::Card, card::Card, card::Card, card::Card, card::Card)),
    Flush((card::Card, card::Card, card::Card, card::Card, card::Card)),
    FullHouse((card::Card, card::Card, card::Card), (card::Card, card::Card)),
    Quads((card::Card, card::Card, card::Card, card::Card)),
    StraightFlush((card::Card, card::Card, card::Card, card::Card, card::Card)),
}

impl PokerHand {
    fn raw_value(&self) -> u32 {
        match *self {
            PokerHand::HighCard(_) => 0,
            PokerHand::OnePair(_) => 1,
            PokerHand::TwoPair(_, _) => 2,
            PokerHand::Trips(_) => 3,
            PokerHand::Straight(_) => 4,
            PokerHand::Flush(_) => 5,
            PokerHand::FullHouse(_, _) => 6,
            PokerHand::Quads(_) => 7,
            PokerHand::StraightFlush(_) => 8,
        }
    }
}
<commit_msg>Reimplemented has_flush to use bitwise operators<commit_after>use card;
use std::fmt;

mod tests;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Hand {
    pub cards: Vec<card::Card>,
    //pub ranking: PokerRanking
}

impl Hand {
    pub fn new(mut cards: Vec<card::Card>) -> Hand {
        cards.sort();
        Hand {
            cards: cards,

        }
    }

    fn has_flush(&self) -> bool {
        let mut suits = 0b0000;
        for card in &self.cards {
            suits = suits | (0b0001 << card.suit as u32);
        }
        println!("{}", suits);
        match suits {
            0b0001 => true,
            0b0010 => true,
            0b0100 => true,
            0b1000 => true,
            _ => false
        }
    }

    // fn has_straight(&self) -> bool {
    //
    // }
}

impl fmt::Display for Hand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {} {} {} {}", self.cards.get(0).unwrap(),
                                    self.cards.get(1).unwrap(),
                                    self.cards.get(2).unwrap(),
                                    self.cards.get(3).unwrap(),
                                    self.cards.get(4).unwrap())
    }
}

#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum PokerRanking {
    HighCard,
    OnePair,
    TwoPair,
    Trips,
    Straight,
    Flush,
    FullHouse,
    Quads,
    StraightFlush,
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use core::fmt;
use core::cell::UnsafeCell;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::{Acquire, Release, AcqRel};

use task::Waker;

/// A synchronization primitive for task wakeup.
///
/// Sometimes the task interested in a given event will change over time.
/// An `AtomicWaker` can coordinate concurrent notifications with the consumer
/// potentially "updating" the underlying task to wake up. This is useful in
/// scenarios where a computation completes in another thread and wants to
/// notify the consumer, but the consumer is in the process of being migrated to
/// a new logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
///
/// `AtomicWaker` does not provide any memory ordering guarantees, as such the
/// user should use caution and use other synchronization primitives to guard
/// the result of the underlying computation.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: UnsafeCell<Option<Waker>>,
}

/// Initial state, the `AtomicWaker` is currently not being used.
///
/// The value `2` is picked specifically because it between the write lock &
/// read lock values. Since the read lock is represented by an incrementing
/// counter, this enables an atomic fetch_sub operation to be used for releasing
/// a lock.
const WAITING: usize = 2;

/// The `register` function has determined that the task is no longer current.
/// This implies that `AtomicWaker::register` is being called from a different
/// task than is represented by the currently stored task. The write lock is
/// obtained to update the task cell.
const LOCKED_WRITE: usize = 0;

/// At least one call to `wake` happened concurrently to `register` updating
/// the task cell. This state is detected when `register` exits the mutation
/// code and signals to `register` that it is responsible for notifying its own
/// task.
const LOCKED_WRITE_NOTIFIED: usize = 1;

/// The `wake` function has locked access to the task cell for notification.
///
/// The constant is left here mostly for documentation reasons.
#[allow(dead_code)]
const LOCKED_READ: usize = 3;

impl AtomicWaker {
    /// Create an `AtomicWaker` with no initial `Waker`
    pub fn new() -> AtomicWaker {
        // Make sure that task is Sync
        trait AssertSync: Sync {}
        impl AssertSync for Waker {}

        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: UnsafeCell::new(None),
        }
    }

    /// Registers the waker to be notified on calls to `wake`.
    ///
    /// The new task will take place of any previous tasks that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// notify the `register` caller's task and deregister the waker from future
    /// notifications. Because of this, callers should ensure `register` gets
    /// invoked with a new `Waker` **each** time they require a wakeup.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being notified once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be notified. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    ///
    /// # Examples
    ///
    /// Here is how `register` is used when implementing a flag.
    ///
    /// ```
    /// # use futures_core::{Future, Poll, Never};
    /// # use futures_core::Async::*;
    /// # use futures_core::task::{self, AtomicWaker};
    /// # use std::sync::atomic::AtomicBool;
    /// # use std::sync::atomic::Ordering::SeqCst;
    /// struct Flag {
    ///     waker: AtomicWaker,
    ///     set: AtomicBool,
    /// }
    ///
    /// impl Future for Flag {
    ///     type Item = ();
    ///     type Error = Never;
    ///
    ///     fn poll(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
    ///         // Register **before** checking `set` to avoid a race condition
    ///         // that would result in lost notifications.
    ///         self.waker.register(cx.waker());
    ///
    ///         if self.set.load(SeqCst) {
    ///             Ok(Ready(()))
    ///         } else {
    ///             Ok(Pending)
    ///         }
    ///     }
    /// }
    /// ```
    pub fn register(&self, waker: &Waker) {
        match self.state.compare_and_swap(WAITING, LOCKED_WRITE, Acquire) {
            WAITING => {
                unsafe {
                    // Locked acquired, update the waker cell
                    *self.waker.get() = Some(waker.clone());

                    // Release the lock. If the state transitioned to
                    // `LOCKED_NOTIFIED`, this means that an notify has been
                    // signaled, so notify the task.
                    //
                    // Start by assuming that the state is LOCKED_WRITE as this
                    // is what we jut set it to.
                    let mut curr = LOCKED_WRITE;

                    loop {
                        let res = self.state.compare_exchange(
                            curr, WAITING, AcqRel, Acquire);

                        match res {
                            Ok(_) => return,
                            Err(actual) => {
                                // Update `curr` for the next iteration of the
                                // loop
                                curr = actual;
                            }
                        }

                        // Since we aren't using the weak variant of the atomic
                        // operation, the only possible option for `curr` is
                        // `LOCKED_WRITE_NOTIFIED`.
                        assert_eq!(curr, LOCKED_WRITE_NOTIFIED);

                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }
                }
            }
            LOCKED_WRITE | LOCKED_WRITE_NOTIFIED => {
                // A thread is concurrently calling `register`. This shouldn't
                // happen as it doesn't really make much sense, but it isn't
                // unsafe per se. Since two threads are concurrently trying to
                // update the task, it's undefined which one "wins" (no ordering
                // guarantees), so we can just do nothing.
            }
            state => {
                debug_assert!(state != LOCKED_WRITE, "unexpected state LOCKED_WRITE");
                debug_assert!(state != LOCKED_WRITE_NOTIFIED, "unexpected state LOCKED_WRITE_NOTIFIED");

                // Currently in a read locked state, this implies that `wake`
                // is currently being called on the old task handle. So, we call
                // `wake` on the new task handle
                waker.wake();
            }
        }
    }

    /// Calls `wake` on the last `Waker` passed to `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        let mut curr = WAITING;

        loop {
            if curr == LOCKED_WRITE {
                // Transition the state to LOCKED_NOTIFIED
                let actual = self.state.compare_and_swap(LOCKED_WRITE, LOCKED_WRITE_NOTIFIED, Release);

                if curr == actual {
                    // Success, return
                    return;
                }

                // update current state variable and try again
                curr = actual;

            } else if curr == LOCKED_WRITE_NOTIFIED {
                // Currently in `LOCKED_WRITE_NOTIFIED` state, nothing else to do.
                return;

            } else {
                // Currently in a LOCKED_READ state, so attempt to increment the
                // lock count.
                let actual = self.state.compare_and_swap(curr, curr + 1, Acquire);

                // Locked acquired
                if actual == curr {
                    // Notify the task
                    unsafe {
                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }

                    // Release the lock
                    self.state.fetch_sub(1, Release);

                    // Done
                    return;
                }

                // update current state variable and try again
                curr = actual;

            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}
<commit_msg>Fix `AtomicWaker`<commit_after>use core::fmt;
use core::cell::UnsafeCell;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::{Acquire, Release, AcqRel};

use task::Waker;

/// A synchronization primitive for task wakeup.
///
/// Sometimes the task interested in a given event will change over time.
/// An `AtomicWaker` can coordinate concurrent notifications with the consumer
/// potentially "updating" the underlying task to wake up. This is useful in
/// scenarios where a computation completes in another thread and wants to
/// notify the consumer, but the consumer is in the process of being migrated to
/// a new logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
///
/// `AtomicWaker` does not provide any memory ordering guarantees, as such the
/// user should use caution and use other synchronization primitives to guard
/// the result of the underlying computation.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: UnsafeCell<Option<Waker>>,
}

// `AtomicWaker` is a multi-consumer, single-producer transfer cell. The cell
// stores a `Waker` value produced by calls to `register` and many threads can
// race to take the waker (to wake it) by calling `wake`.
//
// If a new `Waker` instance is produced by calling `register` before an
// existing one is consumed, then the existing one is overwritten.
//
// While `AtomicWaker` is single-producer, the implementation ensures memory
// safety. In the event of concurrent calls to `register`, there will be a
// single winner whose waker will get stored in the cell. The losers will not
// have their tasks woken. As such, callers should ensure to add synchronization
// to calls to `register`.
//
// The implementation uses a single `AtomicUsize` value to coordinate access to
// the `Waker` cell. There are two bits that are operated on independently.
// These are represented by `REGISTERING` and `WAKING`.
//
// The `REGISTERING` bit is set when a producer enters the critical section. The
// `WAKING` bit is set when a consumer enters the critical section. Neither bit
// being set is represented by `WAITING`.
//
// A thread obtains an exclusive lock on the waker cell by transitioning the
// state from `WAITING` to `REGISTERING` or `WAKING`, depending on the operation
// the thread wishes to perform. When this transition is made, it is guaranteed
// that no other thread will access the waker cell.
//
// # Registering
//
// On a call to `register`, an attempt to transition the state from WAITING to
// REGISTERING is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread sets the waker cell to the waker
// provided as an argument. Then it attempts to transition the state back from
// `REGISTERING` -> `WAITING`.
//
// If this transition is successful, then the registering process is complete
// and the next call to `wake` will observe the waker.
//
// If the transition fails, then there was a concurrent call to `wake` that was
// unable to access the waker cell (due to the registering thread holding the
// lock). To handle this, the registering thread removes the waker it just set
// from the cell and calls `wake` on it. This call to wake represents the
// attempt to wake by the other thread (that set the `WAKING` bit). The state is
// then transitioned from `REGISTERING | WAKING` back to `WAITING`.  This
// transition must succeed because, at this point, the state cannot be
// transitioned by another thread.
//
// # Waking
//
// On a call to `wake`, an attempt to transition the state from `WAITING` to
// `WAKING` is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread takes ownership of the current value
// in the waker cell, and calls `wake` on it. The state is then transitioned
// back to `WAITING`. This transition must succeed as, at this point, the state
// cannot be transitioned by another thread.
//
// If the thread is unable to obtain the lock, the `WAKING` bit is still.  This
// is because it has either been set by the current thread but the previous
// value included the `REGISTERING` bit **or** a concurrent thread is in the
// `WAKING` critical section. Either way, no action must be taken.
//
// If the current thread is the only concurrent call to `wake` and another
// thread is in the `register` critical section, when the other thread **exits**
// the `register` critical section, it will observe the `WAKING` bit and handle
// the wake itself.
//
// If another thread is in the `wake` critical section, then it will handle
// waking the task.
//
// # A potential race (is safely handled).
//
// Imagine the following situation:
//
// * Thread A obtains the `wake` lock and wakes a task.
//
// * Before thread A releases the `wake` lock, the woken task is scheduled.
//
// * Thread B attempts to wake the task. In theory this should result in the
//   task being woken, but it cannot because thread A still holds the wake lock.
//
// This case is handled by requiring users of `AtomicWaker` to call `register`
// **before** attempting to observe the application state change that resulted
// in the task being awoken. The wakers also change the application state before
// calling wake.
//
// Because of this, the waker will do one of two things.
//
// 1) Observe the application state change that Thread B is woken for. In this
//    case, it is OK for Thread B's wake to be lost.
//
// 2) Call register before attempting to observe the application state. Since
//    Thread A still holds the `wake` lock, the call to `register` will result
//    in the task waking itself and get scheduled again.

/// Idle state
const WAITING: usize = 0;

/// A new waker value is being registered with the `AtomicWaker` cell.
const REGISTERING: usize = 0b01;

/// The waker currently registered with the `AtomicWaker` cell is being woken.
const WAKING: usize = 0b10;

impl AtomicWaker {
    /// Create an `AtomicWaker`.
    pub fn new() -> AtomicWaker {
        // Make sure that task is Sync
        trait AssertSync: Sync {}
        impl AssertSync for Waker {}

        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: UnsafeCell::new(None),
        }
    }

    /// Registers the waker to be notified on calls to `wake`.
    ///
    /// The new task will take place of any previous tasks that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// notify the `register` caller's task and deregister the waker from future
    /// notifications. Because of this, callers should ensure `register` gets
    /// invoked with a new `Waker` **each** time they require a wakeup.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being notified once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be notified. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    ///
    /// # Examples
    ///
    /// Here is how `register` is used when implementing a flag.
    ///
    /// ```
    /// # use futures_core::{Future, Poll, Never};
    /// # use futures_core::Async::*;
    /// # use futures_core::task::{self, AtomicWaker};
    /// # use std::sync::atomic::AtomicBool;
    /// # use std::sync::atomic::Ordering::SeqCst;
    /// struct Flag {
    ///     waker: AtomicWaker,
    ///     set: AtomicBool,
    /// }
    ///
    /// impl Future for Flag {
    ///     type Item = ();
    ///     type Error = Never;
    ///
    ///     fn poll(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
    ///         // Register **before** checking `set` to avoid a race condition
    ///         // that would result in lost notifications.
    ///         self.waker.register(cx.waker());
    ///
    ///         if self.set.load(SeqCst) {
    ///             Ok(Ready(()))
    ///         } else {
    ///             Ok(Pending)
    ///         }
    ///     }
    /// }
    /// ```
    pub fn register(&self, waker: &Waker) {
        match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
            WAITING => {
                unsafe {
                    // Locked acquired, update the waker cell
                    *self.waker.get() = Some(waker.clone());

                    // Release the lock. If the state transitioned to include
                    // the `WAKING` bit, this means that a wake has been
                    // called concurrently, so we have to remove the waker and
                    // wake it.`
                    //
                    // Start by assuming that the state is `REGISTERING` as this
                    // is what we jut set it to.
                    let mut curr = REGISTERING;

                    // If a task has to be woken, the waker will be set here.
                    let mut wake_now: Option<Waker> = None;

                    loop {
                        let res = self.state.compare_exchange(
                            curr, WAITING, AcqRel, Acquire);

                        match res {
                            Ok(_) => {
                                // The atomic exchange was successful, now
                                // wake the task (if set) and return.
                                if let Some(waker) = wake_now {
                                    waker.wake();
                                }

                                return;
                            }
                            Err(actual) => {
                                // This branch can only be reached if a
                                // concurrent thread called `wake`. In this
                                // case, `actual` **must** be `REGISTERING |
                                // `WAKING`.
                                debug_assert_eq!(actual, REGISTERING | WAKING);

                                // Take the waker to wake once the atomic operation has
                                // completed.
                                wake_now = (*self.waker.get()).take();

                                // Update `curr` for the next iteration of the
                                // loop
                                curr = actual;
                            }
                        }
                    }
                }
            }
            WAKING => {
                // Currently in the process of waking the task, i.e.,
                // `wake` is currently being called on the old task handle.
                // So, we call wake on the new waker
                waker.wake();
            }
            state => {
                // In this case, a concurrent thread is holding the
                // "registering" lock. This probably indicates a bug in the
                // caller's code as racing to call `register` doesn't make much
                // sense.
                //
                // We just want to maintain memory safety. It is ok to drop the
                // call to `register`.
                debug_assert!(
                    state == REGISTERING ||
                    state == REGISTERING | WAKING);
            }
        }
    }

    /// Calls `wake` on the last `Waker` passed to `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        // AcqRel ordering is used in order to acquire the value of the `task`
        // cell as well as to establish a `release` ordering with whatever
        // memory the `AtomicWaker` is associated with.
        match self.state.fetch_or(WAKING, AcqRel) {
            WAITING => {
                // The waking lock has been acquired.
                let waker = unsafe { (*self.waker.get()).take() };

                // Release the lock
                self.state.fetch_and(!WAKING, Release);

                if let Some(waker) = waker {
                    waker.wake();
                }
            }
            state => {
                // There is a concurrent thread currently updating the
                // associated task.
                //
                // Nothing more to do as the `WAKING` bit has been set. It
                // doesn't matter if there are concurrent registering threads or
                // not.
                //
                debug_assert!(
                    state == REGISTERING ||
                    state == REGISTERING | WAKING ||
                    state == WAKING);
            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}
<|endoftext|>


<commit_before>/* Module: math */

#[link_name = ""]
#[abi = "cdecl"]
native mod libc {
    fn sqrt(n: float) -> float;
    fn sin(n: float) -> float;
    fn asin(n: float) -> float;
    fn cos(n: float) -> float;
    fn acos(n: float) -> float;
    fn tan(n: float) -> float;
    fn atan(n: float) -> float;
    #[link_name="log"]
    fn ln(n: float) -> float;
    fn log2(n: float) -> float;
    fn log10(n: float) -> float;
    fn log1p(n: float) -> float;
}

/*
Function: sqrt

Returns the square root
*/
fn sqrt(x: float) -> float { libc::sqrt(x) }

/*
Function: sin

Returns the sine of an angle
*/
fn sin(x: float) -> float { libc::sin(x) }

/*
Function: cos

Returns the cosine of an angle
*/
fn cos(x: float) -> float { libc::cos(x) }

/*
Function: tan

Returns the tangent of an angle
*/
fn tan(x: float) -> float { libc::tan(x) }

/*
Function: asin

Returns the arcsine of an angle
*/
fn asin(x: float) -> float { libc::asin(x) }

/*
Function: acos

Returns the arccosine of an angle
*/
fn acos(x: float) -> float { libc::acos(x) }

/*
Function: atan

Returns the arctangent of an angle
*/
fn atan(x: float) -> float { libc::atan(x) }

/*
Const: pi

Archimedes' constant
*/
const pi: float = 3.141592653589793;

/*
Function: min

Returns the minimum of two values
*/
fn min<copy T>(x: T, y: T) -> T { x < y ? x : y }

/*
Function: max

Returns the maximum of two values
*/
fn max<copy T>(x: T, y: T) -> T { x < y ? y : x }

/*
Const: e

Euler's number
*/
const e: float = 2.718281828459045235;

/*
Function: ln

Returns the natural logaritm
*/
fn ln(n: float) -> float { libc::ln(n) }

/*
Function: log2

Returns the logarithm to base 2
*/
fn log2(n: float) -> float { libc::log2(n) }

/*
Function: log2

Returns the logarithm to base 10
*/
fn log10(n: float) -> float { libc::log10(n) }

/*
Function: log1p

Returns the natural logarithm of `1+n` accurately,
even for very small values of `n`
*/
fn ln1p(n: float) -> float { libc::log1p(n) }
<commit_msg>std: declared fns in math to be pure; requires calling libc via unsafe<commit_after>/* Module: math */

#[link_name = ""]
#[abi = "cdecl"]
native mod libc {
    fn sqrt(n: float) -> float;
    fn sin(n: float) -> float;
    fn asin(n: float) -> float;
    fn cos(n: float) -> float;
    fn acos(n: float) -> float;
    fn tan(n: float) -> float;
    fn atan(n: float) -> float;
    #[link_name="log"]
    fn ln(n: float) -> float;
    fn log2(n: float) -> float;
    fn log10(n: float) -> float;
    fn log1p(n: float) -> float;
}

/*
Function: sqrt

Returns the square root
*/
pure fn sqrt(x: float) -> float { unsafe { libc::sqrt(x) } }

/*
Function: sin

Returns the sine of an angle
*/
pure fn sin(x: float) -> float { unsafe { libc::sin(x) } }

/*
Function: cos

Returns the cosine of an angle
*/
pure fn cos(x: float) -> float { unsafe { libc::cos(x) } }

/*
Function: tan

Returns the tangent of an angle
*/
pure fn tan(x: float) -> float { unsafe { libc::tan(x) } }

/*
Function: asin

Returns the arcsine of an angle
*/
pure fn asin(x: float) -> float { unsafe { libc::asin(x) } }

/*
Function: acos

Returns the arccosine of an angle
*/
pure fn acos(x: float) -> float { unsafe { libc::acos(x) } }

/*
Function: atan

Returns the arctangent of an angle
*/
pure fn atan(x: float) -> float { unsafe { libc::atan(x) } }

/*
Const: pi

Archimedes' constant
*/
const pi: float = 3.141592653589793;

/*
Function: min

Returns the minimum of two values
*/
pure fn min<copy T>(x: T, y: T) -> T { x < y ? x : y }

/*
Function: max

Returns the maximum of two values
*/
pure fn max<copy T>(x: T, y: T) -> T { x < y ? y : x }

/*
Const: e

Euler's number
*/
const e: float = 2.718281828459045235;

/*
Function: ln

Returns the natural logaritm
*/
pure fn ln(n: float) -> float { unsafe { libc::ln(n) } }

/*
Function: log2

Returns the logarithm to base 2
*/
pure fn log2(n: float) -> float { unsafe { libc::log2(n) } }

/*
Function: log2

Returns the logarithm to base 10
*/
pure fn log10(n: float) -> float { unsafe { libc::log10(n) } }

/*
Function: log1p

Returns the natural logarithm of `1+n` accurately,
even for very small values of `n`
*/
pure fn ln1p(n: float) -> float { unsafe { libc::log1p(n) } }
<|endoftext|>


<commit_before>//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.

#![unstable(
    feature = "rt",
    reason = "this public module should not exist and is highly likely \
              to disappear",
    issue = "none"
)]
#![doc(hidden)]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(unused_macros)]

use crate::ffi::CString;

// Re-export some of our utilities which are expected by other crates.
pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count};
pub use core::panicking::panic_display;

use crate::sync::Once;
use crate::sys;
use crate::sys_common::thread_info;
use crate::thread::Thread;

// Prints to the "panic output", depending on the platform this may be:
// - the standard error output
// - some dedicated platform specific output
// - nothing (so this macro is a no-op)
macro_rules! rtprintpanic {
    ($($t:tt)*) => {
        if let Some(mut out) = crate::sys::stdio::panic_output() {
            let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
        }
    }
}

macro_rules! rtabort {
    ($($t:tt)*) => {
        {
            rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*));
            crate::sys::abort_internal();
        }
    }
}

macro_rules! rtassert {
    ($e:expr) => {
        if !$e {
            rtabort!(concat!("assertion failed: ", stringify!($e)));
        }
    };
}

macro_rules! rtunwrap {
    ($ok:ident, $e:expr) => {
        match $e {
            $ok(v) => v,
            ref err => {
                let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug
                rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err)
            }
        }
    };
}

// One-time runtime initialization.
// Runs before `main`.
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
#[cfg_attr(test, allow(dead_code))]
unsafe fn init(argc: isize, argv: *const *const u8) {
    unsafe {
        sys::init(argc, argv);

        let main_guard = sys::thread::guard::init();
        // Next, set up the current Thread with the guard information we just
        // created. Note that this isn't necessary in general for new threads,
        // but we just do this to name the main thread and to give it correct
        // info about the stack bounds.
        let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
        thread_info::set(main_guard, thread);
    }
}

// One-time runtime cleanup.
// Runs after `main` or at program exit.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub(crate) fn cleanup() {
    static CLEANUP: Once = Once::new();
    CLEANUP.call_once(|| unsafe {
        // Flush stdout and disable buffering.
        crate::io::cleanup();
        // SAFETY: Only called once during runtime cleanup.
        sys::cleanup();
    });
}

// To reduce the generated code of the new `lang_start`, this function is doing
// the real work.
#[cfg(not(test))]
fn lang_start_internal(
    main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
    argc: isize,
    argv: *const *const u8,
) -> Result<isize, !> {
    use crate::{mem, panic};
    let rt_abort = move |e| {
        mem::forget(e);
        rtabort!("initialization or cleanup bug");
    };
    // Guard against the code called by this function from unwinding outside of the Rust-controlled
    // code, which is UB. This is a requirement imposed by a combination of how the
    // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
    // mechanism itself.
    //
    // There are a couple of instances where unwinding can begin. First is inside of the
    // `rt::init`, `rt::cleanup` and similar functions controlled by libstd. In those instances a
    // panic is a libstd implementation bug. A quite likely one too, as there isn't any way to
    // prevent libstd from accidentally introducing a panic to these functions. Another is from
    // user code from `main` or, more nefariously, as described in e.g. issue #86030.
    // SAFETY: Only called once during runtime initialization.
    panic::catch_unwind(move || unsafe { init(argc, argv) }).map_err(rt_abort)?;
    let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
        .map_err(move |e| {
            mem::forget(e);
            rtprintpanic!("drop of the panic payload panicked");
            sys::abort_internal()
        });
    panic::catch_unwind(cleanup).map_err(rt_abort)?;
    ret_code
}

#[cfg(not(test))]
#[lang = "start"]
fn lang_start<T: crate::process::Termination + 'static>(
    main: fn() -> T,
    argc: isize,
    argv: *const *const u8,
) -> isize {
    let Ok(v) = lang_start_internal(
        &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
        argc,
        argv,
    );
    v
}
<commit_msg>Use rtabort! instead of rtprintpanic! + abort_internal<commit_after>//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.

#![unstable(
    feature = "rt",
    reason = "this public module should not exist and is highly likely \
              to disappear",
    issue = "none"
)]
#![doc(hidden)]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(unused_macros)]

use crate::ffi::CString;

// Re-export some of our utilities which are expected by other crates.
pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count};
pub use core::panicking::panic_display;

use crate::sync::Once;
use crate::sys;
use crate::sys_common::thread_info;
use crate::thread::Thread;

// Prints to the "panic output", depending on the platform this may be:
// - the standard error output
// - some dedicated platform specific output
// - nothing (so this macro is a no-op)
macro_rules! rtprintpanic {
    ($($t:tt)*) => {
        if let Some(mut out) = crate::sys::stdio::panic_output() {
            let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
        }
    }
}

macro_rules! rtabort {
    ($($t:tt)*) => {
        {
            rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*));
            crate::sys::abort_internal();
        }
    }
}

macro_rules! rtassert {
    ($e:expr) => {
        if !$e {
            rtabort!(concat!("assertion failed: ", stringify!($e)));
        }
    };
}

macro_rules! rtunwrap {
    ($ok:ident, $e:expr) => {
        match $e {
            $ok(v) => v,
            ref err => {
                let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug
                rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err)
            }
        }
    };
}

// One-time runtime initialization.
// Runs before `main`.
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
#[cfg_attr(test, allow(dead_code))]
unsafe fn init(argc: isize, argv: *const *const u8) {
    unsafe {
        sys::init(argc, argv);

        let main_guard = sys::thread::guard::init();
        // Next, set up the current Thread with the guard information we just
        // created. Note that this isn't necessary in general for new threads,
        // but we just do this to name the main thread and to give it correct
        // info about the stack bounds.
        let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
        thread_info::set(main_guard, thread);
    }
}

// One-time runtime cleanup.
// Runs after `main` or at program exit.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub(crate) fn cleanup() {
    static CLEANUP: Once = Once::new();
    CLEANUP.call_once(|| unsafe {
        // Flush stdout and disable buffering.
        crate::io::cleanup();
        // SAFETY: Only called once during runtime cleanup.
        sys::cleanup();
    });
}

// To reduce the generated code of the new `lang_start`, this function is doing
// the real work.
#[cfg(not(test))]
fn lang_start_internal(
    main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
    argc: isize,
    argv: *const *const u8,
) -> Result<isize, !> {
    use crate::{mem, panic};
    let rt_abort = move |e| {
        mem::forget(e);
        rtabort!("initialization or cleanup bug");
    };
    // Guard against the code called by this function from unwinding outside of the Rust-controlled
    // code, which is UB. This is a requirement imposed by a combination of how the
    // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
    // mechanism itself.
    //
    // There are a couple of instances where unwinding can begin. First is inside of the
    // `rt::init`, `rt::cleanup` and similar functions controlled by libstd. In those instances a
    // panic is a libstd implementation bug. A quite likely one too, as there isn't any way to
    // prevent libstd from accidentally introducing a panic to these functions. Another is from
    // user code from `main` or, more nefariously, as described in e.g. issue #86030.
    // SAFETY: Only called once during runtime initialization.
    panic::catch_unwind(move || unsafe { init(argc, argv) }).map_err(rt_abort)?;
    let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
        .map_err(move |e| {
            mem::forget(e);
            rtabort!("drop of the panic payload panicked");
        });
    panic::catch_unwind(cleanup).map_err(rt_abort)?;
    ret_code
}

#[cfg(not(test))]
#[lang = "start"]
fn lang_start<T: crate::process::Termination + 'static>(
    main: fn() -> T,
    argc: isize,
    argv: *const *const u8,
) -> isize {
    let Ok(v) = lang_start_internal(
        &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
        argc,
        argv,
    );
    v
}
<|endoftext|>