<commit_before><commit_msg>Initial version of rm(1).<commit_after>// Copyright 2016 James Bostock. See the LICENSE file at the top-level
// directory of this distribution.

// An implementation of the rm(1) command in Rust.
// See http://man.cat-v.org/unix-6th/1/rm
use std::env;
use std::fs;
use std::io;
use std::io::Write;

#[macro_use]
mod util;

fn main() {
    let args: Vec<_> = env::args().collect();
    let mut processing_options: bool = true;
    let mut force: bool = false;
    let mut recursive: bool = false;

    if args.len() > 1 {
        for arg in args.iter().skip(1) {
            if arg == "-f" {
                if processing_options {
                    force = true;
                    continue;
                }
            } else if arg == "-r" {
                if processing_options {
                    recursive = true;
                    continue;
                }
            } else {
                processing_options = false;
            }

            match fs::metadata(arg) {
                Ok(md) => {
                    if md.permissions().readonly() {
                        print!("rm: remove readonly file {}? ", arg);
                        io::stdout().flush();
                        let mut resp = String::new();
                        match io::stdin().read_line(&mut resp) {
                            Ok(_) => {
                                match resp.chars().next() {
                                    Some(c) => {
                                        if c != 'y' {
                                            continue;
                                        }
                                    },
                                    None => {}
                                }
                            },
                            Err(e) => {
                                errln!("Error reading response: {}", e);
                                break;
                            }
                        }
                    }
                },
                Err(e) => {
                    errln!("{}; {}", arg, e);
                    continue;
                }
            }

            match if recursive {
                fs::remove_dir_all(arg)
            } else {
                fs::remove_file(arg)
            } {
                Ok(_) => {},
                Err(e) => { if !force { errln!("{}: {}", arg, e); } }
            }
        }
    } else {
        errln!("usage: {} [-f][-r] file ...", args[0]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add datetime <-> string conversion utility<commit_after><|endoftext|>


<commit_before><commit_msg>Add readers & writers mutex<commit_after><|endoftext|>


<commit_before><commit_msg>Switch to A: ?Sized syntax<commit_after><|endoftext|>


<commit_before><commit_msg>fix: Fix newlines in stages ls output (#13)<commit_after><|endoftext|>


<commit_before><commit_msg>rustup<commit_after><|endoftext|>


<commit_before><commit_msg>Implement LT for type-level nat<commit_after><|endoftext|>


<commit_before><commit_msg>:hammer: Fix the stub for test<commit_after><|endoftext|>


<commit_before><commit_msg>Keep unused buffers associated with their layer<commit_after><|endoftext|>


<commit_before>use std::io::net::ip::{Port, IpAddr};

use router::{Router, RequestHandler, HttpRouter};
use middleware::{MiddlewareStack, Middleware, ErrorHandler, MiddlewareResult};
use nickel_error::{ NickelError, ErrorWithStatusCode };
use server::Server;

use http::method::Method;
use http::status::NotFound;
use request::Request;
use response::Response;

//pre defined middleware
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;
use default_error_handler::DefaultErrorHandler;

/// Nickel is the application object. It's the surface that
/// holds all public APIs.
pub struct Nickel{
    middleware_stack: MiddlewareStack,
}

impl HttpRouter for Nickel {
    fn add_route<H: RequestHandler>(&mut self, method: Method, uri: &str, handler: H) {
        let mut router = Router::new();
        router.add_route(method, uri, handler);
        self.utilize(router);
    }
}

impl Nickel {
    /// Creates an instance of Nickel with default error handling.
    pub fn new() -> Nickel {
        let mut middleware_stack = MiddlewareStack::new();

        // Hook up the default error handler by default. Users are
        // free to cancel it out from their custom error handler if
        // they don't like the default behaviour.
        middleware_stack.add_error_handler(DefaultErrorHandler);

        Nickel { middleware_stack: middleware_stack }
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a result of either Action or NickelError.
    /// That is to indicate whether other middleware handlers (if any) further
    /// down the stack should continue or if the middleware invocation should
    /// be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```{rust}
    /// use nickel::{Nickel, Request, Response, Continue, MiddlewareResult};
    /// fn logger(req: &Request, res: &mut Response) -> MiddlewareResult {
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Ok(Continue)
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(logger);
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add_middleware(handler);
    }

    /// Registers an error handler which will be invoked among other error handler
    /// as soon as any regular handler returned an error
    ///
    /// A error handler is nearly identical to a regular middleware handler with the only
    /// difference that it takes an additional error parameter or type `NickelError.
    ///
    /// # Example
    ///
    /// ```{rust}
    /// # extern crate http;
    /// # extern crate nickel;
    /// # fn main() {
    /// use nickel::{Nickel, Request, Response, Continue, Halt, MiddlewareResult};
    /// use nickel::{NickelError, ErrorWithStatusCode, get_media_type};
    /// use http::status::NotFound;
    ///
    /// fn error_handler(err: &NickelError, req: &Request, response: &mut Response)
    ///                  -> MiddlewareResult {
    ///    match err.kind {
    ///        ErrorWithStatusCode(NotFound) => {
    ///            response.origin.headers.content_type = get_media_type("html");
    ///            response.origin.status = NotFound;
    ///            response.send("<h1>Call the police!<h1>");
    ///            Ok(Halt)
    ///        },
    ///        _ => Ok(Continue)
    ///    }
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.handle_error(error_handler)
    /// # }
    /// ```
    pub fn handle_error<T: ErrorHandler>(&mut self, handler: T){
        self.middleware_stack.add_error_handler(handler);
    }

    /// Create a new middleware to serve as a router.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// use nickel::{Nickel, Request, Response, HttpRouter};
    ///
    /// let mut server = Nickel::new();
    /// let mut router = Nickel::router();
    ///
    /// fn foo_handler(request: &Request, response: &mut Response) {
    ///     response.send("Hi from /foo");
    /// };
    ///
    /// router.get("/foo", foo_handler);
    /// server.utilize(router);
    /// ```
    pub fn router() -> Router {
        Router::new()
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # extern crate serialize;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::JsonBody;
    ///
    /// # fn main() {
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     first_name: String,
    ///     last_name:  String,
    /// }
    ///
    /// let router = router! {
    ///     post "/a/post/request" => |request, response| {
    ///         let person = request.json_as::<Person>().unwrap();
    ///         let text = format!("Hello {} {}", person.first_name, person.last_name);
    ///         response.send(text);
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the json_body_parser middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::json_body_parser());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::QueryString;
    /// # fn main() {
    /// let router = router! {
    ///     get "/a/get/request" => |request, response| {
    ///         let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///         response.send(foo[0].as_slice());
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the query_string middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::query_string());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        fn not_found_handler(_: &Request, _: &mut Response) -> MiddlewareResult {
            Err(NickelError::new("File Not Found", ErrorWithStatusCode(NotFound)))
        }

        self.middleware_stack.add_middleware(not_found_handler);
        Server::new(self.middleware_stack, ip, port).serve();
    }
}
<commit_msg>fix(nickel): handle inference bug<commit_after>use std::io::net::ip::{Port, IpAddr};

use router::{Router, RequestHandler, HttpRouter};
use middleware::{MiddlewareStack, Middleware, ErrorHandler, MiddlewareResult};
use nickel_error::{ NickelError, ErrorWithStatusCode };
use server::Server;

use http::method::Method;
use http::status::NotFound;
use request::Request;
use response::Response;

//pre defined middleware
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;
use default_error_handler::DefaultErrorHandler;

/// Nickel is the application object. It's the surface that
/// holds all public APIs.
pub struct Nickel{
    middleware_stack: MiddlewareStack,
}

impl HttpRouter for Nickel {
    fn add_route<H: RequestHandler>(&mut self, method: Method, uri: &str, handler: H) {
        let mut router = Router::new();
        // FIXME: Inference failure in nightly 22/10/2014
        router.add_route::<H>(method, uri, handler);
        self.utilize(router);
    }
}

impl Nickel {
    /// Creates an instance of Nickel with default error handling.
    pub fn new() -> Nickel {
        let mut middleware_stack = MiddlewareStack::new();

        // Hook up the default error handler by default. Users are
        // free to cancel it out from their custom error handler if
        // they don't like the default behaviour.
        middleware_stack.add_error_handler(DefaultErrorHandler);

        Nickel { middleware_stack: middleware_stack }
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a result of either Action or NickelError.
    /// That is to indicate whether other middleware handlers (if any) further
    /// down the stack should continue or if the middleware invocation should
    /// be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```{rust}
    /// use nickel::{Nickel, Request, Response, Continue, MiddlewareResult};
    /// fn logger(req: &Request, res: &mut Response) -> MiddlewareResult {
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Ok(Continue)
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(logger);
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add_middleware(handler);
    }

    /// Registers an error handler which will be invoked among other error handler
    /// as soon as any regular handler returned an error
    ///
    /// A error handler is nearly identical to a regular middleware handler with the only
    /// difference that it takes an additional error parameter or type `NickelError.
    ///
    /// # Example
    ///
    /// ```{rust}
    /// # extern crate http;
    /// # extern crate nickel;
    /// # fn main() {
    /// use nickel::{Nickel, Request, Response, Continue, Halt, MiddlewareResult};
    /// use nickel::{NickelError, ErrorWithStatusCode, get_media_type};
    /// use http::status::NotFound;
    ///
    /// fn error_handler(err: &NickelError, req: &Request, response: &mut Response)
    ///                  -> MiddlewareResult {
    ///    match err.kind {
    ///        ErrorWithStatusCode(NotFound) => {
    ///            response.origin.headers.content_type = get_media_type("html");
    ///            response.origin.status = NotFound;
    ///            response.send("<h1>Call the police!<h1>");
    ///            Ok(Halt)
    ///        },
    ///        _ => Ok(Continue)
    ///    }
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.handle_error(error_handler)
    /// # }
    /// ```
    pub fn handle_error<T: ErrorHandler>(&mut self, handler: T){
        self.middleware_stack.add_error_handler(handler);
    }

    /// Create a new middleware to serve as a router.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// use nickel::{Nickel, Request, Response, HttpRouter};
    ///
    /// let mut server = Nickel::new();
    /// let mut router = Nickel::router();
    ///
    /// fn foo_handler(request: &Request, response: &mut Response) {
    ///     response.send("Hi from /foo");
    /// };
    ///
    /// router.get("/foo", foo_handler);
    /// server.utilize(router);
    /// ```
    pub fn router() -> Router {
        Router::new()
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # extern crate serialize;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::JsonBody;
    ///
    /// # fn main() {
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     first_name: String,
    ///     last_name:  String,
    /// }
    ///
    /// let router = router! {
    ///     post "/a/post/request" => |request, response| {
    ///         let person = request.json_as::<Person>().unwrap();
    ///         let text = format!("Hello {} {}", person.first_name, person.last_name);
    ///         response.send(text);
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the json_body_parser middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::json_body_parser());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::QueryString;
    /// # fn main() {
    /// let router = router! {
    ///     get "/a/get/request" => |request, response| {
    ///         let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///         response.send(foo[0].as_slice());
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the query_string middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::query_string());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        fn not_found_handler(_: &Request, _: &mut Response) -> MiddlewareResult {
            Err(NickelError::new("File Not Found", ErrorWithStatusCode(NotFound)))
        }

        self.middleware_stack.add_middleware(not_found_handler);
        Server::new(self.middleware_stack, ip, port).serve();
    }
}
<|endoftext|>


