<commit_before><commit_msg>First batch of tests<commit_after>extern crate foxbox_adapters;
extern crate foxbox_taxonomy;

use foxbox_adapters::adapter::*;
use foxbox_adapters::manager::*;
use foxbox_taxonomy::api::{ AdapterError, API, ResultMap };
use foxbox_taxonomy::selector::*;
use foxbox_taxonomy::services::*;
use foxbox_taxonomy::util::*;
use foxbox_taxonomy::values::*;

use std::collections::HashSet;

struct TestAdapter {
    id: Id<AdapterId>,
    name: String
}

impl TestAdapter {
    fn new(id: &Id<AdapterId>) -> Self {
        TestAdapter {
            id: id.clone(),
            name: id.as_atom().to_string().clone()
        }
    }
}

static VERSION : [u32;4] = [0, 0, 0, 0];

impl Adapter for TestAdapter {
    /// An id unique to this adapter. This id must persist between
    /// reboots/reconnections.
    fn id(&self) -> Id<AdapterId> {
        self.id.clone()
    }

    /// The name of the adapter.
    fn name(&self) -> &str {
        &self.name
    }

    fn vendor(&self) -> &str {
        "test@foxbox_adapters"
    }

    fn version(&self) -> &[u32;4] {
        &VERSION
    }

    /// Request a value from a channel. The FoxBox (not the adapter)
    /// is in charge of keeping track of the age of values.
    fn fetch_values(&self, set: Vec<Id<Getter>>) -> ResultMap<Id<Getter>, Option<Value>, AdapterError> {
        unimplemented!()
    }

    /// Request that a value be sent to a channel.
    fn send_values(&self, values: Vec<(Id<Setter>, Value)>) -> ResultMap<Id<Setter>, (), AdapterError> {
        unimplemented!()
    }

    fn register_watch(&self, id: &Id<Getter>, threshold: Option<Value>, cb: Box<Fn(Value) + Send>) -> Result<Box<AdapterWatchGuard>, AdapterError> {
        unimplemented!()
    }
}

#[test]
fn test_add_remove_adapter() {
    let manager = AdapterManager::new();
    let id_1 = Id::new("id 1".to_owned());
    let id_2 = Id::new("id 2".to_owned());

    println!("* Adding two distinct test adapters should work.");
    manager.add_adapter(Box::new(TestAdapter::new(&id_1)), vec![]).unwrap();
    manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![]).unwrap();

    println!("* Attempting to add yet another test adapter with id_1 or id_2 should fail.");
    match manager.add_adapter(Box::new(TestAdapter::new(&id_1)), vec![]) {
        Err(AdapterError::DuplicateAdapter(ref id)) if *id == id_1 => {},
        other => panic!("Unexpected result {:?}", other)
    }
    match manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![]) {
        Err(AdapterError::DuplicateAdapter(ref id)) if *id == id_2 => {},
        other => panic!("Unexpected result {:?}", other)
    }

    println!("* Removing id_1 should succeed. At this stage, we still shouldn't be able to add id_2, \
              but we should be able to re-add id_1");
    manager.remove_adapter(&id_1).unwrap();
    match manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![]) {
        Err(AdapterError::DuplicateAdapter(ref id)) if *id == id_2 => {},
        other => panic!("Unexpected result {:?}", other)
    }
    manager.add_adapter(Box::new(TestAdapter::new(&id_1)), vec![]).unwrap();

    println!("* Removing id_1 twice should fail the second time.");
    manager.remove_adapter(&id_1).unwrap();
    match manager.remove_adapter(&id_1) {
        Err(AdapterError::NoSuchAdapter(ref id)) if *id == id_1 => {},
        other => panic!("Unexpected result {:?}", other)
    }
}

#[test]
fn test_add_remove_adapter_with_services() {
    let manager = AdapterManager::new();
    let id_1 = Id::new("adapter id 1".to_owned());
    let id_2 = Id::new("adapter id 2".to_owned());
    let id_3 = Id::new("adapter id 3".to_owned());

    let getter_id_1 = Id::new("getter id 1".to_owned());
    let getter_id_2 = Id::new("getter id 2".to_owned());
    let getter_id_3 = Id::new("getter id 3".to_owned());

    let setter_id_1 = Id::new("setter id 1".to_owned());
    let setter_id_2 = Id::new("setter id 2".to_owned());
    let setter_id_3 = Id::new("setter id 3".to_owned());

    let service_id_1 = Id::new("service id 1".to_owned());
    let service_id_2 = Id::new("service id 2".to_owned());
    let service_id_3 = Id::new("service id 3".to_owned());

    let getter_1 = Channel {
        id: getter_id_1.clone(),
        service: service_id_1.clone(),
        adapter: id_1.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Getter {
            updated: None,
            kind: ChannelKind::OnOff,
            watch: false,
            poll: None,
            trigger: None,
        },
    };

    let setter_1 = Channel {
        id: setter_id_1.clone(),
        service: service_id_1.clone(),
        adapter: id_1.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Setter {
            updated: None,
            kind: ChannelKind::OnOff,
            push: None,
        },
    };

    let service_1 = Service {
        id: service_id_1.clone(),
        adapter: id_1.clone(),
        tags: HashSet::new(),
        getters: vec![(getter_id_1.clone(), getter_1)].iter().cloned().collect(),
        setters: vec![(setter_id_1.clone(), setter_1)].iter().cloned().collect(),
    };

    let getter_2 = Channel {
        id: getter_id_2.clone(),
        service: service_id_2.clone(),
        adapter: id_2.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Getter {
            updated: None,
            kind: ChannelKind::OnOff,
            watch: false,
            poll: None,
            trigger: None,
        },
    };

    let setter_2 = Channel {
        id: setter_id_2.clone(),
        service: service_id_2.clone(),
        adapter: id_2.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Setter {
            updated: None,
            kind: ChannelKind::OnOff,
            push: None,
        },
    };

    let service_2 = Service {
        id: service_id_2.clone(),
        adapter: id_2.clone(),
        tags: HashSet::new(),
        getters: vec![(getter_id_2.clone(), getter_2)].iter().cloned().collect(),
        setters: vec![(setter_id_2.clone(), setter_2)].iter().cloned().collect(),
    };
    println!("* Adding an adapter with a service should fail if the adapter id doesn't match.");
    match manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![service_1.clone()]) {
        Err(AdapterError::ConflictingAdapter(ref err_1, ref err_2))
            if (*err_1 == id_1 && *err_2 == id_2)
            || (*err_1 == id_2 && *err_2 == id_1) => {},
        other => panic!("Unexpected result {:?}", other)
    }
    println!("* Adding an adapter with a service should fail if one of the adapter ids doesn't match.");
    match manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![service_2.clone(), service_1.clone()]) {
        Err(AdapterError::ConflictingAdapter(ref err_1, ref err_2))
            if (*err_1 == id_1 && *err_2 == id_2)
            || (*err_1 == id_2 && *err_2 == id_1) => {},
        other => panic!("Unexpected result {:?}", other)
    }
    println!("* Make sure that none of the getters, setters or services has been added.");
    assert_eq!(manager.get_services(&vec![ServiceSelector::new()]).len(), 0);
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new()]).len(), 0);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new()]).len(), 0);

    println!("* Adding an adapter with a service can succeed.");
    manager.add_adapter(Box::new(TestAdapter::new(&id_1)), vec![service_1.clone()]).unwrap();
    assert_eq!(manager.get_services(&vec![ServiceSelector::new()]).len(), 1);
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new()]).len(), 1);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new()]).len(), 1);

    println!("* Make sure that we are finding the right service.");
    assert_eq!(manager.get_services(&vec![ServiceSelector::new().with_id(service_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_services(&vec![ServiceSelector::new().with_id(service_id_2.clone())]).len(), 0);

    println!("* Make sure that we are finding the right channels.");
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new().with_id(getter_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new().with_id(getter_id_2.clone())]).len(), 0);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new().with_id(setter_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new().with_id(setter_id_2.clone())]).len(), 0);

    // This service has adapter id_2 but its channels disagree
    let getter_3 = Channel {
        id: getter_id_3.clone(),
        service: service_id_3.clone(),
        adapter: id_3.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Getter {
            updated: None,
            kind: ChannelKind::OnOff,
            watch: false,
            poll: None,
            trigger: None,
        },
    };

    let setter_3 = Channel {
        id: setter_id_3.clone(),
        service: service_id_3.clone(),
        adapter: id_3.clone(),
        last_seen: None,
        tags: HashSet::new(),
        mechanism: Setter {
            updated: None,
            kind: ChannelKind::OnOff,
            push: None,
        },
    };

    let service_3 = Service {
        id: service_id_3.clone(),
        adapter: id_2.clone(),
        tags: HashSet::new(),
        getters: vec![(getter_id_3.clone(), getter_3)].iter().cloned().collect(),
        setters: vec![(setter_id_3.clone(), setter_3)].iter().cloned().collect(),
    };
    println!("* Adding an adapter with a service should fail if channels don't have the right adapter id.");
    match manager.add_adapter(Box::new(TestAdapter::new(&id_2)), vec![service_3.clone()]) {
        Err(AdapterError::ConflictingAdapter(ref err_1, ref err_2))
            if (*err_1 == id_3 && *err_2 == id_2)
            || (*err_1 == id_2 && *err_2 == id_3) => {},
        other => panic!("Unexpected result {:?}", other)
    }

    println!("* Make sure that the old service is still here and the new one isn't.");
    assert_eq!(manager.get_services(&vec![ServiceSelector::new().with_id(service_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_services(&vec![ServiceSelector::new().with_id(service_id_3.clone())]).len(), 0);

    println!("* Make sure that the old channels are still here and the new ones aren't.");
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new().with_id(getter_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new().with_id(getter_id_3.clone())]).len(), 0);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new().with_id(setter_id_1.clone())]).len(), 1);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new().with_id(setter_id_3.clone())]).len(), 0);

    println!("* Make sure that we can remove the adapter we have successfully added and that this \
                removes the service and channels.");
    manager.remove_adapter(&id_1).unwrap();
    assert_eq!(manager.get_services(&vec![ServiceSelector::new().with_id(service_id_1.clone())]).len(), 0);
    assert_eq!(manager.get_getter_channels(&vec![GetterSelector::new().with_id(getter_id_1.clone())]).len(), 0);
    assert_eq!(manager.get_setter_channels(&vec![SetterSelector::new().with_id(setter_id_1.clone())]).len(), 0);

    println!("* Make sure that we cannot remove the adapter we failed to add.");
    match manager.remove_adapter(&id_2) {
        Err(AdapterError::NoSuchAdapter(ref id)) if *id == id_2 => {},
        other => panic!("Unexpected result {:?}", other)
    }
    println!("* Make sure that we cannot remove the non-existing adapter that we \
                implicitly mentioned.");
    match manager.remove_adapter(&id_3) {
        Err(AdapterError::NoSuchAdapter(ref id)) if *id == id_3 => {},
        other => panic!("Unexpected result {:?}", other)
    }
}<|endoftext|>


