<commit_before>// xfail-pretty

// An example of the bank protocol from eholk's blog post.
//
// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/

import pipes::try_recv;

type username = ~str;
type password = ~str;
type money = float;
type amount = float;

proto! bank {
    login:send {
        login(username, password) -> login_response
    }

    login_response:recv {
        ok -> connected,
        invalid -> login
    }

    connected:send {
        deposit(money) -> connected,
        withdrawal(amount) -> withdrawal_response
    }

    withdrawal_response:recv {
        money(money) -> connected,
        insufficient_funds -> connected
    }
}

fn macros() {
    #macro[
        [#move[x],
         unsafe { let y <- *ptr::addr_of(x); y }]
    ];
}

fn bank_client(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = alt try_recv(bank) {
      some(ok(connected)) {
        #move(connected)
      }
      some(invalid(_)) { fail ~"login unsuccessful" }
      none { fail ~"bank closed the connection" }
    };

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    alt try_recv(bank) {
      some(money(m, _)) {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) {
        fail ~"someone stole my money"
      }
      none {
        fail ~"bank closed the connection"
      }
    }
}

fn main() {
}<commit_msg>Started playing with macros to make receiving easier<commit_after>// xfail-pretty

// An example of the bank protocol from eholk's blog post.
//
// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/

import pipes::try_recv;

type username = ~str;
type password = ~str;
type money = float;
type amount = float;

proto! bank {
    login:send {
        login(username, password) -> login_response
    }

    login_response:recv {
        ok -> connected,
        invalid -> login
    }

    connected:send {
        deposit(money) -> connected,
        withdrawal(amount) -> withdrawal_response
    }

    withdrawal_response:recv {
        money(money) -> connected,
        insufficient_funds -> connected
    }
}

macro_rules! move {
    { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
}

fn switch<T: send, U>(+endp: pipes::recv_packet<T>,
                      f: fn(+option<T>) -> U) -> U {
    f(pipes::try_recv(endp))
}

fn move<T>(-x: T) -> T { x }

macro_rules! follow {
    {
        $($message:path($($x: ident),+) => $next:ident $e:expr)+
    } => (
        |m| alt move(m) {
          $(some($message($($x,)* next)) {
            let $next = move!{next};
            $e })+
          _ { fail }
        }
    );

    {
        $($message:path => $next:ident $e:expr)+
    } => (
        |m| alt move(m) {
            $(some($message(next)) {
                let $next = move!{next};
                $e })+
                _ { fail }
        }
    )
}

/*
fn client_follow(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = switch(bank, follow! {
        ok => connected { connected }
        invalid => _next { fail ~"bank closed the connected" }
    });

    /* // potential alternate syntax
    let bank = recv_alt! {
        bank => {
            | ok -> connected { connected }
            | invalid -> _next { fail }
        }
        bank2 => {
            | foo -> _n { fail }
        }
    }
    */

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    alt try_recv(bank) {
      some(money(m, _)) {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) {
        fail ~"someone stole my money"
      }
      none {
        fail ~"bank closed the connection"
      }
    }
}
*/

fn bank_client(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = alt try_recv(bank) {
      some(ok(connected)) {
        move!{connected}
      }
      some(invalid(_)) { fail ~"login unsuccessful" }
      none { fail ~"bank closed the connection" }
    };

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    alt try_recv(bank) {
      some(money(m, _)) {
        io::println(~"Yay! I got money!");
      }
      some(insufficient_funds(_)) {
        fail ~"someone stole my money"
      }
      none {
        fail ~"bank closed the connection"
      }
    }
}

fn main() {
}<|endoftext|>


<commit_before>use core::clone::Clone;
use core::iter::Iterator;
use core::mem::size_of;
use core::ops::Drop;
use core::option::Option;
use core::ptr;
use core::slice;
use core::slice::SliceExt;

use syscall::call::*;

/// An iterator over a vec
pub struct VecIterator<'a, T: 'a> {
    vec: &'a Vec<T>,
    offset: usize,
}

impl <'a, T> Iterator for VecIterator<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        match self.vec.get(self.offset) {
            Option::Some(item) => {
                self.offset += 1;
                Option::Some(item)
            }
            Option::None => {
                Option::None
            }
        }
    }
}

/// A owned, heap allocated list of elements
pub struct Vec<T> {
    pub data: *mut T,
    pub length: usize,
}

impl <T> Vec<T> {
    /// Create a empty vector
    pub fn new() -> Vec<T> {
        Vec::<T> {
            data: 0 as *mut T,
            length: 0,
        }
    }

    /// Convert to pointer
    pub unsafe fn as_ptr(&self) -> *const T {
        self.data
    }

    /// Convert from a raw (unsafe) buffer
    pub unsafe fn from_raw_buf(ptr: *const T, len: usize) -> Vec<T> {
        let data = sys_alloc(size_of::<T>() * len);

        ptr::copy(ptr, data as *mut T, len);

        Vec::<T> {
            data: data as *mut T,
            length: len,
        }
    }

    /// Get the nth element. Returns None if out of bounds.
    pub fn get(&self, i: usize) -> Option<&mut T> {
        if i >= self.length {
            Option::None
        } else {
            unsafe { Option::Some(&mut *self.data.offset(i as isize)) }
        }
    }

    /// Set the nth element
    pub fn set(&self, i: usize, value: T) {
        if i <= self.length {
            unsafe {
                ptr::write(self.data.offset(i as isize), value);
            }
        }
    }

    /// Insert element at a given position
    pub fn insert(&mut self, i: usize, value: T) {
        if i <= self.length {
            self.length += 1;
            unsafe {
                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                //Move all things ahead of insert forward one
                let mut j = self.length - 1;
                while j > i {
                    ptr::write(self.data.offset(j as isize),
                               ptr::read(self.data.offset(j as isize - 1)));
                    j -= 1;
                }

                ptr::write(self.data.offset(i as isize), value);
            }
        }
    }

    /// Remove a element and return it as a Option
    pub fn remove(&mut self, i: usize) -> Option<T> {
        if i < self.length {
            self.length -= 1;
            unsafe {
                let item = ptr::read(self.data.offset(i as isize));

                //Move all things ahead of remove back one
                let mut j = i;
                while j < self.length {
                    ptr::write(self.data.offset(j as isize),
                               ptr::read(self.data.offset(j as isize + 1)));
                    j += 1;
                }

                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                Option::Some(item)
            }
        } else {
            Option::None
        }
    }

    /// Push an element to a vector
    pub fn push(&mut self, value: T) {
        self.length += 1;
        unsafe {
            self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;
            ptr::write(self.data.offset(self.length as isize - 1), value);
        }
    }

    /// Pop the last element
    pub fn pop(&mut self) -> Option<T> {
        if self.length > 0 {
            self.length -= 1;
            unsafe {
                let item = ptr::read(self.data.offset(self.length as isize));
                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                Option::Some(item)
            }
        } else {
            Option::None
        }
    }

    /// Get the length of the vector
    pub fn len(&self) -> usize {
        self.length
    }

    /// Create an iterator
    pub fn iter(&self) -> VecIterator<T> {
        VecIterator {
            vec: self,
            offset: 0,
        }
    }

    // TODO: Consider returning a slice instead
    pub fn sub(&self, start: usize, count: usize) -> Vec<T> {
        let mut i = start;
        if i > self.len() {
            i = self.len();
        }

        let mut j = i + count;
        if j > self.len() {
            j = self.len();
        }

        let length = j - i;
        if length == 0 {
            return Vec::new();
        }

        unsafe {
            let data = sys_alloc(length * size_of::<T>()) as *mut T;

            for k in i..j {
                ptr::write(data.offset((k - i) as isize),
                           ptr::read(self.data.offset(k as isize)));
            }

            Vec {
                data: data,
                length: length,
            }
        }
    }

    pub fn as_slice(&self) -> &[T] {
        if self.data as usize > 0 && self.length > 0 {
            unsafe { slice::from_raw_parts(self.data, self.length) }
        } else {
            &[]
        }
    }
}

impl<T> Vec<T> where T: Clone {
    /// Append a vector to another vector
    pub fn push_all(&mut self, vec: &Vec<T>) {
        let mut i = self.length as isize;
        self.length += vec.len();
        unsafe {
            self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

            for value in vec.iter() {
                ptr::write(self.data.offset(i), value.clone());
                i += 1;
            }
        }
    }
}

impl<T> Clone for Vec<T> where T: Clone {
    fn clone(&self) -> Vec<T> {
        let mut ret = Vec::new();
        ret.push_all(self);
        ret
    }
}

impl<T> Drop for Vec<T> {
    fn drop(&mut self) {
        unsafe {
            for i in 0..self.len() {
                ptr::read(self.data.offset(i as isize));
            }

            sys_unalloc(self.data as usize);
            self.data = 0 as *mut T;
            self.length = 0;
        }
    }
}
<commit_msg>Add vec!<commit_after>use core::clone::Clone;
use core::iter::Iterator;
use core::mem::size_of;
use core::ops::Drop;
use core::option::Option;
use core::ptr;
use core::slice;
use core::slice::SliceExt;

use syscall::call::*;