<commit_before><commit_msg>remove enforce_bounds<commit_after><|endoftext|>


<commit_before><commit_msg>Create a native_thread module to get the thread_id<commit_after><|endoftext|>


<commit_before><commit_msg>Add a regression test for issue-75299<commit_after>// compile-flags: -Zmir-opt-level=3
// run-pass

#![feature(const_generics)]
#![allow(incomplete_features)]
fn main() {
    fn foo<const N: usize>() -> [u8; N] {
        [0; N]
    }
    let _x = foo::<1>();
}
<|endoftext|>


<commit_before>#[doc = "

The layout task. Performs layout on the dom, builds display lists and sends
them to be rendered

"];

import task::*;
import comm::*;
import gfx::geom;
import gfx::geom::*;
import gfx::renderer;
import dom::base::*;
import display_list::*;

enum msg {
    build,
    exit
}

fn layout(renderer: chan<renderer::msg>) -> chan<msg> {

    spawn_listener::<msg> {|po|

        let dom = new_node(nk_div);

        loop {
            alt recv(po) {
              build {

                let box = layout_dom(dom);
                let dlist = build_display_list(box);

                send(renderer, gfx::renderer::draw(dlist));
              }
              exit {
                break;
              }
            }
        }
    }

}

fn layout_dom(dom: node) -> base::box {
    base::new_box(dom)
}

fn build_display_list(_box: base::box) -> display_list::display_list {
    [
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(0),
                int_to_au(0),
                int_to_au(100),
                int_to_au(100))
        }),
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(100),
                int_to_au(100),
                int_to_au(100),
                int_to_au(100))
        })
    ]
}<commit_msg>fix various small build failures<commit_after>#[doc = "

The layout task. Performs layout on the dom, builds display lists and sends
them to be rendered

"];

