<commit_before>#[doc = "Generic pass for performing an operation on all descriptions"];

export mk_pass;

fn mk_pass(op: fn~(str) -> str) -> pass {
    fn~(srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc {
        run(srv, doc, op)
    }
}

type op = fn~(str) -> str;

fn run(
    _srv: astsrv::srv,
    doc: doc::cratedoc,
    op: op
) -> doc::cratedoc {
    let fold = fold::fold({
        fold_mod: fold_mod,
        fold_const: fold_const,
        fold_fn: fold_fn,
        fold_enum: fold_enum
        with *fold::default_seq_fold(op)
    });
    fold.fold_crate(fold, doc)
}

fn maybe_apply_op(op: op, s: option<str>) -> option<str> {
    option::map(s) {|s| op(s) }
}

fn fold_mod(fold: fold::fold<op>, doc: doc::moddoc) -> doc::moddoc {
    let doc = fold::default_seq_fold_mod(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc)
        with *doc
    }
}

fn fold_const(fold: fold::fold<op>, doc: doc::constdoc) -> doc::constdoc {
    let doc = fold::default_seq_fold_const(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc)
        with *doc
    }
}

fn fold_fn(fold: fold::fold<op>, doc: doc::fndoc) -> doc::fndoc {
    let doc = fold::default_seq_fold_fn(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc),
        args: vec::map(doc.args) {|doc|
            ~{
                desc: maybe_apply_op(fold.ctxt, doc.desc)
                with *doc
            }
        },
        return: {
            desc: maybe_apply_op(fold.ctxt, doc.return.desc)
            with doc.return
        },
        failure: maybe_apply_op(fold.ctxt, doc.failure)
        with *doc
    }
}

fn fold_enum(fold: fold::fold<op>, doc: doc::enumdoc) -> doc::enumdoc {
    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc),
        variants: vec::map(doc.variants) {|variant|
            ~{
                desc: maybe_apply_op(fold.ctxt, variant.desc)
                with *variant
            }
        }
        with *doc
    }
}

#[test]
fn should_execute_op_on_enum_brief() {
    let source = "#[doc(brief = \" a \")] enum a { b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].brief == some("a");
}

#[test]
fn should_execute_op_on_enum_desc() {
    let source = "#[doc(desc = \" a \")] enum a { b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].desc == some("a");
}

#[test]
fn should_execute_op_on_variant_desc() {
    let source = "enum a { #[doc = \" a \"] b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].variants[0].desc == some("a");
}<commit_msg>rustdoc: Apply generic string-op passes to resources<commit_after>#[doc = "Generic pass for performing an operation on all descriptions"];

export mk_pass;

fn mk_pass(op: fn~(str) -> str) -> pass {
    fn~(srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc {
        run(srv, doc, op)
    }
}

type op = fn~(str) -> str;

fn run(
    _srv: astsrv::srv,
    doc: doc::cratedoc,
    op: op
) -> doc::cratedoc {
    let fold = fold::fold({
        fold_mod: fold_mod,
        fold_const: fold_const,
        fold_fn: fold_fn,
        fold_enum: fold_enum,
        fold_res: fold_res
        with *fold::default_seq_fold(op)
    });
    fold.fold_crate(fold, doc)
}

fn maybe_apply_op(op: op, s: option<str>) -> option<str> {
    option::map(s) {|s| op(s) }
}

fn fold_mod(fold: fold::fold<op>, doc: doc::moddoc) -> doc::moddoc {
    let doc = fold::default_seq_fold_mod(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc)
        with *doc
    }
}

fn fold_const(fold: fold::fold<op>, doc: doc::constdoc) -> doc::constdoc {
    let doc = fold::default_seq_fold_const(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc)
        with *doc
    }
}

fn fold_fn(fold: fold::fold<op>, doc: doc::fndoc) -> doc::fndoc {
    let doc = fold::default_seq_fold_fn(fold, doc);

    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc),
        args: vec::map(doc.args) {|doc|
            ~{
                desc: maybe_apply_op(fold.ctxt, doc.desc)
                with *doc
            }
        },
        return: {
            desc: maybe_apply_op(fold.ctxt, doc.return.desc)
            with doc.return
        },
        failure: maybe_apply_op(fold.ctxt, doc.failure)
        with *doc
    }
}

fn fold_enum(fold: fold::fold<op>, doc: doc::enumdoc) -> doc::enumdoc {
    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc),
        variants: vec::map(doc.variants) {|variant|
            ~{
                desc: maybe_apply_op(fold.ctxt, variant.desc)
                with *variant
            }
        }
        with *doc
    }
}

fn fold_res(fold: fold::fold<op>, doc: doc::resdoc) -> doc::resdoc {
    ~{
        brief: maybe_apply_op(fold.ctxt, doc.brief),
        desc: maybe_apply_op(fold.ctxt, doc.desc),
        args: vec::map(doc.args) {|arg|
            ~{
                desc: maybe_apply_op(fold.ctxt, arg.desc)
                with *arg
            }
        }
        with *doc
    }
}

#[test]
fn should_execute_op_on_enum_brief() {
    let source = "#[doc(brief = \" a \")] enum a { b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].brief == some("a");
}

#[test]
fn should_execute_op_on_enum_desc() {
    let source = "#[doc(desc = \" a \")] enum a { b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].desc == some("a");
}

#[test]
fn should_execute_op_on_variant_desc() {
    let source = "enum a { #[doc = \" a \"] b }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.enums[0].variants[0].desc == some("a");
}

#[test]
fn should_execute_op_on_resource_brief() {
    let source = "#[doc(brief = \" a \")] resource r(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.resources[0].brief == some("a");
}

#[test]
fn should_execute_op_on_resource_desc() {
    let source = "#[doc(desc = \" a \")] resource r(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.resources[0].desc == some("a");
}

#[test]
fn should_execute_op_on_resource_args() {
    let source = "#[doc(args(a = \" a \"))] resource r(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = attr_pass::mk_pass()(srv, doc);
    let doc = mk_pass(str::trim)(srv, doc);
    assert doc.topmod.resources[0].args[0].desc == some("a");
}<|endoftext|>


<commit_before><commit_msg>include missing collision file.<commit_after>// Checks
use specs::{Entities, Join, ReadExpect, ReadStorage, System, WriteStorage};

use crate::campaign::components::{Interactable, HitBox, OnHoverImage};
use crate::combat::components::{Controller, Draw, Position};
use crate::rect::Rect;

pub struct CheckMapCollision;

impl<'a> System<'a> for CheckMapCollision {
    type SystemData = (
        ReadStorage<'a, Position>,
        ReadStorage<'a, Controller>,
        ReadStorage<'a, HitBox>,
        WriteStorage<'a, Interactable>,
        Entities<'a>,
    );
    fn run(
        &mut self,
        (position_storage, controller_storage, hitbox_storage, mut interact_storage, entities): Self::SystemData,
    ) {
        for (position, _, hitbox, moving_entity) in (
            &position_storage,
            &controller_storage,
            &hitbox_storage,
            &*entities,
        )
            .join()
        {
            for (loc_position, loc_hitbox, location) in
                (&position_storage, &hitbox_storage, &*entities).join()
            {
                let mover_rect = Rect {
                    x: position.x,
                    y: position.y,
                    w: hitbox.w,
                    h: hitbox.h,
                };
                let loc_rect = Rect {
                    x: loc_position.x,
                    y: loc_position.y,
                    w: loc_hitbox.w,
                    h: loc_hitbox.h,
                };
                if mover_rect.intersects(&loc_rect) {
                    let result =
                        interact_storage.insert(location, Interactable { target:  moving_entity });
                } else {
                    interact_storage.remove(location);
                }
            }
        }
    }
}
<|endoftext|>


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

use engine::Engine;
use engine::EngineError;
use engine::EngineResult;
use engine::ErrorEnum;

use engine::Pool;

use std::cell::RefCell;
use std::path::Path;
use std::collections::BTreeMap;
use std::iter::FromIterator;
use std::rc::Rc;

use super::blockdev::SimDev;
use super::pool::SimPool;
use super::randomization::Randomizer;

#[derive(Debug)]
pub struct SimEngine {
    pub pools: BTreeMap<String, SimPool>,
    rdm: Rc<RefCell<Randomizer>>,
}

impl SimEngine {
    pub fn new() -> SimEngine {
        SimEngine {
            pools: BTreeMap::new(),
            rdm: Rc::new(RefCell::new(Randomizer::new())),
        }
    }
}

impl Engine for SimEngine {
    fn create_pool(&mut self,
                   name: &str,
                   blockdev_paths: &[&Path],
                   raid_level: u16)
                   -> EngineResult<()> {

        if self.pools.contains_key(name) {
            return Err(EngineError::Stratis(ErrorEnum::AlreadyExists(name.into())));
        }

        let mut devs: Vec<SimDev> =
            blockdev_paths.iter().map(|x| SimDev::new_dev(self.rdm.clone(), x)).collect();

        for dev in devs.iter_mut() {
            dev.update();
        }

        let bad_devs: Vec<&SimDev> = devs.iter().filter(|dev| !dev.usable()).collect();

        if !bad_devs.is_empty() {
            return Err(EngineError::Stratis(ErrorEnum::Busy("some devices are unusable".into())));
        }

        let pool = SimPool::new_pool(self.rdm.clone(), devs.as_slice(), raid_level);

        if self.rdm.borrow_mut().throw_die() {
            return Err(EngineError::Stratis(ErrorEnum::Error("X".into())));
        }

        self.pools.insert(name.to_owned(), pool);
        Ok(())
    }

    fn destroy_pool(&mut self, name: &str) -> EngineResult<()> {
        if self.rdm.borrow_mut().throw_die() {
            return Err(EngineError::Stratis(ErrorEnum::Busy("X".into())));
        }

        self.pools.remove(name);

        Ok(())
    }
    fn get_pool(&mut self, name: &str) -> EngineResult<&mut Pool> {

        let return_pool = match self.pools.get_mut(name) {
            Some(pool) => pool,
            None => return Err(EngineError::Stratis(ErrorEnum::NotFound(name.into()))),
        };

        Ok(return_pool)
    }

    fn pools(&mut self) -> BTreeMap<&str, &mut Pool> {

        BTreeMap::from_iter(self.pools.iter_mut().map(|x| (x.0 as &str, x.1 as &mut Pool)))

    }