#[macro_export]
macro_rules! vec {
    ($($x:expr),*) => (
        Vec::from_slice(&[$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

/// An iterator over a vec
pub struct VecIterator<'a, T: 'a> {
    vec: &'a Vec<T>,
    offset: usize,
}

impl <'a, T> Iterator for VecIterator<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        match self.vec.get(self.offset) {
            Option::Some(item) => {
                self.offset += 1;
                Option::Some(item)
            }
            Option::None => {
                Option::None
            }
        }
    }
}

/// A owned, heap allocated list of elements
pub struct Vec<T> {
    pub data: *mut T,
    pub length: usize,
}

impl <T> Vec<T> {
    /// Create a empty vector
    pub fn new() -> Vec<T> {
        Vec::<T> {
            data: 0 as *mut T,
            length: 0,
        }
    }

    /// Convert to pointer
    pub unsafe fn as_ptr(&self) -> *const T {
        self.data
    }

    /// Convert from a raw (unsafe) buffer
    pub unsafe fn from_raw_buf(ptr: *const T, len: usize) -> Vec<T> {
        let data = sys_alloc(size_of::<T>() * len) as *mut T;

        ptr::copy(ptr, data, len);

        Vec::<T> {
            data: data,
            length: len,
        }
    }

    pub fn from_slice(slice: &[T]) -> Vec<T> {
        let data;
        unsafe{
            data = sys_alloc(size_of::<T>() * slice.len()) as *mut T;

            ptr::copy(slice.as_ptr(), data, slice.len());
        }

        Vec::<T> {
            data: data,
            length: slice.len()
        }
    }

    /// Get the nth element. Returns None if out of bounds.
    pub fn get(&self, i: usize) -> Option<&mut T> {
        if i >= self.length {
            Option::None
        } else {
            unsafe { Option::Some(&mut *self.data.offset(i as isize)) }
        }
    }

    /// Set the nth element
    pub fn set(&self, i: usize, value: T) {
        if i <= self.length {
            unsafe {
                ptr::write(self.data.offset(i as isize), value);
            }
        }
    }

    /// Insert element at a given position
    pub fn insert(&mut self, i: usize, value: T) {
        if i <= self.length {
            self.length += 1;
            unsafe {
                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                //Move all things ahead of insert forward one
                let mut j = self.length - 1;
                while j > i {
                    ptr::write(self.data.offset(j as isize),
                               ptr::read(self.data.offset(j as isize - 1)));
                    j -= 1;
                }

                ptr::write(self.data.offset(i as isize), value);
            }
        }
    }

    /// Remove a element and return it as a Option
    pub fn remove(&mut self, i: usize) -> Option<T> {
        if i < self.length {
            self.length -= 1;
            unsafe {
                let item = ptr::read(self.data.offset(i as isize));

                //Move all things ahead of remove back one
                let mut j = i;
                while j < self.length {
                    ptr::write(self.data.offset(j as isize),
                               ptr::read(self.data.offset(j as isize + 1)));
                    j += 1;
                }

                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                Option::Some(item)
            }
        } else {
            Option::None
        }
    }

    /// Push an element to a vector
    pub fn push(&mut self, value: T) {
        self.length += 1;
        unsafe {
            self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;
            ptr::write(self.data.offset(self.length as isize - 1), value);
        }
    }

    /// Pop the last element
    pub fn pop(&mut self) -> Option<T> {
        if self.length > 0 {
            self.length -= 1;
            unsafe {
                let item = ptr::read(self.data.offset(self.length as isize));
                self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

                Option::Some(item)
            }
        } else {
            Option::None
        }
    }

    /// Get the length of the vector
    pub fn len(&self) -> usize {
        self.length
    }

    /// Create an iterator
    pub fn iter(&self) -> VecIterator<T> {
        VecIterator {
            vec: self,
            offset: 0,
        }
    }

    // TODO: Consider returning a slice instead
    pub fn sub(&self, start: usize, count: usize) -> Vec<T> {
        let mut i = start;
        if i > self.len() {
            i = self.len();
        }

        let mut j = i + count;
        if j > self.len() {
            j = self.len();
        }

        let length = j - i;
        if length == 0 {
            return Vec::new();
        }

        unsafe {
            let data = sys_alloc(length * size_of::<T>()) as *mut T;

            for k in i..j {
                ptr::write(data.offset((k - i) as isize),
                           ptr::read(self.data.offset(k as isize)));
            }

            Vec {
                data: data,
                length: length,
            }
        }
    }

    pub fn as_slice(&self) -> &[T] {
        if self.data as usize > 0 && self.length > 0 {
            unsafe { slice::from_raw_parts(self.data, self.length) }
        } else {
            &[]
        }
    }
}

impl<T> Vec<T> where T: Clone {
    /// Append a vector to another vector
    pub fn push_all(&mut self, vec: &Vec<T>) {
        let mut i = self.length as isize;
        self.length += vec.len();
        unsafe {
            self.data = sys_realloc(self.data as usize, self.length * size_of::<T>()) as *mut T;

            for value in vec.iter() {
                ptr::write(self.data.offset(i), value.clone());
                i += 1;
            }
        }
    }
}

impl<T> Clone for Vec<T> where T: Clone {
    fn clone(&self) -> Vec<T> {
        let mut ret = Vec::new();
        ret.push_all(self);
        ret
    }
}

impl<T> Drop for Vec<T> {
    fn drop(&mut self) {
        unsafe {
            for i in 0..self.len() {
                ptr::read(self.data.offset(i as isize));
            }

            sys_unalloc(self.data as usize);
            self.data = 0 as *mut T;
            self.length = 0;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a benchmark test for edit_distance function.<commit_after>#![feature(test)]

extern crate test;
extern crate bloodhound;

use test::Bencher;
use std::path::PathBuf;
use bloodhound::matching::find;

#[bench]
fn bench_edit_distance(b: &mut Bencher) {
    let haystack = vec![PathBuf::from("src/hound.rs"),
        PathBuf::from("lib/hounds.rs"), PathBuf::from("Houndfile")];
    b.iter(|| find("match", &haystack, 5));
}
<|endoftext|>


<commit_before>use runtime::Runtime;
use std::error::Error;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::fmt::Display;
use std::path::Path;
use std::result::Result;

use module::todo::TodoModule;

mod todo;

#[derive(Debug)]
pub struct ModuleError {
    desc: String,
}

impl ModuleError {
    fn mk(desc: &'static str) -> ModuleError {
        ModuleError {
            desc: desc.to_owned().to_string(),
        }
    }
}

impl Error for ModuleError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        None
    }

}

impl Display for ModuleError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "ModuleError: {}", self.description())
    }
}

pub type ModuleResult = Result<(), ModuleError>;

pub trait Module {

    fn new(rt : &Runtime) -> Self;
    fn callnames() -> &'static [&'static str];
    fn name(&self) -> &'static str;

    fn execute(&self, rt : &Runtime) -> ModuleResult;
    fn shutdown(&self, rt : &Runtime) -> ModuleResult;

}

pub mod file {

    pub struct ParserError {
        summary: String,
        parsertext: String,
        index: i32,
        explanation: Option<String>,
    }

    pub mod header {

        pub enum FileHeaderSpec {
            Null,
            Bool,
            Integer,
            UInteger,
            Float,
            Text,
            Key { name: String, value_type: Box<FileHeaderSpec> },
            Array { allowed_types: Box<Vec<FileHeaderSpec>> },
        }

        pub enum FileHeaderData {
            Null,
            Bool(bool),
            Integer(i64),
            UInteger(u64),
            Float(f64),
            Text(String),
            Key { name: String, value: Box<FileHeaderData> },
            Array { values: Box<Vec<FileHeaderData>> },
        }

        pub trait FileHeaderParser {
            fn new(spec: &FileHeaderSpec) -> Self;
            fn read(&self, string: &String) -> Result<FileHeaderData, super::ParserError>;
            fn write(&self, data: &FileHeaderData) -> Result<String, super::ParserError>;
        }

    }

    pub trait FileData {
        fn get_fulltext(&self) -> String;
        fn get_abbrev(&self) -> String;
    }

    pub trait FileParser {
        fn new(header_parser: &header::FileHeaderParser) -> FileParser;
        fn read(&self, string: String) -> (header::FileHeaderData, FileData);
        fn write(&self, hdr: &header::FileHeaderData, data: &FileData) -> Result<String, ParserError>;
    }

}
<commit_msg>Implement ParserError<commit_after>use runtime::Runtime;
use std::error::Error;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::fmt::Display;
use std::path::Path;
use std::result::Result;

use module::todo::TodoModule;

mod todo;

#[derive(Debug)]
pub struct ModuleError {
    desc: String,
}

impl ModuleError {
    fn mk(desc: &'static str) -> ModuleError {
        ModuleError {
            desc: desc.to_owned().to_string(),
        }
    }
}

impl Error for ModuleError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        None
    }

}

impl Display for ModuleError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "ModuleError: {}", self.description())
    }
}

pub type ModuleResult = Result<(), ModuleError>;

pub trait Module {

    fn new(rt : &Runtime) -> Self;
    fn callnames() -> &'static [&'static str];
    fn name(&self) -> &'static str;

    fn execute(&self, rt : &Runtime) -> ModuleResult;
    fn shutdown(&self, rt : &Runtime) -> ModuleResult;

}

pub mod file {

    pub struct ParserError {
        summary: String,
        parsertext: String,
        index: i32,
        explanation: Option<String>,
    }