import task::*;
import comm::*;
import gfx::geom;
import gfx::geom::*;
import gfx::renderer;
import dom::base::*;
import display_list::*;
import dom::rcu::scope;

enum msg {
    build,
    exit
}

fn layout(renderer: chan<renderer::msg>) -> chan<msg> {

    spawn_listener::<msg> {|po|

        let s = scope();
        let dom = s.new_node(nk_div);

        loop {
            alt recv(po) {
              build {

                let box = layout_dom(dom);
                let dlist = build_display_list(box);

                send(renderer, gfx::renderer::draw(dlist));
              }
              exit {
                break;
              }
            }
        }
    }

}

fn layout_dom(dom: node) -> @base::box {
    base::new_box(dom)
}

fn build_display_list(_box: @base::box) -> display_list::display_list {
    [
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(0),
                int_to_au(0),
                int_to_au(100),
                int_to_au(100))
        }),
        display_item({
            item_type: solid_color,
            bounds: geom::box(
                int_to_au(100),
                int_to_au(100),
                int_to_au(100),
                int_to_au(100))
        })
    ]
}<|endoftext|>


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

use option::*;
use super::stack::StackSegment;
use libc::c_void;
use cast::{transmute, transmute_mut_unsafe,
           transmute_region, transmute_mut_region};

// XXX: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// XXX: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    start: Option<~~fn()>,
    /// Hold the registers while the task or scheduler is suspended
    regs: ~Registers
}

pub impl Context {
    fn empty() -> Context {
        Context {
            start: None,
            regs: new_regs()
        }
    }

    /// Create a new context that will resume execution by running ~fn()
    fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
        // XXX: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let start = ~start;

        // The C-ABI function that is the task entry point
        extern fn task_start_wrapper(f: &~fn()) { (*f)() }

        let fp: *c_void = task_start_wrapper as *c_void;
        let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };

        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
        };

        initialize_call_frame(&mut *regs, fp, argp, sp);

        return Context {
            start: Some(start),
            regs: regs
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    fn swap(out_context: &mut Context, in_context: &Context) {
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, _ } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, _ } => r
        };

        unsafe { swap_registers(out_regs, in_regs) };
    }
}

extern {
    fn swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint; }
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0; } // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

#[cfg(target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    // Redefinitions from regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr %x", fptr as uint);
    rtdebug!("arg %x", arg as uint);
    rtdebug!("sp %x", sp as uint);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~[0, .. 32] }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~[0, .. 32] }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp = transmute::<*mut uint, uint>(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// XXX: ptr::offset is positive ints only
#[inline(always)]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use core::sys::size_of;
    unsafe {
        (ptr as int + count * (size_of::<T>() as int)) as *mut T
    }
}

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

use option::*;
use super::stack::StackSegment;
use libc::c_void;
use cast::{transmute, transmute_mut_unsafe,
           transmute_region, transmute_mut_region};

// XXX: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// XXX: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    start: Option<~~fn()>,
    /// Hold the registers while the task or scheduler is suspended
    regs: ~Registers
}

pub impl Context {
    fn empty() -> Context {
        Context {
            start: None,
            regs: new_regs()
        }
    }

    /// Create a new context that will resume execution by running ~fn()
    fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
        // XXX: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let start = ~start;

        // The C-ABI function that is the task entry point
        extern fn task_start_wrapper(f: &~fn()) { (*f)() }

        let fp: *c_void = task_start_wrapper as *c_void;
        let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };

        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
        };

        initialize_call_frame(&mut *regs, fp, argp, sp);

        return Context {
            start: Some(start),
            regs: regs
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    fn swap(out_context: &mut Context, in_context: &Context) {
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, _ } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, _ } => r
        };

        unsafe { swap_registers(out_regs, in_regs) };
    }
}

extern {
    fn swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint; }
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0; } // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

#[cfg(target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    // Redefinitions from regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr %x", fptr as uint);
    rtdebug!("arg %x", arg as uint);
    rtdebug!("sp %x", sp as uint);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp = transmute::<*mut uint, uint>(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// XXX: ptr::offset is positive ints only
#[inline(always)]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use core::sys::size_of;
    unsafe {
        (ptr as int + count * (size_of::<T>() as int)) as *mut T
    }
}

<|endoftext|>


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

/*!
 * A simple map based on a vector for small integer keys. Space requirements
 * are O(highest integer key).
 */
#[forbid(deprecated_mode)];

use core::container::{Container, Mutable, Map, Set};
use core::option::{Some, None};
use core::prelude::*;

pub struct SmallIntMap<T> {
    priv v: ~[Option<T>],
}

impl<V> SmallIntMap<V>: Container {
    /// Return the number of elements in the map
    pure fn len(&self) -> uint {
        let mut sz = 0;
        for self.v.each |item| {
            if item.is_some() {
                sz += 1;
            }
        }
        sz
    }

    /// Return true if the map contains no elements
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<V> SmallIntMap<V>: Mutable {
    /// Clear the map, removing all key-value pairs.
    fn clear(&mut self) { self.v.clear() }
}

impl<V> SmallIntMap<V>: Map<uint, V> {
    /// Return true if the map contains a value for the specified key
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all key-value pairs
    pure fn each(&self, it: fn(key: &uint, value: &V) -> bool) {
        for uint::range(0, self.v.len()) |i| {
            match self.v[i] {
              Some(ref elt) => if !it(&i, elt) { break },
              None => ()
            }
        }
    }

    /// Visit all keys
    pure fn each_key(&self, blk: fn(key: &uint) -> bool) {
        self.each(|k, _| blk(k))
    }

    /// Visit all values
    pure fn each_value(&self, blk: fn(value: &V) -> bool) {
        self.each(|_, v| blk(v))
    }

    /// Return the value corresponding to the key in the map
    pure fn find(&self, key: &uint) -> Option<&self/V> {
        if *key < self.v.len() {
            match self.v[*key] {
              Some(ref value) => Some(value),
              None => None
            }
        } else {
            None
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    fn insert(&mut self, key: uint, value: V) -> bool {
        let exists = self.contains_key(&key);
        let len = self.v.len();
        if len <= key {
            vec::grow_fn(&mut self.v, key - len + 1, |_| None);
        }
        self.v[key] = Some(value);
        !exists
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    fn remove(&mut self, key: &uint) -> bool {
        if *key >= self.v.len() {
            return false;
        }
        let removed = self.v[*key].is_some();
        self.v[*key] = None;
        removed
    }
}

pub impl<V> SmallIntMap<V> {
    /// Create an empty SmallIntMap
    static pure fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} }

    pure fn get(&self, key: &uint) -> &self/V {
        self.find(key).expect("key not present")
    }
}

pub impl<V: Copy> SmallIntMap<V> {
    // FIXME: #4733, remove after the next snapshot
    #[cfg(stage2)]
    fn update_with_key(&mut self, key: uint, val: V,
                       ff: fn(uint, V, V) -> V) -> bool {
        match self.find(&key) {
          None => self.insert(key, val),
          Some(orig) => self.insert(key, ff(key, copy *orig, val)),
        }
    }

