<commit_before>//! A graph-like structure used to represent a set of dependencies and in what
//! order they should be built.
//!
//! This structure is used to store the dependency graph and dynamically update
//! it to figure out when a dependency should be built.
//!
//! Dependencies in this queue are represented as a (node, edge) pair. This is
//! used to model nodes which produce multiple outputs at different times but
//! some nodes may only require one of the outputs and can start before the
//! whole node is finished.

use std::collections::{HashMap, HashSet};
use std::hash::Hash;

#[derive(Debug)]
pub struct DependencyQueue<N: Hash + Eq, E: Hash + Eq, V> {
    /// A list of all known keys to build.
    ///
    /// The value of the hash map is list of dependencies which still need to be
    /// built before the package can be built. Note that the set is dynamically
    /// updated as more dependencies are built.
    dep_map: HashMap<N, (HashSet<(N, E)>, V)>,

    /// A reverse mapping of a package to all packages that depend on that
    /// package.
    ///
    /// This map is statically known and does not get updated throughout the
    /// lifecycle of the DependencyQueue.
    ///
    /// This is sort of like a `HashMap<(N, E), HashSet<N>>` map, but more
    /// easily indexable with just an `N`
    reverse_dep_map: HashMap<N, HashMap<E, HashSet<N>>>,

    /// The total number of packages that are transitively waiting on this package
    priority: HashMap<N, usize>,
}

impl<N: Hash + Eq, E: Hash + Eq, V> Default for DependencyQueue<N, E, V> {
    fn default() -> DependencyQueue<N, E, V> {
        DependencyQueue::new()
    }
}

impl<N: Hash + Eq, E: Hash + Eq, V> DependencyQueue<N, E, V> {
    /// Creates a new dependency queue with 0 packages.
    pub fn new() -> DependencyQueue<N, E, V> {
        DependencyQueue {
            dep_map: HashMap::new(),
            reverse_dep_map: HashMap::new(),
            priority: HashMap::new(),
        }
    }
}

impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
    /// Adds a new ndoe and its dependencies to this queue.
    ///
    /// The `key` specified is a new node in the dependency graph, and the node
    /// depend on all the dependencies iterated by `dependencies`. Each
    /// dependency is a node/edge pair, where edges can be thought of as
    /// productions from nodes (aka if it's just `()` it's just waiting for the
    /// node to finish).
    ///
    /// An optional `value` can also be associated with `key` which is reclaimed
    /// when the node is ready to go.
    pub fn queue(&mut self, key: N, value: V, dependencies: impl IntoIterator<Item = (N, E)>) {
        assert!(!self.dep_map.contains_key(&key));

        let mut my_dependencies = HashSet::new();
        for (dep, edge) in dependencies {
            my_dependencies.insert((dep.clone(), edge.clone()));
            self.reverse_dep_map
                .entry(dep)
                .or_insert_with(HashMap::new)
                .entry(edge)
                .or_insert_with(HashSet::new)
                .insert(key.clone());
        }
        self.dep_map.insert(key, (my_dependencies, value));
    }

    /// All nodes have been added, calculate some internal metadata and prepare
    /// for `dequeue`.
    pub fn queue_finished(&mut self) {
        let mut out = HashMap::new();
        for key in self.dep_map.keys() {
            depth(key, &self.reverse_dep_map, &mut out);
        }
        self.priority = out.into_iter().map(|(n, set)| (n, set.len())).collect();

        fn depth<'a, N: Hash + Eq + Clone, E: Hash + Eq + Clone>(
            key: &N,
            map: &HashMap<N, HashMap<E, HashSet<N>>>,
            results: &'a mut HashMap<N, HashSet<N>>,
        ) -> &'a HashSet<N> {
            if results.contains_key(key) {
                let depth = &results[key];
                assert!(!depth.is_empty(), "cycle in DependencyQueue");
                return depth;
            }
            results.insert(key.clone(), HashSet::new());

            let mut set = HashSet::new();
            set.insert(key.clone());

            for dep in map
                .get(key)
                .into_iter()
                .flat_map(|it| it.values())
                .flatten()
            {
                set.extend(depth(dep, map, results).iter().cloned())
            }

            let slot = results.get_mut(key).unwrap();
            *slot = set;
            &*slot
        }
    }

    /// Dequeues a package that is ready to be built.
    ///
    /// A package is ready to be built when it has 0 un-built dependencies. If
    /// `None` is returned then no packages are ready to be built.
    pub fn dequeue(&mut self) -> Option<(N, V)> {
        // Look at all our crates and find everything that's ready to build (no
        // deps). After we've got that candidate set select the one which has
        // the maximum priority in the dependency graph. This way we should
        // hopefully keep CPUs hottest the longest by ensuring that long
        // dependency chains are scheduled early on in the build process and the
        // leafs higher in the tree can fill in the cracks later.
        //
        // TODO: it'd be best here to throw in a heuristic of crate size as
        //       well. For example how long did this crate historically take to
        //       compile? How large is its source code? etc.
        let next = self
            .dep_map
            .iter()
            .filter(|(_, (deps, _))| deps.is_empty())
            .map(|(key, _)| key.clone())
            .max_by_key(|k| self.priority[k]);
        let key = match next {
            Some(key) => key,
            None => return None,
        };
        let (_, data) = self.dep_map.remove(&key).unwrap();
        Some((key, data))
    }

    /// Returns `true` if there are remaining packages to be built.
    pub fn is_empty(&self) -> bool {
        self.dep_map.is_empty()
    }

    /// Returns the number of remaining packages to be built.
    pub fn len(&self) -> usize {
        self.dep_map.len()
    }

    /// Indicate that something has finished.
    ///
    /// Calling this function indicates that the `node` has produced `edge`. All
    /// remaining work items which only depend on this node/edge pair are now
    /// candidates to start their job.
    ///
    /// Returns the nodes that are now allowed to be dequeued as a result of
    /// finishing this node.
    pub fn finish(&mut self, node: &N, edge: &E) -> Vec<&N> {
        // hashset<Node>
        let reverse_deps = self.reverse_dep_map.get(node).and_then(|map| map.get(edge));
        let reverse_deps = match reverse_deps {
            Some(deps) => deps,
            None => return Vec::new(),
        };
        let key = (node.clone(), edge.clone());
        let mut result = Vec::new();
        for dep in reverse_deps.iter() {
            let edges = &mut self.dep_map.get_mut(dep).unwrap().0;
            assert!(edges.remove(&key));
            if edges.is_empty() {
                result.push(dep);
            }
        }
        result
    }
}

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

    #[test]
    fn deep_first() {
        let mut q = DependencyQueue::new();

        q.queue(1, (), vec![]);
        q.queue(2, (), vec![(1, ())]);
        q.queue(3, (), vec![]);
        q.queue(4, (), vec![(2, ()), (3, ())]);
        q.queue(5, (), vec![(4, ()), (3, ())]);
        q.queue_finished();

        assert_eq!(q.dequeue(), Some((1, ())));
        assert_eq!(q.dequeue(), Some((3, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&3, &());
        assert_eq!(q.dequeue(), None);
        q.finish(&1, &());
        assert_eq!(q.dequeue(), Some((2, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&2, &());
        assert_eq!(q.dequeue(), Some((4, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&4, &());
        assert_eq!(q.dequeue(), Some((5, ())));
    }
}
<commit_msg>Fix a typo<commit_after>//! A graph-like structure used to represent a set of dependencies and in what
//! order they should be built.
//!
//! This structure is used to store the dependency graph and dynamically update
//! it to figure out when a dependency should be built.
//!
//! Dependencies in this queue are represented as a (node, edge) pair. This is
//! used to model nodes which produce multiple outputs at different times but
//! some nodes may only require one of the outputs and can start before the
//! whole node is finished.

use std::collections::{HashMap, HashSet};
use std::hash::Hash;

#[derive(Debug)]
pub struct DependencyQueue<N: Hash + Eq, E: Hash + Eq, V> {
    /// A list of all known keys to build.
    ///
    /// The value of the hash map is list of dependencies which still need to be
    /// built before the package can be built. Note that the set is dynamically
    /// updated as more dependencies are built.
    dep_map: HashMap<N, (HashSet<(N, E)>, V)>,

    /// A reverse mapping of a package to all packages that depend on that
    /// package.
    ///
    /// This map is statically known and does not get updated throughout the
    /// lifecycle of the DependencyQueue.
    ///
    /// This is sort of like a `HashMap<(N, E), HashSet<N>>` map, but more
    /// easily indexable with just an `N`
    reverse_dep_map: HashMap<N, HashMap<E, HashSet<N>>>,

    /// The total number of packages that are transitively waiting on this package
    priority: HashMap<N, usize>,
}

impl<N: Hash + Eq, E: Hash + Eq, V> Default for DependencyQueue<N, E, V> {
    fn default() -> DependencyQueue<N, E, V> {
        DependencyQueue::new()
    }
}

impl<N: Hash + Eq, E: Hash + Eq, V> DependencyQueue<N, E, V> {
    /// Creates a new dependency queue with 0 packages.
    pub fn new() -> DependencyQueue<N, E, V> {
        DependencyQueue {
            dep_map: HashMap::new(),
            reverse_dep_map: HashMap::new(),
            priority: HashMap::new(),
        }
    }
}

impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
    /// Adds a new node and its dependencies to this queue.
    ///
    /// The `key` specified is a new node in the dependency graph, and the node
    /// depend on all the dependencies iterated by `dependencies`. Each
    /// dependency is a node/edge pair, where edges can be thought of as
    /// productions from nodes (aka if it's just `()` it's just waiting for the
    /// node to finish).
    ///
    /// An optional `value` can also be associated with `key` which is reclaimed
    /// when the node is ready to go.
    pub fn queue(&mut self, key: N, value: V, dependencies: impl IntoIterator<Item = (N, E)>) {
        assert!(!self.dep_map.contains_key(&key));

        let mut my_dependencies = HashSet::new();
        for (dep, edge) in dependencies {
            my_dependencies.insert((dep.clone(), edge.clone()));
            self.reverse_dep_map
                .entry(dep)
                .or_insert_with(HashMap::new)
                .entry(edge)
                .or_insert_with(HashSet::new)
                .insert(key.clone());
        }
        self.dep_map.insert(key, (my_dependencies, value));
    }

    /// All nodes have been added, calculate some internal metadata and prepare
    /// for `dequeue`.
    pub fn queue_finished(&mut self) {
        let mut out = HashMap::new();
        for key in self.dep_map.keys() {
            depth(key, &self.reverse_dep_map, &mut out);
        }
        self.priority = out.into_iter().map(|(n, set)| (n, set.len())).collect();

        fn depth<'a, N: Hash + Eq + Clone, E: Hash + Eq + Clone>(
            key: &N,
            map: &HashMap<N, HashMap<E, HashSet<N>>>,
            results: &'a mut HashMap<N, HashSet<N>>,
        ) -> &'a HashSet<N> {
            if results.contains_key(key) {
                let depth = &results[key];
                assert!(!depth.is_empty(), "cycle in DependencyQueue");
                return depth;
            }
            results.insert(key.clone(), HashSet::new());

            let mut set = HashSet::new();
            set.insert(key.clone());

            for dep in map
                .get(key)
                .into_iter()
                .flat_map(|it| it.values())
                .flatten()
            {
                set.extend(depth(dep, map, results).iter().cloned())
            }

            let slot = results.get_mut(key).unwrap();
            *slot = set;
            &*slot
        }
    }

    /// Dequeues a package that is ready to be built.
    ///
    /// A package is ready to be built when it has 0 un-built dependencies. If
    /// `None` is returned then no packages are ready to be built.
    pub fn dequeue(&mut self) -> Option<(N, V)> {
        // Look at all our crates and find everything that's ready to build (no
        // deps). After we've got that candidate set select the one which has
        // the maximum priority in the dependency graph. This way we should
        // hopefully keep CPUs hottest the longest by ensuring that long
        // dependency chains are scheduled early on in the build process and the
        // leafs higher in the tree can fill in the cracks later.
        //
        // TODO: it'd be best here to throw in a heuristic of crate size as
        //       well. For example how long did this crate historically take to
        //       compile? How large is its source code? etc.
        let next = self
            .dep_map
            .iter()
            .filter(|(_, (deps, _))| deps.is_empty())
            .map(|(key, _)| key.clone())
            .max_by_key(|k| self.priority[k]);
        let key = match next {
            Some(key) => key,
            None => return None,
        };
        let (_, data) = self.dep_map.remove(&key).unwrap();
        Some((key, data))
    }

    /// Returns `true` if there are remaining packages to be built.
    pub fn is_empty(&self) -> bool {
        self.dep_map.is_empty()
    }

    /// Returns the number of remaining packages to be built.
    pub fn len(&self) -> usize {
        self.dep_map.len()
    }

    /// Indicate that something has finished.
    ///
    /// Calling this function indicates that the `node` has produced `edge`. All
    /// remaining work items which only depend on this node/edge pair are now
    /// candidates to start their job.
    ///
    /// Returns the nodes that are now allowed to be dequeued as a result of
    /// finishing this node.
    pub fn finish(&mut self, node: &N, edge: &E) -> Vec<&N> {
        // hashset<Node>
        let reverse_deps = self.reverse_dep_map.get(node).and_then(|map| map.get(edge));
        let reverse_deps = match reverse_deps {
            Some(deps) => deps,
            None => return Vec::new(),
        };
        let key = (node.clone(), edge.clone());
        let mut result = Vec::new();
        for dep in reverse_deps.iter() {
            let edges = &mut self.dep_map.get_mut(dep).unwrap().0;
            assert!(edges.remove(&key));
            if edges.is_empty() {
                result.push(dep);
            }
        }
        result
    }
}

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

    #[test]
    fn deep_first() {
        let mut q = DependencyQueue::new();

        q.queue(1, (), vec![]);
        q.queue(2, (), vec![(1, ())]);
        q.queue(3, (), vec![]);
        q.queue(4, (), vec![(2, ()), (3, ())]);
        q.queue(5, (), vec![(4, ()), (3, ())]);
        q.queue_finished();

        assert_eq!(q.dequeue(), Some((1, ())));
        assert_eq!(q.dequeue(), Some((3, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&3, &());
        assert_eq!(q.dequeue(), None);
        q.finish(&1, &());
        assert_eq!(q.dequeue(), Some((2, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&2, &());
        assert_eq!(q.dequeue(), Some((4, ())));
        assert_eq!(q.dequeue(), None);
        q.finish(&4, &());
        assert_eq!(q.dequeue(), Some((5, ())));
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use attribute::{
    Order,
    RowMajor,
    Transpose,
    NoTrans,
};

pub mod ll;
pub mod ops;

pub trait BlasMatrix<T> {
    fn lead_dim(&self) -> i32 { self.rows() }
    fn order(&self) -> Order { RowMajor }
    fn transpose(&self) -> Transpose { NoTrans }
    fn rows(&self) -> i32;
    fn cols(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

pub trait BandMatrix<T>: BlasMatrix<T> {
    fn sub_diagonals(&self) -> i32;
    fn sup_diagonals(&self) -> i32;
}
<commit_msg>Implement BlasMatrix on Mat<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use attribute::{
    Order,
    RowMajor,
    Transpose,
    NoTrans,
};
use mat::Mat;

pub mod ll;
pub mod ops;

pub trait BlasMatrix<T> {
    fn lead_dim(&self) -> i32 { self.rows() }
    fn order(&self) -> Order { RowMajor }
    fn transpose(&self) -> Transpose { NoTrans }
    fn rows(&self) -> i32;
    fn cols(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

pub trait BandMatrix<T>: BlasMatrix<T> {
    fn sub_diagonals(&self) -> i32;
    fn sup_diagonals(&self) -> i32;
}

impl<T> BlasMatrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}
<|endoftext|>


<commit_before>mod prelude {
    pub use conduit::{box_error, header, Body, Handler, RequestExt, Response, StatusCode};
    pub use conduit_middleware::{AfterResult, AroundMiddleware, BeforeResult, Middleware};
}

use self::app::AppMiddleware;
use self::current_user::CaptureUserIdFromCookie;
use self::debug::*;
use self::ember_html::EmberHtml;
use self::head::Head;
use self::log_connection_pool_status::LogConnectionPoolStatus;
use self::static_or_continue::StaticOrContinue;

pub mod app;
mod balance_capacity;
mod block_traffic;
pub mod current_user;
mod debug;
mod ember_html;
mod ensure_well_formed_500;
mod head;
mod log_connection_pool_status;
pub mod log_request;
mod require_user_agent;
mod static_or_continue;

use conduit_conditional_get::ConditionalGet;
use conduit_cookie::{Middleware as Cookie, SessionMiddleware};
use conduit_middleware::MiddlewareBuilder;

use std::env;
use std::sync::Arc;

use crate::router::R404;
use crate::{App, Env};

pub fn build_middleware(app: Arc<App>, endpoints: R404) -> MiddlewareBuilder {
    let mut m = MiddlewareBuilder::new(endpoints);
    let config = app.config.clone();
    let env = config.env;

    if env != Env::Test {
        m.add(ensure_well_formed_500::EnsureWellFormed500);
        m.add(log_request::LogRequests::default());
    }

    if env == Env::Development {
        // Print a log for each request.
        m.add(Debug);
        // Locally serve crates and readmes
        m.around(StaticOrContinue::new("local_uploads"));
    }

    if env::var_os("DEBUG_REQUESTS").is_some() {
        m.add(DebugRequest);
    }

    if env::var_os("LOG_CONNECTION_POOL_STATUS").is_some() {
        m.add(LogConnectionPoolStatus::new(&app));
    }

    m.add(ConditionalGet);

    m.add(Cookie::new());
    m.add(SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));

    m.add(AppMiddleware::new(app));

    // Parse and save the user_id from the session cookie as part of the authentication logic
    m.add(CaptureUserIdFromCookie);

    // Note: The following `m.around()` middleware is run from bottom to top

    // This is currently the final middleware to run. If a middleware layer requires a database
    // connection, it should be run after this middleware so that the potential pool usage can be
    // tracked here.
    //
    // In production we currently have 2 equally sized pools (primary and a read-only replica).
    // Because such a large portion of production traffic is for download requests (which update
    // download counts), we consider only the primary pool here.
    if let Ok(capacity) = env::var("DB_POOL_SIZE") {
        if let Ok(capacity) = capacity.parse() {
            if capacity >= 10 {
                println!(
                    "Enabling BalanceCapacity middleware with {} pool capacity",
                    capacity
                );
                m.around(balance_capacity::BalanceCapacity::new(capacity))
            } else {
                println!("BalanceCapacity middleware not enabled. DB_POOL_SIZE is too low.");
            }
        }
    }

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(EmberHtml::new("dist"));
        m.around(StaticOrContinue::new("dist"));
    }

    m.around(Head::default());

    for (header, blocked_values) in config.blocked_traffic {
        m.around(block_traffic::BlockTraffic::new(header, blocked_values));
    }

    m.around(require_user_agent::RequireUserAgent::default());

    m
}
<commit_msg>Fix serving `local_uploads` during development<commit_after>mod prelude {
    pub use conduit::{box_error, header, Body, Handler, RequestExt, Response, StatusCode};
    pub use conduit_middleware::{AfterResult, AroundMiddleware, BeforeResult, Middleware};
}

use self::app::AppMiddleware;
use self::current_user::CaptureUserIdFromCookie;
use self::debug::*;
use self::ember_html::EmberHtml;
use self::head::Head;
use self::log_connection_pool_status::LogConnectionPoolStatus;
use self::static_or_continue::StaticOrContinue;

pub mod app;
mod balance_capacity;
mod block_traffic;
pub mod current_user;
mod debug;
mod ember_html;
mod ensure_well_formed_500;
mod head;
mod log_connection_pool_status;
pub mod log_request;
mod require_user_agent;
mod static_or_continue;

use conduit_conditional_get::ConditionalGet;
use conduit_cookie::{Middleware as Cookie, SessionMiddleware};
use conduit_middleware::MiddlewareBuilder;

use std::env;
use std::sync::Arc;

use crate::router::R404;
use crate::{App, Env};

pub fn build_middleware(app: Arc<App>, endpoints: R404) -> MiddlewareBuilder {
    let mut m = MiddlewareBuilder::new(endpoints);
    let config = app.config.clone();
    let env = config.env;

    if env != Env::Test {
        m.add(ensure_well_formed_500::EnsureWellFormed500);
        m.add(log_request::LogRequests::default());
    }

    if env == Env::Development {
        // Print a log for each request.
        m.add(Debug);
    }

    if env::var_os("DEBUG_REQUESTS").is_some() {
        m.add(DebugRequest);
    }

    if env::var_os("LOG_CONNECTION_POOL_STATUS").is_some() {
        m.add(LogConnectionPoolStatus::new(&app));
    }

    m.add(ConditionalGet);

    m.add(Cookie::new());
    m.add(SessionMiddleware::new(
        "cargo_session",
        cookie::Key::from_master(app.session_key.as_bytes()),
        env == Env::Production,
    ));

    m.add(AppMiddleware::new(app));

    // Parse and save the user_id from the session cookie as part of the authentication logic
    m.add(CaptureUserIdFromCookie);

    // Note: The following `m.around()` middleware is run from bottom to top

    // This is currently the final middleware to run. If a middleware layer requires a database
    // connection, it should be run after this middleware so that the potential pool usage can be
    // tracked here.
    //
    // In production we currently have 2 equally sized pools (primary and a read-only replica).
    // Because such a large portion of production traffic is for download requests (which update
    // download counts), we consider only the primary pool here.
    if let Ok(capacity) = env::var("DB_POOL_SIZE") {
        if let Ok(capacity) = capacity.parse() {
            if capacity >= 10 {
                println!(
                    "Enabling BalanceCapacity middleware with {} pool capacity",
                    capacity
                );
                m.around(balance_capacity::BalanceCapacity::new(capacity))
            } else {
                println!("BalanceCapacity middleware not enabled. DB_POOL_SIZE is too low.");
            }
        }
    }

    // Serve the static files in the *dist* directory, which are the frontend assets.
    // Not needed for the backend tests.
    if env != Env::Test {
        m.around(EmberHtml::new("dist"));
        m.around(StaticOrContinue::new("dist"));
    }

    if env == Env::Development {
        // Locally serve crates and readmes
        m.around(StaticOrContinue::new("local_uploads"));
    }

    m.around(Head::default());

    for (header, blocked_values) in config.blocked_traffic {
        m.around(block_traffic::BlockTraffic::new(header, blocked_values));
    }

    m.around(require_user_agent::RequireUserAgent::default());

    m
}
<|endoftext|>


<commit_before>//! Cranelift IR builder library.
//!
//! Provides a straightforward way to create a Cranelift IR function and fill it with instructions
//! corresponding to your source program written in another language.
//!
//! To get started, create an [`FunctionBuilderContext`](struct.FunctionBuilderContext.html) and
//! pass it as an argument to a [`FunctionBuilder`](struct.FunctionBuilder.html).
//!
//! # Source Language Variables and Cranelift IR values
//!
//! The most interesting feature of this API is that it provides a single way to deal with all your
//! variable problems. Indeed, the [`FunctionBuilder`](struct.FunctionBuilder.html) struct has a
//! type parameter `Variable` that should be instantiated with the type of your Source Language
//! Variables (SLV). Then, through calling the functions
//! [`declare_var`](struct.FunctionBuilder.html#method.declare_var),
//! [`def_var`](struct.FunctionBuilder.html#method.def_var) and
//! [`use_var`](struct.FunctionBuilder.html#method.use_var), the
//! [`FunctionBuilder`](struct.FunctionBuilder.html) will create for you all the Cranelift IR
//! values corresponding to your SLVs.
//!
//! If a SLV is immutable (defined only once), then it will get mapped to one and only Cranelift IR
//! value. If a SLV is mutable ([`def_var`](struct.FunctionBuilder.html#method.def_var) multiple
//! times), then internally a [`SSA`](https://en.wikipedia.org/wiki/Static_single_assignment_form)
//! construction algorithm will automatically create multiple Cranelift IR values that will be
//! returned to you by [`use_var`](struct.FunctionBuilder.html#method.use_var) depending on where
//! you want to use your SLV.
//!
//! The morality is that you should use these three functions to handle all your SLVs, even those
//! that are not present in the source code but artefacts of the translation. For instance, if your
//! source language is expression-based, then you will need to introduce artifical SLVs to store
//! intermediate results of the computation of your expressions. Hence The `Variable` type that you
//! would pass to [`FunctionBuilder`](struct.FunctionBuilder.html) could look like this
//!
//! ```
//! enum Variable {
//!     OriginalSourceVariable(String),
//!     IntermediateExpressionVariable(u32)
//! }
//! ```
//!
//! # Example
//!
//! Here is a pseudo-program we want to transform into Cranelift IR:
//!
//! ```clif
//! function(x) {
//! x, y, z : i32
//! block0:
//!    y = 2;
//!    z = x + y;
//!    jump block1
//! block1:
//!    z = z + y;
//!    brnz y, block2;
//!    z = z - x;
//!    return y
//! block2:
//!    y = y - x
//!    jump block1
//! }
//! ```
//!
//! Here is how you build the corresponding Cranelift IR function using `FunctionBuilderContext`:
//!
//! ```rust
//! extern crate cranelift_codegen;
//! extern crate cranelift_frontend;
//!
//! use cranelift_codegen::entity::EntityRef;
//! use cranelift_codegen::ir::{ExternalName, Function, Signature, AbiParam, InstBuilder};
//! use cranelift_codegen::ir::types::*;
//! use cranelift_codegen::settings::{self, CallConv};
//! use cranelift_frontend::{FunctionBuilderContext, FunctionBuilder, Variable};
//! use cranelift_codegen::verifier::verify_function;
//!
//! fn main() {
//!     let mut sig = Signature::new(CallConv::SystemV);
//!     sig.returns.push(AbiParam::new(I32));
//!     sig.params.push(AbiParam::new(I32));
//!     let mut fn_builder_ctx = FunctionBuilderContext::<Variable>::new();
//!     let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
//!     {
//!         let mut builder = FunctionBuilder::<Variable>::new(&mut func, &mut fn_builder_ctx);
//!
//!         let block0 = builder.create_ebb();
//!         let block1 = builder.create_ebb();
//!         let block2 = builder.create_ebb();
//!         let x = Variable::new(0);
//!         let y = Variable::new(1);
//!         let z = Variable::new(2);
//!         builder.declare_var(x, I32);
//!         builder.declare_var(y, I32);
//!         builder.declare_var(z, I32);
//!         builder.append_ebb_params_for_function_params(block0);
//!
//!         builder.switch_to_block(block0);
//!         builder.seal_block(block0);
//!         {
//!             let tmp = builder.ebb_params(block0)[0]; // the first function parameter
//!             builder.def_var(x, tmp);
//!         }
//!         {
//!             let tmp = builder.ins().iconst(I32, 2);
//!             builder.def_var(y, tmp);
//!         }
//!         {
//!             let arg1 = builder.use_var(x);
//!             let arg2 = builder.use_var(y);
//!             let tmp = builder.ins().iadd(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         builder.ins().jump(block1, &[]);
//!
//!         builder.switch_to_block(block1);
//!         {
//!             let arg1 = builder.use_var(y);
//!             let arg2 = builder.use_var(z);
//!             let tmp = builder.ins().iadd(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         {
//!             let arg = builder.use_var(y);
//!             builder.ins().brnz(arg, block2, &[]);
//!         }
//!         {
//!             let arg1 = builder.use_var(z);
//!             let arg2 = builder.use_var(x);
//!             let tmp = builder.ins().isub(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         {
//!             let arg = builder.use_var(y);
//!             builder.ins().return_(&[arg]);
//!         }
//!
//!         builder.switch_to_block(block2);
//!         builder.seal_block(block2);
//!
//!         {
//!             let arg1 = builder.use_var(y);
//!             let arg2 = builder.use_var(x);
//!             let tmp = builder.ins().isub(arg1, arg2);
//!             builder.def_var(y, tmp);
//!         }
//!         builder.ins().jump(block1, &[]);
//!         builder.seal_block(block1);
//!
//!         builder.finalize();
//!     }
//!
//!     let flags = settings::Flags::new(settings::builder());
//!     let res = verify_function(&func, &flags);
//!     println!("{}", func.display(None));
//!     if let Err(errors) = res {
//!         panic!("{}", errors);
//!     }
//! }
//! ```

#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
#![warn(unused_import_braces)]
#![cfg_attr(feature = "std", deny(unstable_features))]
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default))]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, option_map_unwrap_or_else,
        print_stdout, unicode_not_nfc, use_self
    )
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]

extern crate cranelift_codegen;

pub use frontend::{FunctionBuilder, FunctionBuilderContext};
pub use variable::Variable;

mod frontend;
mod ssa;
mod variable;

#[cfg(not(feature = "std"))]
mod std {
    extern crate alloc;

    pub use self::alloc::vec;
    pub use core::*;
}
<commit_msg>Rewrote doc with @sunfishcode's comments in mind<commit_after>//! Cranelift IR builder library.
//!
//! Provides a straightforward way to create a Cranelift IR function and fill it with instructions
//! corresponding to your source program written in another language.
//!
//! To get started, create an [`FunctionBuilderContext`](struct.FunctionBuilderContext.html) and
//! pass it as an argument to a [`FunctionBuilder`](struct.FunctionBuilder.html).
//!
//! # Mutable variables and Cranelift IR values
//!
//! The most interesting feature of this API is that it provides a single way to deal with all your
//! variable problems. Indeed, the [`FunctionBuilder`](struct.FunctionBuilder.html) struct has a
//! type parameter `Variable` that should be instantiated with the type of your source language
//! variables. Then, through calling the functions
//! [`declare_var`](struct.FunctionBuilder.html#method.declare_var),
//! [`def_var`](struct.FunctionBuilder.html#method.def_var) and
//! [`use_var`](struct.FunctionBuilder.html#method.use_var), the
//! [`FunctionBuilder`](struct.FunctionBuilder.html) will create for you all the Cranelift IR
//! values corresponding to your variables.
//!
//! This API has been designed to help you translate your mutable variables into
//! [`SSA`](https://en.wikipedia.org/wiki/Static_single_assignment_form) form.
//! [`use_var`](struct.FunctionBuilder.html#method.use_var) will returns the Cranelift IR value
//! that corresponds to your mutable variable at a precise point in the program. However, you know
//! beforehand that one of your variables is defined only once, for instance if it is the result
//! of an intermediate expression in an expression-based language, then you can translate it
//! directly by the Cranelift IR value returned by the instruction builder. Using the
//! [`use_var`](struct.FunctionBuilder.html#method.use_var) API for such an immutable variable
//! would also work but with a slight additional overhead (the SSA algorithm does not know
//! beforehand if a variable is immutable or not).
//!
//!
//! The moral is that you should use these three functions to handle all your mutable variables, even those
//! that are not present in the source code but artefacts of the translation. Hence The `Variable` type that you
//! would pass to [`FunctionBuilder`](struct.FunctionBuilder.html) could look like this
//!
//! ```
//! enum Variable {
//!     OriginalSourceVariable(String),
//!     TranslationArtefact(u32)
//! }
//! ```
//!
//! # Example
//!
//! Here is a pseudo-program we want to transform into Cranelift IR:
//!
//! ```clif
//! function(x) {
//! x, y, z : i32
//! block0:
//!    y = 2;
//!    z = x + y;
//!    jump block1
//! block1:
//!    z = z + y;
//!    brnz y, block2;
//!    z = z - x;
//!    return y
//! block2:
//!    y = y - x
//!    jump block1
//! }
//! ```
//!
//! Here is how you build the corresponding Cranelift IR function using `FunctionBuilderContext`:
//!
//! ```rust
//! extern crate cranelift_codegen;
//! extern crate cranelift_frontend;
//!
//! use cranelift_codegen::entity::EntityRef;
//! use cranelift_codegen::ir::{ExternalName, Function, Signature, AbiParam, InstBuilder};
//! use cranelift_codegen::ir::types::*;
//! use cranelift_codegen::settings::{self, CallConv};
//! use cranelift_frontend::{FunctionBuilderContext, FunctionBuilder, Variable};
//! use cranelift_codegen::verifier::verify_function;
//!
//! fn main() {
//!     let mut sig = Signature::new(CallConv::SystemV);
//!     sig.returns.push(AbiParam::new(I32));
//!     sig.params.push(AbiParam::new(I32));
//!     let mut fn_builder_ctx = FunctionBuilderContext::<Variable>::new();
//!     let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
//!     {
//!         let mut builder = FunctionBuilder::<Variable>::new(&mut func, &mut fn_builder_ctx);
//!
//!         let block0 = builder.create_ebb();
//!         let block1 = builder.create_ebb();
//!         let block2 = builder.create_ebb();
//!         let x = Variable::new(0);
//!         let y = Variable::new(1);
//!         let z = Variable::new(2);
//!         builder.declare_var(x, I32);
//!         builder.declare_var(y, I32);
//!         builder.declare_var(z, I32);
//!         builder.append_ebb_params_for_function_params(block0);
//!
//!         builder.switch_to_block(block0);
//!         builder.seal_block(block0);
//!         {
//!             let tmp = builder.ebb_params(block0)[0]; // the first function parameter
//!             builder.def_var(x, tmp);
//!         }
//!         {
//!             let tmp = builder.ins().iconst(I32, 2);
//!             builder.def_var(y, tmp);
//!         }
//!         {
//!             let arg1 = builder.use_var(x);
//!             let arg2 = builder.use_var(y);
//!             let tmp = builder.ins().iadd(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         builder.ins().jump(block1, &[]);
//!
//!         builder.switch_to_block(block1);
//!         {
//!             let arg1 = builder.use_var(y);
//!             let arg2 = builder.use_var(z);
//!             let tmp = builder.ins().iadd(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         {
//!             let arg = builder.use_var(y);
//!             builder.ins().brnz(arg, block2, &[]);
//!         }
//!         {
//!             let arg1 = builder.use_var(z);
//!             let arg2 = builder.use_var(x);
//!             let tmp = builder.ins().isub(arg1, arg2);
//!             builder.def_var(z, tmp);
//!         }
//!         {
//!             let arg = builder.use_var(y);
//!             builder.ins().return_(&[arg]);
//!         }
//!
//!         builder.switch_to_block(block2);
//!         builder.seal_block(block2);
//!
//!         {
//!             let arg1 = builder.use_var(y);
//!             let arg2 = builder.use_var(x);
//!             let tmp = builder.ins().isub(arg1, arg2);
//!             builder.def_var(y, tmp);
//!         }
//!         builder.ins().jump(block1, &[]);
//!         builder.seal_block(block1);
//!
//!         builder.finalize();
//!     }
//!
//!     let flags = settings::Flags::new(settings::builder());
//!     let res = verify_function(&func, &flags);
//!     println!("{}", func.display(None));
//!     if let Err(errors) = res {
//!         panic!("{}", errors);
//!     }
//! }
//! ```

#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
#![warn(unused_import_braces)]
#![cfg_attr(feature = "std", deny(unstable_features))]
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default))]
#![cfg_attr(
    feature = "cargo-clippy",
    warn(
        float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, option_map_unwrap_or_else,
        print_stdout, unicode_not_nfc, use_self
    )
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]