    fn configure_simulator(&mut self, denominator: u32) -> EngineResult<()> {
        self.rdm.borrow_mut().set_probability(denominator);
        Ok(())
    }
}
<commit_msg>Now checking existance of filesystems on pool before freeing.<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/.

use engine::Engine;
use engine::EngineError;
use engine::EngineResult;
use engine::ErrorEnum;

use engine::Pool;

use std::cell::RefCell;
use std::path::Path;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use std::iter::FromIterator;
use std::rc::Rc;

use super::blockdev::SimDev;
use super::pool::SimPool;
use super::randomization::Randomizer;

#[derive(Debug)]
pub struct SimEngine {
    pub pools: BTreeMap<String, SimPool>,
    rdm: Rc<RefCell<Randomizer>>,
}

impl SimEngine {
    pub fn new() -> SimEngine {
        SimEngine {
            pools: BTreeMap::new(),
            rdm: Rc::new(RefCell::new(Randomizer::new())),
        }
    }
}

impl Engine for SimEngine {
    fn create_pool(&mut self,
                   name: &str,
                   blockdev_paths: &[&Path],
                   raid_level: u16)
                   -> EngineResult<()> {

        if self.pools.contains_key(name) {
            return Err(EngineError::Stratis(ErrorEnum::AlreadyExists(name.into())));
        }

        let mut devs: Vec<SimDev> =
            blockdev_paths.iter().map(|x| SimDev::new_dev(self.rdm.clone(), x)).collect();

        for dev in devs.iter_mut() {
            dev.update();
        }

        let bad_devs: Vec<&SimDev> = devs.iter().filter(|dev| !dev.usable()).collect();

        if !bad_devs.is_empty() {
            return Err(EngineError::Stratis(ErrorEnum::Busy("some devices are unusable".into())));
        }

        let pool = SimPool::new_pool(self.rdm.clone(), devs.as_slice(), raid_level);

        if self.rdm.borrow_mut().throw_die() {
            return Err(EngineError::Stratis(ErrorEnum::Error("X".into())));
        }

        self.pools.insert(name.to_owned(), pool);
        Ok(())
    }

    fn destroy_pool(&mut self, name: &str) -> EngineResult<()> {
        let entry = match self.pools.entry(name.into()) {
            Entry::Vacant(_) => return Ok(()),
            Entry::Occupied(entry) => entry,
        };
        if !entry.get().filesystems.is_empty() {
            return Err(EngineError::Stratis(ErrorEnum::Busy("filesystems remaining on pool"
                .into())));
        };
        if self.rdm.borrow_mut().throw_die() {
            return Err(EngineError::Stratis(ErrorEnum::Busy("could not free devices in pool"
                .into())));
        };
        entry.remove();
        Ok(())
    }
    fn get_pool(&mut self, name: &str) -> EngineResult<&mut Pool> {

        let return_pool = match self.pools.get_mut(name) {
            Some(pool) => pool,
            None => return Err(EngineError::Stratis(ErrorEnum::NotFound(name.into()))),
        };

        Ok(return_pool)
    }

    fn pools(&mut self) -> BTreeMap<&str, &mut Pool> {

        BTreeMap::from_iter(self.pools.iter_mut().map(|x| (x.0 as &str, x.1 as &mut Pool)))

    }

    fn configure_simulator(&mut self, denominator: u32) -> EngineResult<()> {
        self.rdm.borrow_mut().set_probability(denominator);
        Ok(())
    }
}
<|endoftext|>


<commit_before><commit_msg>Improve Syntax Validator<commit_after><|endoftext|>


<commit_before><commit_msg>When creating the Vulkan device, enable all features that the physical device supports<commit_after><|endoftext|>


<commit_before><commit_msg>Add command doc<commit_after><|endoftext|>


<commit_before>use au = gfx::geometry;
use au::au;
use dvec::DVec;
use geom::size::Size2D;

struct ElementData {
    tag_name: ~str,
    kind: ~ElementKind,
    attrs: DVec<~Attr>,
}

impl ElementData {
    fn get_attr(attr_name: ~str) -> Option<~str> {
        let mut i = 0u;
        while i < self.attrs.len() {
            if attr_name == self.attrs[i].name {
                return Some(copy self.attrs[i].value);
            }
            i += 1u;
        }

        None
    }

    fn set_attr(_attr_name: ~str, attr_value: ~str) {
        // TODO: add new attr of name, or delete old one
    }
}

fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
    ElementData {
        tag_name : tag_name,
        kind : kind,
        attrs : DVec(),
    }
}

struct Attr {
    name: ~str,
    value: ~str,
}

fn Attr(name: ~str, value: ~str) -> Attr {
    Attr {
        name : name,
        value : value,
    }
}

enum HeadingLevel {
    Heading1,
    Heading2,
    Heading3,
    Heading4,
    Heading5,
    Heading6,
}

enum ElementKind {
    HTMLAnchorElement,
    HTMLAsideElement,
    HTMLBRElement,
    HTMLBodyElement,
    HTMLBoldElement,
    HTMLDivElement,
    HTMLFontElement,
    HTMLFormElement,
    HTMLHRElement,
    HTMLHeadElement,
    HTMLHeadingElement(HeadingLevel),
    HTMLHtmlElement,
    // TODO: should not take this as argument--it is fetched from
    // layout task as requested.
    HTMLImageElement({mut size: Size2D<au>}),
    HTMLInputElement,
    HTMLItalicElement,
    HTMLLinkElement,
    HTMLListItemElement,
    HTMLMetaElement,
    HTMLOListElement,
    HTMLOptionElement,
    HTMLParagraphElement,
    HTMLScriptElement,
    HTMLSectionElement,
    HTMLSelectElement,
    HTMLSmallElement,
    HTMLSpanElement,
    HTMLStyleElement,
    HTMLTableBodyElement,
    HTMLTableCellElement,
    HTMLTableElement,
    HTMLTableRowElement,
    HTMLTitleElement,
    HTMLUListElement,
    UnknownElement,
}
<commit_msg>Implement dom::element::Element.{get_attr, set_attr}<commit_after>use au = gfx::geometry;
use au::au;
use dvec::DVec;
use geom::size::Size2D;

struct ElementData {
    tag_name: ~str,
    kind: ~ElementKind,
    attrs: DVec<~Attr>,
}

impl ElementData {
    fn get_attr(name: ~str) -> Option<~str> {
        let found = do self.attrs.find |attr| { attr.name == name };
        match found {
            Some(attr) => Some(copy attr.value),
            None => None
        }
    }

    fn set_attr(name: ~str, value: ~str) {
        let idx = do self.attrs.position |attr| { attr.name == name };
        match idx {
            Some(idx) => self.attrs.set_elt(idx, ~Attr(name, value)),
            None => {}
        }
    }
}

fn ElementData(tag_name: ~str, kind: ~ElementKind) -> ElementData {
    ElementData {
        tag_name : tag_name,
        kind : kind,
        attrs : DVec(),
    }
}

struct Attr {
    name: ~str,
    value: ~str,
}

fn Attr(name: ~str, value: ~str) -> Attr {
    Attr {
        name : name,
        value : value,
    }
}

enum HeadingLevel {
    Heading1,
    Heading2,
    Heading3,
    Heading4,
    Heading5,
    Heading6,
}

enum ElementKind {
    HTMLAnchorElement,
    HTMLAsideElement,
    HTMLBRElement,
    HTMLBodyElement,
    HTMLBoldElement,
    HTMLDivElement,
    HTMLFontElement,
    HTMLFormElement,
    HTMLHRElement,
    HTMLHeadElement,
    HTMLHeadingElement(HeadingLevel),
    HTMLHtmlElement,
    // TODO: should not take this as argument--it is fetched from
    // layout task as requested.
    HTMLImageElement({mut size: Size2D<au>}),
    HTMLInputElement,
    HTMLItalicElement,
    HTMLLinkElement,
    HTMLListItemElement,
    HTMLMetaElement,
    HTMLOListElement,
    HTMLOptionElement,
    HTMLParagraphElement,
    HTMLScriptElement,
    HTMLSectionElement,
    HTMLSelectElement,
    HTMLSmallElement,
    HTMLSpanElement,
    HTMLStyleElement,
    HTMLTableBodyElement,
    HTMLTableCellElement,
    HTMLTableElement,
    HTMLTableRowElement,
    HTMLTitleElement,
    HTMLUListElement,
    UnknownElement,
}
<|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.

use lib::llvm::*;
use driver::config::FullDebugInfo;
use middle::def;
use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::cleanup::CleanupMethods;
use middle::trans::cleanup;
use middle::trans::common::*;
use middle::trans::debuginfo;
use middle::trans::expr;
use middle::trans::type_of;
use middle::ty;
use util::ppaux::Repr;

use syntax::ast;
use syntax::ast::Ident;
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit::Visitor;

pub fn trans_stmt<'a>(cx: &'a Block<'a>,
                      s: &ast::Stmt)
                      -> &'a Block<'a> {
    let _icx = push_ctxt("trans_stmt");
    let fcx = cx.fcx;
    debug!("trans_stmt({})", s.repr(cx.tcx()));

    if cx.sess().asm_comments() {
        add_span_comment(cx, s.span, s.repr(cx.tcx()).as_slice());
    }

    let mut bcx = cx;

    let id = ast_util::stmt_id(s);
    fcx.push_ast_cleanup_scope(id);

    match s.node {
        ast::StmtExpr(e, _) | ast::StmtSemi(e, _) => {
            bcx = trans_stmt_semi(bcx, e);
        }
        ast::StmtDecl(d, _) => {
            match d.node {
                ast::DeclLocal(ref local) => {
                    bcx = init_local(bcx, *local);
                    if cx.sess().opts.debuginfo == FullDebugInfo {
                        debuginfo::create_local_var_metadata(bcx, *local);
                    }
                }
                ast::DeclItem(i) => trans_item(cx.fcx.ccx, i)
            }
        }
        ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro")
    }

    bcx = fcx.pop_and_trans_ast_cleanup_scope(
        bcx, ast_util::stmt_id(s));

    return bcx;
}

pub fn trans_stmt_semi<'a>(cx: &'a Block<'a>, e: &ast::Expr) -> &'a Block<'a> {
    let _icx = push_ctxt("trans_stmt_semi");
    let ty = expr_ty(cx, e);
    if ty::type_needs_drop(cx.tcx(), ty) {
        expr::trans_to_lvalue(cx, e, "stmt").bcx
    } else {
        expr::trans_into(cx, e, expr::Ignore)
    }
}