    // FIXME: #4733, remove after the next snapshot
    #[cfg(stage2)]
    fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
        self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
    }
}

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

    #[test]
    fn test_len() {
        let mut map = SmallIntMap::new();
        assert map.len() == 0;
        assert map.is_empty();
        assert map.insert(5, 20);
        assert map.len() == 1;
        assert !map.is_empty();
        assert map.insert(11, 12);
        assert map.len() == 2;
        assert !map.is_empty();
        assert map.insert(14, 22);
        assert map.len() == 3;
        assert !map.is_empty();
    }

    #[test]
    fn test_clear() {
        let mut map = SmallIntMap::new();
        assert map.insert(5, 20);
        assert map.insert(11, 12);
        assert map.insert(14, 22);
        map.clear();
        assert map.is_empty();
        assert map.find(&5).is_none();
        assert map.find(&11).is_none();
        assert map.find(&14).is_none();
    }

    #[test]
    fn test_insert_with_key() {
        let mut map = SmallIntMap::new();

        // given a new key, initialize it with this new count, given
        // given an existing key, add more to its count
        fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint {
            v0 + v1
        }

        fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
            v0 + v1
        }

        // count integers
        map.update(3, 1, addMoreToCount_simple);
        map.update_with_key(9, 1, addMoreToCount);
        map.update(3, 7, addMoreToCount_simple);
        map.update_with_key(5, 3, addMoreToCount);
        map.update_with_key(3, 2, addMoreToCount);

        // check the total counts
        assert map.find(&3).get() == &10;
        assert map.find(&5).get() == &3;
        assert map.find(&9).get() == &1;

        // sadly, no sevens were counted
        assert map.find(&7).is_none();
    }
}
<commit_msg>remove old snapshot workaround from smallintmap<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
 * A simple map based on a vector for small integer keys. Space requirements
 * are O(highest integer key).
 */
#[forbid(deprecated_mode)];

use core::container::{Container, Mutable, Map, Set};
use core::option::{Some, None};
use core::prelude::*;

pub struct SmallIntMap<T> {
    priv v: ~[Option<T>],
}

impl<V> SmallIntMap<V>: Container {
    /// Return the number of elements in the map
    pure fn len(&self) -> uint {
        let mut sz = 0;
        for self.v.each |item| {
            if item.is_some() {
                sz += 1;
            }
        }
        sz
    }

    /// Return true if the map contains no elements
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<V> SmallIntMap<V>: Mutable {
    /// Clear the map, removing all key-value pairs.
    fn clear(&mut self) { self.v.clear() }
}

impl<V> SmallIntMap<V>: Map<uint, V> {
    /// Return true if the map contains a value for the specified key
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all key-value pairs
    pure fn each(&self, it: fn(key: &uint, value: &V) -> bool) {
        for uint::range(0, self.v.len()) |i| {
            match self.v[i] {
              Some(ref elt) => if !it(&i, elt) { break },
              None => ()
            }
        }
    }

    /// Visit all keys
    pure fn each_key(&self, blk: fn(key: &uint) -> bool) {
        self.each(|k, _| blk(k))
    }

    /// Visit all values
    pure fn each_value(&self, blk: fn(value: &V) -> bool) {
        self.each(|_, v| blk(v))
    }

    /// Return the value corresponding to the key in the map
    pure fn find(&self, key: &uint) -> Option<&self/V> {
        if *key < self.v.len() {
            match self.v[*key] {
              Some(ref value) => Some(value),
              None => None
            }
        } else {
            None
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    fn insert(&mut self, key: uint, value: V) -> bool {
        let exists = self.contains_key(&key);
        let len = self.v.len();
        if len <= key {
            vec::grow_fn(&mut self.v, key - len + 1, |_| None);
        }
        self.v[key] = Some(value);
        !exists
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    fn remove(&mut self, key: &uint) -> bool {
        if *key >= self.v.len() {
            return false;
        }
        let removed = self.v[*key].is_some();
        self.v[*key] = None;
        removed
    }
}

pub impl<V> SmallIntMap<V> {
    /// Create an empty SmallIntMap
    static pure fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} }

    pure fn get(&self, key: &uint) -> &self/V {
        self.find(key).expect("key not present")
    }
}

pub impl<V: Copy> SmallIntMap<V> {
    fn update_with_key(&mut self, key: uint, val: V,
                       ff: fn(uint, V, V) -> V) -> bool {
        match self.find(&key) {
          None => self.insert(key, val),
          Some(orig) => self.insert(key, ff(key, copy *orig, val)),
        }
    }

    fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
        self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
    }
}

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

    #[test]
    fn test_len() {
        let mut map = SmallIntMap::new();
        assert map.len() == 0;
        assert map.is_empty();
        assert map.insert(5, 20);
        assert map.len() == 1;
        assert !map.is_empty();
        assert map.insert(11, 12);
        assert map.len() == 2;
        assert !map.is_empty();
        assert map.insert(14, 22);
        assert map.len() == 3;
        assert !map.is_empty();
    }

    #[test]
    fn test_clear() {
        let mut map = SmallIntMap::new();
        assert map.insert(5, 20);
        assert map.insert(11, 12);
        assert map.insert(14, 22);
        map.clear();
        assert map.is_empty();
        assert map.find(&5).is_none();
        assert map.find(&11).is_none();
        assert map.find(&14).is_none();
    }

    #[test]
    fn test_insert_with_key() {
        let mut map = SmallIntMap::new();

        // given a new key, initialize it with this new count, given
        // given an existing key, add more to its count
        fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint {
            v0 + v1
        }

        fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
            v0 + v1
        }

        // count integers
        map.update(3, 1, addMoreToCount_simple);
        map.update_with_key(9, 1, addMoreToCount);
        map.update(3, 7, addMoreToCount_simple);
        map.update_with_key(5, 3, addMoreToCount);
        map.update_with_key(3, 2, addMoreToCount);

        // check the total counts
        assert map.find(&3).get() == &10;
        assert map.find(&5).get() == &3;
        assert map.find(&9).get() == &1;

        // sadly, no sevens were counted
        assert map.find(&7).is_none();
    }
}
<|endoftext|>


<commit_before><commit_msg>Added more tests to catch crlf splitting errors.<commit_after>//! Randomized tests to try to catch crlf seam errors.

extern crate rand;
extern crate ropey;

use rand::Rng;
use ropey::Rope;