<commit_before><commit_msg>Make FOV slightly narrower<commit_after><|endoftext|>


<commit_before><commit_msg>Extract more information about job offers<commit_after><|endoftext|>


<commit_before><commit_msg>Regression test for #14386<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.

mod foo {
    pub use self::bar::X;
    use self::bar::X;
    //~^ ERROR a value named `X` has already been imported in this module
    //~| ERROR a type named `X` has already been imported in this module

    mod bar {
        pub struct X;
    }
}

fn main() {
    let _ = foo::X;
}
<|endoftext|>


<commit_before><commit_msg>Exponential distr.<commit_after><|endoftext|>


<commit_before><commit_msg>Split a long line.<commit_after><|endoftext|>


<commit_before><commit_msg>just time<commit_after><|endoftext|>


<commit_before><commit_msg>re-introducing trie.rs<commit_after>//! A trie representation of `(key, time, value, weight)` tuples, and routines to merge them.

use std::rc::Rc;
use std::collections::HashMap;
use std::cmp::Ordering;
use std::hash::Hash;

use iterators::merge::Merge as Whatever;
use iterators::coalesce::Coalesce;

/// Changes to frequencies.
pub type W = i32;

/// A collection of `(K, T, V, W)` tuples, grouped by `K` then `T` then `V`.
///
/// A `Trie` is a trie-representation of `(K, T, V, W)` tuples, meaning its representation is as a
/// sorted list of these tuples, where each of the fields are then stored separately and run-length
/// coded. The `keys` field is a sorted list of pairs `(K, usize)`, indicating a key and an offset
/// in the next-level array, `idxs`. Likewise, the `idxs` field contains a flat list of pairs
/// `(usize, usize)`, where each interval described by one entry of `keys` is sorted. Each entry
/// `(usize, usize)` indicates a time (element of the `times` field), and an offset in the `vals`
/// field. Finally, the `vals` field has each interval sorted by `V`.
#[derive(Debug, Eq, PartialEq)]
pub struct Trie<K, T, V> {
    /// Pairs of key and offset into `self.idxs`. Sorted by `key`.
    pub keys: Vec<(K, usize)>,
    /// Pairs of idx and offset into `self.vals`. Sorted by `idx`
    pub idxs: Vec<(usize, usize)>,
    /// Pairs of val and weight. Sorted by `val`.
    pub vals: Vec<(V, W)>,
    /// Pairs of timestamp and the number of references to the timestamp.
    pub times: Vec<(T, usize)>,
}

impl<K: Ord, T: Eq, V: Ord+Clone> Trie<K, T, V> {
    /// Constructs a new `Trie` containing no data.
    pub fn new() -> Trie<K, T, V> {
        Trie::with_capacities(0, 0, 0)
    }

    /// Allocates a new `Trie` with initial capacities for `keys`, `idxs`, and `vals`.
    pub fn with_capacities(k: usize, i: usize, v: usize) -> Trie<K, T, V> {
        Trie {
            keys: Vec::with_capacity(k),
            idxs: Vec::with_capacity(i),
            vals: Vec::with_capacity(v),
            times: Vec::new(),
        }
    }

    /// Returns the number of tuples represented by `Self`.
    pub fn len(&self) -> usize {
        self.vals.len()
    }

    /// A helper method used to merge slices `&[(V,W)]` with the same index and push to the result.
    fn merge_and_push(&mut self, idxs: &mut [(usize, &[(V,W)])]) {

        // track the length of `vals` to know if our merge resulted in any `(V,W)` output.
        let vals_len = self.vals.len();

        if idxs.len() == 1 {
            self.vals.extend_from_slice(idxs[0].1);
        }
        else {
            // TODO : merge_using may be important here
            self.vals.extend(idxs.iter()
                                         .map(|&(_, ref slice)| slice.iter().cloned())
                                         .merge()
                                         .coalesce());
        }

        // if we produced `(val,wgt)` data, push the new length and the indicated `idx` in result.
        // also increment the reference count for `idx`, so that we know it is important.
        if self.vals.len() > vals_len {
            self.idxs.push((idxs[0].0, self.vals.len()));
            self.times[idxs[0].0].1 += 1;
        }
    }
}

/// Per-Trie information used as part of merging Tries.
struct MergePart<K, T, V> {
    /// Source Trie to merge from.
    trie: Rc<Trie<K, T, V>>,
    /// Mapping from timestamp indices used in `self.trie` to indices used in the merge result.
    remap: Vec<usize>,
    /// Current key under consideration.
    key: usize,
}

impl<K, T, V> MergePart<K, T, V> {
    /// Constructs a new `MergePart` from a source `Rc<Trie>`.
    fn new(trie: &Rc<Trie<K, T, V>>) -> MergePart<K, T, V> {
        MergePart {
            trie: trie.clone(),
            remap: Vec::with_capacity(trie.times.len()),
            key: 0,
        }
    }
    /// Returns a reference to the part's next key, or `None` if all keys have been exhausted.
    fn key(&self) -> Option<&K> {
        if self.key < self.trie.keys.len() {
            Some(&self.trie.keys[self.key].0)
        }
        else {
            None
        }
    }
}

/// A merge-in-progress of two instances of `Trie<K, T, V>`.
///
/// A `Merge` represents a partial merge of two instances of `Trie<K, T, V>` into one instance,
/// where times are advanced according to a function `advance` supplied to the `new` constructor,
/// and like `(K, T, V, _)` tuples are consolidated into at most on result tuple.
///
/// A `Merge` can execute progressively, allowing a large amount of work to be amortized over the
/// large number of tuples involved. The `MergePart` structs contained in a `Merge` use `Rc<Trie>`
/// fields to capture their Tries, as the `Merge` does not mutate the source `Trie` instances.
pub struct Merge<K, T, V> {
    /// The first Trie and associated information.
    part1: MergePart<K, T, V>,
    /// The second Trie and associated information.
    part2: MergePart<K, T, V>,
    /// The result Trie, in progress.
    result: Trie<K, T, V>,
}

// The `Merge` struct merges two `Trie`s, progressively. Ideally, it does this relatively quickly,
// without lots of sorting and shuffling and such. The common case is likely to be many regions
// left un-adjusted, and it would be good to optimize for this case.
impl<K: Ord+Clone, T: Eq+Clone+Hash, V: Ord+Clone> Merge<K, T, V> {
    /// Constructs a new `Merge` from two instances of `Teir` and a function advancing timestamps.
    ///
    /// This method initiates a merge of two Tries, consolidating their representation which can
    /// potentially reduce the complexity and amount of memory required to describe a trace. The
    /// required inputs are two `Rc<Trie<K, T, V>>` instances to merge, and a function `advance`
    /// from `&T` to `T` indicating how timestamps should be advanced.
    ///
    /// As part of initiating the merge, `new` will scan through the timestamps used by each source
    /// `Trie`, advancing each and creating a mapping from timestamp indices in each source to new
    /// advanced and unified timestamp indices.
    pub fn new<F: Fn(&T)->T>(trie1: &Rc<Trie<K, T, V>>, trie2: &Rc<Trie<K, T, V>>, advance: &F) -> Merge<K, T, V> {

        // construct wrappers for each Trie.
        let part1 = MergePart::<K, T, V>::new(trie1);
        let part2 = MergePart::<K, T, V>::new(trie2);

        // prepare the result, which we will adjust further before returning.
        let mut result = Merge { part1: part1, part2: part2, result: Trie::<K, T, V>::new() };

        // advance times in trie1, update `times_map` and `result.part1.remap`,
        let mut times_map = HashMap::new();
        for &(ref time, count) in trie1.times.iter() {
            if count > 0 {
                let time = advance(time);
                if !times_map.contains_key(&time) {
                    let len = times_map.len();
                    times_map.insert(time.clone(), len);
                    result.result.times.push((time.clone(), 0));
                }

                result.part1.remap.push(times_map[&time]);
            }
        }

        // advance times in trie2, update `times_map` and `result.part1.remap`,
        for &(ref time, count) in trie2.times.iter() {
            if count > 0 {
                let time = advance(time);
                if !times_map.contains_key(&time) {
                    let len = times_map.len();
                    times_map.insert(time.clone(), len);
                    result.result.times.push((time.clone(), 0));
                }

                result.part2.remap.push(times_map[&time]);
            }
        }

        result
    }