extern crate cranelift_codegen;

pub use frontend::{FunctionBuilder, FunctionBuilderContext};
pub use variable::Variable;

mod frontend;
mod ssa;
mod variable;

#[cfg(not(feature = "std"))]
mod std {
    extern crate alloc;

    pub use self::alloc::vec;
    pub use core::*;
}
<|endoftext|>


<commit_before>use std::fmt;

#[derive(Debug)]
struct Structure(i32);

#[derive(Debug)]
struct Deep(Structure);

impl fmt::Display for Structure {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

// A structure holding 2 numbers `Debug` will be derived so the results can be contrasted with `Display`
#[derive(Debug)]
struct MinMax(i64, i64);

impl fmt::Display for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.0, self.1)
    }
}

// Define a structure where the fields are nameable for comparison.
#[derive(Debug)]
struct Point2 {
    x: f64,
    y: f64,
}

// Similarly, implement for Point2
impl fmt::Display for Point2 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Customize so only `x` and `y` are denoted.
        write!(f, "{{ x: {}, y: {} }}", self.x, self.y)
    }
}

// My Complex structure
struct Complex {
    real: f64,
    imag: f64,
}

impl fmt::Display for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{real} + {imag}i", real=self.real, imag=self.imag)
    }
}

impl fmt::Debug for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Complex {{ real: {real}, imag: {imag} }}", real=self.real, imag=self.imag)
    }
}