#[test]
fn crlf_inserts() {
    let mut rng = rand::thread_rng();
    let mut tree = Rope::new();

    // Do a bunch of random incoherent inserts of CRLF
    // pairs.
    for _ in 0..(1 << 11) {
        let len = tree.len_chars().max(1);
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n");
        tree.insert(rng.gen::<usize>() % len, "\n\r\n\r");

        // Make sure the tree is sound
        tree.assert_integrity();
        tree.assert_invariants();
    }
}

#[test]
fn crlf_removals() {
    let mut rng = rand::thread_rng();
    let mut tree = Rope::new();

    // Build tree.
    for _ in 0..(1 << 11) {
        let len = tree.len_chars().max(1);
        tree.insert(rng.gen::<usize>() % len, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r");
    }

    // Do a bunch of random incoherent removals
    for _ in 0..(1 << 10) {
        let start = rng.gen::<usize>() % tree.len_chars().max(1);
        let end = (start + 5).min(tree.len_chars());
        tree.remove(start..end);

        let start = rng.gen::<usize>() % tree.len_chars().max(1);
        let end = (start + 6).min(tree.len_chars());
        tree.remove(start..end);

        // Make sure the tree is sound
        tree.assert_integrity();
        tree.assert_invariants();
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix off-by-one in PFCOUNT args<commit_after><|endoftext|>


<commit_before><commit_msg>Added destructure structs example<commit_after>fn main() {
    struct Foo { x: (u32, u32), y: u32 }

    // destructure members of the struct
    let foo = Foo { x: (1, 2), y: 3 };
    let Foo { x: (a, b), y } = foo;

    println!("a = {}, b = {},  y = {} ", a, b, y);

    // you can destructure structs and rename the variables,
    // the order is not important

    let Foo { y: i, x: j } = foo;
    println!("i = {:?}, j = {:?}", i, j);

    // and you can also ignore some variables:
    let Foo { y, .. } = foo;
    println!("y = {}", y);

    // this will give an error: pattern does not mention field `x`
    // let Foo { y } = foo;
}
<|endoftext|>


<commit_before><commit_msg>Added two benchmarks `big_loop_big_objects`, `macro_big_object`<commit_after>#![feature(test)]
extern crate test;
extern crate tera;
#[macro_use]
extern crate serde_derive;

use tera::{Tera, Template, Context, escape_html};

#[derive(Serialize)]
struct DataWrapper {
    i: usize,
    v: String,
}

impl DataWrapper {
    fn new(i: usize) ->  DataWrapper {
        DataWrapper { i, v: "Meta
Before we get to the details, two important notes about the ownership system.

Rust has a focus on safety and speed. It accomplishes these goals through many ‘zero-cost abstractions’, which means that in Rust, abstractions cost as little as possible in order to make them work. The ownership system is a prime example of a zero cost abstraction. All of the analysis we’ll talk about in this guide is done at compile time. You do not pay any run-time cost for any of these features.

However, this system does have a certain cost: learning curve. Many new users to Rust experience something we like to call ‘fighting with the borrow checker’, where the Rust compiler refuses to compile a program that the author thinks is valid. This often happens because the programmer’s mental model of how ownership should work doesn’t match the actual rules that Rust implements. You probably will experience similar things at first. There is good news, however: more experienced Rust developers report that once they work with the rules of the ownership system for a period of time, they fight the borrow checker less and less.

With that in mind, let’s learn about borrowing.".into() }
    }
}

#[derive(Serialize)]
struct BigObject {
    field_a: DataWrapper,
    field_b: DataWrapper,
    field_c: DataWrapper,
    field_d: DataWrapper,
    field_e: DataWrapper,
    field_f: DataWrapper,
}

impl BigObject {
    fn new(i: usize) -> BigObject {
        BigObject {
            field_a: DataWrapper::new(i),
            field_b: DataWrapper::new(i),
            field_c: DataWrapper::new(i),
            field_d: DataWrapper::new(i),
            field_e: DataWrapper::new(i),
            field_f: DataWrapper::new(i),
        }
    }
}

#[bench]
fn bench_big_loop_big_object(b: &mut test::Bencher) {
    const NUM_OBJECTS: usize = 100;
    let mut objects = Vec::with_capacity(NUM_OBJECTS);
    for i in 0..NUM_OBJECTS {
        objects.push(BigObject::new(i));
    }

    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("big_loop.html", "
{%- for object in objects -%}
{{ object.field_a.i }}
{%- if object.field_a.i > 2 -%}
{%- break -%}
{%- endif -%}
{%- endfor -%}
"),
    ]).unwrap();
    let mut context = Context::new();
    context.add("objects", &objects);
    let rendering = tera.render("big_loop.html", &context).expect("Good render");
    assert_eq!(&rendering[..], "0123");
    b.iter(|| tera.render("big_loop.html", &context));
}

#[bench]
fn bench_macro_big_object(b: &mut test::Bencher) {
    let big_object = BigObject::new(1);
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("big_loop.html", "
{%- import \"macros.html\" as macros -%}
{%- for i in iterations -%}{{ macros::get_first(bo=big_object) }}{% endfor %}"),
        ("macros.html", "{%- macro get_first(bo) -%}{{ bo.field_a.i }}{% endmacro get_first %}"),
    ]).unwrap();
    let mut context = Context::new();
    context.add("big_object", &big_object);
    context.add("iterations", &(0..500).collect::<Vec<usize>>());
    let rendering = tera.render("big_loop.html", &context).expect("Good render");
    assert_eq!(rendering.len(), 500);
    assert_eq!(rendering.chars().next().expect("Char"), '1');
    b.iter(|| tera.render("big_loop.html", &context));
}

<|endoftext|>


<commit_before><commit_msg>Fix incorrect save on vampire lord on zombie dragon with sword and shield<commit_after><|endoftext|>


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

use target::Target;

pub fn target() -> Target {
    let mut base = super::android_base::opts();
    base.features = "+v7,+thumb2,+vfp3,+d16".to_string();

    Target {
        llvm_target: "armv7-none-linux-android".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "android".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    }
}
<commit_msg>Add missing "max_atomic_width" to new armv7 android target.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::Target;

pub fn target() -> Target {
    let mut base = super::android_base::opts();
    base.features = "+v7,+thumb2,+vfp3,+d16".to_string();
    base.max_atomic_width = 64;

    Target {
        llvm_target: "armv7-none-linux-android".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "android".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    }
}
<|endoftext|>


<commit_before><commit_msg>(feat) Added a ContentType modifier, for quickly setting the content-type header.<commit_after><|endoftext|>


<commit_before><commit_msg>Added mutability example<commit_after>fn main() {
    let _immutable_binding = 1;
    let mut mutable_binding = 1;

    println!("Before mutation: {}", mutable_binding);

    // Ok
    mutable_binding += 1;

    println!("After mutation: {}", mutable_binding);

    // Error!
    // _immutable_binding += 1;
    // FIXME ^ Comment out this line
}
<|endoftext|>


<commit_before>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(usize::from_be(*d))
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        Ok(0)
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, offset: usize) -> XdrResult<()> {
        Ok(())
    }

    fn destroy(&mut self) {
    }
}
<commit_msg>More MemOps stuff. Added a unit test<commit_after>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl MemOps {
    pub fn new(buffer: Vec<u8>) -> MemOps {
        MemOps {
            pos: 0,
            buffer: buffer,
        }
    }
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(usize::from_be(*d))
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &i32 = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(i32::from_be(*d))
        }
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, new_pos: usize) -> XdrResult<()> {
        self.pos = new_pos;
        Ok(())
    }

    fn destroy(&mut self) {
    }
}