    impl ParserError {
        fn new(sum: &'static str, text: String, idx: i32, expl: &'static str) -> ParserError {
            ParserError {
                summary: String::from(sum),
                parsertext: text,
                index: idx,
                explanation: Some(String::from(expl)),
            }
        }

        fn short(sum: &'static str, text: String, idx: i32) -> ParserError {
            ParserError {
                summary: String::from(sum),
                parsertext: text,
                index: idx,
                explanation: None
            }
        }
    }

    pub mod header {

        pub enum FileHeaderSpec {
            Null,
            Bool,
            Integer,
            UInteger,
            Float,
            Text,
            Key { name: String, value_type: Box<FileHeaderSpec> },
            Array { allowed_types: Box<Vec<FileHeaderSpec>> },
        }

        pub enum FileHeaderData {
            Null,
            Bool(bool),
            Integer(i64),
            UInteger(u64),
            Float(f64),
            Text(String),
            Key { name: String, value: Box<FileHeaderData> },
            Array { values: Box<Vec<FileHeaderData>> },
        }

        pub trait FileHeaderParser {
            fn new(spec: &FileHeaderSpec) -> Self;
            fn read(&self, string: &String) -> Result<FileHeaderData, super::ParserError>;
            fn write(&self, data: &FileHeaderData) -> Result<String, super::ParserError>;
        }

    }

    pub trait FileData {
        fn get_fulltext(&self) -> String;
        fn get_abbrev(&self) -> String;
    }

    pub trait FileParser {
        fn new(header_parser: &header::FileHeaderParser) -> FileParser;
        fn read(&self, string: String) -> (header::FileHeaderData, FileData);
        fn write(&self, hdr: &header::FileHeaderData, data: &FileData) -> Result<String, ParserError>;
    }

}
<|endoftext|>


<commit_before><commit_msg>Added Rust factorial solution (#133)<commit_after>fn iterative(n: u128) -> u128 {
    if n <= 1 { 1 } else {
        let mut acc = 1u128;
        let mut x = n;
        while x > 1 {
            acc *= x;
            x -= 1;
        }
        acc
    }
}

fn recursive(n: u128) -> u128 {
    if n <= 1 { 1 } else { n * recursive(n - 1) }
}

mod tests {
    #[test]
    fn iterative_test() {
        use super::iterative;

        assert_eq!(iterative(0), 1);
        assert_eq!(iterative(1), 1);
        assert_eq!(iterative(2), 2);
        assert_eq!(iterative(3), 6);
        assert_eq!(iterative(4), 24);
        assert_eq!(iterative(5), 120);
        assert_eq!(iterative(20), 2_432_902_008_176_640_000);
    }

    #[test]
    fn recursive_test() {
        use super::recursive;

        assert_eq!(recursive(0), 1);
        assert_eq!(recursive(1), 1);
        assert_eq!(recursive(2), 2);
        assert_eq!(recursive(3), 6);
        assert_eq!(recursive(4), 24);
        assert_eq!(recursive(5), 120);
        assert_eq!(recursive(20), 2_432_902_008_176_640_000);
    }
}
<|endoftext|>


<commit_before><commit_msg>Move the binding of the descriptor set for static uniforms out of the main render loop<commit_after><|endoftext|>


<commit_before><commit_msg>Primary Color Binary<commit_after>extern crate image;
extern crate vibrant;

use std::env;
use std::path::Path;

use vibrant::Palette;

fn main() {
    let source = env::args().skip(1).next().expect("No source image given.");
    let img = image::open(&Path::new(&source))
                  .ok()
                  .expect(&format!("Could not load image {:?}", source));

    println!("{}", Palette::new(&img, 10, 10).sort_by_frequency());
}
<|endoftext|>


<commit_before><commit_msg>remove blackboard from space<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unecessary String instantiation<commit_after><|endoftext|>


<commit_before><commit_msg>fix: fixes Windows build for 2x release<commit_after><|endoftext|>


<commit_before><commit_msg>Add some docs for TarArchiver<commit_after><|endoftext|>


<commit_before><commit_msg>list5<commit_after>use std::fmt;
use List::{Cons, Nil};
use std::sync::Arc;

#[derive(PartialEq, Clone)]
enum List<T> {
  Cons(T, Arc<List<T>>),
  Nil
}

impl<T> fmt::Display for List<T> where T : fmt::Display {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match *self {
      Cons(ref head, ref tail) =>
        {
          write!(f, "{head} :: ", head = head);
          write!(f, "{tail} ", tail = tail)
        }
      Nil => write!(f, "Nil")
    }
  }
}

fn flat_map<T, U>(list: &List<T>, f: &Fn(T) -> List<U>) -> List<U> where T: Copy, T: Sized, T: Copy, T: PartialEq, U: Copy, U: Sized, U: PartialEq {
  match *list {
    Cons(ref head, ref tail) => concat(&f(*head), flat_map(tail, f)),
    Nil => Nil
  }
}

fn filter<T>(list: &List<T>, f: &Fn(T) -> bool) -> List<T> where T : Copy {
  fold_right(list, Nil, &|x, y| if f(x) { Cons(x, Arc::new(filter(&y, f))) } else { filter(&y, f) })
}

fn concat<T>(list: &List<T>, b: List<T>) -> List<T> where T: Copy, T: Sized {
  fold_right(list, b, &|x, y| Cons(x, Arc::new(y)))
}

fn fold_right<T, U>(list: &List<T>, result: U, f: &Fn(T, U) -> U) -> U where T: Copy, T: Sized {
  match *list {
    Cons(ref head, ref tail) =>
      f(*head, fold_right(tail, result, f)),
    Nil => result
  }
}

fn fold_left<T, U>(list: &List<T>, result: U, f: &Fn(U, T) -> U) -> U where T: Copy, T: Sized {
  match *list {
    Cons(ref head, ref tail) => fold_left(tail, f(result, *head), f),
    Nil => result
  }
}

fn map<T, U>(list: &List<T>, f: &Fn(T) -> U) -> List<U> where T: Copy , U: Copy {
  fold_right(list, Nil, &|x, y| Cons(f(x), Arc::new(y)))
}

fn new_list<T>(args: Vec<T>) -> List<T> where T: Copy {
  let mut vec = args;
  let mut x: List<T> = Nil;
  while vec.len() > 0 {
    match vec.pop() {
      Some(e) => x = Cons(e, Arc::new(x)),
      None => {}
    }
  }
  x
}

fn main() {
  let list = new_list(vec![1, 2, 3, 4, 5]);
  println!("{list}", list = filter(&list, &|x| x < 4));
}
<|endoftext|>


<commit_before><commit_msg>check pthread_create return code<commit_after><|endoftext|>


<commit_before><commit_msg>Add a regression test for #50041<commit_after>// build-pass
// compile-flags: -Z mir-opt-level=3

#![crate_type="lib"]
#![feature(lang_items)]
#![no_std]

#[lang = "owned_box"]
pub struct Box<T: ?Sized>(*mut T);

impl<T: ?Sized> Drop for Box<T> {
    fn drop(&mut self) {
    }
}

#[lang = "box_free"]
#[inline(always)]
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
    dealloc(ptr)
}

#[inline(never)]
fn dealloc<T: ?Sized>(_: *mut T) {
}

pub struct Foo<T>(T);

pub fn foo(a: Option<Box<Foo<usize>>>) -> usize {
    let f = match a {
        None => Foo(0),
        Some(vec) => *vec,
    };
    f.0
}
<|endoftext|>


<commit_before><commit_msg>Added workspace.rs file<commit_after>use petgraph::graph::NodeIndex;
use rustwlc::{Geometry, Point};
use super::super::LayoutTree;
use super::super::core::container::{Container, ContainerType};

impl LayoutTree {
    /// Gets a workspace by name or creates it
    fn get_or_make_workspace(&mut self, name: &str) -> NodeIndex {
        let active_index = self.active_ix_of(ContainerType::Output)
            .or_else(|| self.tree.follow_path_until(self.tree.root_ix(), ContainerType::Output).ok())
            .expect("get_or_make_wksp: Couldn't get output");
        let workspace_ix = self.tree.workspace_ix_by_name(name).unwrap_or_else(|| {
            let root_ix = self.init_workspace(name.to_string(), active_index);
            self.tree.parent_of(root_ix)
                .expect("Workspace was not properly initialized with a root container")
        });
        self.validate();
        workspace_ix
    }

    /// Initializes a workspace and gets the index of the root container
    pub fn init_workspace(&mut self, name: String, output_ix: NodeIndex)
                      -> NodeIndex {
        let size = self.tree.get(output_ix)
            .expect("init_workspace: invalid output").get_geometry()
            .expect("init_workspace: no geometry for output").size;
        let worksp = Container::new_workspace(name.to_string(), size.clone());

        trace!("Adding workspace {:?}", worksp);
        let worksp_ix = self.tree.add_child(output_ix, worksp, false);
        let geometry = Geometry {
            size: size, origin: Point { x: 0, y: 0 }
        };
        let container_ix = self.tree.add_child(worksp_ix,
                                               Container::new_container(geometry), false);
        self.validate();
        container_ix
    }