    /// Advances the `Merge` by one step, returning the merged Tries if it is now complete.
    ///
    /// The `step` method considers the next key proposed by `trie1` and `trie2`, and populates
    /// `self.result` as appropriate. If both `trie1` and `trie2` have the same key and the merged
    /// results cancel one-another, `self.result` may not actually change (although the merge has
    /// performed useful work).
    ///
    /// The `step` method returns `Some(result)` if the merge is now complete, and `None` if it is
    /// not yet complete, and should be called more.
    ///
    /// Once `step` returns a result, the `Merge` contains an empty `result` field. It is then a
    /// logic error to do anything other than discard the `Merge`, though the usage patterns don't
    /// currently enforce this.
    pub fn step(&mut self) -> Option<Trie<K, T, V>> {

        // the intended logic here is that we must first determine which keys in each of the input
        // Tries we are going to merge. having done this, we populate a vector `to_merge` of pairs
        // `(idx, &[(val, wgt)])`, which is then sorted by `idx` and subranges of the sorted vector
        // and then passed to `merge_and_push`, which performs a merge for several `&[(val, wgt)]`
        // which correspond to the same `idx`.

        // note that even if only a single key is selected, because timestamps have been advanced
        // there may be indices that now occur multiple times. we could consider adding a fast-path
        // for the case where the entries of `to_merge` are already sorted, which could be reduced
        // to a memcpy from the `vals` fields of the corresponding Tries. be careful that just
        // because `to_merge` is sorted does not mean that it derives from only one Trie.

        // determine the minimum key, and which of part1 and part2 are involved.
        let (min1, min2) = {
            let (min_key, min1, min2) = match (self.part1.key(), self.part2.key()) {
                (None, None)             => { return Some(::std::mem::replace(&mut self.result, Trie::new())); },
                (Some(key), None)        => (key, true, false),
                (None, Some(key))        => (key, false, true),
                (Some(key1), Some(key2)) => {
                    match key1.cmp(key2) {
                        Ordering::Less    => (key1, true, false),
                        Ordering::Equal   => (key1, true, true),
                        Ordering::Greater => (key2, false, true),
                    }
                },
            };

            // create a vector to populate with &[(V,W)] slices to merge.
            // TODO : can we stash this; maybe with an unsafe transmute?
            let mut to_merge = Vec::new();

            if min1 {
                // the lower bound is either the previous offset or zero.
                let lower = if self.part1.key > 0 { self.part1.trie.keys[self.part1.key-1].1 } else { 0 };
                for i in lower .. self.part1.trie.keys[self.part1.key].1 {
                    let (idx, off) = self.part1.trie.idxs[i];
                    let lower = if i > 0 { self.part1.trie.idxs[i-1].1 } else { 0 };
                    to_merge.push((self.part1.remap[idx], &self.part1.trie.vals[lower .. off]));
                }
            }

            if min2 {
                // the lower bound is either the previous offset or zero.
                let lower = if self.part2.key > 0 { self.part2.trie.keys[self.part2.key-1].1 } else { 0 };
                for i in lower .. self.part2.trie.keys[self.part2.key].1 {
                    let (idx, off) = self.part2.trie.idxs[i];
                    let lower = if i > 0 { self.part2.trie.idxs[i-1].1 } else { 0 };
                    to_merge.push((self.part2.remap[idx], &self.part2.trie.vals[lower .. off]));
                }
            }

            // `to_merge` now has everything we need to merge.
            // we now sort it by index, to co-locate indices.
            to_merge.sort_by(|x,y| (x.0).cmp(&(y.0)));

            // capture the current list of idxs so that we know if our additions have resulted in
            // any data. we should not push the key if we pushed no idxs due to consolidation.
            let idxs_len = self.result.idxs.len();

            let mut old_idx = 0;
            let mut idx_cnt = 0;
            for i in 0..to_merge.len() {

                // if the idx changes we should merge.
                if i > 0 && old_idx != to_merge[i].0 {
                    self.result.merge_and_push(&mut to_merge[i - idx_cnt .. i]);
                    old_idx = to_merge[i].0;
                    idx_cnt = 0;
                }

                idx_cnt += 1;
            }

            let len = to_merge.len();
            self.result.merge_and_push(&mut to_merge[len - idx_cnt .. len]);

            // if the merge resulted in data, push a clone of the key and the current offset.
            if self.result.idxs.len() > idxs_len {
                self.result.keys.push((min_key.clone(), self.result.idxs.len()));
            }

            (min1, min2)
        };

        // we can only advance keys after we release the borrow on the key.
        if min1 { self.part1.key += 1; }
        if min2 { self.part2.key += 1; }

        None
    }
}

#[cfg(test)]
mod tests {

    use std::rc::Rc;
    use super::{Trie, Merge};

    #[test] fn merge_none() {

        let trie1: Rc<Trie<u64, u64, u64>> = Rc::new(Trie::new());
        let trie2: Rc<Trie<u64, u64, u64>> = Rc::new(Trie::new());

        let mut merge = Merge::new(&trie1, &trie2, &|_x| 0);

        loop {
            println!("step");
            if let Some(result) = merge.step() {
                println!("yay");
                println!("{:?}", result);

                assert_eq!(result, Trie::new());

                break;
            }
        }
    }
    #[test] fn merge_one() {

        let trie1 = Rc::new(Trie {
            keys: vec![("a", 2), ("b", 5), ("c", 6)],
            idxs: vec![(0, 2), (1, 3), (0, 5), (1, 6), (2, 7), (0, 9)],
            vals: vec![(0, 1), (1, 1), (0, -1), (0,1), (1,1), (1,-1), (0,-1), (2, 1), (3, 1)],
            times: vec![(0, 3), (1, 2), (2, 1)],
        });

        let trie2 = Rc::new(Trie::new());

        let mut merge = Merge::new(&trie1, &trie2, &|_x| 0);

        loop {
            println!("step");
            if let Some(result) = merge.step() {
                println!("yay");
                println!("{:?}", result);

                assert_eq!(result, Trie {
                    keys: vec![("a", 1), ("c", 2)],
                    idxs: vec![(0, 1), (0, 3)],
                    vals: vec![(1, 1), (2, 1), (3, 1)],
                    times: vec![(0, 2)],
                });

                break;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>fix non_exhaustive: forgot to add new file<commit_after>/// This type is public but not publically reachable
///
/// It is used to prevent direct construction of structs, but allow functional updates like: `Foo
/// { bar: 0, ..Default::default() }`
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
pub struct NonExhaustiveMarker;
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>Added dsl_pool<commit_after>pub struct DslPool {
    // Immutable
    root_dir_obj: u64,
}
<|endoftext|>


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

//! Useful synchronization primitives.
//!
//! This module contains useful safe and unsafe synchronization primitives.
//! Most of the primitives in this module do not provide any sort of locking
//! and/or blocking at all, but rather provide the necessary tools to build
//! other types of concurrent primitives.

#![stable(feature = "rust1", since = "1.0.0")]

#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::arc::{Arc, Weak};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::sync::atomic;

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::barrier::{Barrier, BarrierWaitResult};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::mutex::MUTEX_INIT;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::once::{Once, ONCE_INIT};
#[stable(feature = "rust1", since = "1.0.0")]
pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};

pub mod mpsc;

mod barrier;
mod condvar;
mod mutex;
mod once;
mod rwlock;
<commit_msg>Export OnceState from libstd<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.

//! Useful synchronization primitives.
//!
//! This module contains useful safe and unsafe synchronization primitives.
//! Most of the primitives in this module do not provide any sort of locking
//! and/or blocking at all, but rather provide the necessary tools to build
//! other types of concurrent primitives.

#![stable(feature = "rust1", since = "1.0.0")]

#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::arc::{Arc, Weak};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::sync::atomic;

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::barrier::{Barrier, BarrierWaitResult};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::mutex::MUTEX_INIT;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::once::{Once, OnceState, ONCE_INIT};
#[stable(feature = "rust1", since = "1.0.0")]
pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};

pub mod mpsc;

mod barrier;
mod condvar;
mod mutex;
mod once;
mod rwlock;
<|endoftext|>