#[test]
fn test_mem_ops_u32() {
    let mem_ops = MemOps::new(vec![1, 1, 0, 0]);
    assert!(mem_ops.get_u32() == 257);
}
<|endoftext|>


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

pub type DOMString = ~str;

pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString {
    // We don't use map_default because it would allocate ~"" even for Some.
    match *s {
        Some(ref s) => s.clone(),
        None => ~""
    }
}

pub fn null_str_as_empty_ref<'a>(s: &'a Option<DOMString>) -> &'a str {
    match *s {
        Some(ref s) => s.as_slice(),
        None => &'a ""
    }
}

<|endoftext|>


<commit_before><commit_msg>rust: added snippet with hashmap+vector exercise (ch. 8) - Editorial<commit_after><|endoftext|>


<commit_before><commit_msg>move data method from PosRead to Read; it was meant to be in Read<commit_after><|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.

#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![allocator]
#![cfg_attr(not(stage0), deny(warnings))]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "x86",
              target_arch = "arm",
              target_arch = "mips",
              target_arch = "powerpc",
              target_arch = "powerpc64",
              target_arch = "asmjs")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    size: usize,
                                    align: usize)
                                    -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                            old_size: usize,
                                            size: usize,
                                            align: usize)
                                            -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            let mut out = ptr::null_mut();
            let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
            if ret != 0 {
                ptr::null_mut()
            } else {
                out as *mut u8
            }
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
            deallocate(ptr, old_size, align);
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
                                     old_size: usize,
                                     _size: usize,
                                     _align: usize)
                                     -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
#[allow(bad_style)]
mod imp {
    use MIN_ALIGN;

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() {
                return ptr;
            }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(),
                                  0,
                                  header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() {
                return new;
            }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8,
                                     old_size: usize,
                                     size: usize,
                                     align: usize)
                                     -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(),
                                  HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID,
                                  size as SIZE_T) as *mut u8;
            if new.is_null() {
                old_size
            } else {
                size
            }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<commit_msg>Rollup merge of #32997 - alexcrichton:fix-alloc-system-how-did-this-land, r=nagisa<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.

#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![allocator]
#![cfg_attr(not(stage0), deny(warnings))]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "x86",
              target_arch = "arm",
              target_arch = "mips",
              target_arch = "powerpc",
              target_arch = "powerpc64",
              target_arch = "asmjs")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    size: usize,
                                    align: usize)
                                    -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                            old_size: usize,
                                            size: usize,
                                            align: usize)
                                            -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            let mut out = ptr::null_mut();
            let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
            if ret != 0 {
                ptr::null_mut()
            } else {
                out as *mut u8
            }
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            if !new_ptr.is_null() {
                ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
                deallocate(ptr, old_size, align);
            }
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
                                     old_size: usize,
                                     _size: usize,
                                     _align: usize)
                                     -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
#[allow(bad_style)]
mod imp {
    use MIN_ALIGN;

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() {
                return ptr;
            }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(),
                                  0,
                                  header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() {
                return new;
            }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8,
                                     old_size: usize,
                                     size: usize,
                                     align: usize)
                                     -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(),
                                  HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID,
                                  size as SIZE_T) as *mut u8;
            if new.is_null() {
                old_size
            } else {
                size
            }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<|endoftext|>


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

/*!

typeck.rs, an introduction

The type checker is responsible for:

1. Determining the type of each expression
2. Resolving methods and traits
3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
   Well, dear reader, read on)

The main entry point is `check_crate()`.  Type checking operates in
several major phases:

1. The collect phase first passes over all items and determines their
   type, without examining their "innards".

2. Variance inference then runs to compute the variance of each parameter

3. Coherence checks for overlapping or orphaned impls

4. Finally, the check phase then checks function bodies and so forth.
   Within the check phase, we check each function body one at a time
   (bodies of function expressions are checked as part of the
   containing function).  Inference is used to supply types wherever
   they are unknown. The actual checking of a function itself has
   several phases (check, regionck, writeback), as discussed in the
   documentation for the `check` module.

The type checker is defined into various submodules which are documented
independently:

- astconv: converts the AST representation of types
  into the `ty` representation

- collect: computes the types of each top-level item and enters them into
  the `cx.tcache` table for later use

- coherence: enforces coherence rules, builds some tables

- variance: variance inference

- check: walks over function bodies and type checks them, inferring types for
  local variables, type parameters, etc as necessary.

- infer: finds the types to use for each type variable such that
  all subtyping and assignment constraints are met.  In essence, the check
  module specifies the constraints, and the infer module solves them.

# Note

This API is completely unstable and subject to change.

*/

#![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]

#![allow(non_camel_case_types)]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
extern crate syntax_pos;

extern crate arena;
extern crate fmt_macros;
#[macro_use] extern crate rustc;
extern crate rustc_platform_intrinsics as intrinsics;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_const_eval;
extern crate rustc_errors as errors;

pub use rustc::dep_graph;
pub use rustc::hir;
pub use rustc::lint;
pub use rustc::middle;
pub use rustc::session;
pub use rustc::util;

use dep_graph::DepNode;
use hir::map as hir_map;
use rustc::infer::TypeOrigin;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::traits::ProjectionMode;
use session::{config, CompileResult};
use util::common::time;

use syntax::ast;
use syntax::abi::Abi;
use syntax_pos::Span;

use std::cell::RefCell;
use util::nodemap::NodeMap;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod check;
pub mod check_unused;
mod rscope;
mod astconv;
pub mod collect;
mod constrained_type_params;
pub mod coherence;
pub mod variance;

pub struct TypeAndSubsts<'tcx> {
    pub substs: Substs<'tcx>,
    pub ty: Ty<'tcx>,
}