fn main() {
    println!("Hello, formatted print!");

    println!("Arg 1:{} and arg 2:{}", "first", "second");

    println!("Args can be named: {first} and {second}", first=1, second="two");

    println!("We can fmt binary! {:b}", 5);

    println!("We can align text with spaces or zeros: {number:>width$}, {number:>0width$}",
             number=3,
             width=6);

    let pi: f32 = 3.14159;

    let pi_3 = format!("{:.3}", pi);
    let pi_5 = format!("{:.5}", pi);

    println!("Pi to 3 places: {} and to 5 places: {}", pi_3, pi_5);

    // e, pi, & golden ratio
    let special_nums = vec![2.71828, 3.14159, 1.61803];

    // some iteration over a vector.
    for special_num in &special_nums {
        println!("This is a special number: {val:.3}", val=special_num);
    }

    println!("\nDebugging stuff:");

    println!("Now {:?} is a thing!", Structure(3));

    println!("And Deep: {:?}", Deep(Structure(3)));

    println!("A MinMax: debug: {obj:?}  display: {obj}", obj=MinMax(23, 56));
    println!("A Point : debug: {obj:?}  display: {obj}", obj=Point2 { x: 3.3, y: 56. });
    println!("My Complex struct: {0}  Debugged: {0:?}", Complex { real: 4.6, imag: 8.9 });
}
<commit_msg>RBE 1.2.2.1 Testcase: List<commit_after>use std::fmt;

#[derive(Debug)]
struct Structure(i32);

#[derive(Debug)]
struct Deep(Structure);

impl fmt::Display for Structure {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

// A structure holding 2 numbers `Debug` will be derived so the results can be contrasted with `Display`
#[derive(Debug)]
struct MinMax(i64, i64);

impl fmt::Display for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.0, self.1)
    }
}

// Define a structure where the fields are nameable for comparison.
#[derive(Debug)]
struct Point2 {
    x: f64,
    y: f64,
}

// Similarly, implement for Point2
impl fmt::Display for Point2 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Customize so only `x` and `y` are denoted.
        write!(f, "{{ x: {}, y: {} }}", self.x, self.y)
    }
}

// My Complex structure
struct Complex {
    real: f64,
    imag: f64,
}

impl fmt::Display for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{real} + {imag}i", real=self.real, imag=self.imag)
    }
}

impl fmt::Debug for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Complex {{ real: {real}, imag: {imag} }}", real=self.real, imag=self.imag)
    }
}

// Define a structure named `List` containing a `Vec`.
struct List(Vec<i32>);

impl fmt::Display for List {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Dereference `self` and create a reference to `vec`
        // via destructuring.
        let List(ref vec) = *self;

        try!(write!(f, "["));

        // Iterate over `vec` in `v` while enumerating the iteration
        // count in `count`.
        for (count, v) in vec.iter().enumerate() {
            // For every element except the first, add a comma
            // before calling `write!`. Use `try!` to return on errors.
            if count != 0 { try!(write!(f, ", ")); }
            try!(write!(f, "{i}: {val}", i=count, val=v));
        }

        // Close the opened bracket and return a fmt::Result value
        write!(f, "]")
    }
}

fn main() {
    println!("Hello, formatted print!");

    println!("Arg 1:{} and arg 2:{}", "first", "second");

    println!("Args can be named: {first} and {second}", first=1, second="two");

    println!("We can fmt binary! {:b}", 5);

    println!("We can align text with spaces or zeros: {number:>width$}, {number:>0width$}",
             number=3,
             width=6);

    let pi: f32 = 3.14159;

    let pi_3 = format!("{:.3}", pi);
    let pi_5 = format!("{:.5}", pi);

    println!("Pi to 3 places: {} and to 5 places: {}", pi_3, pi_5);

    // e, pi, & golden ratio
    let special_nums = vec![2.71828, 3.14159, 1.61803];

    // some iteration over a vector.
    for special_num in &special_nums {
        println!("This is a special number: {val:.3}", val=special_num);
    }

    println!("\nDebugging stuff:");

    println!("Now {:?} is a thing!", Structure(3));

    println!("And Deep: {:?}", Deep(Structure(3)));

    println!("A MinMax: debug: {obj:?}  display: {obj}", obj=MinMax(23, 56));
    println!("A Point : debug: {obj:?}  display: {obj}", obj=Point2 { x: 3.3, y: 56. });
    println!("My Complex struct: {0}  Debugged: {0:?}", Complex { real: 4.6, imag: 8.9 });

    println!("My List: {}", List(vec![2, 4, 6, 8, 10]));
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// 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.

//! [`Uuid`] parsing constructs and utilities.
//!
//! [`Uuid`]: ../struct.Uuid.html

mod core_support;
#[cfg(feature = "std")]
mod std_support;

/// The expected value.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Expected {
    /// Expected any one of the given values.
    Any(&'static [usize]),
    /// Expected the given value.
    Exact(usize),
    /// Expected any values in the given range.
    Range {
        /// The minimum expected value.
        min: usize,
        /// The maximum expected value.
        max: usize,
    },
}

/// An error that can occur while parsing a [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum ParseError {
    /// Invalid character in the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidCharacter {
        /// The expected characters.
        expected: &'static str,
        /// The invalid character found.
        found: char,
        /// The invalid character position.
        index: usize,
    },
    /// Invalid number of segments in the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidGroupCount {
        /// The expected number of segments.
        // TODO: explain multiple segment count.
        // BODY: Parsers can expect a range of Uuid segment count.
        //       This needs to be expanded on.
        expected: Expected,
        /// The number of segments found.
        found: usize,
    },
    /// Invalid length of a segment in a [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidGroupLength {
        /// The expected length of the segment.
        expected: Expected,
        /// The length of segment found.
        found: usize,
        /// The segment with invalid length.
        group: usize,
    },
    /// Invalid length of the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidLength {
        /// The expected length(s).
        // TODO: explain multiple lengths.
        // BODY: Parsers can expect a range of Uuid lenghts.
        //       This needs to be expanded on.
        expected: Expected,
        /// The invalid length found.
        found: usize,
    },
}

impl ParseError {
    fn _description(&self) -> &str {
        match *self {
            ParseError::InvalidCharacter { .. } => "invalid character",
            ParseError::InvalidGroupCount { .. } => "invalid number of groups",
            ParseError::InvalidGroupLength { .. } => "invalid group length",
            ParseError::InvalidLength { .. } => "invalid length",
        }
    }
}

/// Check if the length matches any of the given criteria lengths.
pub(crate) fn len_matches_any(len: usize, crits: &[usize]) -> bool {
    for crit in crits {
        if len == *crit {
            return true;
        }
    }

    false
}