<commit_before><commit_msg>languages/rust/rust-book/3-chapter/25-code/multiple_phrases/src/chinese/greetings.rs<commit_after><|endoftext|>


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

// A module for searching for libraries
// FIXME (#2658): I'm not happy how this module turned out. Should
// probably just be folded into cstore.

use core::prelude::*;

use core::option;
use core::os;
use core::result::Result;
use core::result;
use core::str;

export FileSearch;
export mk_filesearch;
export pick;
export pick_file;
export search;
export relative_target_lib_path;
export get_cargo_sysroot;
export get_cargo_root;
export get_cargo_root_nearest;
export libdir;

type pick<T> = fn(path: &Path) -> Option<T>;

fn pick_file(file: Path, path: &Path) -> Option<Path> {
    if path.file_path() == file { option::Some(copy *path) }
    else { option::None }
}

trait FileSearch {
    fn sysroot() -> Path;
    fn lib_search_paths() -> ~[Path];
    fn get_target_lib_path() -> Path;
    fn get_target_lib_file_path(file: &Path) -> Path;
}

fn mk_filesearch(maybe_sysroot: Option<Path>,
                 target_triple: &str,
                 +addl_lib_search_paths: ~[Path]) -> FileSearch {
    type filesearch_impl = {sysroot: Path,
                            addl_lib_search_paths: ~[Path],
                            target_triple: ~str};
    impl filesearch_impl: FileSearch {
        fn sysroot() -> Path { /*bad*/copy self.sysroot }
        fn lib_search_paths() -> ~[Path] {
            let mut paths = /*bad*/copy self.addl_lib_search_paths;

            paths.push(
                make_target_lib_path(&self.sysroot,
                                     self.target_triple));
            match get_cargo_lib_path_nearest() {
              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
              result::Err(_) => ()
            }
            match get_cargo_lib_path() {
              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
              result::Err(_) => ()
            }
            paths
        }
        fn get_target_lib_path() -> Path {
            make_target_lib_path(&self.sysroot, self.target_triple)
        }
        fn get_target_lib_file_path(file: &Path) -> Path {
            self.get_target_lib_path().push_rel(file)
        }
    }

    let sysroot = get_sysroot(maybe_sysroot);
    debug!("using sysroot = %s", sysroot.to_str());
    {sysroot: sysroot,
     addl_lib_search_paths: addl_lib_search_paths,
     target_triple: str::from_slice(target_triple)} as FileSearch
}

fn search<T: Copy>(filesearch: FileSearch, pick: pick<T>) -> Option<T> {
    let mut rslt = None;
    for filesearch.lib_search_paths().each |lib_search_path| {
        debug!("searching %s", lib_search_path.to_str());
        for os::list_dir_path(lib_search_path).each |path| {
            debug!("testing %s", path.to_str());
            let maybe_picked = pick(*path);
            if maybe_picked.is_some() {
                debug!("picked %s", path.to_str());
                rslt = maybe_picked;
                break;
            } else {
                debug!("rejected %s", path.to_str());
            }
        }
        if rslt.is_some() { break; }
    }
    return rslt;
}

fn relative_target_lib_path(target_triple: &str) -> Path {
    Path(libdir()).push_many([~"rustc",
                              str::from_slice(target_triple),
                              libdir()])
}

fn make_target_lib_path(sysroot: &Path,
                        target_triple: &str) -> Path {
    sysroot.push_rel(&relative_target_lib_path(target_triple))
}

fn get_or_default_sysroot() -> Path {
    match os::self_exe_path() {
      option::Some(ref p) => (*p).pop(),
      option::None => fail ~"can't determine value for sysroot"
    }
}

fn get_sysroot(maybe_sysroot: Option<Path>) -> Path {
    match maybe_sysroot {
      option::Some(ref sr) => (/*bad*/copy *sr),
      option::None => get_or_default_sysroot()
    }
}

fn get_cargo_sysroot() -> Result<Path, ~str> {
    result::Ok(get_or_default_sysroot().push_many([libdir(), ~"cargo"]))
}

fn get_cargo_root() -> Result<Path, ~str> {
    match os::getenv(~"CARGO_ROOT") {
        Some(ref _p) => result::Ok(Path((*_p))),
        None => match os::homedir() {
          Some(ref _q) => result::Ok((*_q).push(".cargo")),
          None => result::Err(~"no CARGO_ROOT or home directory")
        }
    }
}

fn get_cargo_root_nearest() -> Result<Path, ~str> {
    do result::chain(get_cargo_root()) |p| {
        let cwd = os::getcwd();
        let cwd_cargo = cwd.push(".cargo");
        let mut par_cargo = cwd.pop().push(".cargo");
        let mut rslt = result::Ok(copy cwd_cargo);  // XXX: Bad copy.

        if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p {
            while par_cargo != p {
                if os::path_is_dir(&par_cargo) {
                    rslt = result::Ok(par_cargo);
                    break;
                }
                if par_cargo.components.len() == 1 {
                    // We just checked /.cargo, stop now.
                    break;
                }
                par_cargo = par_cargo.pop().pop().push(".cargo");
            }
        }
        rslt
    }
}

fn get_cargo_lib_path() -> Result<Path, ~str> {
    do result::chain(get_cargo_root()) |p| {
        result::Ok(p.push(libdir()))
    }
}

fn get_cargo_lib_path_nearest() -> Result<Path, ~str> {
    do result::chain(get_cargo_root_nearest()) |p| {
        result::Ok(p.push(libdir()))
    }
}

// The name of the directory rustc expects libraries to be located.
// On Unix should be "lib", on windows "bin"
fn libdir() -> ~str {
   let libdir = env!("CFG_LIBDIR");
   if str::is_empty(libdir) {
      fail ~"rustc compiled without CFG_LIBDIR environment variable";
   }
   libdir
}
<commit_msg>rustc: One Less Bad Copy<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// A module for searching for libraries
// FIXME (#2658): I'm not happy how this module turned out. Should
// probably just be folded into cstore.

use core::prelude::*;

use core::option;
use core::os;
use core::result::Result;
use core::result;
use core::str;

export FileSearch;
export mk_filesearch;
export pick;
export pick_file;
export search;
export relative_target_lib_path;
export get_cargo_sysroot;
export get_cargo_root;
export get_cargo_root_nearest;
export libdir;

type pick<T> = fn(path: &Path) -> Option<T>;

fn pick_file(file: Path, path: &Path) -> Option<Path> {
    if path.file_path() == file { option::Some(copy *path) }
    else { option::None }
}

trait FileSearch {
    fn sysroot() -> Path;
    fn lib_search_paths() -> ~[Path];
    fn get_target_lib_path() -> Path;
    fn get_target_lib_file_path(file: &Path) -> Path;
}

fn mk_filesearch(maybe_sysroot: Option<Path>,
                 target_triple: &str,
                 +addl_lib_search_paths: ~[Path]) -> FileSearch {
    type filesearch_impl = {sysroot: Path,
                            addl_lib_search_paths: ~[Path],
                            target_triple: ~str};
    impl filesearch_impl: FileSearch {
        fn sysroot() -> Path { /*bad*/copy self.sysroot }
        fn lib_search_paths() -> ~[Path] {
            let mut paths = /*bad*/copy self.addl_lib_search_paths;

            paths.push(
                make_target_lib_path(&self.sysroot,
                                     self.target_triple));
            match get_cargo_lib_path_nearest() {
              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
              result::Err(_) => ()
            }
            match get_cargo_lib_path() {
              result::Ok(ref p) => paths.push((/*bad*/copy *p)),
              result::Err(_) => ()
            }
            paths
        }
        fn get_target_lib_path() -> Path {
            make_target_lib_path(&self.sysroot, self.target_triple)
        }
        fn get_target_lib_file_path(file: &Path) -> Path {
            self.get_target_lib_path().push_rel(file)
        }
    }

    let sysroot = get_sysroot(maybe_sysroot);
    debug!("using sysroot = %s", sysroot.to_str());
    {sysroot: sysroot,
     addl_lib_search_paths: addl_lib_search_paths,
     target_triple: str::from_slice(target_triple)} as FileSearch
}

fn search<T: Copy>(filesearch: FileSearch, pick: pick<T>) -> Option<T> {
    let mut rslt = None;
    for filesearch.lib_search_paths().each |lib_search_path| {
        debug!("searching %s", lib_search_path.to_str());
        for os::list_dir_path(lib_search_path).each |path| {
            debug!("testing %s", path.to_str());
            let maybe_picked = pick(*path);
            if maybe_picked.is_some() {
                debug!("picked %s", path.to_str());
                rslt = maybe_picked;
                break;
            } else {
                debug!("rejected %s", path.to_str());
            }
        }
        if rslt.is_some() { break; }
    }
    return rslt;
}

fn relative_target_lib_path(target_triple: &str) -> Path {
    Path(libdir()).push_many([~"rustc",
                              str::from_slice(target_triple),
                              libdir()])
}

fn make_target_lib_path(sysroot: &Path,
                        target_triple: &str) -> Path {
    sysroot.push_rel(&relative_target_lib_path(target_triple))
}

fn get_or_default_sysroot() -> Path {
    match os::self_exe_path() {
      option::Some(ref p) => (*p).pop(),
      option::None => fail ~"can't determine value for sysroot"
    }
}