pub struct CrateCtxt<'a, 'tcx: 'a> {
    ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,

    /// A mapping from method call sites to traits that have that method.
    pub trait_map: hir::TraitMap,

    /// A vector of every trait accessible in the whole crate
    /// (i.e. including those from subcrates). This is used only for
    /// error reporting, and so is lazily initialised and generally
    /// shouldn't taint the common path (hence the RefCell).
    pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,

    /// This stack is used to identify cycles in the user's source.
    /// Note that these cycles can cross multiple items.
    pub stack: RefCell<Vec<collect::AstConvRequest>>,

    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

// Functions that write types into the node type table
fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
    debug!("write_ty_to_tcx({}, {:?})", node_id,  ty);
    assert!(!ty.needs_infer());
    ccx.tcx.node_type_insert(node_id, ty);
}

fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 node_id: ast::NodeId,
                                 item_substs: ty::ItemSubsts<'tcx>) {
    if !item_substs.is_noop() {
        debug!("write_substs_to_tcx({}, {:?})",
               node_id,
               item_substs);

        assert!(!item_substs.substs.types.needs_infer());

        ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
    }
}

fn require_c_abi_if_variadic(tcx: TyCtxt,
                             decl: &hir::FnDecl,
                             abi: Abi,
                             span: Span) {
    if decl.variadic && abi != Abi::C {
        span_err!(tcx.sess, span, E0045,
                  "variadic function must have C calling convention");
    }
}

fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                origin: TypeOrigin,
                                t1: Ty<'tcx>,
                                t2: Ty<'tcx>)
                                -> bool {
    ccx.tcx.infer_ctxt(None, None, ProjectionMode::AnyFinal).enter(|infcx| {
        if let Err(err) = infcx.eq_types(false, origin.clone(), t1, t2) {
            infcx.report_mismatched_types(origin, t1, t2, err);
            false
        } else {
            true
        }
    })
}

fn check_main_fn_ty(ccx: &CrateCtxt,
                    main_id: ast::NodeId,
                    main_span: Span) {
    let tcx = ccx.tcx;
    let main_t = tcx.node_id_to_type(main_id);
    match main_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(main_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_, _, _, _, ref generics, _) => {
                            if let Some(gen_span) = generics.span() {
                                struct_span_err!(ccx.tcx.sess, gen_span, E0131,
                                         "main function is not allowed to have type parameters")
                                    .span_label(gen_span,
                                                &format!("main cannot have type parameters"))
                                    .emit();
                                return;
                            }
                        }
                        _ => ()
                    }
                }
                _ => ()
            }
            let main_def_id = tcx.map.local_def_id(main_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(main_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: Vec::new(),
                    output: ty::FnConverging(tcx.mk_nil()),
                    variadic: false
                })
            }));

            require_same_types(
                ccx,
                TypeOrigin::MainFunctionType(main_span),
                main_t,
                se_ty);
        }
        _ => {
            span_bug!(main_span,
                      "main has a non-function type: found `{}`",
                      main_t);
        }
    }
}

fn check_start_fn_ty(ccx: &CrateCtxt,
                     start_id: ast::NodeId,
                     start_span: Span) {
    let tcx = ccx.tcx;
    let start_t = tcx.node_id_to_type(start_id);
    match start_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(start_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_,_,_,_,ref ps,_)
                        if ps.is_parameterized() => {
                            struct_span_err!(tcx.sess, start_span, E0132,
                                "start function is not allowed to have type parameters")
                                .span_label(ps.span().unwrap(),
                                            &format!("start function cannot have type parameters"))
                                .emit();
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }

            let start_def_id = ccx.tcx.map.local_def_id(start_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(start_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: vec!(
                        tcx.types.isize,
                        tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
                    ),
                    output: ty::FnConverging(tcx.types.isize),
                    variadic: false,
                }),
            }));

            require_same_types(
                ccx,
                TypeOrigin::StartFunctionType(start_span),
                start_t,
                se_ty);
        }
        _ => {
            span_bug!(start_span,
                      "start has a non-function type: found `{}`",
                      start_t);
        }
    }
}

fn check_for_entry_fn(ccx: &CrateCtxt) {
    let tcx = ccx.tcx;
    let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
    if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
        match tcx.sess.entry_type.get() {
            Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
            Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
            Some(config::EntryNone) => {}
            None => bug!("entry function without a type")
        }
    }
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             trait_map: hir::TraitMap)
                             -> CompileResult {
    let time_passes = tcx.sess.time_passes();
    let ccx = CrateCtxt {
        ast_ty_to_ty_cache: RefCell::new(NodeMap()),
        trait_map: trait_map,
        all_traits: RefCell::new(None),
        stack: RefCell::new(Vec::new()),
        tcx: tcx
    };

    // this ensures that later parts of type checking can assume that items
    // have valid types and not error
    tcx.sess.track_errors(|| {
        time(time_passes, "type collecting", ||
             collect::collect_item_types(&ccx));

    })?;

    time(time_passes, "variance inference", ||
         variance::infer_variance(tcx));

    tcx.sess.track_errors(|| {
      time(time_passes, "coherence checking", ||
          coherence::check_coherence(&ccx));
    })?;

    time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;

    time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;

    time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;

    time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;

    check_unused::check_crate(tcx);
    check_for_entry_fn(&ccx);

    let err_count = tcx.sess.err_count();
    if err_count == 0 {
        Ok(())
    } else {
        Err(err_count)
    }
}

__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
<commit_msg>Updated error for E0045 (no bonus)<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

typeck.rs, an introduction

The type checker is responsible for:

1. Determining the type of each expression
2. Resolving methods and traits
3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
   Well, dear reader, read on)

The main entry point is `check_crate()`.  Type checking operates in
several major phases:

1. The collect phase first passes over all items and determines their
   type, without examining their "innards".

2. Variance inference then runs to compute the variance of each parameter

3. Coherence checks for overlapping or orphaned impls

4. Finally, the check phase then checks function bodies and so forth.
   Within the check phase, we check each function body one at a time
   (bodies of function expressions are checked as part of the
   containing function).  Inference is used to supply types wherever
   they are unknown. The actual checking of a function itself has
   several phases (check, regionck, writeback), as discussed in the
   documentation for the `check` module.

The type checker is defined into various submodules which are documented
independently:

- astconv: converts the AST representation of types
  into the `ty` representation

- collect: computes the types of each top-level item and enters them into
  the `cx.tcache` table for later use

- coherence: enforces coherence rules, builds some tables

- variance: variance inference

- check: walks over function bodies and type checks them, inferring types for
  local variables, type parameters, etc as necessary.

- infer: finds the types to use for each type variable such that
  all subtyping and assignment constraints are met.  In essence, the check
  module specifies the constraints, and the infer module solves them.