/// Check if the length matches any criteria lengths in the given range
/// (inclusive).
pub(crate) fn len_matches_range(len: usize, min: usize, max: usize) -> bool {
    for crit in min..(max + 1) {
        if len == crit {
            return true;
        }
    }

    false
}

// Accumulated length of each hyphenated group in hex digits.
pub(crate) const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32];

// Length of each hyphenated group in hex digits.
pub(crate) const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];
<commit_msg>lint unused function<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// 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.

//! [`Uuid`] parsing constructs and utilities.
//!
//! [`Uuid`]: ../struct.Uuid.html

mod core_support;
#[cfg(feature = "std")]
mod std_support;

/// The expected value.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Expected {
    /// Expected any one of the given values.
    Any(&'static [usize]),
    /// Expected the given value.
    Exact(usize),
    /// Expected any values in the given range.
    Range {
        /// The minimum expected value.
        min: usize,
        /// The maximum expected value.
        max: usize,
    },
}

/// An error that can occur while parsing a [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum ParseError {
    /// Invalid character in the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidCharacter {
        /// The expected characters.
        expected: &'static str,
        /// The invalid character found.
        found: char,
        /// The invalid character position.
        index: usize,
    },
    /// Invalid number of segments in the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidGroupCount {
        /// The expected number of segments.
        // TODO: explain multiple segment count.
        // BODY: Parsers can expect a range of Uuid segment count.
        //       This needs to be expanded on.
        expected: Expected,
        /// The number of segments found.
        found: usize,
    },
    /// Invalid length of a segment in a [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidGroupLength {
        /// The expected length of the segment.
        expected: Expected,
        /// The length of segment found.
        found: usize,
        /// The segment with invalid length.
        group: usize,
    },
    /// Invalid length of the [`Uuid`] string.
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    InvalidLength {
        /// The expected length(s).
        // TODO: explain multiple lengths.
        // BODY: Parsers can expect a range of Uuid lenghts.
        //       This needs to be expanded on.
        expected: Expected,
        /// The invalid length found.
        found: usize,
    },
}

impl ParseError {
    fn _description(&self) -> &str {
        match *self {
            ParseError::InvalidCharacter { .. } => "invalid character",
            ParseError::InvalidGroupCount { .. } => "invalid number of groups",
            ParseError::InvalidGroupLength { .. } => "invalid group length",
            ParseError::InvalidLength { .. } => "invalid length",
        }
    }
}

/// Check if the length matches any of the given criteria lengths.
pub(crate) fn len_matches_any(len: usize, crits: &[usize]) -> bool {
    for crit in crits {
        if len == *crit {
            return true;
        }
    }

    false
}

/// Check if the length matches any criteria lengths in the given range
/// (inclusive).
#[allow(dead_code)]
pub(crate) fn len_matches_range(len: usize, min: usize, max: usize) -> bool {
    for crit in min..(max + 1) {
        if len == crit {
            return true;
        }
    }

    false
}

// Accumulated length of each hyphenated group in hex digits.
pub(crate) const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32];

// Length of each hyphenated group in hex digits.
pub(crate) const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];
<|endoftext|>


<commit_before>use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

use world::World;

static OFFSET: u32 = 10;
static MAX_FPS: u64 = 30;

struct App {
    gl: GlGraphics, // OpenGL drawing backend.
    cell_size: u32,
    world: World
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const BG_GOLOR: [f32; 4] = [0.150, 0.164, 0.176, 1.0];
        const CELL_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];

        let cells = self.world.generation();
        let cell_size = self.cell_size as f64;
        let offset = OFFSET as f64 * cell_size;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(BG_GOLOR, gl);

            for cell in cells {
                let (x, y) = *cell;
                Rectangle::new(CELL_COLOR)
                .draw(
                    [(x as f64 * cell_size) + offset, (y as f64 * cell_size) + offset, cell_size, cell_size],
                    &c.draw_state,
                    c.transform,
                    gl)}
        });
    }

    fn update(&mut self, _: &UpdateArgs) {
        self.world.evolve();
    }
}

pub fn start_piston_app(world: World, period: u64, cell_size: u32, gl_version: u32) {
    let opengl = match gl_version {
        30 => OpenGL::_3_0,
        _ => OpenGL::_3_2
    };
    let (width, height) = world.size();
    let window = Window::new(
        opengl,
        WindowSettings::new(
            "G-O-L-R",
            [width as u32 * cell_size + 2 * OFFSET, height as u32 * cell_size + 2 * OFFSET]
        )
        .exit_on_esc(true)
    );

    let mut app = App {
        gl: GlGraphics::new(opengl),
        cell_size: cell_size,
        world: world
    };

    let ups = 1000/period;

    for e in window.events().max_fps(MAX_FPS).ups(ups) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }

        if let Some(u) = e.update_args() {
            app.update(&u);
        }
    }
}
<commit_msg>micro win fix<commit_after>use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

use world::World;

static OFFSET: u32 = 10;
static MAX_FPS: u64 = 30;

struct App {
    gl: GlGraphics, // OpenGL drawing backend.
    cell_size: u32,
    world: World
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const BG_GOLOR: [f32; 4] = [0.150, 0.164, 0.176, 1.0];
        const CELL_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];

        let cells = self.world.generation();
        let cell_size = self.cell_size as f64;
        let offset = OFFSET as f64 * cell_size;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(BG_GOLOR, gl);

            for cell in cells {
                let (x, y) = *cell;
                Rectangle::new(CELL_COLOR)
                .draw(
                    [(x as f64 * cell_size) + offset, (y as f64 * cell_size) + offset, cell_size, cell_size],
                    &c.draw_state,
                    c.transform,
                    gl)}
        });
    }

    fn update(&mut self, _: &UpdateArgs) {
        self.world.evolve();
    }
}

pub fn start_piston_app(world: World, period: u64, cell_size: u32, gl_version: u32) {
    let opengl = match gl_version {
        30 => OpenGL::_3_0,
        _ => OpenGL::_3_2
    };
    let (width, height) = world.size();
    let window = Window::new(
        opengl,
        WindowSettings::new(
            "G-O-L-R",
            [width as u32 * cell_size + 4 * OFFSET,
             height as u32 * cell_size + 4 * OFFSET]
        )
        .exit_on_esc(true)
    );

    let mut app = App {
        gl: GlGraphics::new(opengl),
        cell_size: cell_size,
        world: world
    };

    let ups = 1000/period;

    for e in window.events().max_fps(MAX_FPS).ups(ups) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }

        if let Some(u) = e.update_args() {
            app.update(&u);
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::{Arc, RwLock};
use subject::{self, Subject, Source, Mapper, Receiver, WrapListener};

pub trait HasSource {
    type Source: Subject;

    fn source(&self) -> &Arc<RwLock<Self::Source>>;
}

pub trait Event: HasSource {
    fn map(&self, f: F) -> Map
        where B: Send + Sync + Clone,
              F: Fn(A) -> B + Send + Sync,
    {
        Map::new(&mut *self.source().write().unwrap(), f)
    }

    fn filter<F>(&self, f: F) -> Filter
        where F: Fn(&A) -> bool + Send + Sync,
    {
        Filter::new(&mut *self.source().write().unwrap(), f)
    }

    fn merge<E: Event>(&self, other: &E) -> Merge {
        Merge::new(
            &mut *self.source().write().unwrap(),
            &mut *other.source().write().unwrap(),
        )
    }

    fn iter(&self) -> Iter {
        Iter::new(&mut *self.source().write().unwrap())
    }
}

impl<A: Send + Sync + Clone, T: HasSource> Event for T {}

pub struct Sink {
    source: Arc<RwLock<Source>>,
}

impl Sink {
    pub fn new() -> Sink {
        Sink { source: Arc::new(RwLock::new(Source::new())) }
    }
}

impl Sink {
    pub fn send(&self, a: A) {
        self.source.write().unwrap().send(a);
    }
}

impl HasSource for Sink {
    type Source = subject::Source;

    fn source(&self) -> &Arc<RwLock<subject::Source>> {
        &self.source
    }
}

pub struct Map {
    mapper: Arc<RwLock<Mapper>>,
}

impl Map
    where A: Send + Sync + Clone,
          B: Send + Sync + Clone,
          F: Fn(A) -> B + Send + Sync,
{
    fn new<S: Subject>(sub: &mut S, f: F) -> Map {
        let map = Map { mapper: Arc::new(RwLock::new(Mapper::new(f))) };
        sub.listen(map.mapper.wrap());
        map
    }
}

impl HasSource for Map
    where A: Send + Sync + Clone,
          B: Send + Sync + Clone,
          F: Fn(A) -> B + Send + Sync,
{
    type Source = Mapper;

    fn source(&self) -> &Arc<RwLock<Mapper>> {
        &self.mapper
    }
}

pub struct Filter {
    filter: Arc<RwLock<subject::Filter>>,
}

impl Filter
    where A: Send + Sync + Clone,
          F: Fn(&A) -> bool + Send + Sync,
{
    fn new<S: Subject>(sub: &mut S, f: F) -> Filter {
        let filter = Filter {
            filter: Arc::new(RwLock::new(subject::Filter::new(f)))
        };
        sub.listen(filter.filter.wrap());
        filter
    }
}

impl HasSource for Filter
    where A: Send + Sync + Clone,
          F: Fn(&A) -> bool + Send + Sync,
{
    type Source = subject::Filter;

    fn source(&self) -> &Arc<RwLock<subject::Filter>> {
        &self.filter
    }
}

pub struct Merge {
    source: Arc<RwLock<Source>>,
}

impl Merge
    where A: Send + Sync + Clone,
{
    fn new<S1: Subject, S2: Subject>(sub1: &mut S1, sub2: &mut S2) -> Merge {
        let merge = Merge {
            source: Arc::new(RwLock::new(Source::new()))
        };
        sub1.listen(merge.source.wrap());
        sub2.listen(merge.source.wrap());
        merge
    }
}

impl HasSource for Merge
    where A: Send + Sync + Clone,
{
    type Source = Source;

    fn source(&self) -> &Arc<RwLock<Source>> {
        &self.source
    }
}

pub struct Iter {
    recv: Arc<RwLock<Receiver>>,
}

impl Iter {
    fn new<S: Subject>(sub: &mut S) -> Iter {
        let iter = Iter { recv: Arc::new(RwLock::new(Receiver::new())) };
        sub.listen(iter.recv.wrap());
        iter
    }
}

impl Iterator for Iter {
    type Item = A;
    fn next(&mut self) -> Option {
        self.recv.write().unwrap().next()
    }
}

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

    #[test]
    fn sink() {
        let sink = Sink::new();
        let mut iter = sink.iter();
        sink.send(1);
        sink.send(2);
        assert_eq!(iter.next(), Some(1));
        assert_eq!(iter.next(), Some(2));
    }

    #[test]
    fn map() {
        let sink = Sink::new();
        let triple = sink.map(|x| 3 * x);
        let mut iter = triple.iter();
        sink.send(1);
        assert_eq!(iter.next(), Some(3));
    }

    #[test]
    fn filter() {
        let sink = Sink::new();
        let small = sink.filter(|&x: &i32| x < 11);
        let mut iter = small.iter();
        sink.send(12);
        sink.send(9);
        assert_eq!(iter.next(), Some(9));
    }

    #[test]
    fn merge() {
        let sink1 = Sink::new();
        let sink2 = Sink::new();
        let merge = sink1.merge(&sink2);
        let mut iter = merge.iter();
        sink1.send(12);
        sink2.send(9);
        assert_eq!(iter.next(), Some(12));
        assert_eq!(iter.next(), Some(9));
    }
}
<commit_msg>Change event adaptor constructor semantics<commit_after>use std::sync::{Arc, RwLock};
use subject::{self, Subject, Source, Mapper, Receiver, WrapListener};

