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

// Functions for dealing with device mapper devices.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, ThinDevId};

use super::super::errors::EngineResult;

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// Format a name for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_name(pool_uuid: &PoolUuid, role: FlexRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-flex-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 72")

}

/// Format a name for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_name(pool_uuid: &PoolUuid, role: ThinRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thin-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 50")
}

/// Format a name for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_name(pool_uuid: &PoolUuid, role: ThinPoolRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thinpool-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display_length < 81")
}

#[derive(Debug)]
/// A pool of thindev ids, all unique.
pub struct ThinDevIdPool {
    next_id: u32,
}

impl ThinDevIdPool {
    /// Make a new pool from a possibly empty Vec of ids.
    /// Does not verify the absence of duplicate ids.
    pub fn new_from_ids(ids: &[ThinDevId]) -> ThinDevIdPool {
        let max_id: Option<u32> = ids.into_iter().map(|x| (*x).into()).max();
        ThinDevIdPool { next_id: max_id.map(|x| x + 1).unwrap_or(0) }
    }

    /// Get a new id for a thindev.
    /// Returns an error if no thindev id can be constructed.
    // TODO: Improve this so that it is guaranteed only to fail if every 24 bit
    // number has been used.
    pub fn new_id(&mut self) -> EngineResult<ThinDevId> {
        let next_id = ThinDevId::new_u64((self.next_id) as u64)?;
        self.next_id += 1;
        Ok(next_id)
    }
}
<commit_msg>Fix cast-lossless clippy error<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Functions for dealing with device mapper devices.

use std::fmt;
use std::fmt::Display;

use devicemapper::{DmNameBuf, ThinDevId};

use super::super::errors::EngineResult;

use super::super::super::engine::{FilesystemUuid, PoolUuid};

const FORMAT_VERSION: u16 = 1;

pub enum FlexRole {
    MetadataVolume,
    ThinData,
    ThinMeta,
    ThinMetaSpare,
}

impl Display for FlexRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            FlexRole::MetadataVolume => write!(f, "mdv"),
            FlexRole::ThinData => write!(f, "thindata"),
            FlexRole::ThinMeta => write!(f, "thinmeta"),
            FlexRole::ThinMetaSpare => write!(f, "thinmetaspare"),
        }
    }
}

pub enum ThinRole {
    Filesystem(FilesystemUuid),
}

impl Display for ThinRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinRole::Filesystem(uuid) => write!(f, "fs-{}", uuid.simple().to_string()),
        }
    }
}

pub enum ThinPoolRole {
    Pool,
}

impl Display for ThinPoolRole {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ThinPoolRole::Pool => write!(f, "pool"),
        }
    }
}

/// Format a name for the flex layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 72
pub fn format_flex_name(pool_uuid: &PoolUuid, role: FlexRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-flex-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 72")

}

/// Format a name for the thin layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 50
pub fn format_thin_name(pool_uuid: &PoolUuid, role: ThinRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thin-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display length < 50")
}

/// Format a name for the thin pool layer.
/// Prerequisite: len(format!("{}", FORMAT_VERSION)) < 81
pub fn format_thinpool_name(pool_uuid: &PoolUuid, role: ThinPoolRole) -> DmNameBuf {
    DmNameBuf::new(format!("stratis-{}-{}-thinpool-{}",
                           FORMAT_VERSION,
                           pool_uuid.simple().to_string(),
                           role))
            .expect("FORMAT_VERSION display_length < 81")
}

#[derive(Debug)]
/// A pool of thindev ids, all unique.
pub struct ThinDevIdPool {
    next_id: u32,
}

impl ThinDevIdPool {
    /// Make a new pool from a possibly empty Vec of ids.
    /// Does not verify the absence of duplicate ids.
    pub fn new_from_ids(ids: &[ThinDevId]) -> ThinDevIdPool {
        let max_id: Option<u32> = ids.into_iter().map(|x| (*x).into()).max();
        ThinDevIdPool { next_id: max_id.map(|x| x + 1).unwrap_or(0) }
    }

    /// Get a new id for a thindev.
    /// Returns an error if no thindev id can be constructed.
    // TODO: Improve this so that it is guaranteed only to fail if every 24 bit
    // number has been used.
    pub fn new_id(&mut self) -> EngineResult<ThinDevId> {
        let next_id = ThinDevId::new_u64(u64::from(self.next_id))?;
        self.next_id += 1;
        Ok(next_id)
    }
}
<|endoftext|>


<commit_before>pub use alloc::boxed::*;

pub use core::cmp::max;
pub use core::cmp::min;
pub use core::clone::Clone;
pub use core::mem::size_of;
pub use core::mem::size_of_val;
pub use core::option::Option;
pub use core::ptr;
pub use core::sync::atomic::*;

pub use graphics::color::*;
pub use graphics::display::*;
pub use graphics::point::*;
pub use graphics::size::*;
pub use graphics::window::*;

pub use syscall::call::*;

use common::resource::{NoneResource, Resource, URL};
use common::string::String;

#[allow(unused_variables)]
pub trait SessionItem {
    fn on_irq(&mut self, irq: u8) {

    }

    fn on_poll(&mut self) {

    }

    fn scheme(&self) -> String {
        String::new()
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        box NoneResource
    }
}
<commit_msg>Remove the other pub imports in programs::common while were at it<commit_after>pub use core::clone::Clone;
pub use core::option::Option;
pub use core::sync::atomic::*;

use alloc::boxed::*;

use common::resource::{NoneResource, Resource, URL};
use common::string::String;

#[allow(unused_variables)]
pub trait SessionItem {
    fn on_irq(&mut self, irq: u8) {

    }

    fn on_poll(&mut self) {

    }

    fn scheme(&self) -> String {
        String::new()
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        box NoneResource
    }
}
<|endoftext|>


<commit_before><commit_msg>Capture newline in line doc comment.<commit_after><|endoftext|>


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

//! A work queue for scheduling units of work across threads in a fork-join fashion.
//!
//! Data associated with queues is simply a pair of unsigned integers. It is expected that a
//! higher-level API on top of this could allow safe fork-join parallelism.

use task_state;

use native::task::NativeTaskBuilder;
use rand::{Rng, XorShiftRng};
use std::mem;
use std::rand::weak_rng;
use std::sync::atomics::{AtomicUint, SeqCst};
use std::sync::deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
use std::task::TaskBuilder;
use libc::funcs::posix88::unistd::usleep;

/// A unit of work.
///
/// # Type parameters
///
/// - `QueueData`: global custom data for the entire work queue.
/// - `WorkData`: custom data specific to each unit of work.
pub struct WorkUnit<QueueData, WorkData> {
    /// The function to execute.
    pub fun: extern "Rust" fn(WorkData, &mut WorkerProxy<QueueData, WorkData>),
    /// Arbitrary data.
    pub data: WorkData,
}

/// Messages from the supervisor to the worker.
enum WorkerMsg<QueueData, WorkData> {
    /// Tells the worker to start work.
    StartMsg(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData),
    /// Tells the worker to stop. It can be restarted again with a `StartMsg`.
    StopMsg,
    /// Tells the worker thread to terminate.
    ExitMsg,
}

/// Messages to the supervisor.
enum SupervisorMsg<QueueData, WorkData> {
    FinishedMsg,
    ReturnDequeMsg(uint, Worker<WorkUnit<QueueData, WorkData>>),
}

/// Information that the supervisor thread keeps about the worker threads.
struct WorkerInfo<QueueData, WorkData> {
    /// The communication channel to the workers.
    chan: Sender<WorkerMsg<QueueData, WorkData>>,
    /// The worker end of the deque, if we have it.
    deque: Option<Worker<WorkUnit<QueueData, WorkData>>>,
    /// The thief end of the work-stealing deque.
    thief: Stealer<WorkUnit<QueueData, WorkData>>,
}

/// Information specific to each worker thread that the thread keeps.
struct WorkerThread<QueueData, WorkData> {
    /// The index of this worker.
    index: uint,
    /// The communication port from the supervisor.
    port: Receiver<WorkerMsg<QueueData, WorkData>>,
    /// The communication channel on which messages are sent to the supervisor.
    chan: Sender<SupervisorMsg<QueueData, WorkData>>,
    /// The thief end of the work-stealing deque for all other workers.
    other_deques: Vec<Stealer<WorkUnit<QueueData, WorkData>>>,
    /// The random number generator for this worker.
    rng: XorShiftRng,
}

static SPIN_COUNT: uint = 128;

impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
    /// The main logic. This function starts up the worker and listens for
    /// messages.
    fn start(&mut self) {
        loop {
            // Wait for a start message.
            let (mut deque, ref_count, queue_data) = match self.port.recv() {
                StartMsg(deque, ref_count, queue_data) => (deque, ref_count, queue_data),
                StopMsg => fail!("unexpected stop message"),
                ExitMsg => return,
            };

            // We're off!
            //
            // FIXME(pcwalton): Can't use labeled break or continue cross-crate due to a Rust bug.
            let mut back_off_sleep = 0 as u32;
            loop {
                // FIXME(pcwalton): Nasty workaround for the lack of labeled break/continue
                // cross-crate.
                let mut work_unit = unsafe {
                    mem::uninitialized()
                };
                match deque.pop() {
                    Some(work) => work_unit = work,
                    None => {
                        // Become a thief.
                        let mut i = 0;
                        let mut should_continue = true;
                        loop {
                            let victim = (self.rng.next_u32() as uint) % self.other_deques.len();
                            match self.other_deques.get_mut(victim).steal() {
                                Empty | Abort => {
                                    // Continue.
                                }
                                Data(work) => {
                                    work_unit = work;
                                    back_off_sleep = 0 as u32;
                                    break
                                }
                            }

                            if (i>100) {
                                unsafe {usleep(back_off_sleep as u32)};
                                back_off_sleep = back_off_sleep + 5;
                            }
                            if i == SPIN_COUNT {
                                match self.port.try_recv() {
                                    Ok(StopMsg) => {
                                        should_continue = false;
                                        break
                                    }
                                    Ok(ExitMsg) => return,
                                    Ok(_) => fail!("unexpected message"),
                                    _ => {}
                                }

                                i = 0
                            } else {
                                i += 1
                            }
                        }

                        if !should_continue {
                            break
                        }
                    }
                }

                // At this point, we have some work. Perform it.
                let mut proxy = WorkerProxy {
                    worker: &mut deque,
                    ref_count: ref_count,
                    queue_data: queue_data,
                };
                (work_unit.fun)(work_unit.data, &mut proxy);

                // The work is done. Now decrement the count of outstanding work items. If this was
                // the last work unit in the queue, then send a message on the channel.
                unsafe {
                    if (*ref_count).fetch_sub(1, SeqCst) == 1 {
                        self.chan.send(FinishedMsg)
                    }
                }
            }

            // Give the deque back to the supervisor.
            self.chan.send(ReturnDequeMsg(self.index, deque))
        }
    }
}

/// A handle to the work queue that individual work units have.
pub struct WorkerProxy<'a, QueueData: 'a, WorkData: 'a> {
    worker: &'a mut Worker<WorkUnit<QueueData, WorkData>>,
    ref_count: *mut AtomicUint,
    queue_data: *const QueueData,
}

impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData> {
    /// Enqueues a block into the work queue.
    #[inline]
    pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) {
        unsafe {
            drop((*self.ref_count).fetch_add(1, SeqCst));
        }
        self.worker.push(work_unit);
    }

    /// Retrieves the queue user data.
    #[inline]
    pub fn user_data<'a>(&'a self) -> &'a QueueData {
        unsafe {
            mem::transmute(self.queue_data)
        }
    }
}

/// A work queue on which units of work can be submitted.
pub struct WorkQueue<QueueData, WorkData> {
    /// Information about each of the workers.
    workers: Vec<WorkerInfo<QueueData, WorkData>>,
    /// A port on which deques can be received from the workers.
    port: Receiver<SupervisorMsg<QueueData, WorkData>>,
    /// The amount of work that has been enqueued.
    work_count: uint,
    /// Arbitrary user data.
    pub data: QueueData,
}

impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
    /// Creates a new work queue and spawns all the threads associated with
    /// it.
    pub fn new(task_name: &'static str,
               state: task_state::TaskState,
               thread_count: uint,
               user_data: QueueData) -> WorkQueue<QueueData, WorkData> {
        // Set up data structures.
        let (supervisor_chan, supervisor_port) = channel();
        let (mut infos, mut threads) = (vec!(), vec!());
        for i in range(0, thread_count) {
            let (worker_chan, worker_port) = channel();
            let pool = BufferPool::new();
            let (worker, thief) = pool.deque();
            infos.push(WorkerInfo {
                chan: worker_chan,
                deque: Some(worker),
                thief: thief,
            });
            threads.push(WorkerThread {
                index: i,
                port: worker_port,
                chan: supervisor_chan.clone(),
                other_deques: vec!(),
                rng: weak_rng(),
            });
        }

        // Connect workers to one another.
        for i in range(0, thread_count) {
            for j in range(0, thread_count) {
                if i != j {
                    threads.get_mut(i).other_deques.push(infos[j].thief.clone())
                }
            }
            assert!(threads[i].other_deques.len() == thread_count - 1)
        }

        // Spawn threads.
        for thread in threads.into_iter() {
            TaskBuilder::new().named(task_name).native().spawn(proc() {
                task_state::initialize(state | task_state::InWorker);
                let mut thread = thread;
                thread.start()
            })
        }

        WorkQueue {
            workers: infos,
            port: supervisor_port,
            work_count: 0,
            data: user_data,
        }
    }

    /// Enqueues a block into the work queue.
    #[inline]
    pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) {
        match self.workers.get_mut(0).deque {
            None => {
                fail!("tried to push a block but we don't have the deque?!")
            }
            Some(ref mut deque) => deque.push(work_unit),
        }
        self.work_count += 1
    }

    /// Synchronously runs all the enqueued tasks and waits for them to complete.
    pub fn run(&mut self) {
        // Tell the workers to start.
        let mut work_count = AtomicUint::new(self.work_count);
        for worker in self.workers.iter_mut() {
            worker.chan.send(StartMsg(worker.deque.take().unwrap(), &mut work_count, &self.data))
        }

        // Wait for the work to finish.
        drop(self.port.recv());
        self.work_count = 0;

        // Tell everyone to stop.
        for worker in self.workers.iter() {
            worker.chan.send(StopMsg)
        }

        // Get our deques back.
        for _ in range(0, self.workers.len()) {
            match self.port.recv() {
                ReturnDequeMsg(index, deque) => self.workers.get_mut(index).deque = Some(deque),
                FinishedMsg => fail!("unexpected finished message!"),
            }
        }
    }

    pub fn shutdown(&mut self) {
        for worker in self.workers.iter() {
            worker.chan.send(ExitMsg)
        }
    }
}
<commit_msg>Addressed code review comments.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A work queue for scheduling units of work across threads in a fork-join fashion.
//!
//! Data associated with queues is simply a pair of unsigned integers. It is expected that a
//! higher-level API on top of this could allow safe fork-join parallelism.

use task_state;

use native::task::NativeTaskBuilder;
use rand::{Rng, XorShiftRng};
use std::mem;
use std::rand::weak_rng;
use std::sync::atomics::{AtomicUint, SeqCst};
use std::sync::deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
use std::task::TaskBuilder;
use libc::funcs::posix88::unistd::usleep;

/// A unit of work.
///
/// # Type parameters
///
/// - `QueueData`: global custom data for the entire work queue.
/// - `WorkData`: custom data specific to each unit of work.
pub struct WorkUnit<QueueData, WorkData> {
    /// The function to execute.
    pub fun: extern "Rust" fn(WorkData, &mut WorkerProxy<QueueData, WorkData>),
    /// Arbitrary data.
    pub data: WorkData,
}

/// Messages from the supervisor to the worker.
enum WorkerMsg<QueueData, WorkData> {
    /// Tells the worker to start work.
    StartMsg(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData),
    /// Tells the worker to stop. It can be restarted again with a `StartMsg`.
    StopMsg,
    /// Tells the worker thread to terminate.
    ExitMsg,
}

/// Messages to the supervisor.
enum SupervisorMsg<QueueData, WorkData> {
    FinishedMsg,
    ReturnDequeMsg(uint, Worker<WorkUnit<QueueData, WorkData>>),
}

/// Information that the supervisor thread keeps about the worker threads.
struct WorkerInfo<QueueData, WorkData> {
    /// The communication channel to the workers.
    chan: Sender<WorkerMsg<QueueData, WorkData>>,
    /// The worker end of the deque, if we have it.
    deque: Option<Worker<WorkUnit<QueueData, WorkData>>>,
    /// The thief end of the work-stealing deque.
    thief: Stealer<WorkUnit<QueueData, WorkData>>,
}