pub fn trans_block<'a>(bcx: &'a Block<'a>,
                       b: &ast::Block,
                       mut dest: expr::Dest)
                       -> &'a Block<'a> {
    let _icx = push_ctxt("trans_block");
    let fcx = bcx.fcx;
    let mut bcx = bcx;

    fcx.push_ast_cleanup_scope(b.id);

    for s in b.stmts.iter() {
        bcx = trans_stmt(bcx, *s);
    }

    if dest != expr::Ignore {
        let block_ty = node_id_type(bcx, b.id);
        if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
            dest = expr::Ignore;
        }
    }

    match b.expr {
        Some(e) => {
            bcx = expr::trans_into(bcx, e, dest);
        }
        None => {
            assert!(dest == expr::Ignore || bcx.unreachable.get());
        }
    }

    bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, b.id);

    return bcx;
}

pub fn trans_if<'a>(bcx: &'a Block<'a>,
                    if_id: ast::NodeId,
                    cond: &ast::Expr,
                    thn: ast::P<ast::Block>,
                    els: Option<@ast::Expr>,
                    dest: expr::Dest)
                    -> &'a Block<'a> {
    debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
           bcx.to_str(), if_id, bcx.expr_to_str(cond), thn.id,
           dest.to_str(bcx.ccx()));
    let _icx = push_ctxt("trans_if");
    let mut bcx = bcx;

    let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());

    // Drop branches that are known to be impossible
    if is_const(cond_val) && !is_undef(cond_val) {
        if const_to_uint(cond_val) == 1 {
            match els {
                Some(elexpr) => {
                    let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
                    trans.visit_expr(elexpr, ());
                }
                None => {}
            }
            // if true { .. } [else { .. }]
            bcx = trans_block(bcx, thn, dest);
            debuginfo::clear_source_location(bcx.fcx);
        } else {
            let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
            trans.visit_block(thn, ());

            match els {
                // if false { .. } else { .. }
                Some(elexpr) => {
                    bcx = expr::trans_into(bcx, elexpr, dest);
                    debuginfo::clear_source_location(bcx.fcx);
                }

                // if false { .. }
                None => { }
            }
        }

        return bcx;
    }

    let name = format!("then-block-{}-", thn.id);
    let then_bcx_in = bcx.fcx.new_id_block(name.as_slice(), thn.id);
    let then_bcx_out = trans_block(then_bcx_in, thn, dest);
    debuginfo::clear_source_location(bcx.fcx);

    let next_bcx;
    match els {
        Some(elexpr) => {
            let else_bcx_in = bcx.fcx.new_id_block("else-block", elexpr.id);
            let else_bcx_out = expr::trans_into(else_bcx_in, elexpr, dest);
            next_bcx = bcx.fcx.join_blocks(if_id,
                                           [then_bcx_out, else_bcx_out]);
            CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb);
        }

        None => {
            next_bcx = bcx.fcx.new_id_block("next-block", if_id);
            Br(then_bcx_out, next_bcx.llbb);
            CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb);
        }
    }

    // Clear the source location because it is still set to whatever has been translated
    // right before.
    debuginfo::clear_source_location(next_bcx.fcx);

    next_bcx
}

pub fn trans_while<'a>(bcx: &'a Block<'a>,
                       loop_id: ast::NodeId,
                       cond: &ast::Expr,
                       body: &ast::Block)
                       -> &'a Block<'a> {
    let _icx = push_ctxt("trans_while");
    let fcx = bcx.fcx;

    //            bcx
    //             |
    //         cond_bcx_in  <--------+
    //             |                 |
    //         cond_bcx_out          |
    //           |      |            |
    //           |    body_bcx_in    |
    // cleanup_blk      |            |
    //    |           body_bcx_out --+
    // next_bcx_in

    let next_bcx_in = fcx.new_id_block("while_exit", loop_id);
    let cond_bcx_in = fcx.new_id_block("while_cond", cond.id);
    let body_bcx_in = fcx.new_id_block("while_body", body.id);

    fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, cond_bcx_in]);

    Br(bcx, cond_bcx_in.llbb);

    // compile the block where we will handle loop cleanups
    let cleanup_llbb = fcx.normal_exit_block(loop_id, cleanup::EXIT_BREAK);

    // compile the condition
    let Result {bcx: cond_bcx_out, val: cond_val} =
        expr::trans(cond_bcx_in, cond).to_llbool();
    CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb);

    // loop body:
    let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
    Br(body_bcx_out, cond_bcx_in.llbb);

    fcx.pop_loop_cleanup_scope(loop_id);
    return next_bcx_in;
}

pub fn trans_loop<'a>(bcx:&'a Block<'a>,
                      loop_id: ast::NodeId,
                      body: &ast::Block)
                      -> &'a Block<'a> {
    let _icx = push_ctxt("trans_loop");
    let fcx = bcx.fcx;

    //            bcx
    //             |
    //         body_bcx_in
    //             |
    //         body_bcx_out
    //
    // next_bcx
    //
    // Links between body_bcx_in and next_bcx are created by
    // break statements.

    let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_id);
    let body_bcx_in = bcx.fcx.new_id_block("loop_body", body.id);

    fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, body_bcx_in]);

    Br(bcx, body_bcx_in.llbb);
    let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
    Br(body_bcx_out, body_bcx_in.llbb);

    fcx.pop_loop_cleanup_scope(loop_id);

    if ty::type_is_bot(node_id_type(bcx, loop_id)) {
        Unreachable(next_bcx_in);
    }

    return next_bcx_in;
}

pub fn trans_break_cont<'a>(bcx: &'a Block<'a>,
                            expr_id: ast::NodeId,
                            opt_label: Option<Ident>,
                            exit: uint)
                            -> &'a Block<'a> {
    let _icx = push_ctxt("trans_break_cont");
    let fcx = bcx.fcx;

    if bcx.unreachable.get() {
        return bcx;
    }

    // Locate loop that we will break to
    let loop_id = match opt_label {
        None => fcx.top_loop_scope(),
        Some(_) => {
            match bcx.tcx().def_map.borrow().find(&expr_id) {
                Some(&def::DefLabel(loop_id)) => loop_id,
                ref r => {
                    bcx.tcx().sess.bug(format!("{:?} in def-map for label",
                                               r).as_slice())
                }
            }
        }
    };

    // Generate appropriate cleanup code and branch
    let cleanup_llbb = fcx.normal_exit_block(loop_id, exit);
    Br(bcx, cleanup_llbb);
    Unreachable(bcx); // anything afterwards should be ignored
    return bcx;
}

pub fn trans_break<'a>(bcx: &'a Block<'a>,
                       expr_id: ast::NodeId,
                       label_opt: Option<Ident>)
                       -> &'a Block<'a> {
    return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_BREAK);
}

pub fn trans_cont<'a>(bcx: &'a Block<'a>,
                      expr_id: ast::NodeId,
                      label_opt: Option<Ident>)
                      -> &'a Block<'a> {
    return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_LOOP);
}

pub fn trans_ret<'a>(bcx: &'a Block<'a>,
                     e: Option<@ast::Expr>)
                     -> &'a Block<'a> {
    let _icx = push_ctxt("trans_ret");
    let fcx = bcx.fcx;
    let mut bcx = bcx;
    let dest = match bcx.fcx.llretptr.get() {
        None => expr::Ignore,
        Some(retptr) => expr::SaveIn(retptr),
    };
    match e {
        Some(x) => {
            bcx = expr::trans_into(bcx, x, dest);
        }
        _ => {}
    }
    let cleanup_llbb = fcx.return_exit_block();
    Br(bcx, cleanup_llbb);
    Unreachable(bcx);
    return bcx;
}

fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
    let ccx = bcx.ccx();
    let t = ty::mk_str_slice(bcx.tcx(), ty::ReStatic, ast::MutImmutable);
    let s = C_str_slice(ccx, s);
    let slot = alloca(bcx, val_ty(s), "__temp");
    Store(bcx, s, slot);

    // The type of C_str_slice is { i8*, i64 }, but the type of the &str is
    // %str_slice, so we do a bitcast here to the right type.
    BitCast(bcx, slot, type_of::type_of(ccx, t).ptr_to())
}

pub fn trans_fail<'a>(
                  bcx: &'a Block<'a>,
                  sp: Span,
                  fail_str: InternedString)
                  -> &'a Block<'a> {
    let ccx = bcx.ccx();
    let _icx = push_ctxt("trans_fail_value");

    let v_str = str_slice_arg(bcx, fail_str);
    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
    let filename = token::intern_and_get_ident(loc.file.name.as_slice());
    let v_filename = str_slice_arg(bcx, filename);
    let v_line = loc.line as int;
    let args = vec!(v_str, v_filename, C_int(ccx, v_line));
    let did = langcall(bcx, Some(sp), "", FailFnLangItem);
    let bcx = callee::trans_lang_call(bcx,
                                      did,
                                      args.as_slice(),
                                      Some(expr::Ignore)).bcx;
    Unreachable(bcx);
    return bcx;
}

pub fn trans_fail_bounds_check<'a>(
                               bcx: &'a Block<'a>,
                               sp: Span,
                               index: ValueRef,
                               len: ValueRef)
                               -> &'a Block<'a> {
    let _icx = push_ctxt("trans_fail_bounds_check");

    // Extract the file/line from the span
    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
    let filename = token::intern_and_get_ident(loc.file.name.as_slice());

    // Invoke the lang item
    let filename = str_slice_arg(bcx, filename);
    let line = C_int(bcx.ccx(), loc.line as int);
    let args = vec!(filename, line, index, len);
    let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
    let bcx = callee::trans_lang_call(bcx,
                                      did,
                                      args.as_slice(),
                                      Some(expr::Ignore)).bcx;
    Unreachable(bcx);
    return bcx;
}
<commit_msg>Remove a redundant bitcast from fail!() handling<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.

use lib::llvm::*;
use driver::config::FullDebugInfo;
use middle::def;
use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::cleanup::CleanupMethods;
use middle::trans::cleanup;
use middle::trans::common::*;
use middle::trans::debuginfo;
use middle::trans::expr;
use middle::ty;
use util::ppaux::Repr;