pub trait HasSource {
    type Source: Subject;

    fn source(&self) -> &Arc<RwLock<Self::Source>>;
}

pub trait Event: HasSource + Sized {
    fn map(&self, f: F) -> Map
        where B: Send + Sync + Clone,
              F: Fn(A) -> B + Send + Sync,
    {
        Map::new(self, f)
    }

    fn filter<F>(&self, f: F) -> Filter
        where F: Fn(&A) -> bool + Send + Sync,
    {
        Filter::new(self, f)
    }

    fn merge<E: Event>(&self, other: &E) -> Merge {
        Merge::new(self, other)
    }

    fn iter(&self) -> Iter {
        Iter::new(self)
    }
}

impl<A: Send + Sync + Clone, T: HasSource> Event for T {}

pub struct Sink {
    source: Arc<RwLock<Source>>,
}

impl Sink {
    pub fn new() -> Sink {
        Sink { source: Arc::new(RwLock::new(Source::new())) }
    }
}

impl Sink {
    pub fn send(&self, a: A) {
        self.source.write().unwrap().send(a);
    }
}

impl HasSource for Sink {
    type Source = subject::Source;

    fn source(&self) -> &Arc<RwLock<subject::Source>> {
        &self.source
    }
}

pub struct Map {
    mapper: Arc<RwLock<Mapper>>,
}

impl Map
    where A: Send + Sync + Clone,
          B: Send + Sync + Clone,
          F: Fn(A) -> B + Send + Sync,
{
    fn new<E: Event>(event: &E, f: F) -> Map {
        let map = Map { mapper: Arc::new(RwLock::new(Mapper::new(f))) };
        event.source().write().unwrap().listen(map.mapper.wrap());
        map
    }
}

impl HasSource for Map
    where A: Send + Sync + Clone,
          B: Send + Sync + Clone,
          F: Fn(A) -> B + Send + Sync,
{
    type Source = Mapper;

    fn source(&self) -> &Arc<RwLock<Mapper>> {
        &self.mapper
    }
}

pub struct Filter {
    filter: Arc<RwLock<subject::Filter>>,
}

impl Filter
    where A: Send + Sync + Clone,
          F: Fn(&A) -> bool + Send + Sync,
{
    fn new<E: Event>(event: &E, f: F) -> Filter {
        let filter = Filter {
            filter: Arc::new(RwLock::new(subject::Filter::new(f)))
        };
        event.source().write().unwrap().listen(filter.filter.wrap());
        filter
    }
}

impl HasSource for Filter
    where A: Send + Sync + Clone,
          F: Fn(&A) -> bool + Send + Sync,
{
    type Source = subject::Filter;

    fn source(&self) -> &Arc<RwLock<subject::Filter>> {
        &self.filter
    }
}

pub struct Merge {
    source: Arc<RwLock<Source>>,
}

impl Merge
    where A: Send + Sync + Clone,
{
    fn new<E1: Event, E2: Event>(event1: &E1, event2: &E2) -> Merge {
        let merge = Merge {
            source: Arc::new(RwLock::new(Source::new()))
        };
        event1.source().write().unwrap().listen(merge.source.wrap());
        event2.source().write().unwrap().listen(merge.source.wrap());
        merge
    }
}

impl HasSource for Merge
    where A: Send + Sync + Clone,
{
    type Source = Source;

    fn source(&self) -> &Arc<RwLock<Source>> {
        &self.source
    }
}

pub struct Iter {
    recv: Arc<RwLock<Receiver>>,
}

impl Iter {
    fn new<E: Event>(event: &E) -> Iter {
        let iter = Iter { recv: Arc::new(RwLock::new(Receiver::new())) };
        event.source().write().unwrap().listen(iter.recv.wrap());
        iter
    }
}

impl Iterator for Iter {
    type Item = A;
    fn next(&mut self) -> Option {
        self.recv.write().unwrap().next()
    }
}

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

    #[test]
    fn sink() {
        let sink = Sink::new();
        let mut iter = sink.iter();
        sink.send(1);
        sink.send(2);
        assert_eq!(iter.next(), Some(1));
        assert_eq!(iter.next(), Some(2));
    }

    #[test]
    fn map() {
        let sink = Sink::new();
        let triple = sink.map(|x| 3 * x);
        let mut iter = triple.iter();
        sink.send(1);
        assert_eq!(iter.next(), Some(3));
    }

    #[test]
    fn filter() {
        let sink = Sink::new();
        let small = sink.filter(|&x: &i32| x < 11);
        let mut iter = small.iter();
        sink.send(12);
        sink.send(9);
        assert_eq!(iter.next(), Some(9));
    }

    #[test]
    fn merge() {
        let sink1 = Sink::new();
        let sink2 = Sink::new();
        let merge = sink1.merge(&sink2);
        let mut iter = merge.iter();
        sink1.send(12);
        sink2.send(9);
        assert_eq!(iter.next(), Some(12));
        assert_eq!(iter.next(), Some(9));
    }
}
<|endoftext|>


<commit_before>#![cfg(not(syn_disable_nightly_tests))]
#![recursion_limit = "1024"]
#![feature(rustc_private)]

extern crate rustc_ast;
extern crate rustc_errors;
extern crate rustc_expand;
extern crate rustc_parse as parse;
extern crate rustc_session;
extern crate rustc_span;

use crate::common::eq::SpanlessEq;
use quote::quote;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rustc_ast::ast;
use rustc_errors::PResult;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
use rustc_span::FileName;
use std::fs;
use std::panic;
use std::path::Path;
use std::process;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
use walkdir::{DirEntry, WalkDir};

#[macro_use]
mod macros;

#[allow(dead_code)]
mod common;

mod repo;

#[test]
fn test_round_trip() {
    common::rayon_init();
    repo::clone_rust();
    let abort_after = common::abort_after();
    if abort_after == 0 {
        panic!("Skipping all round_trip tests");
    }

    let failed = AtomicUsize::new(0);

    WalkDir::new("tests/rust")
        .sort_by(|a, b| a.file_name().cmp(b.file_name()))
        .into_iter()
        .filter_entry(repo::base_dir_filter)
        .collect::<Result<Vec<DirEntry>, walkdir::Error>>()
        .unwrap()
        .into_par_iter()
        .for_each(|entry| {
            let path = entry.path();
            if !path.is_dir() {
                test(path, &failed, abort_after);
            }
        });

    let failed = failed.load(Ordering::SeqCst);
    if failed > 0 {
        panic!("{} failures", failed);
    }
}

fn test(path: &Path, failed: &AtomicUsize, abort_after: usize) {
    let content = fs::read_to_string(path).unwrap();

    let start = Instant::now();
    let (krate, elapsed) = match syn::parse_file(&content) {
        Ok(krate) => (krate, start.elapsed()),
        Err(msg) => {
            errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
            if prev_failed + 1 >= abort_after {
                process::exit(1);
            }
            return;
        }
    };
    let back = quote!(#krate).to_string();
    let edition = repo::edition(path).parse().unwrap();

    rustc_span::with_session_globals(edition, || {
        let equal = match panic::catch_unwind(|| {
            let sess = ParseSess::new(FilePathMapping::empty());
            let before = match librustc_parse(content, &sess) {
                Ok(before) => before,
                Err(mut diagnostic) => {
                    diagnostic.cancel();
                    if diagnostic
                        .message()
                        .starts_with("file not found for module")
                    {
                        errorf!("=== {}: ignore\n", path.display());
                    } else {
                        errorf!(
                            "=== {}: ignore - librustc failed to parse original content: {}\n",
                            path.display(),
                            diagnostic.message(),
                        );
                    }
                    return Err(true);
                }
            };
            let after = match librustc_parse(back, &sess) {
                Ok(after) => after,
                Err(mut diagnostic) => {
                    errorf!("=== {}: librustc failed to parse", path.display());
                    diagnostic.emit();
                    return Err(false);
                }
            };
            Ok((before, after))
        }) {
            Err(_) => {
                errorf!("=== {}: ignoring librustc panic\n", path.display());
                true
            }
            Ok(Err(equal)) => equal,
            Ok(Ok((before, after))) => {
                if SpanlessEq::eq(&before, &after) {
                    errorf!(
                        "=== {}: pass in {}ms\n",
                        path.display(),
                        elapsed.as_secs() * 1000 + u64::from(elapsed.subsec_nanos()) / 1_000_000
                    );
                    true
                } else {
                    errorf!(
                        "=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
                        path.display(),
                        before,
                        after,
                    );
                    false
                }
            }
        };
        if !equal {
            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
            if prev_failed + 1 >= abort_after {
                process::exit(1);
            }
        }
    });
}

fn librustc_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
    let name = FileName::Custom("test_round_trip".to_string());
    parse::parse_crate_from_source_str(name, content, sess)
}
<commit_msg>Work around ParseSess cache in test_round_trip<commit_after>#![cfg(not(syn_disable_nightly_tests))]
#![recursion_limit = "1024"]
#![feature(rustc_private)]

extern crate rustc_ast;
extern crate rustc_errors;
extern crate rustc_expand;
extern crate rustc_parse as parse;
extern crate rustc_session;
extern crate rustc_span;

use crate::common::eq::SpanlessEq;
use quote::quote;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rustc_ast::ast;
use rustc_errors::PResult;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
use rustc_span::FileName;
use std::fs;
use std::panic;
use std::path::Path;
use std::process;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
use walkdir::{DirEntry, WalkDir};

#[macro_use]
mod macros;

#[allow(dead_code)]
mod common;

mod repo;

#[test]
fn test_round_trip() {
    common::rayon_init();
    repo::clone_rust();
    let abort_after = common::abort_after();
    if abort_after == 0 {
        panic!("Skipping all round_trip tests");
    }

    let failed = AtomicUsize::new(0);

    WalkDir::new("tests/rust")
        .sort_by(|a, b| a.file_name().cmp(b.file_name()))
        .into_iter()
        .filter_entry(repo::base_dir_filter)
        .collect::<Result<Vec<DirEntry>, walkdir::Error>>()
        .unwrap()
        .into_par_iter()
        .for_each(|entry| {
            let path = entry.path();
            if !path.is_dir() {
                test(path, &failed, abort_after);
            }
        });

    let failed = failed.load(Ordering::SeqCst);
    if failed > 0 {
        panic!("{} failures", failed);
    }
}