/// Information specific to each worker thread that the thread keeps.
struct WorkerThread<QueueData, WorkData> {
    /// The index of this worker.
    index: uint,
    /// The communication port from the supervisor.
    port: Receiver<WorkerMsg<QueueData, WorkData>>,
    /// The communication channel on which messages are sent to the supervisor.
    chan: Sender<SupervisorMsg<QueueData, WorkData>>,
    /// The thief end of the work-stealing deque for all other workers.
    other_deques: Vec<Stealer<WorkUnit<QueueData, WorkData>>>,
    /// The random number generator for this worker.
    rng: XorShiftRng,
}

static SPIN_COUNT: u32 = 128;
static SPINS_UNTIL_BACKOFF: u32 = 100;
static BACKOFF_INCREMENT_IN_US: u32 = 5;

impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
    /// The main logic. This function starts up the worker and listens for
    /// messages.
    fn start(&mut self) {
        loop {
            // Wait for a start message.
            let (mut deque, ref_count, queue_data) = match self.port.recv() {
                StartMsg(deque, ref_count, queue_data) => (deque, ref_count, queue_data),
                StopMsg => fail!("unexpected stop message"),
                ExitMsg => return,
            };

            let mut back_off_sleep = 0 as u32;

            // We're off!
            //
            // FIXME(pcwalton): Can't use labeled break or continue cross-crate due to a Rust bug.
            loop {
                // FIXME(pcwalton): Nasty workaround for the lack of labeled break/continue
                // cross-crate.
                let mut work_unit = unsafe {
                    mem::uninitialized()
                };
                match deque.pop() {
                    Some(work) => work_unit = work,
                    None => {
                        // Become a thief.
                        let mut i = 0;
                        let mut should_continue = true;
                        loop {
                            let victim = (self.rng.next_u32() as uint) % self.other_deques.len();
                            match self.other_deques.get_mut(victim).steal() {
                                Empty | Abort => {
                                    // Continue.
                                }
                                Data(work) => {
                                    work_unit = work;
                                    back_off_sleep = 0 as u32;
                                    break
                                }
                            }

                            if i > SPINS_UNTIL_BACKOFF {
                                unsafe {
                                    usleep(back_off_sleep as u32);
                                }
                                back_off_sleep += BACKOFF_INCREMENT_IN_US;
                            }

                            if i == SPIN_COUNT {
                                match self.port.try_recv() {
                                    Ok(StopMsg) => {
                                        should_continue = false;
                                        break
                                    }
                                    Ok(ExitMsg) => return,
                                    Ok(_) => fail!("unexpected message"),
                                    _ => {}
                                }

                                i = 0
                            } else {
                                i += 1
                            }
                        }

                        if !should_continue {
                            break
                        }
                    }
                }

                // At this point, we have some work. Perform it.
                let mut proxy = WorkerProxy {
                    worker: &mut deque,
                    ref_count: ref_count,
                    queue_data: queue_data,
                };
                (work_unit.fun)(work_unit.data, &mut proxy);

                // The work is done. Now decrement the count of outstanding work items. If this was
                // the last work unit in the queue, then send a message on the channel.
                unsafe {
                    if (*ref_count).fetch_sub(1, SeqCst) == 1 {
                        self.chan.send(FinishedMsg)
                    }
                }
            }

            // Give the deque back to the supervisor.
            self.chan.send(ReturnDequeMsg(self.index, deque))
        }
    }
}

/// A handle to the work queue that individual work units have.
pub struct WorkerProxy<'a, QueueData: 'a, WorkData: 'a> {
    worker: &'a mut Worker<WorkUnit<QueueData, WorkData>>,
    ref_count: *mut AtomicUint,
    queue_data: *const QueueData,
}

impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData> {
    /// Enqueues a block into the work queue.
    #[inline]
    pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) {
        unsafe {
            drop((*self.ref_count).fetch_add(1, SeqCst));
        }
        self.worker.push(work_unit);
    }

    /// Retrieves the queue user data.
    #[inline]
    pub fn user_data<'a>(&'a self) -> &'a QueueData {
        unsafe {
            mem::transmute(self.queue_data)
        }
    }
}

/// A work queue on which units of work can be submitted.
pub struct WorkQueue<QueueData, WorkData> {
    /// Information about each of the workers.
    workers: Vec<WorkerInfo<QueueData, WorkData>>,
    /// A port on which deques can be received from the workers.
    port: Receiver<SupervisorMsg<QueueData, WorkData>>,
    /// The amount of work that has been enqueued.
    work_count: uint,
    /// Arbitrary user data.
    pub data: QueueData,
}

impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
    /// Creates a new work queue and spawns all the threads associated with
    /// it.
    pub fn new(task_name: &'static str,
               state: task_state::TaskState,
               thread_count: uint,
               user_data: QueueData) -> WorkQueue<QueueData, WorkData> {
        // Set up data structures.
        let (supervisor_chan, supervisor_port) = channel();
        let (mut infos, mut threads) = (vec!(), vec!());
        for i in range(0, thread_count) {
            let (worker_chan, worker_port) = channel();
            let pool = BufferPool::new();
            let (worker, thief) = pool.deque();
            infos.push(WorkerInfo {
                chan: worker_chan,
                deque: Some(worker),
                thief: thief,
            });
            threads.push(WorkerThread {
                index: i,
                port: worker_port,
                chan: supervisor_chan.clone(),
                other_deques: vec!(),
                rng: weak_rng(),
            });
        }

        // Connect workers to one another.
        for i in range(0, thread_count) {
            for j in range(0, thread_count) {
                if i != j {
                    threads.get_mut(i).other_deques.push(infos[j].thief.clone())
                }
            }
            assert!(threads[i].other_deques.len() == thread_count - 1)
        }

        // Spawn threads.
        for thread in threads.into_iter() {
            TaskBuilder::new().named(task_name).native().spawn(proc() {
                task_state::initialize(state | task_state::InWorker);
                let mut thread = thread;
                thread.start()
            })
        }

        WorkQueue {
            workers: infos,
            port: supervisor_port,
            work_count: 0,
            data: user_data,
        }
    }

    /// Enqueues a block into the work queue.
    #[inline]
    pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) {
        match self.workers.get_mut(0).deque {
            None => {
                fail!("tried to push a block but we don't have the deque?!")
            }
            Some(ref mut deque) => deque.push(work_unit),
        }
        self.work_count += 1
    }

    /// Synchronously runs all the enqueued tasks and waits for them to complete.
    pub fn run(&mut self) {
        // Tell the workers to start.
        let mut work_count = AtomicUint::new(self.work_count);
        for worker in self.workers.iter_mut() {
            worker.chan.send(StartMsg(worker.deque.take().unwrap(), &mut work_count, &self.data))
        }

        // Wait for the work to finish.
        drop(self.port.recv());
        self.work_count = 0;

        // Tell everyone to stop.
        for worker in self.workers.iter() {
            worker.chan.send(StopMsg)
        }

        // Get our deques back.
        for _ in range(0, self.workers.len()) {
            match self.port.recv() {
                ReturnDequeMsg(index, deque) => self.workers.get_mut(index).deque = Some(deque),
                FinishedMsg => fail!("unexpected finished message!"),
            }
        }
    }

    pub fn shutdown(&mut self) {
        for worker in self.workers.iter() {
            worker.chan.send(ExitMsg)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix Parsing Issue (#319)<commit_after><|endoftext|>


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

trait Foo {}

fn foo<T: Foo + Foo>() {} //~ ERROR `Foo` already appears in the list of bounds

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Do not use Store::retrieve_for_module() anymore here<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #70238 - petrochenkov:procmod, r=Centril<commit_after>// Out-of-line module is found on the filesystem if passed through a proc macro (issue #58818).

// check-pass
// aux-build:test-macros.rs

#[macro_use]
extern crate test_macros;

mod outer {
    identity! { mod inner; }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add a simple example to measuring performance of writing data<commit_after>extern crate da;
extern crate env_logger;
extern crate rand;

use std::path::Path;

use rand::{SeedableRng, XorShiftRng, Rng};

use da::storage::{LevelDB, LevelDBOptions};
use da::storage::{Map, MapExt};

/// usage
/// path  - Directory where database is situated
/// count - Total amount of data items to write
/// data_len - Length of data chunk

fn main() {
    ::std::env::set_var("RUST_LOG", "da=info");

    let mut args = ::std::env::args();
    args.next();

    let path = args.next().unwrap();
    let count: usize = args.next().unwrap().parse().unwrap();
    let data_len: usize = args.next().unwrap().parse().unwrap();
    // TODO get them from command line
    let prefix = vec![1];
    let seed = [192, 168, 56, 1];

    let mut rng = XorShiftRng::from_seed(seed);
    let kv_generator = |_| {
        let mut v = vec![0; data_len];
        let mut k: Vec<u8> = vec![0; 32];

        rng.fill_bytes(&mut v);
        rng.fill_bytes(&mut k);
        (k, v)
    };

    let mut options = LevelDBOptions::new();
    options.create_if_missing = true;
    let mut db = LevelDB::new(&Path::new(&path), options).unwrap();

    let mut map = db.merkle_map(prefix);
    for item in (0..count).map(kv_generator) {
        map.put(&item.0, item.1.clone()).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Added a test for #! comments<commit_after>#!/usr/bin/env rustx
// pp-exact

import io::println;

fn main() { io::println("Hello World"); }
<|endoftext|>


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

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts;

/// Global flags for Servo, currently set on the command line.
#[deriving(Clone)]
pub struct Opts {
    /// The initial URLs to load.
    urls: ~[~str],

    /// The rendering backend to use (`-r`).
    render_backend: BackendType,

    /// How many threads to use for CPU rendering (`-t`).
    ///
    /// FIXME(pcwalton): This is not currently used. All rendering is sequential.
    n_render_threads: uint,

    /// True to use CPU painting, false to use GPU painting via Skia-GL (`-c`). Note that
    /// compositing is always done on the GPU.
    cpu_painting: bool,

    /// The maximum size of each tile in pixels (`-s`).
    tile_size: uint,

    /// `None` to disable the profiler or `Some` with an interval in seconds to enable it and cause
    /// it to produce output on that interval (`-p`).
    profiler_period: Option<f64>,

    /// True to exit after the page load (`-x`).
    exit_after_load: bool,

    output_file: Option<~str>,
    headless: bool,
}

pub fn from_cmdline_args(args: &[~str]) -> Opts {
    let args = args.tail();

    let opts = ~[
        getopts::optflag("c"),      // CPU rendering
        getopts::optopt("o"),       // output file
        getopts::optopt("r"),       // rendering backend
        getopts::optopt("s"),       // size of tiles
        getopts::optopt("t"),       // threads to render with
        getopts::optflagopt("p"),   // profiler flag and output interval
        getopts::optflag("x"),      // exit after load flag
        getopts::optflag("z"),      // headless mode
    ];

    let opt_match = match getopts::getopts(args, opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_err_msg()),
    };

    let urls = if opt_match.free.is_empty() {
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        opt_match.free.clone()
    };

    let render_backend = match opt_match.opt_str("r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match opt_match.opt_str("s") {
        Some(tile_size_str) => from_str(tile_size_str).unwrap(),
        None => 512,
    };

    let n_render_threads: uint = match opt_match.opt_str("t") {
        Some(n_render_threads_str) => from_str(n_render_threads_str).unwrap(),
        None => 1,      // FIXME: Number of cores.
    };

    // if only flag is present, default to 5 second period
    let profiler_period = do opt_match.opt_default("p", "5").map |period| {
        from_str(period).unwrap()
    };

    let cpu_painting = opt_match.opt_present("c");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        cpu_painting: cpu_painting,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: opt_match.opt_present("x"),
        output_file: opt_match.opt_str("o"),
        headless: opt_match.opt_present("z"),
    }
}
<commit_msg>Implemeting help message for servo browser app using groups::opts module.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Configuration options for a single run of the servo application. Created
//! from command line arguments.

use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend};
use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend};
use extra::getopts::groups;

/// Global flags for Servo, currently set on the command line.
#[deriving(Clone)]
pub struct Opts {
    /// The initial URLs to load.
    urls: ~[~str],

    /// The rendering backend to use (`-r`).
    render_backend: BackendType,

    /// How many threads to use for CPU rendering (`-t`).
    ///
    /// FIXME(pcwalton): This is not currently used. All rendering is sequential.
    n_render_threads: uint,

    /// True to use CPU painting, false to use GPU painting via Skia-GL (`-c`). Note that
    /// compositing is always done on the GPU.
    cpu_painting: bool,

    /// The maximum size of each tile in pixels (`-s`).
    tile_size: uint,

    /// `None` to disable the profiler or `Some` with an interval in seconds to enable it and cause
    /// it to produce output on that interval (`-p`).
    profiler_period: Option<f64>,

    /// True to exit after the page load (`-x`).
    exit_after_load: bool,

    output_file: Option<~str>,
    headless: bool,
}

fn print_usage(opts: &[groups::OptGroup]) {
    let message = format!("Usage: ./servo [ options ... ] [URL]\n\twhere options include");
    println(groups::usage(message, opts));
}

pub fn from_cmdline_args(args: &[~str]) -> Opts {
    let args = args.tail();

    let opts = ~[
        groups::optflag("c", "cpu", "CPU rendering"),
        groups::optopt("o", "output", "Output file", "output.png"),
        groups::optopt("r", "rendering", "Rendering backend", "direct2d|core-graphics|core-graphics-accelerated|cairo|skia."),
        groups::optopt("s", "size", "Size of tiles", "512"),
        groups::optopt("t", "threads", "Number of render threads", "1"),
        groups::optflagopt("p", "profile", "Profiler flag and output interval", "10"),
        groups::optflag("x", "exit", "Exit after load flag"),
        groups::optflag("z", "headless", "Headless mode"),
        groups::optflag("h", "help", "Print this message")
    ];

    let opt_match = match groups::getopts(args, opts) {
        Ok(m) => m,
        Err(f) => fail!(f.to_err_msg()),
    };

    if opt_match.opt_present("h") || opt_match.opt_present("help") {
        print_usage(opts);
        // TODO: how to return a null struct and let the caller know that
        // it should abort?
        fail!("")
    };

    let urls = if opt_match.free.is_empty() {
        print_usage(opts);
        fail!(~"servo asks that you provide 1 or more URLs")
    } else {
        opt_match.free.clone()
    };

    let render_backend = match opt_match.opt_str("r") {
        Some(backend_str) => {
            if backend_str == ~"direct2d" {
                Direct2DBackend
            } else if backend_str == ~"core-graphics" {
                CoreGraphicsBackend
            } else if backend_str == ~"core-graphics-accelerated" {
                CoreGraphicsAcceleratedBackend
            } else if backend_str == ~"cairo" {
                CairoBackend
            } else if backend_str == ~"skia" {
                SkiaBackend
            } else {
                fail!(~"unknown backend type")
            }
        }
        None => SkiaBackend
    };

    let tile_size: uint = match opt_match.opt_str("s") {
        Some(tile_size_str) => from_str(tile_size_str).unwrap(),
        None => 512,
    };

    let n_render_threads: uint = match opt_match.opt_str("t") {
        Some(n_render_threads_str) => from_str(n_render_threads_str).unwrap(),
        None => 1,      // FIXME: Number of cores.
    };

    // if only flag is present, default to 5 second period
    let profiler_period = do opt_match.opt_default("p", "5").map |period| {
        from_str(period).unwrap()
    };

    let cpu_painting = opt_match.opt_present("c");

    Opts {
        urls: urls,
        render_backend: render_backend,
        n_render_threads: n_render_threads,
        cpu_painting: cpu_painting,
        tile_size: tile_size,
        profiler_period: profiler_period,
        exit_after_load: opt_match.opt_present("x"),
        output_file: opt_match.opt_str("o"),
        headless: opt_match.opt_present("z"),
    }
}
<|endoftext|>


<commit_before><commit_msg>added closure example<commit_after>struct MyStruct {
    a: u32,
    b: u32,
}

fn main() {
    let mut vec : Vec<MyStruct> = Vec::new();

    vec.push(MyStruct{a: 1, b: 2});
    vec.push(MyStruct{a: 2, b: 2});

    for e in vec.into_iter().filter(|x| x.a > 1) {
        println!("{}", e.a);
    }
}<|endoftext|>


<commit_before><commit_msg>Add test for #2633. Xfailed.<commit_after>// Currently segfaults
// xfail-test
class cat {
    let mut meow: fn@();
    new() { self.meow = fn@() { #error("meow"); };}
}

type kitty_info = {kitty: cat};

// Code compiles and runs successfully if we add a + before the first arg
fn nyan(kitty: cat, _kitty_info: kitty_info) {
    kitty.meow();
}

fn main() {
    let mut kitty = cat();
    nyan(kitty, {kitty: kitty});
}<|endoftext|>


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

// xfail-test

struct Wrapper(~str);

impl Wrapper {
    pub fn new(wrapped: ~str) -> Wrapper {
        Wrapper(wrapped)
    }

    pub fn say_hi(&self) {
        println(fmt!("hello %s", **self));
    }
}

impl Drop for Wrapper {
    fn drop(&mut self) {}
}

fn main() {
    {
        // This runs without complaint.
        let x = Wrapper::new(~"Bob");
        x.say_hi();
    }
    {
        // This fails to compile, circa 0.8-89-gc635fba.
        // error: internal compiler error: drop_ty_immediate: non-box ty
        Wrapper::new(~"Bob").say_hi();
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use std::default::Default;
use std::fmt;
use std::str;

/// Represents a quality used in quality values.
///
/// Can be created with the `q` function.
///
/// # Implementation notes
///
/// The quality value is defined as a number between 0 and 1 with three decimal places. This means
/// there are 1000 possible values. Since floating point numbers are not exact and the smallest
/// floating point data type (`f32`) consumes four bytes, hyper uses an `u16` value to store the
/// quality internally. For performance reasons you may set quality directly to a value between
/// 0 and 1000 e.g. `Quality(532)` matches the quality `q=0.532`.
///
/// [RFC7231 Section 5.3.1](https://tools.ietf.org/html/rfc7231#section-5.3.1)
/// gives more information on quality values in HTTP header fields.
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Quality(pub u16);

impl fmt::Display for Quality {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            1000 => Ok(()),
            0 => f.write_str("; q=0"),
            x => write!(f, "; q=0.{}", format!("{:03}", x).trim_right_matches('0'))
        }
    }
}

impl Default for Quality {
    fn default() -> Quality {
        Quality(1000)
    }
}

/// Represents an item with a quality value as defined in
/// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.1).
#[derive(Clone, PartialEq, Debug)]
pub struct QualityItem<T> {
    /// The actual contents of the field.
    pub item: T,
    /// The quality (client or server preference) for the value.
    pub quality: Quality,
}

impl<T> QualityItem<T> {
    /// Creates a new `QualityItem` from an item and a quality.
    /// The item can be of any type.
    /// The quality should be a value in the range [0, 1].
    pub fn new(item: T, quality: Quality) -> QualityItem<T> {
        QualityItem {
            item: item,
            quality: quality
        }
    }
}

impl<T: PartialEq> cmp::PartialOrd for QualityItem<T> {
    fn partial_cmp(&self, other: &QualityItem<T>) -> Option<cmp::Ordering> {
        self.quality.partial_cmp(&other.quality)
    }
}

impl<T: fmt::Display> fmt::Display for QualityItem<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.item, format!("{}", self.quality))
    }
}

impl<T: str::FromStr> str::FromStr for QualityItem<T> {
    type Err = ::Error;
    fn from_str(s: &str) -> ::Result<QualityItem<T>> {
        // Set defaults used if parsing fails.
        let mut raw_item = s;
        let mut quality = 1f32;

        let parts: Vec<&str> = s.rsplitn(2, ';').map(|x| x.trim()).collect();
        if parts.len() == 2 {
            let start = &parts[0][0..2];
            if start == "q=" || start == "Q=" {
                let q_part = &parts[0][2..parts[0].len()];
                if q_part.len() > 5 {
                    return Err(::Error::Header);
                }
                match q_part.parse::<f32>() {
                    Ok(q_value) => {
                        if 0f32 <= q_value && q_value <= 1f32 {
                            quality = q_value;
                            raw_item = parts[1];
                            } else {
                                return Err(::Error::Header);
                            }
                        },
                    Err(_) => return Err(::Error::Header),
                }
            }
        }
        match raw_item.parse::<T>() {
            // we already checked above that the quality is within range
            Ok(item) => Ok(QualityItem::new(item, from_f32(quality))),
            Err(_) => return Err(::Error::Header),
        }
    }
}

fn from_f32(f: f32) -> Quality {
    // this function is only used internally. A check that `f` is within range
    // should be done before calling this method. Just in case, this
    // debug_assert should catch if we were forgetful
    debug_assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
    Quality((f * 1000f32) as u16)
}

/// Convinience function to wrap a value in a `QualityItem`
/// Sets `q` to the default 1.0
pub fn qitem<T>(item: T) -> QualityItem<T> {
    QualityItem::new(item, Default::default())
}

/// Convenience function to create a `Quality` fromt a float.
pub fn q(f: f32) -> Quality {
    assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
    from_f32(f)
}

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

    #[test]
    fn test_quality_item_show1() {
        let x = qitem(Chunked);
        assert_eq!(format!("{}", x), "chunked");
    }
    #[test]
    fn test_quality_item_show2() {
        let x = QualityItem::new(Chunked, Quality(1));
        assert_eq!(format!("{}", x), "chunked; q=0.001");
    }
    #[test]
    fn test_quality_item_show3() {
        // Custom value
        let x = QualityItem{
            item: EncodingExt("identity".to_owned()),
            quality: Quality(500),
        };
        assert_eq!(format!("{}", x), "identity; q=0.5");
    }

    #[test]
    fn test_quality_item_from_str1() {
        let x: ::Result<QualityItem<Encoding>> = "chunked".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Chunked, quality: Quality(1000), });
    }
    #[test]
    fn test_quality_item_from_str2() {
        let x: ::Result<QualityItem<Encoding>> = "chunked; q=1".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Chunked, quality: Quality(1000), });
    }
    #[test]
    fn test_quality_item_from_str3() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.5".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Gzip, quality: Quality(500), });
    }
    #[test]
    fn test_quality_item_from_str4() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.273".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Gzip, quality: Quality(273), });
    }
    #[test]
    fn test_quality_item_from_str5() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.2739999".parse();
        assert!(x.is_err());
    }
    #[test]
    fn test_quality_item_from_str6() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=2".parse();
        assert!(x.is_err());
    }
    #[test]
    fn test_quality_item_ordering() {
        let x: QualityItem<Encoding> = "gzip; q=0.5".parse().ok().unwrap();
        let y: QualityItem<Encoding> = "gzip; q=0.273".parse().ok().unwrap();
        let comparision_result: bool = x.gt(&y);
        assert!(comparision_result)
    }

    #[test]
    fn test_quality() {
        assert_eq!(q(0.5), Quality(500));
    }

    #[test]
    fn test_quality2() {
        assert_eq!(format!("{}", q(0.0)), "; q=0");
    }

    #[test]
    #[should_panic]
    fn test_quality_invalid() {
        q(-1.0);
    }

    #[test]
    #[should_panic]
    fn test_quality_invalid2() {
        q(2.0);
    }
}
<commit_msg>test(windows): Ignore #[should_panic] tests on 32-bit msvc<commit_after>use std::cmp;
use std::default::Default;
use std::fmt;
use std::str;