use syntax::ast;
use syntax::ast::Ident;
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit::Visitor;

pub fn trans_stmt<'a>(cx: &'a Block<'a>,
                      s: &ast::Stmt)
                      -> &'a Block<'a> {
    let _icx = push_ctxt("trans_stmt");
    let fcx = cx.fcx;
    debug!("trans_stmt({})", s.repr(cx.tcx()));

    if cx.sess().asm_comments() {
        add_span_comment(cx, s.span, s.repr(cx.tcx()).as_slice());
    }

    let mut bcx = cx;

    let id = ast_util::stmt_id(s);
    fcx.push_ast_cleanup_scope(id);

    match s.node {
        ast::StmtExpr(e, _) | ast::StmtSemi(e, _) => {
            bcx = trans_stmt_semi(bcx, e);
        }
        ast::StmtDecl(d, _) => {
            match d.node {
                ast::DeclLocal(ref local) => {
                    bcx = init_local(bcx, *local);
                    if cx.sess().opts.debuginfo == FullDebugInfo {
                        debuginfo::create_local_var_metadata(bcx, *local);
                    }
                }
                ast::DeclItem(i) => trans_item(cx.fcx.ccx, i)
            }
        }
        ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro")
    }

    bcx = fcx.pop_and_trans_ast_cleanup_scope(
        bcx, ast_util::stmt_id(s));

    return bcx;
}

pub fn trans_stmt_semi<'a>(cx: &'a Block<'a>, e: &ast::Expr) -> &'a Block<'a> {
    let _icx = push_ctxt("trans_stmt_semi");
    let ty = expr_ty(cx, e);
    if ty::type_needs_drop(cx.tcx(), ty) {
        expr::trans_to_lvalue(cx, e, "stmt").bcx
    } else {
        expr::trans_into(cx, e, expr::Ignore)
    }
}

pub fn trans_block<'a>(bcx: &'a Block<'a>,
                       b: &ast::Block,
                       mut dest: expr::Dest)
                       -> &'a Block<'a> {
    let _icx = push_ctxt("trans_block");
    let fcx = bcx.fcx;
    let mut bcx = bcx;

    fcx.push_ast_cleanup_scope(b.id);

    for s in b.stmts.iter() {
        bcx = trans_stmt(bcx, *s);
    }

    if dest != expr::Ignore {
        let block_ty = node_id_type(bcx, b.id);
        if b.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
            dest = expr::Ignore;
        }
    }

    match b.expr {
        Some(e) => {
            bcx = expr::trans_into(bcx, e, dest);
        }
        None => {
            assert!(dest == expr::Ignore || bcx.unreachable.get());
        }
    }

    bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, b.id);

    return bcx;
}

pub fn trans_if<'a>(bcx: &'a Block<'a>,
                    if_id: ast::NodeId,
                    cond: &ast::Expr,
                    thn: ast::P<ast::Block>,
                    els: Option<@ast::Expr>,
                    dest: expr::Dest)
                    -> &'a Block<'a> {
    debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
           bcx.to_str(), if_id, bcx.expr_to_str(cond), thn.id,
           dest.to_str(bcx.ccx()));
    let _icx = push_ctxt("trans_if");
    let mut bcx = bcx;

    let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());

    // Drop branches that are known to be impossible
    if is_const(cond_val) && !is_undef(cond_val) {
        if const_to_uint(cond_val) == 1 {
            match els {
                Some(elexpr) => {
                    let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
                    trans.visit_expr(elexpr, ());
                }
                None => {}
            }
            // if true { .. } [else { .. }]
            bcx = trans_block(bcx, thn, dest);
            debuginfo::clear_source_location(bcx.fcx);
        } else {
            let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
            trans.visit_block(thn, ());

            match els {
                // if false { .. } else { .. }
                Some(elexpr) => {
                    bcx = expr::trans_into(bcx, elexpr, dest);
                    debuginfo::clear_source_location(bcx.fcx);
                }

                // if false { .. }
                None => { }
            }
        }

        return bcx;
    }

    let name = format!("then-block-{}-", thn.id);
    let then_bcx_in = bcx.fcx.new_id_block(name.as_slice(), thn.id);
    let then_bcx_out = trans_block(then_bcx_in, thn, dest);
    debuginfo::clear_source_location(bcx.fcx);

    let next_bcx;
    match els {
        Some(elexpr) => {
            let else_bcx_in = bcx.fcx.new_id_block("else-block", elexpr.id);
            let else_bcx_out = expr::trans_into(else_bcx_in, elexpr, dest);
            next_bcx = bcx.fcx.join_blocks(if_id,
                                           [then_bcx_out, else_bcx_out]);
            CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb);
        }

        None => {
            next_bcx = bcx.fcx.new_id_block("next-block", if_id);
            Br(then_bcx_out, next_bcx.llbb);
            CondBr(bcx, cond_val, then_bcx_in.llbb, next_bcx.llbb);
        }
    }

    // Clear the source location because it is still set to whatever has been translated
    // right before.
    debuginfo::clear_source_location(next_bcx.fcx);

    next_bcx
}

pub fn trans_while<'a>(bcx: &'a Block<'a>,
                       loop_id: ast::NodeId,
                       cond: &ast::Expr,
                       body: &ast::Block)
                       -> &'a Block<'a> {
    let _icx = push_ctxt("trans_while");
    let fcx = bcx.fcx;

    //            bcx
    //             |
    //         cond_bcx_in  <--------+
    //             |                 |
    //         cond_bcx_out          |
    //           |      |            |
    //           |    body_bcx_in    |
    // cleanup_blk      |            |
    //    |           body_bcx_out --+
    // next_bcx_in

    let next_bcx_in = fcx.new_id_block("while_exit", loop_id);
    let cond_bcx_in = fcx.new_id_block("while_cond", cond.id);
    let body_bcx_in = fcx.new_id_block("while_body", body.id);

    fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, cond_bcx_in]);

    Br(bcx, cond_bcx_in.llbb);

    // compile the block where we will handle loop cleanups
    let cleanup_llbb = fcx.normal_exit_block(loop_id, cleanup::EXIT_BREAK);

    // compile the condition
    let Result {bcx: cond_bcx_out, val: cond_val} =
        expr::trans(cond_bcx_in, cond).to_llbool();
    CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, cleanup_llbb);

    // loop body:
    let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
    Br(body_bcx_out, cond_bcx_in.llbb);

    fcx.pop_loop_cleanup_scope(loop_id);
    return next_bcx_in;
}

pub fn trans_loop<'a>(bcx:&'a Block<'a>,
                      loop_id: ast::NodeId,
                      body: &ast::Block)
                      -> &'a Block<'a> {
    let _icx = push_ctxt("trans_loop");
    let fcx = bcx.fcx;

    //            bcx
    //             |
    //         body_bcx_in
    //             |
    //         body_bcx_out
    //
    // next_bcx
    //
    // Links between body_bcx_in and next_bcx are created by
    // break statements.

    let next_bcx_in = bcx.fcx.new_id_block("loop_exit", loop_id);
    let body_bcx_in = bcx.fcx.new_id_block("loop_body", body.id);

    fcx.push_loop_cleanup_scope(loop_id, [next_bcx_in, body_bcx_in]);

    Br(bcx, body_bcx_in.llbb);
    let body_bcx_out = trans_block(body_bcx_in, body, expr::Ignore);
    Br(body_bcx_out, body_bcx_in.llbb);

    fcx.pop_loop_cleanup_scope(loop_id);

    if ty::type_is_bot(node_id_type(bcx, loop_id)) {
        Unreachable(next_bcx_in);
    }

    return next_bcx_in;
}

pub fn trans_break_cont<'a>(bcx: &'a Block<'a>,
                            expr_id: ast::NodeId,
                            opt_label: Option<Ident>,
                            exit: uint)
                            -> &'a Block<'a> {
    let _icx = push_ctxt("trans_break_cont");
    let fcx = bcx.fcx;

    if bcx.unreachable.get() {
        return bcx;
    }

    // Locate loop that we will break to
    let loop_id = match opt_label {
        None => fcx.top_loop_scope(),
        Some(_) => {
            match bcx.tcx().def_map.borrow().find(&expr_id) {
                Some(&def::DefLabel(loop_id)) => loop_id,
                ref r => {
                    bcx.tcx().sess.bug(format!("{:?} in def-map for label",
                                               r).as_slice())
                }
            }
        }
    };

    // Generate appropriate cleanup code and branch
    let cleanup_llbb = fcx.normal_exit_block(loop_id, exit);
    Br(bcx, cleanup_llbb);
    Unreachable(bcx); // anything afterwards should be ignored
    return bcx;
}

pub fn trans_break<'a>(bcx: &'a Block<'a>,
                       expr_id: ast::NodeId,
                       label_opt: Option<Ident>)
                       -> &'a Block<'a> {
    return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_BREAK);
}

pub fn trans_cont<'a>(bcx: &'a Block<'a>,
                      expr_id: ast::NodeId,
                      label_opt: Option<Ident>)
                      -> &'a Block<'a> {
    return trans_break_cont(bcx, expr_id, label_opt, cleanup::EXIT_LOOP);
}

pub fn trans_ret<'a>(bcx: &'a Block<'a>,
                     e: Option<@ast::Expr>)
                     -> &'a Block<'a> {
    let _icx = push_ctxt("trans_ret");
    let fcx = bcx.fcx;
    let mut bcx = bcx;
    let dest = match bcx.fcx.llretptr.get() {
        None => expr::Ignore,
        Some(retptr) => expr::SaveIn(retptr),
    };
    match e {
        Some(x) => {
            bcx = expr::trans_into(bcx, x, dest);
        }
        _ => {}
    }
    let cleanup_llbb = fcx.return_exit_block();
    Br(bcx, cleanup_llbb);
    Unreachable(bcx);
    return bcx;
}

fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
    let ccx = bcx.ccx();
    let s = C_str_slice(ccx, s);
    let slot = alloca(bcx, val_ty(s), "__temp");
    Store(bcx, s, slot);
    slot
}