fn test(path: &Path, failed: &AtomicUsize, abort_after: usize) {
    let content = fs::read_to_string(path).unwrap();

    let start = Instant::now();
    let (krate, elapsed) = match syn::parse_file(&content) {
        Ok(krate) => (krate, start.elapsed()),
        Err(msg) => {
            errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
            if prev_failed + 1 >= abort_after {
                process::exit(1);
            }
            return;
        }
    };
    let back = quote!(#krate).to_string();
    let edition = repo::edition(path).parse().unwrap();

    rustc_span::with_session_globals(edition, || {
        let equal = match panic::catch_unwind(|| {
            let sess = ParseSess::new(FilePathMapping::empty());
            let before = match librustc_parse(content, &sess) {
                Ok(before) => before,
                Err(mut diagnostic) => {
                    diagnostic.cancel();
                    if diagnostic
                        .message()
                        .starts_with("file not found for module")
                    {
                        errorf!("=== {}: ignore\n", path.display());
                    } else {
                        errorf!(
                            "=== {}: ignore - librustc failed to parse original content: {}\n",
                            path.display(),
                            diagnostic.message(),
                        );
                    }
                    return Err(true);
                }
            };
            let after = match librustc_parse(back, &sess) {
                Ok(after) => after,
                Err(mut diagnostic) => {
                    errorf!("=== {}: librustc failed to parse", path.display());
                    diagnostic.emit();
                    return Err(false);
                }
            };
            Ok((before, after))
        }) {
            Err(_) => {
                errorf!("=== {}: ignoring librustc panic\n", path.display());
                true
            }
            Ok(Err(equal)) => equal,
            Ok(Ok((before, after))) => {
                if SpanlessEq::eq(&before, &after) {
                    errorf!(
                        "=== {}: pass in {}ms\n",
                        path.display(),
                        elapsed.as_secs() * 1000 + u64::from(elapsed.subsec_nanos()) / 1_000_000
                    );
                    true
                } else {
                    errorf!(
                        "=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
                        path.display(),
                        before,
                        after,
                    );
                    false
                }
            }
        };
        if !equal {
            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
            if prev_failed + 1 >= abort_after {
                process::exit(1);
            }
        }
    });
}

fn librustc_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
    static COUNTER: AtomicUsize = AtomicUsize::new(0);
    let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
    let name = FileName::Custom(format!("test_round_trip{}", counter));
    parse::parse_crate_from_source_str(name, content, sess)
}
<|endoftext|>


<commit_before>//! This pass checks HIR bodies that may be evaluated at compile-time (e.g., `const`, `static`,
//! `const fn`) for structured control flow (e.g. `if`, `while`), which is forbidden in a const
//! context.
//!
//! By the time the MIR const-checker runs, these high-level constructs have been lowered to
//! control-flow primitives (e.g., `Goto`, `SwitchInt`), making it tough to properly attribute
//! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips
//! through, but errors for structured control flow in a `const` should be emitted here.

use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::map::Map;
use rustc::hir;
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc::session::config::nightly_options;
use syntax::ast::Mutability;
use syntax::feature_gate::feature_err;
use syntax::span_err;
use syntax_pos::{sym, Span, Symbol};
use rustc_error_codes::*;

use std::fmt;

/// An expression that is not *always* legal in a const context.
#[derive(Clone, Copy)]
enum NonConstExpr {
    Loop(hir::LoopSource),
    Match(hir::MatchSource),
}

impl NonConstExpr {
    fn name(self) -> &'static str {
        match self {
            Self::Loop(src) => src.name(),
            Self::Match(src) => src.name(),
        }
    }

    fn required_feature_gates(self) -> Option<&'static [Symbol]> {
        use hir::MatchSource::*;
        use hir::LoopSource::*;

        let gates: &[_] = match self {
            | Self::Match(Normal)
            | Self::Match(IfDesugar { .. })
            | Self::Match(IfLetDesugar { .. })
            => &[sym::const_if_match],

            | Self::Loop(Loop)
            => &[sym::const_loop],

            | Self::Loop(While)
            | Self::Loop(WhileLet)
            | Self::Match(WhileDesugar)
            | Self::Match(WhileLetDesugar)
            => &[sym::const_loop, sym::const_if_match],

            // A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
            // so they are not yet allowed with `#![feature(const_loop)]`.
            _ => return None,
        };

        Some(gates)
    }
}

#[derive(Copy, Clone)]
enum ConstKind {
    Static,
    StaticMut,
    ConstFn,
    Const,
    AnonConst,
}

impl ConstKind {
    fn for_body(body: &hir::Body, hir_map: &Map<'_>) -> Option<Self> {
        let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const();

        let owner = hir_map.body_owner(body.id());
        let const_kind = match hir_map.body_owner_kind(owner) {
            hir::BodyOwnerKind::Const => Self::Const,
            hir::BodyOwnerKind::Static(Mutability::Mutable) => Self::StaticMut,
            hir::BodyOwnerKind::Static(Mutability::Immutable) => Self::Static,

            hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn,
            hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None,
        };

        Some(const_kind)
    }
}

impl fmt::Display for ConstKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = match self {
            Self::Static => "static",
            Self::StaticMut => "static mut",
            Self::Const | Self::AnonConst => "const",
            Self::ConstFn => "const fn",
        };

        write!(f, "{}", s)
    }
}

fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: DefId) {
    let mut vis = CheckConstVisitor::new(tcx);
    tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis.as_deep_visitor());
}

pub(crate) fn provide(providers: &mut Providers<'_>) {
    *providers = Providers {
        check_mod_const_bodies,
        ..*providers
    };
}

#[derive(Copy, Clone)]
struct CheckConstVisitor<'tcx> {
    tcx: TyCtxt<'tcx>,
    const_kind: Option<ConstKind>,
}

impl<'tcx> CheckConstVisitor<'tcx> {
    fn new(tcx: TyCtxt<'tcx>) -> Self {
        CheckConstVisitor {
            tcx,
            const_kind: None,
        }
    }

    /// Emits an error when an unsupported expression is found in a const context.
    fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
        let features = self.tcx.features();
        let gates = expr.required_feature_gates();
        match gates {
            // Don't emit an error if the user has enabled the requisite feature gates.
            Some(gates) if gates.iter().all(|&g| features.enabled(g)) => return,

            // `-Zunleash-the-miri-inside-of-you` only works for expressions that don't have a
            // corresponding feature gate. This encourages nightly users to use feature gates when
            // possible.
            None if self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you => {
                self.tcx.sess.span_warn(span, "skipping const checks");
                return;
            }

            _ => {}
        }

        let const_kind = self.const_kind
            .expect("`const_check_violated` may only be called inside a const context");
        let msg = format!("`{}` is not allowed in a `{}`", expr.name(), const_kind);

        let gates = gates.unwrap_or(&[]);
        let missing_gates: Vec<_> = gates
            .iter()
            .copied()
            .filter(|&g| !features.enabled(g))
            .collect();

        match missing_gates.as_slice() {
            &[] => span_err!(self.tcx.sess, span, E0744, "{}", msg),

            // If the user enabled `#![feature(const_loop)]` but not `#![feature(const_if_match)]`,
            // explain why their `while` loop is being rejected.
            &[gate @ sym::const_if_match] if gates.contains(&sym::const_loop) => {
                feature_err(&self.tcx.sess.parse_sess, gate, span, &msg)
                    .note("`#![feature(const_loop)]` alone is not sufficient, \
                           since this loop expression contains an implicit conditional")
                    .emit();
            }

            &[missing_primary, ref missing_secondary @ ..] => {
                let mut err = feature_err(&self.tcx.sess.parse_sess, missing_primary, span, &msg);

                // If multiple feature gates would be required to enable this expression, include
                // them as help messages. Don't emit a separate error for each missing feature gate.
                //
                // FIXME(ecstaticmorse): Maybe this could be incorporated into `feature_err`? This
                // is a pretty narrow case, however.
                if nightly_options::is_nightly_build() {
                    for gate in missing_secondary {
                        let note = format!(
                            "add `#![feature({})]` to the crate attributes to enable",
                            gate,
                        );
                        err.help(&note);
                    }
                }

                err.emit();
            }
        }
    }

    /// Saves the parent `const_kind` before calling `f` and restores it afterwards.
    fn recurse_into(&mut self, kind: Option<ConstKind>, f: impl FnOnce(&mut Self)) {
        let parent_kind = self.const_kind;
        self.const_kind = kind;
        f(self);
        self.const_kind = parent_kind;
    }
}

impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
    }

    fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
        let kind = Some(ConstKind::AnonConst);
        self.recurse_into(kind, |this| hir::intravisit::walk_anon_const(this, anon));
    }

    fn visit_body(&mut self, body: &'tcx hir::Body) {
        let kind = ConstKind::for_body(body, self.tcx.hir());
        self.recurse_into(kind, |this| hir::intravisit::walk_body(this, body));
    }

    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
        match &e.kind {
            // Skip the following checks if we are not currently in a const context.
            _ if self.const_kind.is_none() => {}

            hir::ExprKind::Loop(_, _, source) => {
                self.const_check_violated(NonConstExpr::Loop(*source), e.span);
            }

            hir::ExprKind::Match(_, _, source) => {
                let non_const_expr = match source {
                    // These are handled by `ExprKind::Loop` above.
                    | hir::MatchSource::WhileDesugar
                    | hir::MatchSource::WhileLetDesugar
                    | hir::MatchSource::ForLoopDesugar
                    => None,

                    _ => Some(NonConstExpr::Match(*source)),
                };

                if let Some(expr) = non_const_expr {
                    self.const_check_violated(expr, e.span);
                }
            }

            _ => {},
        }

        hir::intravisit::walk_expr(self, e);
    }
}
<commit_msg>Use better name for local containing required feature gates<commit_after>//! This pass checks HIR bodies that may be evaluated at compile-time (e.g., `const`, `static`,
//! `const fn`) for structured control flow (e.g. `if`, `while`), which is forbidden in a const
//! context.
//!
//! By the time the MIR const-checker runs, these high-level constructs have been lowered to
//! control-flow primitives (e.g., `Goto`, `SwitchInt`), making it tough to properly attribute
//! errors. We still look for those primitives in the MIR const-checker to ensure nothing slips
//! through, but errors for structured control flow in a `const` should be emitted here.

use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::map::Map;
use rustc::hir;
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc::session::config::nightly_options;
use syntax::ast::Mutability;
use syntax::feature_gate::feature_err;
use syntax::span_err;
use syntax_pos::{sym, Span, Symbol};
use rustc_error_codes::*;