fn get_sysroot(maybe_sysroot: Option<Path>) -> Path {
    match maybe_sysroot {
      option::Some(ref sr) => (/*bad*/copy *sr),
      option::None => get_or_default_sysroot()
    }
}

fn get_cargo_sysroot() -> Result<Path, ~str> {
    result::Ok(get_or_default_sysroot().push_many([libdir(), ~"cargo"]))
}

fn get_cargo_root() -> Result<Path, ~str> {
    match os::getenv(~"CARGO_ROOT") {
        Some(ref _p) => result::Ok(Path((*_p))),
        None => match os::homedir() {
          Some(ref _q) => result::Ok((*_q).push(".cargo")),
          None => result::Err(~"no CARGO_ROOT or home directory")
        }
    }
}

fn get_cargo_root_nearest() -> Result<Path, ~str> {
    do result::chain(get_cargo_root()) |p| {
        let cwd = os::getcwd();
        let cwd_cargo = cwd.push(".cargo");
        let cargo_is_non_root_file =
            !os::path_is_dir(&cwd_cargo) && cwd_cargo != p;
        let mut par_cargo = cwd.pop().push(".cargo");
        let mut rslt = result::Ok(cwd_cargo);

        if cargo_is_non_root_file {
            while par_cargo != p {
                if os::path_is_dir(&par_cargo) {
                    rslt = result::Ok(par_cargo);
                    break;
                }
                if par_cargo.components.len() == 1 {
                    // We just checked /.cargo, stop now.
                    break;
                }
                par_cargo = par_cargo.pop().pop().push(".cargo");
            }
        }
        rslt
    }
}

fn get_cargo_lib_path() -> Result<Path, ~str> {
    do result::chain(get_cargo_root()) |p| {
        result::Ok(p.push(libdir()))
    }
}

fn get_cargo_lib_path_nearest() -> Result<Path, ~str> {
    do result::chain(get_cargo_root_nearest()) |p| {
        result::Ok(p.push(libdir()))
    }
}

// The name of the directory rustc expects libraries to be located.
// On Unix should be "lib", on windows "bin"
fn libdir() -> ~str {
   let libdir = env!("CFG_LIBDIR");
   if str::is_empty(libdir) {
      fail ~"rustc compiled without CFG_LIBDIR environment variable";
   }
   libdir
}
<|endoftext|>


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

use check::{FnCtxt, structurally_resolved_type};
use check::demand;
use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode};
use middle::traits::{Obligation, ObligationCause};
use middle::traits::report_fulfillment_errors;
use middle::ty::{self, Ty, AsPredicate};
use syntax::ast;
use syntax::codemap::Span;
use util::nodemap::FnvHashSet;
use util::ppaux::{Repr, UserString};

pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   cast_expr: &ast::Expr,
                                   source_expr: &ast::Expr,
                                   target_object_ty: Ty<'tcx>)
{
    let tcx = fcx.tcx();
    debug!("check_object_cast(cast_expr={}, target_object_ty={})",
           cast_expr.repr(tcx),
           target_object_ty.repr(tcx));

    // Look up vtables for the type we're casting to,
    // passing in the source and target type.  The source
    // must be a pointer type suitable to the object sigil,
    // e.g.: `&x as &Trait` or `box x as Box<Trait>`

    // First, construct a fresh type that we can feed into `<expr>`
    // within `<expr> as <type>` to inform type inference (e.g. to
    // tell it that we are expecting a `Box<_>` or an `&_`).
    let fresh_ty = fcx.infcx().next_ty_var();
    let (object_trait_ty, source_expected_ty) = match target_object_ty.sty {
        ty::ty_uniq(object_trait_ty) => {
            (object_trait_ty, ty::mk_uniq(fcx.tcx(), fresh_ty))
        }
        ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
                                            mutbl: target_mutbl }) => {
            (object_trait_ty,
             ty::mk_rptr(fcx.tcx(),
                         target_region, ty::mt { ty: fresh_ty,
                                                 mutbl: target_mutbl }))
        }
        _ => {
            fcx.tcx().sess.span_bug(source_expr.span, "expected object type");
        }
    };

    let source_ty = fcx.expr_ty(source_expr);
    debug!("check_object_cast pre unify source_ty={}", source_ty.repr(tcx));

    // This ensures that the source_ty <: source_expected_ty, which
    // will ensure e.g. that &'a T <: &'b T when doing `&'a T as &'b Trait`
    //
    // FIXME (pnkfelix): do we need to use suptype_with_fn in order to
    // override the error message emitted when the types do not work
    // out in the manner desired?
    demand::suptype(fcx, source_expr.span, source_expected_ty, source_ty);

    debug!("check_object_cast postunify source_ty={}", source_ty.repr(tcx));
    let source_ty = structurally_resolved_type(fcx, source_expr.span, source_ty);
    debug!("check_object_cast resolveto source_ty={}", source_ty.repr(tcx));

    let object_trait = object_trait(&object_trait_ty);

    let referent_ty = match source_ty.sty {
        ty::ty_uniq(ty) => ty,
        ty::ty_rptr(_, ty::mt { ty, mutbl: _ }) => ty,
        _ => fcx.tcx().sess.span_bug(source_expr.span,
                                     "expected appropriate reference type"),
    };

    // Ensure that if Ptr<T> is cast to Ptr<Trait>, then T : Trait.
    push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
    check_object_safety(tcx, object_trait, source_expr.span);

    fn object_trait<'a, 'tcx>(t: &'a Ty<'tcx>) -> &'a ty::TyTrait<'tcx> {
        match t.sty {
            ty::ty_trait(ref ty_trait) => &**ty_trait,
            _ => panic!("expected ty_trait")
        }
    }

    fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      cast_expr: &ast::Expr,
                                      object_trait: &ty::TyTrait<'tcx>,
                                      referent_ty: Ty<'tcx>) {
        let object_trait_ref =
            register_object_cast_obligations(fcx,
                                             cast_expr.span,
                                             object_trait,
                                             referent_ty);

        // Finally record the object_trait_ref for use during trans
        // (it would prob be better not to do this, but it's just kind
        // of a pain to have to reconstruct it).
        fcx.write_object_cast(cast_expr.id, object_trait_ref);
    }
}