pub fn trans_fail<'a>(
                  bcx: &'a Block<'a>,
                  sp: Span,
                  fail_str: InternedString)
                  -> &'a Block<'a> {
    let ccx = bcx.ccx();
    let _icx = push_ctxt("trans_fail_value");

    let v_str = str_slice_arg(bcx, fail_str);
    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
    let filename = token::intern_and_get_ident(loc.file.name.as_slice());
    let v_filename = str_slice_arg(bcx, filename);
    let v_line = loc.line as int;
    let args = vec!(v_str, v_filename, C_int(ccx, v_line));
    let did = langcall(bcx, Some(sp), "", FailFnLangItem);
    let bcx = callee::trans_lang_call(bcx,
                                      did,
                                      args.as_slice(),
                                      Some(expr::Ignore)).bcx;
    Unreachable(bcx);
    return bcx;
}

pub fn trans_fail_bounds_check<'a>(
                               bcx: &'a Block<'a>,
                               sp: Span,
                               index: ValueRef,
                               len: ValueRef)
                               -> &'a Block<'a> {
    let _icx = push_ctxt("trans_fail_bounds_check");

    // Extract the file/line from the span
    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
    let filename = token::intern_and_get_ident(loc.file.name.as_slice());

    // Invoke the lang item
    let filename = str_slice_arg(bcx, filename);
    let line = C_int(bcx.ccx(), loc.line as int);
    let args = vec!(filename, line, index, len);
    let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
    let bcx = callee::trans_lang_call(bcx,
                                      did,
                                      args.as_slice(),
                                      Some(expr::Ignore)).bcx;
    Unreachable(bcx);
    return bcx;
}
<|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 libc::{c_void};
#[cfg(unix)]
use libc::{c_uint, c_ulong, c_int};
#[cfg(unix)]
use ptr::null;
#[cfg(windows)]
use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};

#[cfg(unix)]
pub type Key = pthread_key_t;

#[cfg(unix)]
pub unsafe fn create(key: &mut Key) {
    unsafe { fail_unless!(0 == pthread_key_create(key, null())); }
}

#[cfg(unix)]
pub unsafe fn set(key: Key, value: *mut c_void) {
    unsafe { fail_unless!(0 == pthread_setspecific(key, value)); }
}

#[cfg(unix)]
pub unsafe fn get(key: Key) -> *mut c_void {
    unsafe { pthread_getspecific(key) }
}

#[cfg(target_os="macos")]
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = c_ulong;

#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = c_uint;

#[cfg(unix)]
extern {
    fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int;
    fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int;
    fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
}

#[cfg(windows)]
pub type Key = DWORD;

#[cfg(windows)]
pub unsafe fn create(key: &mut Key) {
    const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
    *key = unsafe { TlsAlloc() };
    fail_unless!(*key != TLS_OUT_OF_INDEXES);
}

#[cfg(windows)]
pub unsafe fn set(key: Key, value: *mut c_void) {
    unsafe { fail_unless!(0 != TlsSetValue(key, value)) }
}

#[cfg(windows)]
pub unsafe fn get(key: Key) -> *mut c_void {
    TlsGetValue(key)
}

#[cfg(windows)]
#[abi = "stdcall"]
extern {
       fn TlsAlloc() -> DWORD;
       fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
       fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
}

#[test]
fn tls_smoke_test() {
    use cast::transmute;
    unsafe {
        let mut key = 0;
        let value = ~20;
        create(&mut key);
        set(key, transmute(value));
        let value: ~int = transmute(get(key));
        fail_unless!(value == ~20);
        let value = ~30;
        set(key, transmute(value));
        let value: ~int = transmute(get(key));
        fail_unless!(value == ~30);
    }
}
<commit_msg>auto merge of #5396 : ILyoan/rust/fix_rt_tls, r=graydon<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 libc::{c_void};
#[cfg(unix)]
use libc::{c_uint, c_ulong, c_int};
#[cfg(unix)]
use ptr::null;
#[cfg(windows)]
use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};

#[cfg(unix)]
pub type Key = pthread_key_t;

#[cfg(unix)]
pub unsafe fn create(key: &mut Key) {
    unsafe { fail_unless!(0 == pthread_key_create(key, null())); }
}

#[cfg(unix)]
pub unsafe fn set(key: Key, value: *mut c_void) {
    unsafe { fail_unless!(0 == pthread_setspecific(key, value)); }
}

#[cfg(unix)]
pub unsafe fn get(key: Key) -> *mut c_void {
    unsafe { pthread_getspecific(key) }
}

#[cfg(target_os="macos")]
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = c_ulong;

#[cfg(target_os="linux")]
#[cfg(target_os="freebsd")]
#[cfg(target_os="android")]
#[allow(non_camel_case_types)] // foreign type
type pthread_key_t = c_uint;

#[cfg(unix)]
extern {
    fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int;
    fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int;
    fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
}

#[cfg(windows)]
pub type Key = DWORD;

#[cfg(windows)]
pub unsafe fn create(key: &mut Key) {
    const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
    *key = unsafe { TlsAlloc() };
    fail_unless!(*key != TLS_OUT_OF_INDEXES);
}

#[cfg(windows)]
pub unsafe fn set(key: Key, value: *mut c_void) {
    unsafe { fail_unless!(0 != TlsSetValue(key, value)) }
}

#[cfg(windows)]
pub unsafe fn get(key: Key) -> *mut c_void {
    TlsGetValue(key)
}

#[cfg(windows)]
#[abi = "stdcall"]
extern {
       fn TlsAlloc() -> DWORD;
       fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
       fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
}

#[test]
fn tls_smoke_test() {
    use cast::transmute;
    unsafe {
        let mut key = 0;
        let value = ~20;
        create(&mut key);
        set(key, transmute(value));
        let value: ~int = transmute(get(key));
        fail_unless!(value == ~20);
        let value = ~30;
        set(key, transmute(value));
        let value: ~int = transmute(get(key));
        fail_unless!(value == ~30);
    }
}
<|endoftext|>


<commit_before><commit_msg>test: Add a test for mismatched types of if branches<commit_after>// error-pattern:mismatched types

fn main() {
  auto x = if (true) {
    10
  } else {
    10u
  };
}
<|endoftext|>


<commit_before><commit_msg>parser: don't treat floating properties as errors<commit_after><|endoftext|>


<commit_before><commit_msg>Add problem #102<commit_after>#[link(name = "prob0102", vers = "0.0")];
#[crate_type = "lib"];

extern mod std;
extern mod common;

use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 102,
    answer: "228",
    solver: solve
};

type Point = (int, int);
type Triangle = (Point, Point, Point);

enum Side { L, R, C }

#[inline(alaways)]
fn sub((ax, ay): Point, (bx, by): Point) -> Point { (ax - bx, ay - by) }

#[inline(always)]
fn get_normal(a: Point, b: Point) -> Point {
    let (dx, dy) = sub(b, a);
    return (-dy, dx);
}

#[inline(alawys)]
fn inner_prod((ax, ay): Point, (bx, by): Point) -> int { ax * bx + ay * by }

fn get_side(a: Point, b: Point, p: Point) -> Side {
    let norm = get_normal(b, a);
    return match inner_prod(norm, sub(p, a)).signum() {
        1  => L,
        0  => C,
        -1 => R,
        _  => fail!()
    };
}

fn is_inside((a, b, c): Triangle, p: Point) -> bool {
    match (get_side(a, b, p), get_side(b, c, p), get_side(c, a, p)) {
        (L, L, L) | (L, L, C) | (L, C, L) | (L, C, C)
        | (C, L, L) | (C, L, C) | (C, C, L) | (C, C, C)
        | (R, R, R) | (R, R, C) | (R, C, R) | (R, C, C)
        | (C, R, R) | (C, R, C) | (C, C, R) => true,
        _ => false
    }
}

pub fn solve() -> ~str {
    let result = io::file_reader(&Path("files/triangles.txt"))
        .map(|input| {
            let mut cnt = 0u;
            for input.each_line |line| {
                let mut ns = ~[];
                for line.each_split_char(',') |n| {
                    ns.push(int::from_str(n).get());
                }
                let ps = ((ns[0], ns[1]), (ns[2], ns[3]), (ns[4], ns[5]));
                if is_inside(ps, (0, 0)) { cnt += 1; }
            }
            cnt
        });
    match result {
        Err(msg) => fail!(msg),
        Ok(value) => return value.to_str()
    }
}
<|endoftext|>


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

/*! Type checking. */

use std::collections::HashMap ;

use term::{
  BindMaker, AppMaker, OpMaker, Type, Sym, Term
} ;
use term::zip::* ;
use term::real_term::Var as RVar ;

use super::parse::Context ;

fn checker(
  context: & Context,
  state: & Option<HashMap<Sym, Type>>,
  sig: & Option<HashMap<Sym, Type>>,
  step: Step<(Term, Type)>,
  bindings: & HashMap<Sym, (Term, Type)>,
  quantified: & HashMap<Sym, Type>,
) -> Result<(Term, Type), String> {
  use term::zip::Step::* ;
  match step {

    App(sym, kids) => {
      let (mut nu_kids, mut types) = (
        Vec::with_capacity(kids.len()),
        Vec::with_capacity(kids.len())
      ) ;
      for (term, typ) in kids {
        nu_kids.push(term) ;
        types.push(typ)
      } ;
      match context.get_callable(& sym) {
        Some(fun) => match fun.type_check(& types) {
          Ok(typ) => Ok( (
            context.factory().app(sym, nu_kids), typ
          ) ),
          Err( (arg, bla) ) => return Err(
            format!("{}\nparameter {}:\n  {}", bla, arg, nu_kids[arg])
          ),
        },
        None => return Err(
          format!("application of unknown function symbol {}", sym)
        ),
      }
    },

    Op(op, kids) => {
      let (mut nu_kids, mut types) = (
        Vec::with_capacity(kids.len()),
        Vec::with_capacity(kids.len())
      ) ;
      for (term, typ) in kids {
        nu_kids.push(term) ;
        types.push(typ)
      } ;
      match op.type_check(& types) {
        Ok(typ) => Ok( (
          context.factory().op(op, nu_kids), typ
        ) ),
        Err( (args, mut bla) ) => {
          if let Some(args) = args {
            for arg in args {
              bla = format!("{}\nargument {}:\n  {}", bla, arg, nu_kids[arg])
            } ;
          } ;
          return Err(bla)
        },
      }
    },

    Let(bindings, (kid, typ)) => {
      let mut nu_bindings = Vec::with_capacity(bindings.len()) ;
      for (sym, (term,_)) in bindings {
        nu_bindings.push( (sym, term) )
      } ;
      Ok( (
        context.factory().let_b(nu_bindings, kid), typ
      ) )
    },

    Forall(qf, (kid, typ)) => {
      if typ != Type::Bool {
        return Err(
          format!(
            "forall quantifier expects Bool but got {}\n\
              argument:\n  {}",
            typ, kid
          )
        )
      } ;
      Ok( (
        context.factory().forall(qf, kid), typ
      ) )
    },

    Exists(qf, (kid, typ)) => {
      if typ != Type::Bool {
        return Err(
          format!(
            "exists quantifier expects Bool but got {}\n\
              argument:\n  {}",
            typ, kid
          )
        )
      } ;
      Ok( (
        context.factory().exists(qf, kid), typ
      ) )
    },

    C(cst) => {
      let typ = cst.typ().clone() ;
      Ok( (context.factory().mk_cst(cst), typ) )
    },

    V(var) => {
      let typ = match * var.get() {
        RVar::SVar(ref sym, _) => {
          if let Some(ref state) = * state {
            if let Some(typ) = state.get(sym) {
              typ.clone()
            } else {
              return Err(
                format!("unknown state variable {}", sym)
              )
            }
          } else {
            return Err(
              format!("unexpected state variable ({})", sym)
            )
          }
        },
        RVar::Var(ref sym) => {
          match if let Some(ref sig) = * sig {
            if let Some(typ) = sig.get(sym) {
              Some( typ.clone() )
            } else {
              None
            }
          } else { None } {
            Some(typ) => typ,
            None => {
              match context.get_callable(& sym) {
                Some(fun) => match fun.type_check(& []) {
                  Ok(typ) => typ,
                  Err( (_, bla) ) => return Err( format!("{}", bla) ),
                },
                None => {
                  if let Some( & (_, typ) ) = bindings.get(sym) {
                    typ.clone()
                  } else {
                  if let Some(typ) = quantified.get(sym) { typ.clone() } else {
                      return Err(format!("unknown symbol {}", sym))
                    }
                  }
                }
              }
            }
          }
        },
      } ;
      Ok( ( context.factory().mk_var(var), typ ) )
    },
  }
}