    /// Switch to the specified workspace
    pub fn switch_to_workspace(&mut self, name: &str) {
        let maybe_active_ix = self.active_container
            .or_else(|| {
                let new_active = self.tree.follow_path(self.tree.root_ix());
                match self.tree[new_active].get_type() {
                    ContainerType::View | ContainerType::Container => {
                        Some(new_active)
                    },
                    // else try and get the root container
                    _ => self.tree.descendant_of_type(new_active, ContainerType::Container)
                }
            });
        if maybe_active_ix.is_none() {
            warn!("{:#?}", self);
            warn!("No active container, cannot switch");
            return;
        }
        let active_ix = maybe_active_ix.unwrap();
        // Get the old (current) workspace
        let old_worksp_ix: NodeIndex;
        if let Some(index) = self.tree.ancestor_of_type(active_ix, ContainerType::Workspace) {
            old_worksp_ix = index;
            trace!("Switching to workspace {}", name);
        } else {
            match self.tree[active_ix].get_type() {
                ContainerType::Workspace => {
                    old_worksp_ix = active_ix;
                    trace!("Switching to workspace {}", name);
                },
                _ => {
                    warn!("Could not find old workspace, could not set invisible");
                    return;
                }
            }
        }
        // Get the new workspace, or create one if it doesn't work
        let mut workspace_ix = self.get_or_make_workspace(name);
        if old_worksp_ix == workspace_ix {
            return;
        }
        // Set the old one to invisible
        self.tree.set_family_visible(old_worksp_ix, false);
        // Set the new one to visible
        self.tree.set_family_visible(workspace_ix, true);
        // Delete the old workspace if it has no views on it
        self.active_container = None;
        if self.tree.descendant_of_type(old_worksp_ix, ContainerType::View).is_none() {
            trace!("Removing workspace: {:?}", self.tree[old_worksp_ix].get_name()
                   .expect("Workspace had no name"));
            self.remove_container(old_worksp_ix);
        }
        workspace_ix = self.tree.workspace_ix_by_name(name)
            .expect("Workspace we just made was deleted!");
        let active_ix = self.tree.follow_path(workspace_ix);
        match self.tree[active_ix].get_type() {
            ContainerType::View  => {
                match self.tree[active_ix] {
                    Container::View { ref handle, ..} => {
                        handle.focus();
                    },
                    _ => unreachable!()
                }
                self.active_container = Some(active_ix);
                self.tree.set_ancestor_paths_active(active_ix);
                self.validate();
                return;
            },
            _ => {
                self.active_container = self.tree.descendant_of_type(active_ix, ContainerType::View)
                    .or_else(|| self.tree.descendant_of_type(active_ix, ContainerType::Container));
            }
        }
        self.focus_on_next_container(workspace_ix);
        self.validate();
    }

    /// Moves the current active container to a new workspace
    pub fn send_active_to_workspace(&mut self, name: &str) {
        // Ensure focus
        if let Some(active_ix) = self.active_container {
            let curr_work_ix = self.active_ix_of(ContainerType::Workspace)
                .expect("send_active: Not currently in a workspace!");
            if active_ix == self.tree.children_of(curr_work_ix)[0] {
                warn!("Tried to move the root container of a workspace, aborting move");
                return;
            }
            let next_work_ix = self.get_or_make_workspace(name);

            // Check if the workspaces are the same
            if next_work_ix == curr_work_ix {
                trace!("Attempted to move a view to the same workspace {}!", name);
                return;
            }
            self.tree.set_family_visible(curr_work_ix, false);

            // Save the parent of this view for focusing
            let maybe_active_parent = self.tree.parent_of(active_ix);

            // Get the root container of the next workspace
            let next_work_children = self.tree.children_of(next_work_ix);
            if cfg!(debug_assertions) {
                assert!(next_work_children.len() == 1,
                        "Next workspace has multiple roots!");
            }
            let next_work_root_ix = next_work_children[0];

            // Move the container
            info!("Moving container {:?} to workspace {}",
                self.get_active_container(), name);
            self.tree.move_node(active_ix, next_work_root_ix);

            // Update the active container
            if let Ok(parent_ix) = maybe_active_parent {
                let ctype = self.tree.node_type(parent_ix).unwrap_or(ContainerType::Root);
                if ctype == ContainerType::Container {
                    self.focus_on_next_container(parent_ix);
                } else {
                    trace!("Send to container invalidated a NodeIndex: {:?} to {:?}",
                    parent_ix, ctype);
                }
                if self.tree.can_remove_empty_parent(parent_ix) {
                    self.remove_view_or_container(parent_ix);
                }
            }
            else {
                self.focus_on_next_container(curr_work_ix);
            }

            self.tree.set_family_visible(curr_work_ix, true);

            self.normalize_container(active_ix);
        }
        let root_ix = self.tree.root_ix();
        self.layout(root_ix);
        self.validate();
    }
}
<|endoftext|>


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

use build::{BlockAnd, BlockAndExtension, Builder};
use build::ForGuard::OutsideGuard;
use build::matches::ArmHasGuard;
use hair::*;
use rustc::mir::*;
use rustc::hir;
use syntax_pos::Span;

impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
    pub fn ast_block(&mut self,
                     destination: &Place<'tcx>,
                     block: BasicBlock,
                     ast_block: &'tcx hir::Block,
                     source_info: SourceInfo)
                     -> BlockAnd<()> {
        let Block {
            region_scope,
            opt_destruction_scope,
            span,
            stmts,
            expr,
            targeted_by_break,
            safety_mode
        } =
            self.hir.mirror(ast_block);
        self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
            this.in_scope((region_scope, source_info), LintLevel::Inherited, block, move |this| {
                if targeted_by_break {
                    // This is a `break`-able block
                    let exit_block = this.cfg.start_new_block();
                    let block_exit = this.in_breakable_scope(
                        None, exit_block, destination.clone(), |this| {
                            this.ast_block_stmts(destination, block, span, stmts, expr,
                                                 safety_mode)
                        });
                    this.cfg.terminate(unpack!(block_exit), source_info,
                                       TerminatorKind::Goto { target: exit_block });
                    exit_block.unit()
                } else {
                    this.ast_block_stmts(destination, block, span, stmts, expr,
                                         safety_mode)
                }
            })
        })
    }

    fn ast_block_stmts(&mut self,
                       destination: &Place<'tcx>,
                       mut block: BasicBlock,
                       span: Span,
                       stmts: Vec<StmtRef<'tcx>>,
                       expr: Option<ExprRef<'tcx>>,
                       safety_mode: BlockSafety)
                       -> BlockAnd<()> {
        let this = self;

        // This convoluted structure is to avoid using recursion as we walk down a list
        // of statements. Basically, the structure we get back is something like:
        //
        //    let x = <init> in {
        //       expr1;
        //       let y = <init> in {
        //           expr2;
        //           expr3;
        //           ...
        //       }
        //    }
        //
        // The let bindings are valid till the end of block so all we have to do is to pop all
        // the let-scopes at the end.
        //
        // First we build all the statements in the block.
        let mut let_scope_stack = Vec::with_capacity(8);
        let outer_source_scope = this.source_scope;
        let outer_push_unsafe_count = this.push_unsafe_count;
        let outer_unpushed_unsafe = this.unpushed_unsafe;
        this.update_source_scope_for_safety_mode(span, safety_mode);

        let source_info = this.source_info(span);
        for stmt in stmts {
            let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
            match kind {
                StmtKind::Expr { scope, expr } => {
                    unpack!(block = this.in_opt_scope(
                        opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
                            let si = (scope, source_info);
                            this.in_scope(si, LintLevel::Inherited, block, |this| {
                                let expr = this.hir.mirror(expr);
                                this.stmt_expr(block, expr)
                            })
                        }));
                }
                StmtKind::Let {
                    remainder_scope,
                    init_scope,
                    pattern,
                    ty,
                    initializer,
                    lint_level
                } => {
                    // Enter the remainder scope, i.e. the bindings' destruction scope.
                    this.push_scope((remainder_scope, source_info));
                    let_scope_stack.push(remainder_scope);

                    // Declare the bindings, which may create a source scope.
                    let remainder_span = remainder_scope.span(this.hir.tcx(),
                                                              &this.hir.region_scope_tree);

                    let scope;

                    // Evaluate the initializer, if present.
                    if let Some(init) = initializer {
                        let initializer_span = init.span();

                        scope = this.declare_bindings(
                            None,
                            remainder_span,
                            lint_level,
                            &[pattern.clone()],
                            ArmHasGuard(false),
                            Some((None, initializer_span)),
                        );
                        unpack!(block = this.in_opt_scope(
                            opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
                                let scope = (init_scope, source_info);
                                this.in_scope(scope, lint_level, block, |this| {
                                    this.expr_into_pattern(block, ty, pattern, init)
                                })
                            }));
                    } else {
                        scope = this.declare_bindings(
                            None, remainder_span, lint_level, &[pattern.clone()],
                            ArmHasGuard(false), None);

                        // FIXME(#47184): We currently only insert `UserAssertTy` statements for
                        // patterns that are bindings, this is as we do not want to deconstruct
                        // the type being assertion to match the pattern.
                        if let PatternKind::Binding { var, .. } = *pattern.kind {
                            if let Some(ty) = ty {
                                this.user_assert_ty(block, ty, var, span);
                            }
                        }

                        this.visit_bindings(&pattern, &mut |this, _, _, _, node, span, _| {
                            this.storage_live_binding(block, node, span, OutsideGuard);
                            this.schedule_drop_for_binding(node, span, OutsideGuard);
                        })
                    }

                    // Enter the source scope, after evaluating the initializer.
                    if let Some(source_scope) = scope {
                        this.source_scope = source_scope;
                    }
                }
            }
        }
        // Then, the block may have an optional trailing expression which is a “return” value
        // of the block.
        if let Some(expr) = expr {
            unpack!(block = this.into(destination, block, expr));
        } else {
            // If a block has no trailing expression, then it is given an implicit return type.
            // This return type is usually `()`, unless the block is diverging, in which case the
            // return type is `!`. For the unit type, we need to actually return the unit, but in
            // the case of `!`, no return value is required, as the block will never return.
            let tcx = this.hir.tcx();
            let ty = destination.ty(&this.local_decls, tcx).to_ty(tcx);
            if ty.is_nil() {
                // We only want to assign an implicit `()` as the return value of the block if the
                // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
                this.cfg.push_assign_unit(block, source_info, destination);
            }
        }
        // Finally, we pop all the let scopes before exiting out from the scope of block
        // itself.
        for scope in let_scope_stack.into_iter().rev() {
            unpack!(block = this.pop_scope((scope, source_info), block));
        }
        // Restore the original source scope.
        this.source_scope = outer_source_scope;
        this.push_unsafe_count = outer_push_unsafe_count;
        this.unpushed_unsafe = outer_unpushed_unsafe;
        block.unit()
    }

    /// If we are changing the safety mode, create a new source scope
    fn update_source_scope_for_safety_mode(&mut self,
                                               span: Span,
                                               safety_mode: BlockSafety)
    {
        debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
        let new_unsafety = match safety_mode {
            BlockSafety::Safe => None,
            BlockSafety::ExplicitUnsafe(node_id) => {
                assert_eq!(self.push_unsafe_count, 0);
                match self.unpushed_unsafe {
                    Safety::Safe => {}
                    _ => return
                }
                self.unpushed_unsafe = Safety::ExplicitUnsafe(node_id);
                Some(Safety::ExplicitUnsafe(node_id))
            }
            BlockSafety::PushUnsafe => {
                self.push_unsafe_count += 1;
                Some(Safety::BuiltinUnsafe)
            }
            BlockSafety::PopUnsafe => {
                self.push_unsafe_count =
                    self.push_unsafe_count.checked_sub(1).unwrap_or_else(|| {
                        span_bug!(span, "unsafe count underflow")
                    });
                if self.push_unsafe_count == 0 {
                    Some(self.unpushed_unsafe)
                } else {
                    None
                }
            }
        };

        if let Some(unsafety) = new_unsafety {
            self.source_scope = self.new_source_scope(
                span, LintLevel::Inherited, Some(unsafety));
        }
    }
}
<commit_msg>review feedback: no reason to clone just to make a singleton slice.<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use build::{BlockAnd, BlockAndExtension, Builder};
use build::ForGuard::OutsideGuard;
use build::matches::ArmHasGuard;
use hair::*;
use rustc::mir::*;
use rustc::hir;
use syntax_pos::Span;