use std::fmt;

/// An expression that is not *always* legal in a const context.
#[derive(Clone, Copy)]
enum NonConstExpr {
    Loop(hir::LoopSource),
    Match(hir::MatchSource),
}

impl NonConstExpr {
    fn name(self) -> &'static str {
        match self {
            Self::Loop(src) => src.name(),
            Self::Match(src) => src.name(),
        }
    }

    fn required_feature_gates(self) -> Option<&'static [Symbol]> {
        use hir::MatchSource::*;
        use hir::LoopSource::*;

        let gates: &[_] = match self {
            | Self::Match(Normal)
            | Self::Match(IfDesugar { .. })
            | Self::Match(IfLetDesugar { .. })
            => &[sym::const_if_match],

            | Self::Loop(Loop)
            => &[sym::const_loop],

            | Self::Loop(While)
            | Self::Loop(WhileLet)
            | Self::Match(WhileDesugar)
            | Self::Match(WhileLetDesugar)
            => &[sym::const_loop, sym::const_if_match],

            // A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
            // so they are not yet allowed with `#![feature(const_loop)]`.
            _ => return None,
        };

        Some(gates)
    }
}

#[derive(Copy, Clone)]
enum ConstKind {
    Static,
    StaticMut,
    ConstFn,
    Const,
    AnonConst,
}

impl ConstKind {
    fn for_body(body: &hir::Body, hir_map: &Map<'_>) -> Option<Self> {
        let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const();

        let owner = hir_map.body_owner(body.id());
        let const_kind = match hir_map.body_owner_kind(owner) {
            hir::BodyOwnerKind::Const => Self::Const,
            hir::BodyOwnerKind::Static(Mutability::Mutable) => Self::StaticMut,
            hir::BodyOwnerKind::Static(Mutability::Immutable) => Self::Static,

            hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn,
            hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None,
        };

        Some(const_kind)
    }
}

impl fmt::Display for ConstKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = match self {
            Self::Static => "static",
            Self::StaticMut => "static mut",
            Self::Const | Self::AnonConst => "const",
            Self::ConstFn => "const fn",
        };

        write!(f, "{}", s)
    }
}

fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: DefId) {
    let mut vis = CheckConstVisitor::new(tcx);
    tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis.as_deep_visitor());
}

pub(crate) fn provide(providers: &mut Providers<'_>) {
    *providers = Providers {
        check_mod_const_bodies,
        ..*providers
    };
}

#[derive(Copy, Clone)]
struct CheckConstVisitor<'tcx> {
    tcx: TyCtxt<'tcx>,
    const_kind: Option<ConstKind>,
}

impl<'tcx> CheckConstVisitor<'tcx> {
    fn new(tcx: TyCtxt<'tcx>) -> Self {
        CheckConstVisitor {
            tcx,
            const_kind: None,
        }
    }

    /// Emits an error when an unsupported expression is found in a const context.
    fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
        let features = self.tcx.features();
        let required_gates = expr.required_feature_gates();
        match required_gates {
            // Don't emit an error if the user has enabled the requisite feature gates.
            Some(gates) if gates.iter().all(|&g| features.enabled(g)) => return,

            // `-Zunleash-the-miri-inside-of-you` only works for expressions that don't have a
            // corresponding feature gate. This encourages nightly users to use feature gates when
            // possible.
            None if self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you => {
                self.tcx.sess.span_warn(span, "skipping const checks");
                return;
            }

            _ => {}
        }

        let const_kind = self.const_kind
            .expect("`const_check_violated` may only be called inside a const context");
        let msg = format!("`{}` is not allowed in a `{}`", expr.name(), const_kind);

        let required_gates = required_gates.unwrap_or(&[]);
        let missing_gates: Vec<_> = required_gates
            .iter()
            .copied()
            .filter(|&g| !features.enabled(g))
            .collect();

        match missing_gates.as_slice() {
            &[] => span_err!(self.tcx.sess, span, E0744, "{}", msg),

            // If the user enabled `#![feature(const_loop)]` but not `#![feature(const_if_match)]`,
            // explain why their `while` loop is being rejected.
            &[gate @ sym::const_if_match] if required_gates.contains(&sym::const_loop) => {
                feature_err(&self.tcx.sess.parse_sess, gate, span, &msg)
                    .note("`#![feature(const_loop)]` alone is not sufficient, \
                           since this loop expression contains an implicit conditional")
                    .emit();
            }

            &[missing_primary, ref missing_secondary @ ..] => {
                let mut err = feature_err(&self.tcx.sess.parse_sess, missing_primary, span, &msg);

                // If multiple feature gates would be required to enable this expression, include
                // them as help messages. Don't emit a separate error for each missing feature gate.
                //
                // FIXME(ecstaticmorse): Maybe this could be incorporated into `feature_err`? This
                // is a pretty narrow case, however.
                if nightly_options::is_nightly_build() {
                    for gate in missing_secondary {
                        let note = format!(
                            "add `#![feature({})]` to the crate attributes to enable",
                            gate,
                        );
                        err.help(&note);
                    }
                }

                err.emit();
            }
        }
    }

    /// Saves the parent `const_kind` before calling `f` and restores it afterwards.
    fn recurse_into(&mut self, kind: Option<ConstKind>, f: impl FnOnce(&mut Self)) {
        let parent_kind = self.const_kind;
        self.const_kind = kind;
        f(self);
        self.const_kind = parent_kind;
    }
}

impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
    }

    fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
        let kind = Some(ConstKind::AnonConst);
        self.recurse_into(kind, |this| hir::intravisit::walk_anon_const(this, anon));
    }

    fn visit_body(&mut self, body: &'tcx hir::Body) {
        let kind = ConstKind::for_body(body, self.tcx.hir());
        self.recurse_into(kind, |this| hir::intravisit::walk_body(this, body));
    }

    fn visit_expr(&mut self, e: &'tcx hir::Expr) {
        match &e.kind {
            // Skip the following checks if we are not currently in a const context.
            _ if self.const_kind.is_none() => {}

            hir::ExprKind::Loop(_, _, source) => {
                self.const_check_violated(NonConstExpr::Loop(*source), e.span);
            }

            hir::ExprKind::Match(_, _, source) => {
                let non_const_expr = match source {
                    // These are handled by `ExprKind::Loop` above.
                    | hir::MatchSource::WhileDesugar
                    | hir::MatchSource::WhileLetDesugar
                    | hir::MatchSource::ForLoopDesugar
                    => None,

                    _ => Some(NonConstExpr::Match(*source)),
                };

                if let Some(expr) = non_const_expr {
                    self.const_check_violated(expr, e.span);
                }
            }

            _ => {},
        }

        hir::intravisit::walk_expr(self, e);
    }
}
<|endoftext|>


<commit_before>//! Implementation of line-delimiting codec for Tokio.

use std::io;

use bytes::{BufMut, BytesMut};
use encoding::{DecoderTrap, EncoderTrap, EncodingRef};
use encoding::label::encoding_from_whatwg_label;
use tokio_io::codec::{Decoder, Encoder};

use error;

/// A line-based codec parameterized by an encoding.
pub struct LineCodec {
    encoding: EncodingRef,
}

impl LineCodec {
    /// Creates a new instance of LineCodec from the specified encoding.
    pub fn new(label: &str) -> error::Result<LineCodec> {
        encoding_from_whatwg_label(label)
            .map(|enc| LineCodec { encoding: enc })
            .ok_or(
                io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &format!("Attempted to use unknown codec {}.", label)[..],
                ).into(),
            )
    }
}

impl Decoder for LineCodec {
    type Item = String;
    type Error = error::Error;

    fn decode(&mut self, src: &mut BytesMut) -> error::Result<Option<String>> {
        if let Some(n) = src.as_ref().iter().position(|b| *b == b'\n') {
            // Remove the next frame from the buffer.
            let line = src.split_to(n + 1);

            // Decode the line using the codec's encoding.
            match self.encoding.decode(line.as_ref(), DecoderTrap::Replace) {
                Ok(data) => Ok(Some(data)),
                Err(data) => Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        &format!("Failed to decode {} as {}.", data, self.encoding.name())[..],
                    ).into(),
                ),
            }
        } else {
            Ok(None)
        }
    }
}

impl Encoder for LineCodec {
    type Item = String;
    type Error = error::Error;

    fn encode(&mut self, msg: String, dst: &mut BytesMut) -> error::Result<()> {
        // Encode the message using the codec's encoding.
        let data: error::Result<Vec<u8>> = self.encoding
            .encode(&msg, EncoderTrap::Replace)
            .map_err(|data| {
                io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &format!("Failed to encode {} as {}.", data, self.encoding.name())[..],
                ).into()
            });

        // Write the encoded message to the output buffer.
        dst.put(&data?);

        Ok(())
    }
}
<commit_msg>Changed LineCodec to use extend in encode (fixes #92).<commit_after>//! Implementation of line-delimiting codec for Tokio.

use std::io;

use bytes::BytesMut;
use encoding::{DecoderTrap, EncoderTrap, EncodingRef};
use encoding::label::encoding_from_whatwg_label;
use tokio_io::codec::{Decoder, Encoder};

use error;

/// A line-based codec parameterized by an encoding.
pub struct LineCodec {
    encoding: EncodingRef,
}

impl LineCodec {
    /// Creates a new instance of LineCodec from the specified encoding.
    pub fn new(label: &str) -> error::Result<LineCodec> {
        encoding_from_whatwg_label(label)
            .map(|enc| LineCodec { encoding: enc })
            .ok_or(
                io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &format!("Attempted to use unknown codec {}.", label)[..],
                ).into(),
            )
    }
}

impl Decoder for LineCodec {
    type Item = String;
    type Error = error::Error;

    fn decode(&mut self, src: &mut BytesMut) -> error::Result<Option<String>> {
        if let Some(n) = src.as_ref().iter().position(|b| *b == b'\n') {
            // Remove the next frame from the buffer.
            let line = src.split_to(n + 1);

            // Decode the line using the codec's encoding.
            match self.encoding.decode(line.as_ref(), DecoderTrap::Replace) {
                Ok(data) => Ok(Some(data)),
                Err(data) => Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        &format!("Failed to decode {} as {}.", data, self.encoding.name())[..],
                    ).into(),
                ),
            }
        } else {
            Ok(None)
        }
    }
}

impl Encoder for LineCodec {
    type Item = String;
    type Error = error::Error;

    fn encode(&mut self, msg: String, dst: &mut BytesMut) -> error::Result<()> {
        // Encode the message using the codec's encoding.
        let data: error::Result<Vec<u8>> = self.encoding
            .encode(&msg, EncoderTrap::Replace)
            .map_err(|data| {
                io::Error::new(
                    io::ErrorKind::InvalidInput,
                    &format!("Failed to encode {} as {}.", data, self.encoding.name())[..],
                ).into()
            });

        // Write the encoded message to the output buffer.
        dst.extend(&data?);

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