/** Type checks a term. */
pub fn type_check(
  ctxt: & Context, term: & Term,
  state: Option<& [ (Sym, Type) ]>,
  sig: Option<& [ (Sym, Type) ]>,
) -> Result<Type, String> {
  let state = match state {
    None => None,
    Some(state) => {
      let mut map = HashMap::with_capacity(state.len()) ;
      for & (ref sym, ref typ) in state.iter() {
        map.insert(sym.clone(), typ.clone()) ; ()
      } ;
      Some(map)
    },
  } ;
  let sig = match sig {
    None => None,
    Some(sig) => {
      let mut map = HashMap::with_capacity(sig.len()) ;
      for & (ref sym, ref typ) in sig.iter() {
        map.insert(sym.clone(), typ.clone()) ; ()
      } ;
      Some(map)
    },
  } ;
  match ::term::zip::fold_info(
    move |step, binding, quantified| checker(
      ctxt, & state, & sig, step, binding, quantified
    ),
    term
  ) {
    Ok( (_, typ) ) => Ok(typ),
    Err(e) => Err(e),
  }
}<|endoftext|>


<commit_before><commit_msg>add regression test for #70586<commit_after>// check-pass
#![feature(const_generics)]
#![allow(incomplete_features)]

use std::marker::PhantomData;

// This namespace is necessary for the ICE to trigger
struct Namespace;

impl Namespace {
    pub fn const_chunks_exact<T, const N: usize>() -> ConstChunksExact<'static, T, N> {
        ConstChunksExact { inner: PhantomData }
    }
}

#[derive(Debug)]
pub struct ConstChunksExact<'a, T, const N: usize> {
    inner:  PhantomData<&'a T>
}

impl <'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
    type Item = &'a [T; N];

    fn next(&mut self) -> Option<Self::Item> {
        unreachable!()
    }
}

fn main() {
    let mut chunks = Namespace::const_chunks_exact::<i32, 3usize>();
    let _next: &[i32; 3] = chunks.next().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Rustfmt.<commit_after><|endoftext|>


<commit_before>//! Solvent is a dependency resolver library written in rust.
//!
//! Solvent helps you to resolve dependency orderings by building up a dependency graph and then
//! resolving the dependences of some target node in an order such that each output depends only
//! upon the previous outputs.
//!
//! It is currently quite simple, but is still useful.
//!
//! #Example
//!
//! ```rust
//! extern crate solvent;
//!
//! use solvent::DepGraph;
//!
//! fn main() {
//!     // Create a new empty DepGraph.
//!     let mut depgraph: DepGraph<&str> = DepGraph::new();
//!
//!     // You can register a dependency like this. Solvent will automatically create nodes for
//!     // any term it has not seen before. This means 'b' depends on 'd'
//!     depgraph.register_dependency("b","d");
//!
//!     // You can also register multiple dependencies at once
//!     depgraph.register_dependencies("a",&["b","c","d"]);
//!     depgraph.register_dependencies("c",&["e"]);
//!
//!     // Iterate through each dependency of "a". The dependencies will be returned in an order
//!     // such that each output only depends on the previous outputs (or nothing). The target
//!     // itself will be output last.
//!     for node in depgraph.dependencies_of("a") {
//!         match node {
//!             Ok(n) => print!("{} ", n),
//!             Err(e) => panic!("Solvent error detected: {:?}", e),
//!         }
//!     }
//! }
//! ```
//!
//! The above will output:  `d b e c a` or `e c d b a` or some other valid dependency order.
//!
//! The algorithm is not deterministic, and may give a different answer each time it is run. Beware.
//!
//! The iterator dependencies_of() returns an `Option<Result<E ,SolventError>>`.  The for loop
//! handles the `Option` part for you, but you may want to check the result for `SolventError`s.
//! Once an error is returned, all subsequent calls to the iterator `next()` will yield `None`.
//!
//! You can also mark some elements as already satisfied, and the iterator will take that into
//! account
//!
//! ```ignore
//! depgraph.mark_as_satisfied(["e","c"]);
//! ```
//!
//! Dependency cycles are detected and will return `SolventError::CycleDetected`.

use std::collections::{HashMap,HashSet};
use std::collections::hash_map::Entry;
use std::iter::{Iterator};
use std::fmt;
use std::error::Error;
use std::hash::Hash;

#[derive(Clone,Debug,PartialEq)]
pub enum SolventError {
    /// A cycle has been detected
    CycleDetected,
}

impl fmt::Display for SolventError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            _ => self.description().fmt(f)
        }
    }
}

impl Error for SolventError {
    fn description(&self) -> &str
    {
        match *self {
            SolventError::CycleDetected => "Cycle Detected",
        }
    }
    fn cause(&self) -> Option<&Error> {
        match *self {
            _ => None
        }
    }
}

/// This is the dependency graph
#[derive(Debug,Clone)]
pub struct DepGraph<E: Eq + Copy + Hash> {
    /// List of dependencies. The first Element depends on the set of additional Elements.
    pub dependencies: HashMap<E,HashSet<E>>,

    /// The set of Elements already satisfied.
    pub satisfied: HashSet<E>,
}

impl<E: Eq + Copy + Hash> DepGraph<E> {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph<E> {
        DepGraph {
            dependencies: HashMap::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph. The node does not need to pre-exist, nor do the dependency
    /// nodes. But if the node does pre-exist, the depends_on will be added to its existing
    /// dependency list.
    pub fn register_dependency(&mut self, node: E, depends_on: E) {
        match self.dependencies.entry( node ) {
            Entry::Vacant(entry) => {
                let mut deps = HashSet::with_capacity(1);
                deps.insert( depends_on );
                entry.insert( deps );
            },
            Entry::Occupied(mut entry) => {
                (*entry.get_mut()).insert( depends_on );
            },
        }
    }

    /// Add multiple dependencies of one node to a DepGraph. The node does not need to pre-exist,
    /// nor do the dependency elements. But if the node does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies(&mut self, node: E, depends_on: &[E]) {
        match self.dependencies.entry( node ) {
            Entry::Vacant(entry) => {
                let mut deps: HashSet<E> = HashSet::with_capacity( depends_on.len() );
                for dep in depends_on.iter() {
                    deps.insert( *dep );
                }
                entry.insert( deps );
            },
            Entry::Occupied(mut entry) => {
                for dep in depends_on.iter() {
                    (*entry.get_mut()).insert( *dep );
                }
            },
        }
    }

    /// This marks a node as satisfied.  Iterators will not output such nodes.
    pub fn mark_as_satisfied(&mut self, nodes: &[E]) {
        for node in nodes.iter() {
            self.satisfied.insert( *node );
        }
    }

    /// Get an iterator to iterate through the dependencies of the target node.
    pub fn dependencies_of<'a>(&'a self, target: E) -> DepGraphIterator<'a, E>
    {
        // TODO: iterator's satisfied could start empty, and all checks
        //       could separately check depgraph's and iterator's.  That
        //       would avoid the copy.
        DepGraphIterator {
            depgraph: self,
            target: target,
            satisfied: self.satisfied.clone(),
            curpath: HashSet::new(),
            halted: false,
        }
    }
}

/// This iterates through the dependencies of the DepGraph's target
pub struct DepGraphIterator<'a, E: Eq + Copy + Hash + 'a> {
    depgraph: &'a DepGraph<E>,

    // Target we are trying to satisfy
    target: E,

    // Elements already satisfied during this iterator's walk
    satisfied: HashSet<E>,

    // Current path, for cycle detection
    curpath: HashSet<E>,

    // Halted.  Used so that it can return None after an Err is returned.
    halted: bool,
}

impl<'a, E: Eq + Copy + Hash> DepGraphIterator<'a, E> {

    fn get_next_dependency(&mut self, node: E) -> Result<E,SolventError>
    {
        if self.curpath.contains(&node) {
            return Err(SolventError::CycleDetected);
        }
        self.curpath.insert(node);

        let deplist = match self.depgraph.dependencies.get(&node) {
            None => return Ok(node),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            // Prune satisfied nodes
            if self.satisfied.contains(n) {
                continue;
            }

            return self.get_next_dependency(*n);
        }
        // nodes dependencies are satisfied
        Ok(node)
    }
}

impl<'a, E: Eq + Copy + Hash> Iterator for DepGraphIterator<'a,E> {
    type Item = Result<E,SolventError>;