/// Represents a quality used in quality values.
///
/// Can be created with the `q` function.
///
/// # Implementation notes
///
/// The quality value is defined as a number between 0 and 1 with three decimal places. This means
/// there are 1000 possible values. Since floating point numbers are not exact and the smallest
/// floating point data type (`f32`) consumes four bytes, hyper uses an `u16` value to store the
/// quality internally. For performance reasons you may set quality directly to a value between
/// 0 and 1000 e.g. `Quality(532)` matches the quality `q=0.532`.
///
/// [RFC7231 Section 5.3.1](https://tools.ietf.org/html/rfc7231#section-5.3.1)
/// gives more information on quality values in HTTP header fields.
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Quality(pub u16);

impl fmt::Display for Quality {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            1000 => Ok(()),
            0 => f.write_str("; q=0"),
            x => write!(f, "; q=0.{}", format!("{:03}", x).trim_right_matches('0'))
        }
    }
}

impl Default for Quality {
    fn default() -> Quality {
        Quality(1000)
    }
}

/// Represents an item with a quality value as defined in
/// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.1).
#[derive(Clone, PartialEq, Debug)]
pub struct QualityItem<T> {
    /// The actual contents of the field.
    pub item: T,
    /// The quality (client or server preference) for the value.
    pub quality: Quality,
}

impl<T> QualityItem<T> {
    /// Creates a new `QualityItem` from an item and a quality.
    /// The item can be of any type.
    /// The quality should be a value in the range [0, 1].
    pub fn new(item: T, quality: Quality) -> QualityItem<T> {
        QualityItem {
            item: item,
            quality: quality
        }
    }
}

impl<T: PartialEq> cmp::PartialOrd for QualityItem<T> {
    fn partial_cmp(&self, other: &QualityItem<T>) -> Option<cmp::Ordering> {
        self.quality.partial_cmp(&other.quality)
    }
}