// Check that a trait is 'object-safe'. This should be checked whenever a trait object
// is created (by casting or coercion, etc.). A trait is object-safe if all its
// methods are object-safe. A trait method is object-safe if it does not take
// self by value, has no type parameters and does not use the `Self` type, except
// in self position.
pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                                 object_trait: &ty::TyTrait<'tcx>,
                                 span: Span)
{
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);

    if traits::is_object_safe(tcx, object_trait_ref.clone()) {
        return;
    }

    span_err!(tcx.sess, span, E0038,
              "cannot convert to a trait object because trait `{}` is not object-safe",
              ty::item_path_str(tcx, object_trait_ref.def_id()));

    let violations = traits::object_safety_violations(tcx, object_trait_ref.clone());
    for violation in violations {
        match violation {
            ObjectSafetyViolation::SizedSelf => {
                tcx.sess.span_note(
                    span,
                    "the trait cannot require that `Self : Sized`");
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has a receiver type of `Self`, \
                              which cannot be used with a trait object",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has no receiver",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::ReferencesSelf) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` references the `Self` type \
                              in its arguments or return type",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::Generic) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has generic type parameters",
                             method.name.user_string(tcx)));
            }
        }
    }
}

pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                  span: Span,
                                                  object_trait: &ty::TyTrait<'tcx>,
                                                  referent_ty: Ty<'tcx>)
                                                  -> ty::PolyTraitRef<'tcx>
{
    // We can only make objects from sized types.
    fcx.register_builtin_bound(
        referent_ty,
        ty::BoundSized,
        traits::ObligationCause::new(span, fcx.body_id, traits::ObjectSized));

    // This is just for better error reporting. Kinda goofy. The object type stuff
    // needs some refactoring so there is a more convenient type to pass around.
    let object_trait_ty =
        ty::mk_trait(fcx.tcx(),
                     object_trait.principal.clone(),
                     object_trait.bounds.clone());

    debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
           referent_ty.repr(fcx.tcx()),
           object_trait_ty.repr(fcx.tcx()));

    let cause = ObligationCause::new(span,
                                     fcx.body_id,
                                     traits::ObjectCastObligation(object_trait_ty));

    // Create the obligation for casting from T to Trait.
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(fcx.tcx(), referent_ty);
    let object_obligation =
        Obligation::new(cause.clone(), object_trait_ref.as_predicate());
    fcx.register_predicate(object_obligation);

    // Create additional obligations for all the various builtin
    // bounds attached to the object cast. (In other words, if the
    // object type is Foo+Send, this would create an obligation
    // for the Send check.)
    for builtin_bound in &object_trait.bounds.builtin_bounds {
        fcx.register_builtin_bound(
            referent_ty,
            builtin_bound,
            cause.clone());
    }

    // Create obligations for the projection predicates.
    let projection_bounds =
        object_trait.projection_bounds_with_self_ty(fcx.tcx(), referent_ty);
    for projection_bound in &projection_bounds {
        let projection_obligation =
            Obligation::new(cause.clone(), projection_bound.as_predicate());
        fcx.register_predicate(projection_obligation);
    }

    // Finally, check that there IS a projection predicate for every associated type.
    check_object_type_binds_all_associated_types(fcx.tcx(),
                                                 span,
                                                 object_trait);

    object_trait_ref
}

fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>,
                                                      span: Span,
                                                      object_trait: &ty::TyTrait<'tcx>)
{
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);

    let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> =
        traits::supertraits(tcx, object_trait_ref.clone())
        .flat_map(|tr| {
            let trait_def = ty::lookup_trait_def(tcx, tr.def_id());
            trait_def.associated_type_names
                .clone()
                .into_iter()
                .map(move |associated_type_name| (tr.def_id(), associated_type_name))
        })
        .collect();

    for projection_bound in &object_trait.bounds.projection_bounds {
        let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
                    projection_bound.0.projection_ty.item_name);
        associated_types.remove(&pair);
    }

    for (trait_def_id, name) in associated_types {
        span_err!(tcx.sess, span, E0191,
            "the value of the associated type `{}` (from the trait `{}`) must be specified",
                    name.user_string(tcx),
                    ty::item_path_str(tcx, trait_def_id));
    }
}

pub fn select_all_fcx_obligations_and_apply_defaults(fcx: &FnCtxt) {
    debug!("select_all_fcx_obligations_and_apply_defaults");

    select_fcx_obligations_where_possible(fcx);
    fcx.default_type_parameters();
    select_fcx_obligations_where_possible(fcx);
}

pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
    debug!("select_all_fcx_obligations_or_error");

    // upvar inference should have ensured that all deferred call
    // resolutions are handled by now.
    assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty());

    select_all_fcx_obligations_and_apply_defaults(fcx);
    let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
    let r = fulfillment_cx.select_all_or_error(fcx.infcx(), fcx);
    match r {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

/// Select as many obligations as we can at present.
pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt)
{
    match
        fcx.inh.fulfillment_cx
        .borrow_mut()
        .select_where_possible(fcx.infcx(), fcx)
    {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

/// Try to select any fcx obligation that we haven't tried yet, in an effort to improve inference.
/// You could just call `select_fcx_obligations_where_possible` except that it leads to repeated
/// work.
pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
    match
        fcx.inh.fulfillment_cx
        .borrow_mut()
        .select_new_obligations(fcx.infcx(), fcx)
    {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

<commit_msg>PR #22012 followup: clean up vtable::check_object_cast by reusing `fresh_ty`<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.

use check::{FnCtxt};
use check::demand;
use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode};
use middle::traits::{Obligation, ObligationCause};
use middle::traits::report_fulfillment_errors;
use middle::ty::{self, Ty, AsPredicate};
use syntax::ast;
use syntax::codemap::Span;
use util::nodemap::FnvHashSet;
use util::ppaux::{Repr, UserString};

pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   cast_expr: &ast::Expr,
                                   source_expr: &ast::Expr,
                                   target_object_ty: Ty<'tcx>)
{
    let tcx = fcx.tcx();
    debug!("check_object_cast(cast_expr={}, target_object_ty={})",
           cast_expr.repr(tcx),
           target_object_ty.repr(tcx));

    // Look up vtables for the type we're casting to,
    // passing in the source and target type.  The source
    // must be a pointer type suitable to the object sigil,
    // e.g.: `&x as &Trait` or `box x as Box<Trait>`

    // First, construct a fresh type that we can feed into `<expr>`
    // within `<expr> as <type>` to inform type inference (e.g. to
    // tell it that we are expecting a `Box<_>` or an `&_`).
    let fresh_ty = fcx.infcx().next_ty_var();
    let (object_trait_ty, source_expected_ty) = match target_object_ty.sty {
        ty::ty_uniq(object_trait_ty) => {
            (object_trait_ty, ty::mk_uniq(fcx.tcx(), fresh_ty))
        }
        ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
                                            mutbl: target_mutbl }) => {
            (object_trait_ty,
             ty::mk_rptr(fcx.tcx(),
                         target_region, ty::mt { ty: fresh_ty,
                                                 mutbl: target_mutbl }))
        }
        _ => {
            fcx.tcx().sess.span_bug(source_expr.span, "expected object type");
        }
    };

    let source_ty = fcx.expr_ty(source_expr);
    debug!("check_object_cast pre unify source_ty={}", source_ty.repr(tcx));

    // This ensures that the source_ty <: source_expected_ty, which
    // will ensure e.g. that &'a T <: &'b T when doing `&'a T as &'b Trait`
    //
    // FIXME (pnkfelix): do we need to use suptype_with_fn in order to
    // override the error message emitted when the types do not work
    // out in the manner desired?
    demand::suptype(fcx, source_expr.span, source_expected_ty, source_ty);

    debug!("check_object_cast postunify source_ty={}", source_ty.repr(tcx));

    let object_trait = object_trait(&object_trait_ty);

    // Ensure that if Ptr<T> is cast to Ptr<Trait>, then T : Trait.
    push_cast_obligation(fcx, cast_expr, object_trait, fresh_ty);
    check_object_safety(tcx, object_trait, source_expr.span);

    fn object_trait<'a, 'tcx>(t: &'a Ty<'tcx>) -> &'a ty::TyTrait<'tcx> {
        match t.sty {
            ty::ty_trait(ref ty_trait) => &**ty_trait,
            _ => panic!("expected ty_trait")
        }
    }

    fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      cast_expr: &ast::Expr,
                                      object_trait: &ty::TyTrait<'tcx>,
                                      referent_ty: Ty<'tcx>) {
        let object_trait_ref =
            register_object_cast_obligations(fcx,
                                             cast_expr.span,
                                             object_trait,
                                             referent_ty);

        // Finally record the object_trait_ref for use during trans
        // (it would prob be better not to do this, but it's just kind
        // of a pain to have to reconstruct it).
        fcx.write_object_cast(cast_expr.id, object_trait_ref);
    }
}

// Check that a trait is 'object-safe'. This should be checked whenever a trait object
// is created (by casting or coercion, etc.). A trait is object-safe if all its
// methods are object-safe. A trait method is object-safe if it does not take
// self by value, has no type parameters and does not use the `Self` type, except
// in self position.
pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                                 object_trait: &ty::TyTrait<'tcx>,
                                 span: Span)
{
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);

    if traits::is_object_safe(tcx, object_trait_ref.clone()) {
        return;
    }

    span_err!(tcx.sess, span, E0038,
              "cannot convert to a trait object because trait `{}` is not object-safe",
              ty::item_path_str(tcx, object_trait_ref.def_id()));

    let violations = traits::object_safety_violations(tcx, object_trait_ref.clone());
    for violation in violations {
        match violation {
            ObjectSafetyViolation::SizedSelf => {
                tcx.sess.span_note(
                    span,
                    "the trait cannot require that `Self : Sized`");
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has a receiver type of `Self`, \
                              which cannot be used with a trait object",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has no receiver",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::ReferencesSelf) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` references the `Self` type \
                              in its arguments or return type",
                             method.name.user_string(tcx)));
            }

            ObjectSafetyViolation::Method(method, MethodViolationCode::Generic) => {
                tcx.sess.span_note(
                    span,
                    &format!("method `{}` has generic type parameters",
                             method.name.user_string(tcx)));
            }
        }
    }
}

pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                  span: Span,
                                                  object_trait: &ty::TyTrait<'tcx>,
                                                  referent_ty: Ty<'tcx>)
                                                  -> ty::PolyTraitRef<'tcx>
{
    // We can only make objects from sized types.
    fcx.register_builtin_bound(
        referent_ty,
        ty::BoundSized,
        traits::ObligationCause::new(span, fcx.body_id, traits::ObjectSized));

    // This is just for better error reporting. Kinda goofy. The object type stuff
    // needs some refactoring so there is a more convenient type to pass around.
    let object_trait_ty =
        ty::mk_trait(fcx.tcx(),
                     object_trait.principal.clone(),
                     object_trait.bounds.clone());

    debug!("register_object_cast_obligations: referent_ty={} object_trait_ty={}",
           referent_ty.repr(fcx.tcx()),
           object_trait_ty.repr(fcx.tcx()));

    let cause = ObligationCause::new(span,
                                     fcx.body_id,
                                     traits::ObjectCastObligation(object_trait_ty));

    // Create the obligation for casting from T to Trait.
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(fcx.tcx(), referent_ty);
    let object_obligation =
        Obligation::new(cause.clone(), object_trait_ref.as_predicate());
    fcx.register_predicate(object_obligation);

    // Create additional obligations for all the various builtin
    // bounds attached to the object cast. (In other words, if the
    // object type is Foo+Send, this would create an obligation
    // for the Send check.)
    for builtin_bound in &object_trait.bounds.builtin_bounds {
        fcx.register_builtin_bound(
            referent_ty,
            builtin_bound,
            cause.clone());
    }

    // Create obligations for the projection predicates.
    let projection_bounds =
        object_trait.projection_bounds_with_self_ty(fcx.tcx(), referent_ty);
    for projection_bound in &projection_bounds {
        let projection_obligation =
            Obligation::new(cause.clone(), projection_bound.as_predicate());
        fcx.register_predicate(projection_obligation);
    }

    // Finally, check that there IS a projection predicate for every associated type.
    check_object_type_binds_all_associated_types(fcx.tcx(),
                                                 span,
                                                 object_trait);

    object_trait_ref
}

fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>,
                                                      span: Span,
                                                      object_trait: &ty::TyTrait<'tcx>)
{
    let object_trait_ref =
        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);

    let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> =
        traits::supertraits(tcx, object_trait_ref.clone())
        .flat_map(|tr| {
            let trait_def = ty::lookup_trait_def(tcx, tr.def_id());
            trait_def.associated_type_names
                .clone()
                .into_iter()
                .map(move |associated_type_name| (tr.def_id(), associated_type_name))
        })
        .collect();

    for projection_bound in &object_trait.bounds.projection_bounds {
        let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
                    projection_bound.0.projection_ty.item_name);
        associated_types.remove(&pair);
    }

    for (trait_def_id, name) in associated_types {
        span_err!(tcx.sess, span, E0191,
            "the value of the associated type `{}` (from the trait `{}`) must be specified",
                    name.user_string(tcx),
                    ty::item_path_str(tcx, trait_def_id));
    }
}

pub fn select_all_fcx_obligations_and_apply_defaults(fcx: &FnCtxt) {
    debug!("select_all_fcx_obligations_and_apply_defaults");

    select_fcx_obligations_where_possible(fcx);
    fcx.default_type_parameters();
    select_fcx_obligations_where_possible(fcx);
}

pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
    debug!("select_all_fcx_obligations_or_error");

    // upvar inference should have ensured that all deferred call
    // resolutions are handled by now.
    assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty());

    select_all_fcx_obligations_and_apply_defaults(fcx);
    let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
    let r = fulfillment_cx.select_all_or_error(fcx.infcx(), fcx);
    match r {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

/// Select as many obligations as we can at present.
pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt)
{
    match
        fcx.inh.fulfillment_cx
        .borrow_mut()
        .select_where_possible(fcx.infcx(), fcx)
    {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

/// Try to select any fcx obligation that we haven't tried yet, in an effort to improve inference.
/// You could just call `select_fcx_obligations_where_possible` except that it leads to repeated
/// work.
pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
    match
        fcx.inh.fulfillment_cx
        .borrow_mut()
        .select_new_obligations(fcx.infcx(), fcx)
    {
        Ok(()) => { }
        Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
    }
}

<|endoftext|>


<commit_before>// Copyright 2018 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 std::ffi;
use std::ops::Deref;

const SIZE: usize = 38;

/// Like SmallVec but for C strings.
#[derive(Clone)]
pub enum SmallCStr {
    OnStack {
        data: [u8; SIZE],
        len_with_nul: u8,
    },
    OnHeap {
        data: ffi::CString,
    }
}

impl SmallCStr {
    #[inline]
    pub fn new(s: &str) -> SmallCStr {
        if s.len() < SIZE {
            let mut data = [0; SIZE];
            data[.. s.len()].copy_from_slice(s.as_bytes());
            let len_with_nul = s.len() + 1;

            // Make sure once that this is a valid CStr
            if let Err(e) = ffi::CStr::from_bytes_with_nul(&data[.. len_with_nul]) {
                panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
            }

            SmallCStr::OnStack {
                data,
                len_with_nul: len_with_nul as u8,
            }
        } else {
            SmallCStr::OnHeap {
                data: ffi::CString::new(s).unwrap()
            }
        }
    }

    #[inline]
    pub fn as_c_str(&self) -> &ffi::CStr {
        match *self {
            SmallCStr::OnStack { ref data, len_with_nul } => {
                unsafe {
                    let slice = &data[.. len_with_nul as usize];
                    ffi::CStr::from_bytes_with_nul_unchecked(slice)
                }
            }
            SmallCStr::OnHeap { ref data } => {
                data.as_c_str()
            }
        }
    }

    #[inline]
    pub fn len_with_nul(&self) -> usize {
        match *self {
            SmallCStr::OnStack { len_with_nul, .. } => {
                len_with_nul as usize
            }
            SmallCStr::OnHeap { ref data } => {
                data.as_bytes_with_nul().len()
            }
        }
    }
}

impl Deref for SmallCStr {
    type Target = ffi::CStr;

    fn deref(&self) -> &ffi::CStr {
        self.as_c_str()
    }
}

#[test]
fn short() {
    const TEXT: &str = "abcd";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
}

#[test]
fn empty() {
    const TEXT: &str = "";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false });
}

#[test]
fn long() {
    const TEXT: &str = "01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(if let SmallCStr::OnHeap { .. } = scs { true } else { false });
}

#[test]
#[should_panic]
fn internal_nul() {
    let _ = SmallCStr::new("abcd\0def");
}
<commit_msg>Use SmallVec for SmallCStr<commit_after>// Copyright 2018 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 std::ffi;
use std::ops::Deref;

use smallvec::SmallVec;

const SIZE: usize = 36;

/// Like SmallVec but for C strings.
#[derive(Clone)]
pub struct SmallCStr {
    data: SmallVec<[u8; SIZE]>,
}

impl SmallCStr {
    #[inline]
    pub fn new(s: &str) -> SmallCStr {
        let len = s.len();
        let len1 = len + 1;
        let data = if len < SIZE {
            let mut buf = [0; SIZE];
            buf[..len].copy_from_slice(s.as_bytes());
            SmallVec::from_buf_and_len(buf, len1)
        } else {
            let mut data = Vec::with_capacity(len1);
            data.extend_from_slice(s.as_bytes());
            data.push(0);
            SmallVec::from_vec(data)
        };
        if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
            panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
        }
        SmallCStr { data }
    }

    #[inline]
    pub fn new_with_nul(s: &str) -> SmallCStr {
        let b = s.as_bytes();
        if let Err(e) = ffi::CStr::from_bytes_with_nul(b) {
            panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e);
        }
        SmallCStr { data: SmallVec::from_slice(s.as_bytes()) }
    }

    #[inline]
    pub fn as_c_str(&self) -> &ffi::CStr {
        unsafe {
            ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..])
        }
    }

    #[inline]
    pub fn len_with_nul(&self) -> usize {
        self.data.len()
    }

    pub fn spilled(&self) -> bool {
        self.data.spilled()
    }
}

impl Deref for SmallCStr {
    type Target = ffi::CStr;

    fn deref(&self) -> &ffi::CStr {
        self.as_c_str()
    }
}

#[test]
fn short() {
    const TEXT: &str = "abcd";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(!scs.spilled());
}

#[test]
fn empty() {
    const TEXT: &str = "";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(!scs.spilled());
}

#[test]
fn long() {
    const TEXT: &str = "01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789\
                        01234567890123456789012345678901234567890123456789";
    let reference = ffi::CString::new(TEXT.to_string()).unwrap();

    let scs = SmallCStr::new(TEXT);

    assert_eq!(scs.len_with_nul(), TEXT.len() + 1);
    assert_eq!(scs.as_c_str(), reference.as_c_str());
    assert!(scs.spilled());
}

#[test]
#[should_panic]
fn internal_nul() {
    let _ = SmallCStr::new("abcd\0def");
}
<|endoftext|>


<commit_before><commit_msg>examples/uptime.rs: add `uptime` example (no packet data, but helper use)<commit_after>// Copyright 2016 6WIND S.A. <quentin.monnet@6wind.com>
//
// Licensed under the Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0> or
// the MIT license <http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

extern crate rbpf;
use rbpf::helpers;

// The main objectives of this example is to show:
//
// * the use of EbpfVmNoData function,
// * and the use of a helper.
//
// The two eBPF programs are independent and are not related to one another.
fn main() {
    let prog1 = vec![
        0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov32 r0, 0
        0xb4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov32 r1, 2
        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // add32 r0, 1
        0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // add32 r0, r1
        0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // exit and return r0
    ];

    // We use helper `bpf_time_getns()`, which is similar to helper `bpf_ktime_getns()` from Linux
    // kernel. Hence rbpf::helpers module provides the index of this in-kernel helper as a
    // constant, so that we can remain compatible with programs for the kernel. Here we also cast
    // it to a u8 so as to use it directly in program instructions.
    let hkey = helpers::BPF_KTIME_GETNS_IDX as u8;
    let prog2 = vec![
        0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
        0xb7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
        0xb7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
        0xb7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
        0xb7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
        0x85, 0x00, 0x00, 0x00, hkey, 0x00, 0x00, 0x00, // call helper <hkey>
        0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // exit and return r0
    ];

    // Create a VM: this one takes no data. Load prog1 in it.
    let mut vm = rbpf::EbpfVmNoData::new(&prog1);
    // Execute prog1.
    assert_eq!(vm.prog_exec(), 0x3);

    // As struct EbpfVmNoData does not takes any memory area, its return value is mostly
    // deterministic. So we know prog1 will always return 3. There is an exception: when it uses
    // helpers, the latter may have non-deterministic values, and all calls may not return the same
    // value.
    //
    // In the following example we use a helper to get the elapsed time since boot time: we
    // reimplement uptime in eBPF, in Rust. Because why not.

    vm.set_prog(&prog2);
    vm.register_helper(helpers::BPF_KTIME_GETNS_IDX, helpers::bpf_time_getns);

    vm.jit_compile();
    let t = unsafe { vm.prog_exec_jit() };

    let d =  t / 10u64.pow(9)  / 60   / 60  / 24;
    let h = (t / 10u64.pow(9)  / 60   / 60) % 24;
    let m = (t / 10u64.pow(9)  / 60 ) % 60;
    let s = (t / 10u64.pow(9)) % 60;
    let ns = t % 10u64.pow(9);

    println!("Uptime: {:#x} ns == {} days {:02}:{:02}:{:02}, {} ns", t, d, h, m, s, ns);
}
<|endoftext|>