    /// Get next dependency.  Returns None when finished.  If Some(Err(SolventError)) occurs, all
    // subsequent calls will return None.
    fn next(&mut self) -> Option<Result<E,SolventError>>
    {
        if self.halted {
            return None;
        }

        let node = self.target.clone();
        if self.satisfied.contains(&node) {
            return None;
        }

        self.curpath.clear();
        let next = match self.get_next_dependency(node) {
            Ok(d) => d,
            Err(e) => {
                self.halted = true;
                return Some(Err(e));
            }
        };
        self.satisfied.insert(next);
        Some(Ok(next))
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashSet;
    use super::{SolventError,DepGraph};

    #[test]
    fn solvent_test_branching() {
        let mut depgraph: DepGraph<&str> = DepGraph::new();

        depgraph.register_dependencies("a",&["b","c","d"]);
        depgraph.register_dependency("b","d");
        depgraph.register_dependencies("c",&["e","m","g"]);
        depgraph.register_dependency("e","f");
        depgraph.register_dependency("g","h");
        depgraph.register_dependency("h","i");
        depgraph.register_dependencies("i",&["j","k"]);
        depgraph.register_dependencies("k",&["l","m"]);
        depgraph.register_dependency("m","n");

        let mut results: Vec<&str> = Vec::new();

        for node in depgraph.dependencies_of("a") {
            // detect infinite looping bugs
            assert!(results.len() < 30);

            let n = match node {
                Err(e) => panic!("Solvent error detected: {:?}", e),
                Ok(n) => n,
            };

            // Check that all of that nodes dependencies have already been output
            let deps: Option<&HashSet<&str>> = depgraph.dependencies.get(&n);
            if deps.is_some() {
                for dep in deps.unwrap().iter() {
                    assert!( results.contains(dep) );
                }
            }

            results.push(n.clone());
        }

        // Be sure we actually output enough stuff
        assert!(results.len() == 14);

        // Be sure each output is unique
        for result in results.iter() {
            let mut count: usize = 0;
            for result2 in results.iter() {
                if result == result2 { count = count + 1; }
            }
            assert!(count == 1);
        }
    }

    #[test]
    fn solvent_test_updating_dependencies() {
        let mut depgraph: DepGraph<&str> = DepGraph::new();

        depgraph.register_dependencies("a",&["b","c"]);
        depgraph.register_dependency("a","d");
        assert!(depgraph.dependencies.get("a").unwrap().contains("b"));
        assert!(depgraph.dependencies.get("a").unwrap().contains("c"));
        assert!(depgraph.dependencies.get("a").unwrap().contains("d"));
    }

    #[test]
    fn solvent_test_circular() {

        let mut depgraph: DepGraph<&str> = DepGraph::new();
        depgraph.register_dependency("a","b");
        depgraph.register_dependency("b","c");
        depgraph.register_dependency("c","a");

        for node in depgraph.dependencies_of("a") {
            assert!(node.is_err());
            assert!(node.unwrap_err() == SolventError::CycleDetected);
        }
    }

    #[test]
    fn solvent_test_satisfied_stoppage() {

        let mut depgraph: DepGraph<&str> = DepGraph::new();
        depgraph.register_dependencies("superconn", &[]);
        depgraph.register_dependencies("owneruser", &["superconn"]);
        depgraph.register_dependencies("appuser", &["superconn"]);
        depgraph.register_dependencies("database", &["owneruser"]);
        depgraph.register_dependencies("ownerconn", &["database","owneruser"]);
        depgraph.register_dependencies("adminconn", &["database"]);
        depgraph.register_dependencies("extensions", &["database","adminconn"]);
        depgraph.register_dependencies("schema_table", &["database","ownerconn"]);
        depgraph.register_dependencies("schemas", &["ownerconn","extensions","schema_table","appuser"]);
        depgraph.register_dependencies("appconn", &["database","appuser","schemas"]);

        depgraph.mark_as_satisfied(&["owneruser","appuser"]);

        let mut results: Vec<&str> = Vec::new();

        for node in depgraph.dependencies_of("appconn") {
            assert!(results.len() < 30);
            match node {
                Ok(n) => results.push(n),
                Err(e) => panic!("Solvent error detected: {:?}",e),
            };
        }

        // Be sure we did not depend on these
        assert!( !results.contains( &"appuser") );
        assert!( !results.contains( &"owneruser") );
        assert!( !results.contains( &"superconn") );

        // Be sure we actually output enough stuff
        assert!(results.len() == 7);

        // Be sure each output is unique
        for result in results.iter() {
            let mut count: usize = 0;
            for result2 in results.iter() {
                if result == result2 { count = count + 1; }
            }
            assert!(count == 1);
        }
    }
}
<commit_msg>Change type parameter to T<commit_after>//! Solvent is a dependency resolver library written in rust.
//!
//! Solvent helps you to resolve dependency orderings by building up a dependency graph and then
//! resolving the dependences of some target node in an order such that each output depends only
//! upon the previous outputs.
//!
//! It is currently quite simple, but is still useful.
//!
//! #Example
//!
//! ```rust
//! extern crate solvent;
//!
//! use solvent::DepGraph;
//!
//! fn main() {
//!     // Create a new empty DepGraph.
//!     let mut depgraph: DepGraph<&str> = DepGraph::new();
//!
//!     // You can register a dependency like this. Solvent will automatically create nodes for
//!     // any term it has not seen before. This means 'b' depends on 'd'
//!     depgraph.register_dependency("b","d");
//!
//!     // You can also register multiple dependencies at once
//!     depgraph.register_dependencies("a",&["b","c","d"]);
//!     depgraph.register_dependencies("c",&["e"]);
//!
//!     // Iterate through each dependency of "a". The dependencies will be returned in an order
//!     // such that each output only depends on the previous outputs (or nothing). The target
//!     // itself will be output last.
//!     for node in depgraph.dependencies_of("a") {
//!         match node {
//!             Ok(n) => print!("{} ", n),
//!             Err(e) => panic!("Solvent error detected: {:?}", e),
//!         }
//!     }
//! }
//! ```
//!
//! The above will output:  `d b e c a` or `e c d b a` or some other valid dependency order.
//!
//! The algorithm is not deterministic, and may give a different answer each time it is run. Beware.
//!
//! The iterator dependencies_of() returns an `Option<Result<T ,SolventError>>`.  The for loop
//! handles the `Option` part for you, but you may want to check the result for `SolventError`s.
//! Once an error is returned, all subsequent calls to the iterator `next()` will yield `None`.
//!
//! You can also mark some elements as already satisfied, and the iterator will take that into
//! account
//!
//! ```ignore
//! depgraph.mark_as_satisfied(["e","c"]);
//! ```
//!
//! Dependency cycles are detected and will return `SolventError::CycleDetected`.

use std::collections::{HashMap,HashSet};
use std::collections::hash_map::Entry;
use std::iter::{Iterator};
use std::fmt;
use std::error::Error;
use std::hash::Hash;

#[derive(Clone,Debug,PartialEq)]
pub enum SolventError {
    /// A cycle has been detected
    CycleDetected,
}

impl fmt::Display for SolventError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            _ => self.description().fmt(f)
        }
    }
}

impl Error for SolventError {
    fn description(&self) -> &str
    {
        match *self {
            SolventError::CycleDetected => "Cycle Detected",
        }
    }
    fn cause(&self) -> Option<&Error> {
        match *self {
            _ => None
        }
    }
}

/// This is the dependency graph
#[derive(Debug,Clone)]
pub struct DepGraph<T: Eq + Copy + Hash> {
    /// List of dependencies. The first Element depends on the set of additional Elements.
    pub dependencies: HashMap<T, HashSet<T>>,

    /// The set of Elements already satisfied.
    pub satisfied: HashSet<T>,
}

impl<T: Eq + Copy + Hash> DepGraph<T> {

    /// Create an empty DepGraph.
    pub fn new() -> DepGraph<T> {
        DepGraph {
            dependencies: HashMap::new(),
            satisfied: HashSet::new(),
        }
    }

    /// Add a dependency to a DepGraph. The node does not need to pre-exist, nor do the dependency
    /// nodes. But if the node does pre-exist, the depends_on will be added to its existing
    /// dependency list.
    pub fn register_dependency(&mut self, node: T, depends_on: T) {
        match self.dependencies.entry( node ) {
            Entry::Vacant(entry) => {
                let mut deps = HashSet::with_capacity(1);
                deps.insert( depends_on );
                entry.insert( deps );
            },
            Entry::Occupied(mut entry) => {
                (*entry.get_mut()).insert( depends_on );
            },
        }
    }

    /// Add multiple dependencies of one node to a DepGraph. The node does not need to pre-exist,
    /// nor do the dependency elements. But if the node does pre-exist, the depends_on will be added
    /// to its existing dependency list.
    pub fn register_dependencies(&mut self, node: T, depends_on: &[T]) {
        match self.dependencies.entry( node ) {
            Entry::Vacant(entry) => {
                let mut deps: HashSet<T> = HashSet::with_capacity( depends_on.len() );
                for dep in depends_on.iter() {
                    deps.insert( *dep );
                }
                entry.insert( deps );
            },
            Entry::Occupied(mut entry) => {
                for dep in depends_on.iter() {
                    (*entry.get_mut()).insert( *dep );
                }
            },
        }
    }

    /// This marks a node as satisfied.  Iterators will not output such nodes.
    pub fn mark_as_satisfied(&mut self, nodes: &[T]) {
        for node in nodes.iter() {
            self.satisfied.insert( *node );
        }
    }

    /// Get an iterator to iterate through the dependencies of the target node.
    pub fn dependencies_of<'a>(&'a self, target: T) -> DepGraphIterator<'a, T>
    {
        // TODO: iterator's satisfied could start empty, and all checks
        //       could separately check depgraph's and iterator's.  That
        //       would avoid the copy.
        DepGraphIterator {
            depgraph: self,
            target: target,
            satisfied: self.satisfied.clone(),
            curpath: HashSet::new(),
            halted: false,
        }
    }
}

/// This iterates through the dependencies of the DepGraph's target
pub struct DepGraphIterator<'a, T: Eq + Copy + Hash + 'a> {
    depgraph: &'a DepGraph<T>,

    // Target we are trying to satisfy
    target: T,

    // Elements already satisfied during this iterator's walk
    satisfied: HashSet<T>,