use std::slice;

impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
    pub fn ast_block(&mut self,
                     destination: &Place<'tcx>,
                     block: BasicBlock,
                     ast_block: &'tcx hir::Block,
                     source_info: SourceInfo)
                     -> BlockAnd<()> {
        let Block {
            region_scope,
            opt_destruction_scope,
            span,
            stmts,
            expr,
            targeted_by_break,
            safety_mode
        } =
            self.hir.mirror(ast_block);
        self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
            this.in_scope((region_scope, source_info), LintLevel::Inherited, block, move |this| {
                if targeted_by_break {
                    // This is a `break`-able block
                    let exit_block = this.cfg.start_new_block();
                    let block_exit = this.in_breakable_scope(
                        None, exit_block, destination.clone(), |this| {
                            this.ast_block_stmts(destination, block, span, stmts, expr,
                                                 safety_mode)
                        });
                    this.cfg.terminate(unpack!(block_exit), source_info,
                                       TerminatorKind::Goto { target: exit_block });
                    exit_block.unit()
                } else {
                    this.ast_block_stmts(destination, block, span, stmts, expr,
                                         safety_mode)
                }
            })
        })
    }

    fn ast_block_stmts(&mut self,
                       destination: &Place<'tcx>,
                       mut block: BasicBlock,
                       span: Span,
                       stmts: Vec<StmtRef<'tcx>>,
                       expr: Option<ExprRef<'tcx>>,
                       safety_mode: BlockSafety)
                       -> BlockAnd<()> {
        let this = self;

        // This convoluted structure is to avoid using recursion as we walk down a list
        // of statements. Basically, the structure we get back is something like:
        //
        //    let x = <init> in {
        //       expr1;
        //       let y = <init> in {
        //           expr2;
        //           expr3;
        //           ...
        //       }
        //    }
        //
        // The let bindings are valid till the end of block so all we have to do is to pop all
        // the let-scopes at the end.
        //
        // First we build all the statements in the block.
        let mut let_scope_stack = Vec::with_capacity(8);
        let outer_source_scope = this.source_scope;
        let outer_push_unsafe_count = this.push_unsafe_count;
        let outer_unpushed_unsafe = this.unpushed_unsafe;
        this.update_source_scope_for_safety_mode(span, safety_mode);

        let source_info = this.source_info(span);
        for stmt in stmts {
            let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
            match kind {
                StmtKind::Expr { scope, expr } => {
                    unpack!(block = this.in_opt_scope(
                        opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
                            let si = (scope, source_info);
                            this.in_scope(si, LintLevel::Inherited, block, |this| {
                                let expr = this.hir.mirror(expr);
                                this.stmt_expr(block, expr)
                            })
                        }));
                }
                StmtKind::Let {
                    remainder_scope,
                    init_scope,
                    pattern,
                    ty,
                    initializer,
                    lint_level
                } => {
                    // Enter the remainder scope, i.e. the bindings' destruction scope.
                    this.push_scope((remainder_scope, source_info));
                    let_scope_stack.push(remainder_scope);

                    // Declare the bindings, which may create a source scope.
                    let remainder_span = remainder_scope.span(this.hir.tcx(),
                                                              &this.hir.region_scope_tree);

                    let scope;

                    // Evaluate the initializer, if present.
                    if let Some(init) = initializer {
                        let initializer_span = init.span();

                        scope = this.declare_bindings(
                            None,
                            remainder_span,
                            lint_level,
                            slice::from_ref(&pattern),
                            ArmHasGuard(false),
                            Some((None, initializer_span)),
                        );
                        unpack!(block = this.in_opt_scope(
                            opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
                                let scope = (init_scope, source_info);
                                this.in_scope(scope, lint_level, block, |this| {
                                    this.expr_into_pattern(block, ty, pattern, init)
                                })
                            }));
                    } else {
                        scope = this.declare_bindings(
                            None, remainder_span, lint_level, slice::from_ref(&pattern),
                            ArmHasGuard(false), None);

                        // FIXME(#47184): We currently only insert `UserAssertTy` statements for
                        // patterns that are bindings, this is as we do not want to deconstruct
                        // the type being assertion to match the pattern.
                        if let PatternKind::Binding { var, .. } = *pattern.kind {
                            if let Some(ty) = ty {
                                this.user_assert_ty(block, ty, var, span);
                            }
                        }

                        this.visit_bindings(&pattern, &mut |this, _, _, _, node, span, _| {
                            this.storage_live_binding(block, node, span, OutsideGuard);
                            this.schedule_drop_for_binding(node, span, OutsideGuard);
                        })
                    }

                    // Enter the source scope, after evaluating the initializer.
                    if let Some(source_scope) = scope {
                        this.source_scope = source_scope;
                    }
                }
            }
        }
        // Then, the block may have an optional trailing expression which is a “return” value
        // of the block.
        if let Some(expr) = expr {
            unpack!(block = this.into(destination, block, expr));
        } else {
            // If a block has no trailing expression, then it is given an implicit return type.
            // This return type is usually `()`, unless the block is diverging, in which case the
            // return type is `!`. For the unit type, we need to actually return the unit, but in
            // the case of `!`, no return value is required, as the block will never return.
            let tcx = this.hir.tcx();
            let ty = destination.ty(&this.local_decls, tcx).to_ty(tcx);
            if ty.is_nil() {
                // We only want to assign an implicit `()` as the return value of the block if the
                // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
                this.cfg.push_assign_unit(block, source_info, destination);
            }
        }
        // Finally, we pop all the let scopes before exiting out from the scope of block
        // itself.
        for scope in let_scope_stack.into_iter().rev() {
            unpack!(block = this.pop_scope((scope, source_info), block));
        }
        // Restore the original source scope.
        this.source_scope = outer_source_scope;
        this.push_unsafe_count = outer_push_unsafe_count;
        this.unpushed_unsafe = outer_unpushed_unsafe;
        block.unit()
    }

    /// If we are changing the safety mode, create a new source scope
    fn update_source_scope_for_safety_mode(&mut self,
                                               span: Span,
                                               safety_mode: BlockSafety)
    {
        debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
        let new_unsafety = match safety_mode {
            BlockSafety::Safe => None,
            BlockSafety::ExplicitUnsafe(node_id) => {
                assert_eq!(self.push_unsafe_count, 0);
                match self.unpushed_unsafe {
                    Safety::Safe => {}
                    _ => return
                }
                self.unpushed_unsafe = Safety::ExplicitUnsafe(node_id);
                Some(Safety::ExplicitUnsafe(node_id))
            }
            BlockSafety::PushUnsafe => {
                self.push_unsafe_count += 1;
                Some(Safety::BuiltinUnsafe)
            }
            BlockSafety::PopUnsafe => {
                self.push_unsafe_count =
                    self.push_unsafe_count.checked_sub(1).unwrap_or_else(|| {
                        span_bug!(span, "unsafe count underflow")
                    });
                if self.push_unsafe_count == 0 {
                    Some(self.unpushed_unsafe)
                } else {
                    None
                }
            }
        };

        if let Some(unsafety) = new_unsafety {
            self.source_scope = self.new_source_scope(
                span, LintLevel::Inherited, Some(unsafety));
        }
    }
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Make example use an array and a for loop<commit_after><|endoftext|>