impl<T: fmt::Display> fmt::Display for QualityItem<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.item, format!("{}", self.quality))
    }
}

impl<T: str::FromStr> str::FromStr for QualityItem<T> {
    type Err = ::Error;
    fn from_str(s: &str) -> ::Result<QualityItem<T>> {
        // Set defaults used if parsing fails.
        let mut raw_item = s;
        let mut quality = 1f32;

        let parts: Vec<&str> = s.rsplitn(2, ';').map(|x| x.trim()).collect();
        if parts.len() == 2 {
            let start = &parts[0][0..2];
            if start == "q=" || start == "Q=" {
                let q_part = &parts[0][2..parts[0].len()];
                if q_part.len() > 5 {
                    return Err(::Error::Header);
                }
                match q_part.parse::<f32>() {
                    Ok(q_value) => {
                        if 0f32 <= q_value && q_value <= 1f32 {
                            quality = q_value;
                            raw_item = parts[1];
                            } else {
                                return Err(::Error::Header);
                            }
                        },
                    Err(_) => return Err(::Error::Header),
                }
            }
        }
        match raw_item.parse::<T>() {
            // we already checked above that the quality is within range
            Ok(item) => Ok(QualityItem::new(item, from_f32(quality))),
            Err(_) => return Err(::Error::Header),
        }
    }
}

fn from_f32(f: f32) -> Quality {
    // this function is only used internally. A check that `f` is within range
    // should be done before calling this method. Just in case, this
    // debug_assert should catch if we were forgetful
    debug_assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
    Quality((f * 1000f32) as u16)
}

/// Convinience function to wrap a value in a `QualityItem`
/// Sets `q` to the default 1.0
pub fn qitem<T>(item: T) -> QualityItem<T> {
    QualityItem::new(item, Default::default())
}

/// Convenience function to create a `Quality` fromt a float.
pub fn q(f: f32) -> Quality {
    assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
    from_f32(f)
}

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

    #[test]
    fn test_quality_item_show1() {
        let x = qitem(Chunked);
        assert_eq!(format!("{}", x), "chunked");
    }
    #[test]
    fn test_quality_item_show2() {
        let x = QualityItem::new(Chunked, Quality(1));
        assert_eq!(format!("{}", x), "chunked; q=0.001");
    }
    #[test]
    fn test_quality_item_show3() {
        // Custom value
        let x = QualityItem{
            item: EncodingExt("identity".to_owned()),
            quality: Quality(500),
        };
        assert_eq!(format!("{}", x), "identity; q=0.5");
    }

    #[test]
    fn test_quality_item_from_str1() {
        let x: ::Result<QualityItem<Encoding>> = "chunked".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Chunked, quality: Quality(1000), });
    }
    #[test]
    fn test_quality_item_from_str2() {
        let x: ::Result<QualityItem<Encoding>> = "chunked; q=1".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Chunked, quality: Quality(1000), });
    }
    #[test]
    fn test_quality_item_from_str3() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.5".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Gzip, quality: Quality(500), });
    }
    #[test]
    fn test_quality_item_from_str4() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.273".parse();
        assert_eq!(x.unwrap(), QualityItem{ item: Gzip, quality: Quality(273), });
    }
    #[test]
    fn test_quality_item_from_str5() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=0.2739999".parse();
        assert!(x.is_err());
    }
    #[test]
    fn test_quality_item_from_str6() {
        let x: ::Result<QualityItem<Encoding>> = "gzip; q=2".parse();
        assert!(x.is_err());
    }
    #[test]
    fn test_quality_item_ordering() {
        let x: QualityItem<Encoding> = "gzip; q=0.5".parse().ok().unwrap();
        let y: QualityItem<Encoding> = "gzip; q=0.273".parse().ok().unwrap();
        let comparision_result: bool = x.gt(&y);
        assert!(comparision_result)
    }

    #[test]
    fn test_quality() {
        assert_eq!(q(0.5), Quality(500));
    }

    #[test]
    fn test_quality2() {
        assert_eq!(format!("{}", q(0.0)), "; q=0");
    }

    #[test]
    #[should_panic] // FIXME - 32-bit msvc unwinding broken
    #[cfg_attr(all(target_arch="x86", target_env="msvc"), ignore)]
    fn test_quality_invalid() {
        q(-1.0);
    }

    #[test]
    #[should_panic] // FIXME - 32-bit msvc unwinding broken
    #[cfg_attr(all(target_arch="x86", target_env="msvc"), ignore)]
    fn test_quality_invalid2() {
        q(2.0);
    }
}
<|endoftext|>


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

use abi::{ArgAttribute, ArgType, CastTarget, FnType, LayoutExt, PassMode, Reg, RegKind, Uniform};
use context::CodegenCx;
use rustc::ty::layout::{self, Size};

fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) {
    // Always sign extend u32 values on 64-bit mips
    if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
        if let layout::Int(i, signed) = scalar.value {
            if !signed && i.size().bits() == 32 {
                if let PassMode::Direct(ref mut attrs) = arg.mode {
                    attrs.set(ArgAttribute::SExt);
                    return;
                }
            }
        }
    }

    arg.extend_integer_width_to(bits);
}

fn bits_to_int_reg(bits: u64) -> Reg {
    if bits <= 8 {
        Reg::i8()
    } else if bits <= 16 {
        Reg::i16()
    } else if bits <= 32 {
        Reg::i32()
    } else {
        Reg::i64()
    }
}

fn float_reg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &ArgType<'tcx>, i: usize) -> Option<Reg> {
    match ret.layout.field(cx, i).abi {
        layout::Abi::Scalar(ref scalar) => match scalar.value {
            layout::F32 => Some(Reg::f32()),
            layout::F64 => Some(Reg::f64()),
            _ => None
        },
        _ => None
    }
}

fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
    if !ret.layout.is_aggregate() {
        extend_integer_width_mips(ret, 64);
        return;
    }

    let size = ret.layout.size;
    let bits = size.bits();
    if bits <= 128 {
        // Unlike other architectures which return aggregates in registers, MIPS n64 limits the
        // use of float registers to structures (not unions) containing exactly one or two
        // float fields.

        if let layout::FieldPlacement::Arbitrary { .. } = ret.layout.fields {
            if ret.layout.fields.count() == 1 {
                if let Some(reg) = float_reg(cx, ret, 0) {
                    ret.cast_to(reg);
                    return;
                }
            } else if ret.layout.fields.count() == 2 {
                if let Some(reg0) = float_reg(cx, ret, 0) {
                    if let Some(reg1) = float_reg(cx, ret, 1) {
                        ret.cast_to(CastTarget::pair(reg0, reg1));
                        return;
                    }
                }
            }
        }

        // Cast to a uniform int structure
        ret.cast_to(Uniform {
            unit: bits_to_int_reg(bits),
            total: size
        });
    } else {
        ret.make_indirect();
    }
}

fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) {
    if !arg.layout.is_aggregate() {
        extend_integer_width_mips(arg, 64);
        return;
    }

    let dl = &cx.tcx.data_layout;
    let size = arg.layout.size;
    let mut prefix = [None; 8];
    let mut prefix_index = 0;

    match arg.layout.fields {
        layout::FieldPlacement::Array { .. } => {
            // Arrays are passed indirectly
            arg.make_indirect();
            return;
        }
        layout::FieldPlacement::Union(_) => {
            // Unions and are always treated as a series of 64-bit integer chunks
        },
        layout::FieldPlacement::Arbitrary { .. } => {
            // Structures are split up into a series of 64-bit integer chunks, but any aligned
            // doubles not part of another aggregate are passed as floats.
            let mut last_offset = Size::from_bytes(0);

            for i in 0..arg.layout.fields.count() {
                let field = arg.layout.field(cx, i);
                let offset = arg.layout.fields.offset(i);

                // We only care about aligned doubles
                if let layout::Abi::Scalar(ref scalar) = field.abi {
                    if let layout::F64 = scalar.value {
                        if offset.is_abi_aligned(dl.f64_align) {
                            // Insert enough integers to cover [last_offset, offset)
                            assert!(last_offset.is_abi_aligned(dl.f64_align));
                            for _ in 0..((offset - last_offset).bits() / 64)
                                .min((prefix.len() - prefix_index) as u64) {

                                prefix[prefix_index] = Some(RegKind::Integer);
                                prefix_index += 1;
                            }

                            if prefix_index == prefix.len() {
                                break;
                            }

                            prefix[prefix_index] = Some(RegKind::Float);
                            prefix_index += 1;
                            last_offset = offset + Reg::f64().size;
                        }
                    }
                }
            }
        }
    };

    // Extract first 8 chunks as the prefix
    let rest_size = size - Size::from_bytes(8) * prefix_index as u64;
    arg.cast_to(CastTarget {
        prefix: prefix,
        prefix_chunk: Size::from_bytes(8),
        rest: Uniform { unit: Reg::i64(), total: rest_size }
    });
}

pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) {
    if !fty.ret.is_ignore() {
        classify_ret_ty(cx, &mut fty.ret);
    }

    for arg in &mut fty.args {
        if arg.is_ignore() { continue; }
        classify_arg_ty(cx, arg);
    }
}
<commit_msg> rustc_trans: fix small aggregate returns for big-endian mips64 FFI<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use abi::{ArgAttribute, ArgType, CastTarget, FnType, LayoutExt, PassMode, Reg, RegKind, Uniform};
use context::CodegenCx;
use rustc::ty::layout::{self, Size};

fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) {
    // Always sign extend u32 values on 64-bit mips
    if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
        if let layout::Int(i, signed) = scalar.value {
            if !signed && i.size().bits() == 32 {
                if let PassMode::Direct(ref mut attrs) = arg.mode {
                    attrs.set(ArgAttribute::SExt);
                    return;
                }
            }
        }
    }

    arg.extend_integer_width_to(bits);
}

fn float_reg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &ArgType<'tcx>, i: usize) -> Option<Reg> {
    match ret.layout.field(cx, i).abi {
        layout::Abi::Scalar(ref scalar) => match scalar.value {
            layout::F32 => Some(Reg::f32()),
            layout::F64 => Some(Reg::f64()),
            _ => None
        },
        _ => None
    }
}

fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
    if !ret.layout.is_aggregate() {
        extend_integer_width_mips(ret, 64);
        return;
    }

    let size = ret.layout.size;
    let bits = size.bits();
    if bits <= 128 {
        // Unlike other architectures which return aggregates in registers, MIPS n64 limits the
        // use of float registers to structures (not unions) containing exactly one or two
        // float fields.

        if let layout::FieldPlacement::Arbitrary { .. } = ret.layout.fields {
            if ret.layout.fields.count() == 1 {
                if let Some(reg) = float_reg(cx, ret, 0) {
                    ret.cast_to(reg);
                    return;
                }
            } else if ret.layout.fields.count() == 2 {
                if let Some(reg0) = float_reg(cx, ret, 0) {
                    if let Some(reg1) = float_reg(cx, ret, 1) {
                        ret.cast_to(CastTarget::pair(reg0, reg1));
                        return;
                    }
                }
            }
        }

        // Cast to a uniform int structure
        ret.cast_to(Uniform {
            unit: Reg::i64(),
            total: size
        });
    } else {
        ret.make_indirect();
    }
}

fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) {
    if !arg.layout.is_aggregate() {
        extend_integer_width_mips(arg, 64);
        return;
    }

    let dl = &cx.tcx.data_layout;
    let size = arg.layout.size;
    let mut prefix = [None; 8];
    let mut prefix_index = 0;

    match arg.layout.fields {
        layout::FieldPlacement::Array { .. } => {
            // Arrays are passed indirectly
            arg.make_indirect();
            return;
        }
        layout::FieldPlacement::Union(_) => {
            // Unions and are always treated as a series of 64-bit integer chunks
        },
        layout::FieldPlacement::Arbitrary { .. } => {
            // Structures are split up into a series of 64-bit integer chunks, but any aligned
            // doubles not part of another aggregate are passed as floats.
            let mut last_offset = Size::from_bytes(0);

            for i in 0..arg.layout.fields.count() {
                let field = arg.layout.field(cx, i);
                let offset = arg.layout.fields.offset(i);

                // We only care about aligned doubles
                if let layout::Abi::Scalar(ref scalar) = field.abi {
                    if let layout::F64 = scalar.value {
                        if offset.is_abi_aligned(dl.f64_align) {
                            // Insert enough integers to cover [last_offset, offset)
                            assert!(last_offset.is_abi_aligned(dl.f64_align));
                            for _ in 0..((offset - last_offset).bits() / 64)
                                .min((prefix.len() - prefix_index) as u64) {

                                prefix[prefix_index] = Some(RegKind::Integer);
                                prefix_index += 1;
                            }

                            if prefix_index == prefix.len() {
                                break;
                            }

                            prefix[prefix_index] = Some(RegKind::Float);
                            prefix_index += 1;
                            last_offset = offset + Reg::f64().size;
                        }
                    }
                }
            }
        }
    };

    // Extract first 8 chunks as the prefix
    let rest_size = size - Size::from_bytes(8) * prefix_index as u64;
    arg.cast_to(CastTarget {
        prefix: prefix,
        prefix_chunk: Size::from_bytes(8),
        rest: Uniform { unit: Reg::i64(), total: rest_size }
    });
}

pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) {
    if !fty.ret.is_ignore() {
        classify_ret_ty(cx, &mut fty.ret);
    }

    for arg in &mut fty.args {
        if arg.is_ignore() { continue; }
        classify_arg_ty(cx, arg);
    }
}
<|endoftext|>


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

use ty;

use rustc_data_structures::indexed_vec::Idx;
use serialize::{self, Encoder, Decoder};

use std::fmt;
use std::u32;

newtype_index!(CrateNum
    {
        derive[Debug]
        ENCODABLE = custom

        /// Item definitions in the currently-compiled crate would have the CrateNum
        /// LOCAL_CRATE in their DefId.
        const LOCAL_CRATE = 0,

        /// Virtual crate for builtin macros
        // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
        // `CrateNum`s.
        const BUILTIN_MACROS_CRATE = u32::MAX,

        /// A CrateNum value that indicates that something is wrong.
        const INVALID_CRATE = u32::MAX - 1,
    });

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        assert!(x < (u32::MAX as usize));
        CrateNum(x as u32)
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum(x)
    }

    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    pub fn as_u32(&self) -> u32 {
        self.0
    }

    pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
}

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

impl serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u32(self.0)
    }
}

impl serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        d.read_u32().map(CrateNum)
    }
}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes into two
/// ranges: the "low" range (starting at zero) and the "high" range (starting at
/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these ranges.
newtype_index!(DefIndex
    {
        DEBUG_FORMAT = custom,

        /// The start of the "high" range of DefIndexes.
        const DEF_INDEX_HI_START = 1 << 31,

        /// The crate root is always assigned index 0 by the AST Map code,
        /// thanks to `NodeCollector::new`.
        const CRATE_DEF_INDEX = 0,
    });

impl fmt::Debug for DefIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "DefIndex({}:{})",
               self.address_space().index(),
               self.as_array_index())
    }
}

impl DefIndex {
    #[inline]
    pub fn from_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    #[inline]
    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    #[inline]
    pub fn as_u32(&self) -> u32 {
        self.0
    }

    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        if self.0 < DEF_INDEX_HI_START.0 {
            DefIndexAddressSpace::Low
        } else {
            DefIndexAddressSpace::High
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given "range" of the DefIndex,
    /// that is, if the DefIndex is part of the "high" range, the resulting
    /// index will be (DefIndex - DEF_INDEX_HI_START).
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 & !DEF_INDEX_HI_START.0) as usize
    }

    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
        DefIndex::new(address_space.start() + i)
    }
}

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }

    #[inline]
    pub fn start(&self) -> usize {
        self.index() * DEF_INDEX_HI_START.as_usize()
    }
}

/// A DefId identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DefId {{ krate: {:?}, index: {:?}",
               self.krate, self.index)?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " => {}", tcx.def_path_debug_str(*self))?;
            }
            Ok(())
        })?;

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

impl DefId {
    /// Make a local `DefId` with the given index.
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    pub fn is_local(&self) -> bool {
        self.krate == LOCAL_CRATE
    }
}
<commit_msg>incr.comp.: Implement UseSpecializedXXcodable for DefIndex and DefId.<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ty;

use rustc_data_structures::indexed_vec::Idx;
use serialize::{self, Encoder, Decoder, Decodable, Encodable};

use std::fmt;
use std::u32;

newtype_index!(CrateNum
    {
        derive[Debug]
        ENCODABLE = custom

        /// Item definitions in the currently-compiled crate would have the CrateNum
        /// LOCAL_CRATE in their DefId.
        const LOCAL_CRATE = 0,

        /// Virtual crate for builtin macros
        // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
        // `CrateNum`s.
        const BUILTIN_MACROS_CRATE = u32::MAX,

        /// A CrateNum value that indicates that something is wrong.
        const INVALID_CRATE = u32::MAX - 1,
    });

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        assert!(x < (u32::MAX as usize));
        CrateNum(x as u32)
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum(x)
    }

    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    pub fn as_u32(&self) -> u32 {
        self.0
    }

    pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
}

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