    // Current path, for cycle detection
    curpath: HashSet<T>,

    // Halted.  Used so that it can return None after an Err is returned.
    halted: bool,
}

impl<'a, T: Eq + Copy + Hash> DepGraphIterator<'a, T> {

    fn get_next_dependency(&mut self, node: T) -> Result<T,SolventError>
    {
        if self.curpath.contains(&node) {
            return Err(SolventError::CycleDetected);
        }
        self.curpath.insert(node);

        let deplist = match self.depgraph.dependencies.get(&node) {
            None => return Ok(node),
            Some(deplist) => deplist.clone() // ouch
        };

        for n in deplist.iter() {
            // Prune satisfied nodes
            if self.satisfied.contains(n) {
                continue;
            }

            return self.get_next_dependency(*n);
        }
        // nodes dependencies are satisfied
        Ok(node)
    }
}

impl<'a, T: Eq + Copy + Hash> Iterator for DepGraphIterator<'a, T> {
    type Item = Result<T, SolventError>;

    /// Get next dependency.  Returns None when finished.  If Some(Err(SolventError)) occurs, all
    // subsequent calls will return None.
    fn next(&mut self) -> Option<Result<T, SolventError>>
    {
        if self.halted {
            return None;
        }

        let node = self.target.clone();
        if self.satisfied.contains(&node) {
            return None;
        }

        self.curpath.clear();
        let next = match self.get_next_dependency(node) {
            Ok(d) => d,
            Err(e) => {
                self.halted = true;
                return Some(Err(e));
            }
        };
        self.satisfied.insert(next);
        Some(Ok(next))
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashSet;
    use super::{SolventError,DepGraph};

    #[test]
    fn solvent_test_branching() {
        let mut depgraph: DepGraph<&str> = DepGraph::new();

        depgraph.register_dependencies("a",&["b","c","d"]);
        depgraph.register_dependency("b","d");
        depgraph.register_dependencies("c",&["e","m","g"]);
        depgraph.register_dependency("e","f");
        depgraph.register_dependency("g","h");
        depgraph.register_dependency("h","i");
        depgraph.register_dependencies("i",&["j","k"]);
        depgraph.register_dependencies("k",&["l","m"]);
        depgraph.register_dependency("m","n");

        let mut results: Vec<&str> = Vec::new();

        for node in depgraph.dependencies_of("a") {
            // detect infinite looping bugs
            assert!(results.len() < 30);

            let n = match node {
                Err(e) => panic!("Solvent error detected: {:?}", e),
                Ok(n) => n,
            };

            // Check that all of that nodes dependencies have already been output
            let deps: Option<&HashSet<&str>> = depgraph.dependencies.get(&n);
            if deps.is_some() {
                for dep in deps.unwrap().iter() {
                    assert!( results.contains(dep) );
                }
            }

            results.push(n.clone());
        }

        // Be sure we actually output enough stuff
        assert!(results.len() == 14);

        // Be sure each output is unique
        for result in results.iter() {
            let mut count: usize = 0;
            for result2 in results.iter() {
                if result == result2 { count = count + 1; }
            }
            assert!(count == 1);
        }
    }

    #[test]
    fn solvent_test_updating_dependencies() {
        let mut depgraph: DepGraph<&str> = DepGraph::new();

        depgraph.register_dependencies("a",&["b","c"]);
        depgraph.register_dependency("a","d");
        assert!(depgraph.dependencies.get("a").unwrap().contains("b"));
        assert!(depgraph.dependencies.get("a").unwrap().contains("c"));
        assert!(depgraph.dependencies.get("a").unwrap().contains("d"));
    }

    #[test]
    fn solvent_test_circular() {

        let mut depgraph: DepGraph<&str> = DepGraph::new();
        depgraph.register_dependency("a","b");
        depgraph.register_dependency("b","c");
        depgraph.register_dependency("c","a");

        for node in depgraph.dependencies_of("a") {
            assert!(node.is_err());
            assert!(node.unwrap_err() == SolventError::CycleDetected);
        }
    }

    #[test]
    fn solvent_test_satisfied_stoppage() {

        let mut depgraph: DepGraph<&str> = DepGraph::new();
        depgraph.register_dependencies("superconn", &[]);
        depgraph.register_dependencies("owneruser", &["superconn"]);
        depgraph.register_dependencies("appuser", &["superconn"]);
        depgraph.register_dependencies("database", &["owneruser"]);
        depgraph.register_dependencies("ownerconn", &["database","owneruser"]);
        depgraph.register_dependencies("adminconn", &["database"]);
        depgraph.register_dependencies("extensions", &["database","adminconn"]);
        depgraph.register_dependencies("schema_table", &["database","ownerconn"]);
        depgraph.register_dependencies("schemas", &["ownerconn","extensions","schema_table","appuser"]);
        depgraph.register_dependencies("appconn", &["database","appuser","schemas"]);

        depgraph.mark_as_satisfied(&["owneruser","appuser"]);

        let mut results: Vec<&str> = Vec::new();

        for node in depgraph.dependencies_of("appconn") {
            assert!(results.len() < 30);
            match node {
                Ok(n) => results.push(n),
                Err(e) => panic!("Solvent error detected: {:?}",e),
            };
        }

        // Be sure we did not depend on these
        assert!( !results.contains( &"appuser") );
        assert!( !results.contains( &"owneruser") );
        assert!( !results.contains( &"superconn") );

        // Be sure we actually output enough stuff
        assert!(results.len() == 7);

        // Be sure each output is unique
        for result in results.iter() {
            let mut count: usize = 0;
            for result2 in results.iter() {
                if result == result2 { count = count + 1; }
            }
            assert!(count == 1);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add more context in error messages<commit_after><|endoftext|>


<commit_before><commit_msg>Add some proper tests for the builder.<commit_after><|endoftext|>


<commit_before><commit_msg>examples: add a layout example<commit_after>extern crate textwrap;

use textwrap::wrap;

fn main() {
    let example = "
Memory safety without garbage collection.
Concurrency without data races.
Zero-cost abstractions.
";
    let mut prev_lines = vec![];
    for width in 15..60 {
        let lines = wrap(example, width);
        if lines != prev_lines {
            let title = format!(" Width: {} ", width);
            println!(".{:-^1$}.", title, width + 2);
            for line in &lines {
                println!("| {:1$} |", line, width);
            }
            prev_lines = lines;
        }
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::io::Write;
use std::io::stderr;

use ansi_term::Colour::Red;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Convenience function: calls `trace_error()` with `e` and afterwards `std::process::exit()`
/// with `code`
pub fn trace_error_exit(e: &Error, code: i32) -> ! {
    use std::process::exit;

    debug!("Tracing error...");
    trace_error(e);
    debug!("Calling exit()");
    exit(code);
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    let msg = Red.blink().paint(format!("{}/{} Levels of errors will be printed\n",
                                        (if max > n { n } else { max }), n));
    write!(stderr(), "{}", msg).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        e.cause().map(|cause| {
            match print_trace_maxdepth(idx - 1, cause, max) {
                None    => write!(stderr(), "\n").ok(),
                Some(_) => write!(stderr(), " -- caused:\n").ok(),
            };
        });
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e.description()).ok();
    e.cause()
}

/// Count errors in `Error::cause()` recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + e.cause().map(|c| count_error_causes(c)).unwrap_or(0)
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", idx)), e.description());
    if e.cause().is_some() {
        print_trace_dbg(idx + 1, e.cause().unwrap());
    }
}

<commit_msg>Replace unwrap() with map()<commit_after>use std::error::Error;
use std::io::Write;
use std::io::stderr;

use ansi_term::Colour::Red;

/// Print an Error type and its cause recursively
///
/// The error is printed with "Error NNNN :" as prefix, where "NNNN" is a number which increases
/// which each recursion into the errors cause. The error description is used to visualize what
/// failed and if there is a cause "-- caused by:" is appended, and the cause is printed on the next
/// line.
///
/// Example output:
///
/// ```ignore
/// Error    1 : Some error -- caused by:
/// Error    2 : Some other error -- caused by:
/// Error    3 : Yet another Error -- caused by:
/// ...
///
/// Error <NNNN> : <Error description>
/// ```
pub fn trace_error(e: &Error) {
    print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
    write!(stderr(), "\n").ok();
}

/// Convenience function: calls `trace_error()` with `e` and afterwards `std::process::exit()`
/// with `code`
pub fn trace_error_exit(e: &Error, code: i32) -> ! {
    use std::process::exit;

    debug!("Tracing error...");
    trace_error(e);
    debug!("Calling exit()");
    exit(code);
}

/// Print an Error type and its cause recursively, but only `max` levels
///
/// Output is the same as for `trace_error()`, though there are only `max` levels printed.
pub fn trace_error_maxdepth(e: &Error, max: u64) {
    let n = count_error_causes(e);
    let msg = Red.blink().paint(format!("{}/{} Levels of errors will be printed\n",
                                        (if max > n { n } else { max }), n));
    write!(stderr(), "{}", msg).ok();
    print_trace_maxdepth(n, e, max);
    write!(stderr(), "").ok();
}

/// Print an Error type and its cause recursively with the debug!() macro
///
/// Output is the same as for `trace_error()`.
pub fn trace_error_dbg(e: &Error) {
    print_trace_dbg(0, e);
}

/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
///
/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
/// processed.
fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
    if e.cause().is_some() && idx > 0 {
        e.cause().map(|cause| {
            match print_trace_maxdepth(idx - 1, cause, max) {
                None    => write!(stderr(), "\n").ok(),
                Some(_) => write!(stderr(), " -- caused:\n").ok(),
            };
        });
    } else {
        write!(stderr(), "\n").ok();
    }
    write!(stderr(), "{}: {}", Red.paint(format!("ERROR[{:>4}]", idx)), e.description()).ok();
    e.cause()
}

/// Count errors in `Error::cause()` recursively
fn count_error_causes(e: &Error) -> u64 {
    1 + e.cause().map(|c| count_error_causes(c)).unwrap_or(0)
}

fn print_trace_dbg(idx: u64, e: &Error) {
    debug!("{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", idx)), e.description());
    if e.cause().is_some() {
        e.cause().map(|c| print_trace_dbg(idx + 1, c));
    }
}

<|endoftext|>


<commit_before><commit_msg>Format single_transfer() to pass rustfmt<commit_after><|endoftext|>