# Note

This API is completely unstable and subject to change.

*/

#![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]

#![allow(non_camel_case_types)]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
extern crate syntax_pos;

extern crate arena;
extern crate fmt_macros;
#[macro_use] extern crate rustc;
extern crate rustc_platform_intrinsics as intrinsics;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_const_eval;
extern crate rustc_errors as errors;

pub use rustc::dep_graph;
pub use rustc::hir;
pub use rustc::lint;
pub use rustc::middle;
pub use rustc::session;
pub use rustc::util;

use dep_graph::DepNode;
use hir::map as hir_map;
use rustc::infer::TypeOrigin;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::traits::ProjectionMode;
use session::{config, CompileResult};
use util::common::time;

use syntax::ast;
use syntax::abi::Abi;
use syntax_pos::Span;

use std::cell::RefCell;
use util::nodemap::NodeMap;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod check;
pub mod check_unused;
mod rscope;
mod astconv;
pub mod collect;
mod constrained_type_params;
pub mod coherence;
pub mod variance;

pub struct TypeAndSubsts<'tcx> {
    pub substs: Substs<'tcx>,
    pub ty: Ty<'tcx>,
}

pub struct CrateCtxt<'a, 'tcx: 'a> {
    ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,

    /// A mapping from method call sites to traits that have that method.
    pub trait_map: hir::TraitMap,

    /// A vector of every trait accessible in the whole crate
    /// (i.e. including those from subcrates). This is used only for
    /// error reporting, and so is lazily initialised and generally
    /// shouldn't taint the common path (hence the RefCell).
    pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,

    /// This stack is used to identify cycles in the user's source.
    /// Note that these cycles can cross multiple items.
    pub stack: RefCell<Vec<collect::AstConvRequest>>,

    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

// Functions that write types into the node type table
fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
    debug!("write_ty_to_tcx({}, {:?})", node_id,  ty);
    assert!(!ty.needs_infer());
    ccx.tcx.node_type_insert(node_id, ty);
}

fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 node_id: ast::NodeId,
                                 item_substs: ty::ItemSubsts<'tcx>) {
    if !item_substs.is_noop() {
        debug!("write_substs_to_tcx({}, {:?})",
               node_id,
               item_substs);

        assert!(!item_substs.substs.types.needs_infer());

        ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
    }
}

fn require_c_abi_if_variadic(tcx: TyCtxt,
                             decl: &hir::FnDecl,
                             abi: Abi,
                             span: Span) {
    if decl.variadic && abi != Abi::C {
        let mut err = struct_span_err!(tcx.sess, span, E0045,
                  "variadic function must have C calling convention");
        err.span_label(span, &("variadics require C calling conventions").to_string())
            .emit();
    }
}

fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                origin: TypeOrigin,
                                t1: Ty<'tcx>,
                                t2: Ty<'tcx>)
                                -> bool {
    ccx.tcx.infer_ctxt(None, None, ProjectionMode::AnyFinal).enter(|infcx| {
        if let Err(err) = infcx.eq_types(false, origin.clone(), t1, t2) {
            infcx.report_mismatched_types(origin, t1, t2, err);
            false
        } else {
            true
        }
    })
}

fn check_main_fn_ty(ccx: &CrateCtxt,
                    main_id: ast::NodeId,
                    main_span: Span) {
    let tcx = ccx.tcx;
    let main_t = tcx.node_id_to_type(main_id);
    match main_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(main_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_, _, _, _, ref generics, _) => {
                            if let Some(gen_span) = generics.span() {
                                struct_span_err!(ccx.tcx.sess, gen_span, E0131,
                                         "main function is not allowed to have type parameters")
                                    .span_label(gen_span,
                                                &format!("main cannot have type parameters"))
                                    .emit();
                                return;
                            }
                        }
                        _ => ()
                    }
                }
                _ => ()
            }
            let main_def_id = tcx.map.local_def_id(main_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(main_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: Vec::new(),
                    output: ty::FnConverging(tcx.mk_nil()),
                    variadic: false
                })
            }));

            require_same_types(
                ccx,
                TypeOrigin::MainFunctionType(main_span),
                main_t,
                se_ty);
        }
        _ => {
            span_bug!(main_span,
                      "main has a non-function type: found `{}`",
                      main_t);
        }
    }
}

fn check_start_fn_ty(ccx: &CrateCtxt,
                     start_id: ast::NodeId,
                     start_span: Span) {
    let tcx = ccx.tcx;
    let start_t = tcx.node_id_to_type(start_id);
    match start_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(start_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_,_,_,_,ref ps,_)
                        if ps.is_parameterized() => {
                            struct_span_err!(tcx.sess, start_span, E0132,
                                "start function is not allowed to have type parameters")
                                .span_label(ps.span().unwrap(),
                                            &format!("start function cannot have type parameters"))
                                .emit();
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }

            let start_def_id = ccx.tcx.map.local_def_id(start_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(start_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: vec!(
                        tcx.types.isize,
                        tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
                    ),
                    output: ty::FnConverging(tcx.types.isize),
                    variadic: false,
                }),
            }));

            require_same_types(
                ccx,
                TypeOrigin::StartFunctionType(start_span),
                start_t,
                se_ty);
        }
        _ => {
            span_bug!(start_span,
                      "start has a non-function type: found `{}`",
                      start_t);
        }
    }
}

fn check_for_entry_fn(ccx: &CrateCtxt) {
    let tcx = ccx.tcx;
    let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
    if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
        match tcx.sess.entry_type.get() {
            Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
            Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
            Some(config::EntryNone) => {}
            None => bug!("entry function without a type")
        }
    }
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             trait_map: hir::TraitMap)
                             -> CompileResult {
    let time_passes = tcx.sess.time_passes();
    let ccx = CrateCtxt {
        ast_ty_to_ty_cache: RefCell::new(NodeMap()),
        trait_map: trait_map,
        all_traits: RefCell::new(None),
        stack: RefCell::new(Vec::new()),
        tcx: tcx
    };

    // this ensures that later parts of type checking can assume that items
    // have valid types and not error
    tcx.sess.track_errors(|| {
        time(time_passes, "type collecting", ||
             collect::collect_item_types(&ccx));

    })?;

    time(time_passes, "variance inference", ||
         variance::infer_variance(tcx));

    tcx.sess.track_errors(|| {
      time(time_passes, "coherence checking", ||
          coherence::check_coherence(&ccx));
    })?;

    time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;

    time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;

    time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;

    time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;

    check_unused::check_crate(tcx);
    check_for_entry_fn(&ccx);

    let err_count = tcx.sess.err_count();
    if err_count == 0 {
        Ok(())
    } else {
        Err(err_count)
    }
}

__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
<|endoftext|>