impl serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u32(self.0)
    }
}

impl serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        d.read_u32().map(CrateNum)
    }
}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes into two
/// ranges: the "low" range (starting at zero) and the "high" range (starting at
/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these ranges.
newtype_index!(DefIndex
    {
        DEBUG_FORMAT = custom,

        /// The start of the "high" range of DefIndexes.
        const DEF_INDEX_HI_START = 1 << 31,

        /// The crate root is always assigned index 0 by the AST Map code,
        /// thanks to `NodeCollector::new`.
        const CRATE_DEF_INDEX = 0,
    });

impl fmt::Debug for DefIndex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "DefIndex({}:{})",
               self.address_space().index(),
               self.as_array_index())
    }
}

impl DefIndex {
    #[inline]
    pub fn from_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    #[inline]
    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    #[inline]
    pub fn as_u32(&self) -> u32 {
        self.0
    }

    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        if self.0 < DEF_INDEX_HI_START.0 {
            DefIndexAddressSpace::Low
        } else {
            DefIndexAddressSpace::High
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given "range" of the DefIndex,
    /// that is, if the DefIndex is part of the "high" range, the resulting
    /// index will be (DefIndex - DEF_INDEX_HI_START).
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 & !DEF_INDEX_HI_START.0) as usize
    }

    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
        DefIndex::new(address_space.start() + i)
    }
}

impl serialize::UseSpecializedEncodable for DefIndex {
    #[inline]
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u32(self.0)
    }
}

impl serialize::UseSpecializedDecodable for DefIndex {
    #[inline]
    fn default_decode<D: Decoder>(d: &mut D) -> Result<DefIndex, D::Error> {
        d.read_u32().map(DefIndex)
    }
}

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }

    #[inline]
    pub fn start(&self) -> usize {
        self.index() * DEF_INDEX_HI_START.as_usize()
    }
}

/// A DefId identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DefId {{ krate: {:?}, index: {:?}",
               self.krate, self.index)?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " => {}", tcx.def_path_debug_str(*self))?;
            }
            Ok(())
        })?;

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

impl DefId {
    /// Make a local `DefId` with the given index.
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    pub fn is_local(&self) -> bool {
        self.krate == LOCAL_CRATE
    }
}

impl serialize::UseSpecializedEncodable for DefId {
    #[inline]
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        let DefId {
            krate,
            index,
        } = *self;

        krate.encode(s)?;
        index.encode(s)
    }
}

impl serialize::UseSpecializedDecodable for DefId {
    #[inline]
    fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
        let krate = CrateNum::decode(d)?;
        let index = DefIndex::decode(d)?;

        Ok(DefId {
            krate,
            index
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>(feat) Re-added ResponseTime example.<commit_after><|endoftext|>


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

// Issue #7580

// error-pattern:fail works
#[feature(globs)];

use std::*;

fn main() {
    str::with_capacity(10); // avoid an unused import message

    fail!("fail works")
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #62016 - JohnTitor:add-test-for-issue-27697, r=alexcrichton<commit_after>// run-pass

use std::ops::Deref;

trait MyTrait {
    fn do_something(&self);
    fn as_str(&self) -> &str;
}

impl Deref for dyn MyTrait {
    type Target = str;
    fn deref(&self) -> &Self::Target {
        self.as_str()
    }
}

fn trait_object_does_something(t: &dyn MyTrait) {
    t.do_something()
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>add regression test for #120<commit_after>#![feature(static_recursion)]

struct S(&'static S);
static S1: S = S(&S2);
static S2: S = S(&S1);

fn main() {
    let p: *const S = S2.0;
    let q: *const S = &S1;
    assert_eq!(p, q);
}
<|endoftext|>


<commit_before><commit_msg>FileWatcher now started within run()<commit_after><|endoftext|>


<commit_before>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
#[macro_use] extern crate version;

extern crate libimagnotes;
extern crate libimagrt;
extern crate libimagtag;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagnotes::note::Note;
use libimagutil::trace::trace_error;

mod ui;
use ui::build_ui;

fn main() {
    let name = "imag-notes";
    let version = &version!()[..];
    let about = "Note taking helper";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call: {}", name);
            match name {
                "create" => create(&rt),
                "delete" => delete(&rt),
                "edit"   => edit(&rt),
                "list"   => list(&rt),
                _        => {
                    debug!("Unknown command"); // More error handling
                },
            };
        });
}

fn create(rt: &Runtime) {
    let name = rt.cli()
        .subcommand_matches("create")
        .unwrap() // we already know it is there
        .value_of("name")
        .unwrap(); // enforced by clap

    Note::new(rt.store(), String::from(name), String::new())
        .map_err(|e| trace_error(&e))
        .map(|note| {
            // call editor now...
        });
}

fn delete(rt: &Runtime) {
    let name = rt.cli()
        .subcommand_matches("delete")
        .unwrap() // we already know it is there
        .value_of("name")
        .unwrap(); // enforced by clap

    Note::delete(rt.store(), String::from(name))
        .map_err(|e| trace_error(&e))
        .map(|_| println!("Ok"));
}

fn edit(rt: &Runtime) {
    unimplemented!()
}

fn list(rt: &Runtime) {
    use std::cmp::Ordering;

    let iter = Note::all_notes(rt.store());
    if iter.is_err() {
        trace_error(&iter.err().unwrap());
        exit(1);
    }

    let mut iter = iter.unwrap()
        .filter_map(|note| {
            match note {
                Err(e) => {
                    trace_error(&e);
                    None
                },
                Ok(e) => Some(e)
            }
        })
        .collect::<Vec<Note>>();

    iter.sort_by(|note_a, note_b| {
        if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
            return a.cmp(&b)
        } else {
            return Ordering::Greater;
        }
    });

    for note in iter {
        note.get_name().map(|name| println!("{}", name));
    }
}

<commit_msg>Move cli-name-extracting into helper function<commit_after>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
#[macro_use] extern crate version;

extern crate libimagnotes;
extern crate libimagrt;
extern crate libimagtag;
extern crate libimagutil;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagnotes::note::Note;
use libimagutil::trace::trace_error;

mod ui;
use ui::build_ui;

fn main() {
    let name = "imag-notes";
    let version = &version!()[..];
    let about = "Note taking helper";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call: {}", name);
            match name {
                "create" => create(&rt),
                "delete" => delete(&rt),
                "edit"   => edit(&rt),
                "list"   => list(&rt),
                _        => {
                    debug!("Unknown command"); // More error handling
                },
            };
        });
}

fn name_from_cli(rt: &Runtime, subcmd: &str) -> String {
    rt.cli().subcommand_matches(subcmd).unwrap().value_of("name").map(String::from).unwrap()
}

fn create(rt: &Runtime) {
    Note::new(rt.store(), String::from(name_from_cli(rt, "create")), String::new())
        .map_err(|e| trace_error(&e))
        .map(|note| {
            // call editor now...
        });
}

fn delete(rt: &Runtime) {
    Note::delete(rt.store(), String::from(name_from_cli(rt, "delete")))
        .map_err(|e| trace_error(&e))
        .map(|_| println!("Ok"));
}

fn edit(rt: &Runtime) {
    unimplemented!()
}

fn list(rt: &Runtime) {
    use std::cmp::Ordering;

    let iter = Note::all_notes(rt.store());
    if iter.is_err() {
        trace_error(&iter.err().unwrap());
        exit(1);
    }

    let mut iter = iter.unwrap()
        .filter_map(|note| {
            match note {
                Err(e) => {
                    trace_error(&e);
                    None
                },
                Ok(e) => Some(e)
            }
        })
        .collect::<Vec<Note>>();

    iter.sort_by(|note_a, note_b| {
        if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
            return a.cmp(&b)
        } else {
            return Ordering::Greater;
        }
    });

    for note in iter {
        note.get_name().map(|name| println!("{}", name));
    }
}

<|endoftext|>


<commit_before><commit_msg>Revert the ordering of planet and atmosphere rendering as the green-screen atmosphere problem has gone away<commit_after><|endoftext|>


<commit_before><commit_msg>Do not explicitly create a closure in calc_table_size<commit_after><|endoftext|>


<commit_before><commit_msg>bigpack: Add a 'kind' argument to compress_dir_to_big<commit_after><|endoftext|>