<commit_before><commit_msg>Add LittleEndianInt and BigEndianInt<commit_after><|endoftext|>


<commit_before><commit_msg>Create Names scores.rs<commit_after><|endoftext|>


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

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::middle::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::middle::ty;
use rustc::front::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_front::lowering::{lower_crate, LoweringContext};
use rustc_metadata::cstore::CStore;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(&'a ty::ctxt<'tcx>),
    NotTyped(&'a session::Session)
}

pub type ExternalPaths = RefCell<Option<HashMap<DefId,
                                                (Vec<String>, clean::TypeKind)>>>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub external_paths: ExternalPaths,
    pub external_traits: RefCell<Option<HashMap<DefId, clean::Trait>>>,
    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
    pub inlined: RefCell<Option<HashSet<DefId>>>,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<&'a ty::ctxt<'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub struct CrateAnalysis {
    pub access_levels: AccessLevels<DefId>,
    pub external_paths: ExternalPaths,
    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
    pub inlined: RefCell<Option<HashSet<DefId>>>,
    pub deref_trait_did: Option<DefId>,
}

pub type Externs = HashMap<String, Vec<String>>;

pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
                input: Input, triple: Option<String>)
                -> (clean::Crate, CrateAnalysis) {

    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
    let sess = session::build_session_(sessopts, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = driver::phase_1_parse_input(&sess, cfg, &input);

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);
    // Lower ast -> hir.
    let lcx = LoweringContext::new(&sess, Some(&krate));
    let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), DepGraph::new(false));
    let arenas = ty::CtxtArenas::new();
    let hir_map = driver::make_map(&sess, &mut hir_forest);

    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     &cstore,
                                                     hir_map,
                                                     &arenas,
                                                     &name,
                                                     resolve::MakeGlobMap::No,
                                                     |tcx, _, analysis, _| {
        let _ignore = tcx.dep_graph.in_ignore();
        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            external_traits: RefCell::new(Some(HashMap::new())),
            external_typarams: RefCell::new(Some(HashMap::new())),
            external_paths: RefCell::new(Some(HashMap::new())),
            inlined: RefCell::new(Some(HashSet::new())),
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let mut analysis = CrateAnalysis {
            access_levels: access_levels,
            external_paths: RefCell::new(None),
            external_typarams: RefCell::new(None),
            inlined: RefCell::new(None),
            deref_trait_did: None,
        };

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        let external_paths = ctxt.external_paths.borrow_mut().take();
        *analysis.external_paths.borrow_mut() = external_paths;
        let map = ctxt.external_typarams.borrow_mut().take();
        *analysis.external_typarams.borrow_mut() = map;
        let map = ctxt.inlined.borrow_mut().take();
        *analysis.inlined.borrow_mut() = map;
        analysis.deref_trait_did = ctxt.deref_trait_did.get();
        (krate, analysis)
    }), &sess)
}
<commit_msg>Make rustdoc report driver phase-3 errors instead of continuing<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::MaybeTyped::*;

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::middle::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::middle::ty;
use rustc::front::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_front::lowering::{lower_crate, LoweringContext};
use rustc_metadata::cstore::CStore;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(&'a ty::ctxt<'tcx>),
    NotTyped(&'a session::Session)
}

pub type ExternalPaths = RefCell<Option<HashMap<DefId,
                                                (Vec<String>, clean::TypeKind)>>>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub external_paths: ExternalPaths,
    pub external_traits: RefCell<Option<HashMap<DefId, clean::Trait>>>,
    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
    pub inlined: RefCell<Option<HashSet<DefId>>>,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<&'a ty::ctxt<'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub struct CrateAnalysis {
    pub access_levels: AccessLevels<DefId>,
    pub external_paths: ExternalPaths,
    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
    pub inlined: RefCell<Option<HashSet<DefId>>>,
    pub deref_trait_did: Option<DefId>,
}

pub type Externs = HashMap<String, Vec<String>>;

pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
                input: Input, triple: Option<String>)
                -> (clean::Crate, CrateAnalysis) {

    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let cstore = Rc::new(CStore::new(token::get_ident_interner()));
    let sess = session::build_session_(sessopts, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = driver::phase_1_parse_input(&sess, cfg, &input);

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);
    // Lower ast -> hir.
    let lcx = LoweringContext::new(&sess, Some(&krate));
    let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), DepGraph::new(false));
    let arenas = ty::CtxtArenas::new();
    let hir_map = driver::make_map(&sess, &mut hir_forest);

    let krate_and_analysis = abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     &cstore,
                                                     hir_map,
                                                     &arenas,
                                                     &name,
                                                     resolve::MakeGlobMap::No,
                                                     |tcx, _, analysis, result| {
        // Return if the driver hit an err (in `result`)
        if let Err(_) = result {
            return None
        }

        let _ignore = tcx.dep_graph.in_ignore();
        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            external_traits: RefCell::new(Some(HashMap::new())),
            external_typarams: RefCell::new(Some(HashMap::new())),
            external_paths: RefCell::new(Some(HashMap::new())),
            inlined: RefCell::new(Some(HashSet::new())),
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let mut analysis = CrateAnalysis {
            access_levels: access_levels,
            external_paths: RefCell::new(None),
            external_typarams: RefCell::new(None),
            inlined: RefCell::new(None),
            deref_trait_did: None,
        };

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        let external_paths = ctxt.external_paths.borrow_mut().take();
        *analysis.external_paths.borrow_mut() = external_paths;

        let map = ctxt.external_typarams.borrow_mut().take();
        *analysis.external_typarams.borrow_mut() = map;

        let map = ctxt.inlined.borrow_mut().take();
        *analysis.inlined.borrow_mut() = map;

        analysis.deref_trait_did = ctxt.deref_trait_did.get();

        Some((krate, analysis))
    }), &sess);

    krate_and_analysis.unwrap()
}
<|endoftext|>


<commit_before><commit_msg>Adding missed file.<commit_after>use session::Session;
use frame::Frame;
use option_setter::OptionSetter;
use std::old_io::IoResult;
use connection::{Connection, HeartBeat, Credentials};
use header::{HeaderList, Header};

pub struct SessionBuilder<'a> {
  pub host: &'a str,
  pub port: u16,
  pub credentials: Option<Credentials<'a>>,
  pub heartbeat: HeartBeat,
  pub custom_headers: HeaderList
}

impl <'a> SessionBuilder <'a> {
  pub fn new(host: &'a str, port: u16) -> SessionBuilder<'a> {
    SessionBuilder {
      host: host,
      port: port,
      credentials: None,
      heartbeat: HeartBeat(0,0),
      custom_headers: HeaderList::new()
    }
  }

  #[allow(dead_code)]
  pub fn start(mut self) -> IoResult<Session<'a>> {
    // Create our base header list with required and known fields
    let mut header_list = header_list![
     "host" => self.host,
     "accept-version" => "1.2",
     "content-length" => "0"
    ];

    // Add credentials to the header list if specified
    match self.credentials {
      Some(Credentials(ref login, ref passcode)) => {
        debug!("Using provided credentials: login '{}', passcode '{}'", login, passcode);
        header_list.push(Header::new("login", login));
        header_list.push(Header::new("passcode", passcode));
      },
      None => debug!("No credentials supplied.")
    }

    let HeartBeat(client_tx_ms, client_rx_ms) = self.heartbeat;
    let heart_beat_string = format!("{},{}", client_tx_ms, client_rx_ms);
    debug!("Using heartbeat: {},{}", client_tx_ms, client_rx_ms);
    header_list.push(Header::new("heart-beat", heart_beat_string.as_slice()));

    header_list.concat(&mut self.custom_headers);

    let connect_frame = Frame {
      command : "CONNECT".to_string(),
      headers : header_list,
      body : Vec::new()
    };

    let mut connection = try!(Connection::new(self.host, self.port));
    let (server_tx_ms, server_rx_ms) = try!(connection.start_session_with_frame(connect_frame));
    let (tx_ms, rx_ms) = Connection::select_heartbeat(
      client_tx_ms,
      client_rx_ms,
      server_tx_ms,
      server_rx_ms
    );

    Ok(Session::new(connection, tx_ms, rx_ms))
  }

  #[allow(dead_code)]
  pub fn with<T>(self, option_setter: T) -> SessionBuilder<'a> where T: OptionSetter<SessionBuilder<'a>> {
    option_setter.set_option(self)
  }
}
<|endoftext|>