<commit_before>#[doc = "An atomically reference counted wrapper that can be used to
share immutable data between tasks."]

import comm::{port, chan, methods};

export arc, get, clone, shared_arc, get_arc;

#[abi = "cdecl"]
native mod rustrt {
    #[rust_stack]
    fn rust_atomic_increment(p: &mut libc::intptr_t)
        -> libc::intptr_t;

    #[rust_stack]
    fn rust_atomic_decrement(p: &mut libc::intptr_t)
        -> libc::intptr_t;
}

type arc_data<T: const> = {
    mut count: libc::intptr_t,
    data: T
};

resource arc_destruct<T: const>(data: *libc::c_void) {
    unsafe {
        let data: ~arc_data<T> = unsafe::reinterpret_cast(data);
        let ref_ptr = &mut data.count;

        let new_count = rustrt::rust_atomic_decrement(ref_ptr);
        assert new_count >= 0;
        if new_count == 0 {
            // drop glue takes over.
        } else {
            unsafe::forget(data);
        }
    }
}

type arc<T: const> = arc_destruct<T>;

#[doc="Create an atomically reference counted wrapper."]
fn arc<T: const>(-data: T) -> arc<T> {
    let data = ~{mut count: 1, data: data};
    unsafe {
        let ptr = unsafe::reinterpret_cast(data);
        unsafe::forget(data);
        arc_destruct(ptr)
    }
}

#[doc="Access the underlying data in an atomically reference counted
 wrapper."]
fn get<T: const>(rc: &a.arc<T>) -> &a.T {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast(**rc);
        // Cast us back into the correct region
        let r = unsafe::reinterpret_cast(&ptr.data);
        unsafe::forget(ptr);
        ret r;
    }
}

#[doc="Duplicate an atomically reference counted wrapper.

The resulting two `arc` objects will point to the same underlying data
object. However, one of the `arc` objects can be sent to another task,
allowing them to share the underlying data."]
fn clone<T: const>(rc: &arc<T>) -> arc<T> {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast(**rc);
        rustrt::rust_atomic_increment(&mut ptr.count);
        unsafe::forget(ptr);
    }
    arc_destruct(**rc)
}

// Convenience code for sharing arcs between tasks

type get_chan<T: const send> = chan<chan<arc<T>>>;

// (terminate, get)
type shared_arc<T: const send> = (shared_arc_res, get_chan<T>);

resource shared_arc_res(c: comm::chan<()>) {
    c.send(());
}

fn shared_arc<T: send const>(-data: T) -> shared_arc<T> {
    let a = arc::arc(data);
    let p = port();
    let c = chan(p);
    task::spawn() {|move a|
        let mut live = true;
        let terminate = port();
        let get = port();

        c.send((chan(terminate), chan(get)));

        while live {
            alt comm::select2(terminate, get) {
              either::left(()) { live = false; }
              either::right(cc) {
                comm::send(cc, arc::clone(&a));
              }
            }
        }
    };
    let (terminate, get) = p.recv();
    (shared_arc_res(terminate), get)
}

fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
    let p = port();
    c.send(chan(p));
    p.recv()
}

#[cfg(test)]
mod tests {
    import comm::*;

    #[test]
    fn manually_share_arc() {
        let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let arc_v = arc::arc(v);

        let p = port();
        let c = chan(p);

        task::spawn() {||
            let p = port();
            c.send(chan(p));

            let arc_v = p.recv();

            let v = *arc::get::<[int]>(&arc_v);
            assert v[3] == 4;
        };

        let c = p.recv();
        c.send(arc::clone(&arc_v));

        assert (*arc::get(&arc_v))[2] == 3;

        log(info, arc_v);
    }

    #[test]
    fn auto_share_arc() {
        let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let (_res, arc_c) = shared_arc(v);

        let p = port();
        let c = chan(p);

        task::spawn() {||
            let arc_v = get_arc(arc_c);
            let v = *get(&arc_v);
            assert v[2] == 3;

            c.send(());
        };

        assert p.recv() == ();
    }
}
<commit_msg>constrain scope of mut ptr to please borrowck<commit_after>#[doc = "An atomically reference counted wrapper that can be used to
share immutable data between tasks."]

import comm::{port, chan, methods};

export arc, get, clone, shared_arc, get_arc;

#[abi = "cdecl"]
native mod rustrt {
    #[rust_stack]
    fn rust_atomic_increment(p: &mut libc::intptr_t)
        -> libc::intptr_t;

    #[rust_stack]
    fn rust_atomic_decrement(p: &mut libc::intptr_t)
        -> libc::intptr_t;
}

type arc_data<T: const> = {
    mut count: libc::intptr_t,
    data: T
};

resource arc_destruct<T: const>(data: *libc::c_void) {
    unsafe {
        let data: ~arc_data<T> = unsafe::reinterpret_cast(data);
        let new_count = rustrt::rust_atomic_decrement(&mut data.count);
        assert new_count >= 0;
        if new_count == 0 {
            // drop glue takes over.
        } else {
            unsafe::forget(data);
        }
    }
}

type arc<T: const> = arc_destruct<T>;

#[doc="Create an atomically reference counted wrapper."]
fn arc<T: const>(-data: T) -> arc<T> {
    let data = ~{mut count: 1, data: data};
    unsafe {
        let ptr = unsafe::reinterpret_cast(data);
        unsafe::forget(data);
        arc_destruct(ptr)
    }
}

#[doc="Access the underlying data in an atomically reference counted
 wrapper."]
fn get<T: const>(rc: &a.arc<T>) -> &a.T {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast(**rc);
        // Cast us back into the correct region
        let r = unsafe::reinterpret_cast(&ptr.data);
        unsafe::forget(ptr);
        ret r;
    }
}

#[doc="Duplicate an atomically reference counted wrapper.

The resulting two `arc` objects will point to the same underlying data
object. However, one of the `arc` objects can be sent to another task,
allowing them to share the underlying data."]
fn clone<T: const>(rc: &arc<T>) -> arc<T> {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast(**rc);
        rustrt::rust_atomic_increment(&mut ptr.count);
        unsafe::forget(ptr);
    }
    arc_destruct(**rc)
}

// Convenience code for sharing arcs between tasks

type get_chan<T: const send> = chan<chan<arc<T>>>;

// (terminate, get)
type shared_arc<T: const send> = (shared_arc_res, get_chan<T>);

resource shared_arc_res(c: comm::chan<()>) {
    c.send(());
}

fn shared_arc<T: send const>(-data: T) -> shared_arc<T> {
    let a = arc::arc(data);
    let p = port();
    let c = chan(p);
    task::spawn() {|move a|
        let mut live = true;
        let terminate = port();
        let get = port();

        c.send((chan(terminate), chan(get)));

        while live {
            alt comm::select2(terminate, get) {
              either::left(()) { live = false; }
              either::right(cc) {
                comm::send(cc, arc::clone(&a));
              }
            }
        }
    };
    let (terminate, get) = p.recv();
    (shared_arc_res(terminate), get)
}

fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
    let p = port();
    c.send(chan(p));
    p.recv()
}

#[cfg(test)]
mod tests {
    import comm::*;

    #[test]
    fn manually_share_arc() {
        let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let arc_v = arc::arc(v);

        let p = port();
        let c = chan(p);

        task::spawn() {||
            let p = port();
            c.send(chan(p));

            let arc_v = p.recv();

            let v = *arc::get::<[int]>(&arc_v);
            assert v[3] == 4;
        };

        let c = p.recv();
        c.send(arc::clone(&arc_v));

        assert (*arc::get(&arc_v))[2] == 3;

        log(info, arc_v);
    }

    #[test]
    fn auto_share_arc() {
        let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let (_res, arc_c) = shared_arc(v);

        let p = port();
        let c = chan(p);

        task::spawn() {||
            let arc_v = get_arc(arc_c);
            let v = *get(&arc_v);
            assert v[2] == 3;

            c.send(());
        };

        assert p.recv() == ();
    }
}
<|endoftext|>


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

/*!

The `Ord` and `Eq` comparison traits

This module contains the definition of both `Ord` and `Eq` which define
the common interfaces for doing comparison. Both are language items
that the compiler uses to implement the comparison operators. Rust code
may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and `Eq` to overload the `==` and `!=` operators.

*/

#![allow(missing_doc)]

/**
* Trait for values that can be compared for equality and inequality.
*
* This trait allows partial equality, where types can be unordered instead of strictly equal or
* unequal. For example, with the built-in floating-point types `a == b` and `a != b` will both
* evaluate to false if either `a` or `b` is NaN (cf. IEEE 754-2008 section 5.11).
*
* Eq only requires the `eq` method to be implemented; `ne` is its negation by default.
*
* Eventually, this will be implemented by default for types that implement `TotalEq`.
*/
#[lang="eq"]
pub trait Eq {
    fn eq(&self, other: &Self) -> bool;

    #[inline]
    fn ne(&self, other: &Self) -> bool { !self.eq(other) }
}

/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
pub trait TotalEq: Eq {
    // FIXME #13101: this method is used solely by #[deriving] to
    // assert that every component of a type implements #[deriving]
    // itself, the current deriving infrastructure means doing this
    // assertion without using a method on this trait is nearly
    // impossible.
    //
    // This should never be implemented by hand.
    #[doc(hidden)]
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

macro_rules! totaleq_impl(
    ($t:ty) => {
        impl TotalEq for $t {}
    }
)

totaleq_impl!(bool)

totaleq_impl!(u8)
totaleq_impl!(u16)
totaleq_impl!(u32)
totaleq_impl!(u64)

totaleq_impl!(i8)
totaleq_impl!(i16)
totaleq_impl!(i32)
totaleq_impl!(i64)

totaleq_impl!(int)
totaleq_impl!(uint)

totaleq_impl!(char)

#[deriving(Clone, Eq, Show)]
pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }

/// Trait for types that form a total order
pub trait TotalOrd: TotalEq + Ord {
    fn cmp(&self, other: &Self) -> Ordering;
}

impl TotalEq for Ordering {}
impl TotalOrd for Ordering {
    #[inline]
    fn cmp(&self, other: &Ordering) -> Ordering {
        (*self as int).cmp(&(*other as int))
    }
}

impl Ord for Ordering {
    #[inline]
    fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
}

macro_rules! totalord_impl(
    ($t:ty) => {
        impl TotalOrd for $t {
            #[inline]
            fn cmp(&self, other: &$t) -> Ordering {
                if *self < *other { Less }
                else if *self > *other { Greater }
                else { Equal }
            }
        }
    }
)

totalord_impl!(u8)
totalord_impl!(u16)
totalord_impl!(u32)
totalord_impl!(u64)

totalord_impl!(i8)
totalord_impl!(i16)
totalord_impl!(i32)
totalord_impl!(i64)

totalord_impl!(int)
totalord_impl!(uint)

totalord_impl!(char)

/**
Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the
lexical ordering on a type `(int, int)`.
*/
#[inline]
pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
    match o1 {
        Equal => o2,
        _ => o1
    }
}

/**
* Trait for values that can be compared for a sort-order.
*
* Ord only requires implementation of the `lt` method,
* with the others generated from default implementations.
*
* However it remains possible to implement the others separately,
* for compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord: Eq {
    fn lt(&self, other: &Self) -> bool;
    #[inline]
    fn le(&self, other: &Self) -> bool { !other.lt(self) }
    #[inline]
    fn gt(&self, other: &Self) -> bool {  other.lt(self) }
    #[inline]
    fn ge(&self, other: &Self) -> bool { !self.lt(other) }
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
    fn equiv(&self, other: &T) -> bool;
}

#[inline]
pub fn min<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

#[inline]
pub fn max<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

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

    #[test]
    fn test_int_totalord() {
        assert_eq!(5.cmp(&10), Less);
        assert_eq!(10.cmp(&5), Greater);
        assert_eq!(5.cmp(&5), Equal);
        assert_eq!((-5).cmp(&12), Less);
        assert_eq!(12.cmp(-5), Greater);
    }

    #[test]
    fn test_ordering_order() {
        assert!(Less < Equal);
        assert_eq!(Greater.cmp(&Less), Greater);
    }

    #[test]
    fn test_lexical_ordering() {
        fn t(o1: Ordering, o2: Ordering, e: Ordering) {
            assert_eq!(lexical_ordering(o1, o2), e);
        }

        let xs = [Less, Equal, Greater];
        for &o in xs.iter() {
            t(Less, o, Less);
            t(Equal, o, o);
            t(Greater, o, Greater);
         }
    }
}
<commit_msg>auto merge of #12956 : killerswan/rust/docs, r=alexcrichton<commit_after>// Copyright 2012-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.

/*!

Defines the `Ord` and `Eq` comparison traits.

This module defines both `Ord` and `Eq` traits which are used by the compiler
to implement comparison operators.
Rust programs may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and may implement `Eq` to overload the `==` and `!=` operators.

For example, to define a type with a customized definition for the Eq operators,
you could do the following:

```rust
// Our type.
struct SketchyNum {
    num : int
}

// Our implementation of `Eq` to support `==` and `!=`.
impl Eq for SketchyNum {
    // Our custom eq allows numbers which are near eachother to be equal! :D
    fn eq(&self, other: &SketchyNum) -> bool {
        (self.num - other.num).abs() < 5
    }
}

// Now these binary operators will work when applied!
assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
```

*/

/**
* Trait for values that can be compared for equality and inequality.
*
* This trait allows partial equality, where types can be unordered instead of strictly equal or
* unequal. For example, with the built-in floating-point types `a == b` and `a != b` will both
* evaluate to false if either `a` or `b` is NaN (cf. IEEE 754-2008 section 5.11).
*
* Eq only requires the `eq` method to be implemented; `ne` is its negation by default.
*
* Eventually, this will be implemented by default for types that implement `TotalEq`.
*/
#[lang="eq"]
pub trait Eq {
    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
    fn eq(&self, other: &Self) -> bool;

    /// This method tests for `!=`.
    #[inline]
    fn ne(&self, other: &Self) -> bool { !self.eq(other) }
}

/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
pub trait TotalEq: Eq {
    // FIXME #13101: this method is used solely by #[deriving] to
    // assert that every component of a type implements #[deriving]
    // itself, the current deriving infrastructure means doing this
    // assertion without using a method on this trait is nearly
    // impossible.
    //
    // This should never be implemented by hand.
    #[doc(hidden)]
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

/// A macro which defines an implementation of TotalEq for a given type.
macro_rules! totaleq_impl(
    ($t:ty) => {
        impl TotalEq for $t {}
    }
)

totaleq_impl!(bool)

totaleq_impl!(u8)
totaleq_impl!(u16)
totaleq_impl!(u32)
totaleq_impl!(u64)

totaleq_impl!(i8)
totaleq_impl!(i16)
totaleq_impl!(i32)
totaleq_impl!(i64)

totaleq_impl!(int)
totaleq_impl!(uint)

totaleq_impl!(char)

/// An ordering is, e.g, a result of a comparison between two values.
#[deriving(Clone, Eq, Show)]
pub enum Ordering {
   /// An ordering where a compared value is less [than another].
   Less = -1,
   /// An ordering where a compared value is equal [to another].
   Equal = 0,
   /// An ordering where a compared value is greater [than another].
   Greater = 1
}

/// Trait for types that form a total order.
pub trait TotalOrd: TotalEq + Ord {
    /// This method returns an ordering between `self` and `other` values.
    ///
    /// By convention, `self.cmp(&other)` returns the ordering matching
    /// the expression `self <operator> other` if true.  For example:
    ///
    /// ```
    /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
    /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
    /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
    /// ```
    fn cmp(&self, other: &Self) -> Ordering;
}

impl TotalEq for Ordering {}
impl TotalOrd for Ordering {
    #[inline]
    fn cmp(&self, other: &Ordering) -> Ordering {
        (*self as int).cmp(&(*other as int))
    }
}

impl Ord for Ordering {
    #[inline]
    fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
}

/// A macro which defines an implementation of TotalOrd for a given type.
macro_rules! totalord_impl(
    ($t:ty) => {
        impl TotalOrd for $t {
            #[inline]
            fn cmp(&self, other: &$t) -> Ordering {
                if *self < *other { Less }
                else if *self > *other { Greater }
                else { Equal }
            }
        }
    }
)

totalord_impl!(u8)
totalord_impl!(u16)
totalord_impl!(u32)
totalord_impl!(u64)

totalord_impl!(i8)
totalord_impl!(i16)
totalord_impl!(i32)
totalord_impl!(i64)

totalord_impl!(int)
totalord_impl!(uint)

totalord_impl!(char)

/**
 * Combine orderings, lexically.
 *
 * For example for a type `(int, int)`, two comparisons could be done.
 * If the first ordering is different, the first ordering is all that must be returned.
 * If the first ordering is equal, then second ordering is returned.
*/
#[inline]
pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
    match o1 {
        Equal => o2,
        _ => o1
    }
}

/**
* Trait for values that can be compared for a sort-order.
*
* Ord only requires implementation of the `lt` method,
* with the others generated from default implementations.
*
* However it remains possible to implement the others separately,
* for compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord: Eq {
    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
    fn lt(&self, other: &Self) -> bool;

    /// This method tests less than or equal to (`<=`).
    #[inline]
    fn le(&self, other: &Self) -> bool { !other.lt(self) }

    /// This method tests greater than (`>`).
    #[inline]
    fn gt(&self, other: &Self) -> bool {  other.lt(self) }

    /// This method tests greater than or equal to (`>=`).
    #[inline]
    fn ge(&self, other: &Self) -> bool { !self.lt(other) }
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
    /// Implement this function to decide equivalent values.
    fn equiv(&self, other: &T) -> bool;
}

/// Compare and return the minimum of two values.
#[inline]
pub fn min<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

/// Compare and return the maximum of two values.
#[inline]
pub fn max<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

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

    #[test]
    fn test_int_totalord() {
        assert_eq!(5u.cmp(&10), Less);
        assert_eq!(10u.cmp(&5), Greater);
        assert_eq!(5u.cmp(&5), Equal);
        assert_eq!((-5u).cmp(&12), Less);
        assert_eq!(12u.cmp(-5), Greater);
    }

    #[test]
    fn test_ordering_order() {
        assert!(Less < Equal);
        assert_eq!(Greater.cmp(&Less), Greater);
    }

    #[test]
    fn test_lexical_ordering() {
        fn t(o1: Ordering, o2: Ordering, e: Ordering) {
            assert_eq!(lexical_ordering(o1, o2), e);
        }

        let xs = [Less, Equal, Greater];
        for &o in xs.iter() {
            t(Less, o, Less);
            t(Equal, o, o);
            t(Greater, o, Greater);
         }
    }

    #[test]
    fn test_user_defined_eq() {
        // Our type.
        struct SketchyNum {
            num : int
        }

        // Our implementation of `Eq` to support `==` and `!=`.
        impl Eq for SketchyNum {
            // Our custom eq allows numbers which are near eachother to be equal! :D
            fn eq(&self, other: &SketchyNum) -> bool {
                (self.num - other.num).abs() < 5
            }
        }

        // Now these binary operators will work when applied!
        assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
        assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 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 borrow_check::{Context, MirBorrowckCtxt};
use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
use dataflow::BorrowData;
use rustc::mir::{Local, Location, Mir};
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use util::liveness::{self, DefUse, LivenessMode};

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Adds annotations to `err` explaining *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
    pub(in borrow_check) fn explain_why_borrow_contains_point(
        &mut self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        err: &mut DiagnosticBuilder<'_>,
    ) {
        if let Some(regioncx) = &self.nonlexical_regioncx {
            let mir = self.mir;

            if self.nonlexical_cause_info.is_none() {
                self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
            }

            let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
            if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
                match *cause.root_cause() {
                    Cause::LiveVar(local, location) => {
                        match find_regular_use(mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                err.span_label(
                                    mir.source_info(p).span,
                                    format!("borrow later used here"),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a LiveVar"
                                );
                            }
                        }
                    }

                    Cause::DropVar(local, location) => {
                        match find_drop_use(mir, regioncx, borrow, location, local) {
                            Some(p) => match &mir.local_decls[local].name {
                                Some(local_name) => {
                                    err.span_label(
                                        mir.source_info(p).span,
                                        format!(
                                            "borrow later used here, when `{}` is dropped",
                                            local_name
                                        ),
                                    );
                                }
                                None => {
                                    err.span_label(
                                        mir.local_decls[local].source_info.span,
                                        "borrow may end up in a temporary, created here",
                                    );

                                    err.span_label(
                                        mir.source_info(p).span,
                                        "temporary later dropped here, \
                                         potentially using the reference",
                                    );
                                }
                            },

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a DropVar"
                                );
                            }
                        }
                    }

                    Cause::UniversalRegion(region_vid) => {
                        if let Some(region) = regioncx.to_error_region(region_vid) {
                            self.tcx.note_and_explain_free_region(
                                err,
                                "borrowed value must be valid for ",
                                region,
                                "...",
                            );
                        }
                    }

                    _ => {}
                }
            }
        }
    }
}

fn find_regular_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: true,
            include_drops: false,
        },
    };

    uf.find()
}

fn find_drop_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: false,
            include_drops: true,
        },
    };

    uf.find()
}

struct UseFinder<'gcx, 'tcx> {
    mir: &'gcx Mir<'gcx>,
    regioncx: &'tcx RegionInferenceContext<'tcx>,
    borrow: &'tcx BorrowData<'tcx>,
    start_point: Location,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> {
    fn find(&mut self) -> Option<Location> {
        let mut stack = vec![];
        let mut visited = FxHashSet();

        stack.push(self.start_point);
        while let Some(p) = stack.pop() {
            if !self.regioncx.region_contains_point(self.borrow.region, p) {
                continue;
            }

            if !visited.insert(p) {
                continue;
            }

            let block_data = &self.mir[p.block];
            let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index));

            if used {
                return Some(p);
            } else if !defined {
                if p.statement_index < block_data.statements.len() {
                    stack.push(Location {
                        statement_index: p.statement_index + 1,
                        ..p
                    });
                } else {
                    stack.extend(
                        block_data
                            .terminator()
                            .successors()
                            .iter()
                            .map(|&basic_block| Location {
                                statement_index: 0,
                                block: basic_block,
                            }),
                    );
                }
            }
        }

        None
    }

    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) {
        let mut visitor = DefUseVisitor {
            defined: false,
            used: false,
            local: self.local,
            liveness_mode: self.liveness_mode,
        };

        thing.apply(location, &mut visitor);

        (visitor.defined, visitor.used)
    }
}

struct DefUseVisitor {
    defined: bool,
    used: bool,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'tcx> Visitor<'tcx> for DefUseVisitor {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
        if local == self.local {
            match liveness::categorize(context, self.liveness_mode) {
                Some(DefUse::Def) => self.defined = true,
                Some(DefUse::Use) => self.used = true,
                None => (),
            }
        }
    }
}
<commit_msg>rustfmt explain_borrow/mod<commit_after>// Copyright 2017 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 borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
use borrow_check::{Context, MirBorrowckCtxt};
use dataflow::BorrowData;
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Mir};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use util::liveness::{self, DefUse, LivenessMode};

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Adds annotations to `err` explaining *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
    pub(in borrow_check) fn explain_why_borrow_contains_point(
        &mut self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        err: &mut DiagnosticBuilder<'_>,
    ) {
        if let Some(regioncx) = &self.nonlexical_regioncx {
            let mir = self.mir;

            if self.nonlexical_cause_info.is_none() {
                self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
            }

            let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
            if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
                match *cause.root_cause() {
                    Cause::LiveVar(local, location) => {
                        match find_regular_use(mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                err.span_label(
                                    mir.source_info(p).span,
                                    format!("borrow later used here"),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a LiveVar"
                                );
                            }
                        }
                    }

                    Cause::DropVar(local, location) => {
                        match find_drop_use(mir, regioncx, borrow, location, local) {
                            Some(p) => match &mir.local_decls[local].name {
                                Some(local_name) => {
                                    err.span_label(
                                        mir.source_info(p).span,
                                        format!(
                                            "borrow later used here, when `{}` is dropped",
                                            local_name
                                        ),
                                    );
                                }
                                None => {
                                    err.span_label(
                                        mir.local_decls[local].source_info.span,
                                        "borrow may end up in a temporary, created here",
                                    );

                                    err.span_label(
                                        mir.source_info(p).span,
                                        "temporary later dropped here, \
                                         potentially using the reference",
                                    );
                                }
                            },

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a DropVar"
                                );
                            }
                        }
                    }

                    Cause::UniversalRegion(region_vid) => {
                        if let Some(region) = regioncx.to_error_region(region_vid) {
                            self.tcx.note_and_explain_free_region(
                                err,
                                "borrowed value must be valid for ",
                                region,
                                "...",
                            );
                        }
                    }

                    _ => {}
                }
            }
        }
    }
}

fn find_regular_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: true,
            include_drops: false,
        },
    };

    uf.find()
}

fn find_drop_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: false,
            include_drops: true,
        },
    };

    uf.find()
}

struct UseFinder<'gcx, 'tcx> {
    mir: &'gcx Mir<'gcx>,
    regioncx: &'tcx RegionInferenceContext<'tcx>,
    borrow: &'tcx BorrowData<'tcx>,
    start_point: Location,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> {
    fn find(&mut self) -> Option<Location> {
        let mut stack = vec![];
        let mut visited = FxHashSet();

        stack.push(self.start_point);
        while let Some(p) = stack.pop() {
            if !self.regioncx.region_contains_point(self.borrow.region, p) {
                continue;
            }

            if !visited.insert(p) {
                continue;
            }

            let block_data = &self.mir[p.block];
            let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index));

            if used {
                return Some(p);
            } else if !defined {
                if p.statement_index < block_data.statements.len() {
                    stack.push(Location {
                        statement_index: p.statement_index + 1,
                        ..p
                    });
                } else {
                    stack.extend(
                        block_data
                            .terminator()
                            .successors()
                            .iter()
                            .map(|&basic_block| Location {
                                statement_index: 0,
                                block: basic_block,
                            }),
                    );
                }
            }
        }

        None
    }

    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) {
        let mut visitor = DefUseVisitor {
            defined: false,
            used: false,
            local: self.local,
            liveness_mode: self.liveness_mode,
        };

        thing.apply(location, &mut visitor);

        (visitor.defined, visitor.used)
    }
}

struct DefUseVisitor {
    defined: bool,
    used: bool,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'tcx> Visitor<'tcx> for DefUseVisitor {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
        if local == self.local {
            match liveness::categorize(context, self.liveness_mode) {
                Some(DefUse::Def) => self.defined = true,
                Some(DefUse::Use) => self.used = true,
                None => (),
            }
        }
    }
}
<|endoftext|>