<commit_before>//! Definition of the JoinAll combinator, waiting for all of a list of futures
//! to finish.

use std::prelude::v1::*;

use std::mem;

use {Future, IntoFuture, Poll, Async};

enum ElemState<T> where T: Future {
    Pending(T),
    Done(T::Item),
}

/// A future which takes a list of futures and resolves with a vector of the
/// completed values.
///
/// This future is created with the `join_all` method.
#[must_use = "futures do nothing unless polled"]
pub struct JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    elems: Vec<ElemState<<I::Item as IntoFuture>::Future>>,
}

/// Creates a future which represents a collection of the results of the futures
/// given.
///
/// The returned future will drive execution for all of its underlying futures,
/// collecting the results into a destination `Vec<T>`. If any future returns
/// an error then all other futures will be canceled and an error will be
/// returned immediately. If all futures complete successfully, however, then
/// the returned future will succeed with a `Vec` of all the successful results.
///
/// Note that this function does **not** attempt to execute each future in
/// parallel, they are all executed in sequence.
///
/// # Examples
///
/// ```
/// use futures::future::*;
///
/// let f = join_all(vec![
///     ok::<u32, u32>(1),
///     ok::<u32, u32>(2),
///     ok::<u32, u32>(3),
/// ]);
/// let f = f.map(|x| {
///     assert_eq!(x, [1, 2, 3]);
/// });
///
/// let f = join_all(vec![
///     ok::<u32, u32>(1).boxed(),
///     err::<u32, u32>(2).boxed(),
///     ok::<u32, u32>(3).boxed(),
/// ]);
/// let f = f.then(|x| {
///     assert_eq!(x, Err(2));
///     x
/// });
/// ```
pub fn join_all<I>(i: I) -> JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    let elems = i.into_iter().map(|f| {
        ElemState::Pending(f.into_future())
    }).collect();
    JoinAll { elems: elems }
}

impl<I> Future for JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    type Item = Vec<<I::Item as IntoFuture>::Item>;
    type Error = <I::Item as IntoFuture>::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let mut all_done = true;

        for idx in 0 .. self.elems.len() {
            let done_val = match &mut self.elems[idx] {
                &mut ElemState::Pending(ref mut t) => {
                    match t.poll() {
                        Ok(Async::Ready(v)) => Ok(v),
                        Ok(Async::NotReady) => {
                            all_done = false;
                            continue
                        }
                        Err(e) => Err(e),
                    }
                }
                &mut ElemState::Done(ref mut _v) => continue,
            };

            match done_val {
                Ok(v) => self.elems[idx] = ElemState::Done(v),
                Err(e) => {
                    // On completion drop all our associated resources
                    // ASAP.
                    self.elems = Vec::new();
                    return Err(e)
                }
            }
        }

        if all_done {
            let elems = mem::replace(&mut self.elems, Vec::new());
            let result = elems.into_iter().map(|e| {
                match e {
                    ElemState::Done(t) => t,
                    _ => unreachable!(),
                }
            }).collect();
            Ok(Async::Ready(result))
        } else {
            Ok(Async::NotReady)
        }
    }
}
<commit_msg>Remove obsolete comment in join_all() docs.<commit_after>//! Definition of the JoinAll combinator, waiting for all of a list of futures
//! to finish.

use std::prelude::v1::*;

use std::mem;

use {Future, IntoFuture, Poll, Async};

enum ElemState<T> where T: Future {
    Pending(T),
    Done(T::Item),
}

/// A future which takes a list of futures and resolves with a vector of the
/// completed values.
///
/// This future is created with the `join_all` method.
#[must_use = "futures do nothing unless polled"]
pub struct JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    elems: Vec<ElemState<<I::Item as IntoFuture>::Future>>,
}

/// Creates a future which represents a collection of the results of the futures
/// given.
///
/// The returned future will drive execution for all of its underlying futures,
/// collecting the results into a destination `Vec<T>`. If any future returns
/// an error then all other futures will be canceled and an error will be
/// returned immediately. If all futures complete successfully, however, then
/// the returned future will succeed with a `Vec` of all the successful results.
///
/// # Examples
///
/// ```
/// use futures::future::*;
///
/// let f = join_all(vec![
///     ok::<u32, u32>(1),
///     ok::<u32, u32>(2),
///     ok::<u32, u32>(3),
/// ]);
/// let f = f.map(|x| {
///     assert_eq!(x, [1, 2, 3]);
/// });
///
/// let f = join_all(vec![
///     ok::<u32, u32>(1).boxed(),
///     err::<u32, u32>(2).boxed(),
///     ok::<u32, u32>(3).boxed(),
/// ]);
/// let f = f.then(|x| {
///     assert_eq!(x, Err(2));
///     x
/// });
/// ```
pub fn join_all<I>(i: I) -> JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    let elems = i.into_iter().map(|f| {
        ElemState::Pending(f.into_future())
    }).collect();
    JoinAll { elems: elems }
}

impl<I> Future for JoinAll<I>
    where I: IntoIterator,
          I::Item: IntoFuture,
{
    type Item = Vec<<I::Item as IntoFuture>::Item>;
    type Error = <I::Item as IntoFuture>::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let mut all_done = true;

        for idx in 0 .. self.elems.len() {
            let done_val = match &mut self.elems[idx] {
                &mut ElemState::Pending(ref mut t) => {
                    match t.poll() {
                        Ok(Async::Ready(v)) => Ok(v),
                        Ok(Async::NotReady) => {
                            all_done = false;
                            continue
                        }
                        Err(e) => Err(e),
                    }
                }
                &mut ElemState::Done(ref mut _v) => continue,
            };

            match done_val {
                Ok(v) => self.elems[idx] = ElemState::Done(v),
                Err(e) => {
                    // On completion drop all our associated resources
                    // ASAP.
                    self.elems = Vec::new();
                    return Err(e)
                }
            }
        }

        if all_done {
            let elems = mem::replace(&mut self.elems, Vec::new());
            let result = elems.into_iter().map(|e| {
                match e {
                    ElemState::Done(t) => t,
                    _ => unreachable!(),
                }
            }).collect();
            Ok(Async::Ready(result))
        } else {
            Ok(Async::NotReady)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove redundant OverlapsWith trait<commit_after><|endoftext|>


<commit_before><commit_msg>Formatting<commit_after><|endoftext|>


<commit_before><commit_msg>Remove old comment<commit_after><|endoftext|>


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

use lib::llvm::*;
use driver::config::FullDebugInfo;
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);

    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(&ast::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>Mark the exit of infinite loops as unreachable<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::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(&ast::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;
}
<|endoftext|>


<commit_before><commit_msg>use brackets to mark generic setters<commit_after><|endoftext|>


<commit_before><commit_msg>Add MIPMap implementation.<commit_after>use std::ops::{Mul, AddAssign};
use std::cmp;
use std::f32;

use na;
use num::{zero, one, Zero, One};

use ::Point2i;
use ::Point2f;
use ::lerp;
use blockedarray::BlockedArray;

pub enum WrapMode {
    Repeat,
    Black,
    Clamp,
}

pub struct MIPMap<T> {
    do_trilinear: bool,
    max_anisotropy: f32,
    wrap_mode: WrapMode,
    resolution: Point2i,
    pyramid: Vec<BlockedArray<T>>,
    black: T,
}

impl<T> MIPMap<T>
    where T: Zero,
          T: One,
          T: Clone,
          T: Copy,
          T: PartialOrd,
          T: AddAssign<T>,
          T: Mul<f32, Output = T>
{
    pub fn new(res: &Point2i,
               img: &[T],
               do_trilinear: bool,
               max_anisotropy: f32,
               wrap_mode: WrapMode)
               -> MIPMap<T> {
        let mut resolution = *res;
        let mut resampled_image = Vec::new();
        if !res.x.is_power_of_two() || !res.y.is_power_of_two() {
            // resample image to power of two resolution
            let res_pow2 = Point2i::new(res.x.next_power_of_two(), res.y.next_power_of_two());
            // resample image in s direction
            resampled_image.resize(res_pow2.x as usize * res_pow2.y as usize, zero());
            let s_weights = MIPMap::<T>::resample_weights(res.x, res_pow2.x);
            // apply s_weights to zoom in s direction
            for t in 0..res.y as usize {
                for s in 0..res_pow2.x as usize {
                    // Compute texel (s,t) in s-zoomed image
                    resampled_image[t * res_pow2.x as usize + s] = zero();
                    for j in 0..4 {
                        let mut orig_s = s_weights[s].first_texel as usize + j;
                        orig_s = match wrap_mode {
                            WrapMode::Repeat => orig_s % res.x as usize,
                            WrapMode::Clamp => na::clamp(orig_s, 0, res.x as usize - 1),
                            WrapMode::Black => orig_s,
                        };
                        if orig_s >= 0 && orig_s < res.x as usize {
                            resampled_image[t * res_pow2.x as usize + s] +=
                                img[(t * res.x as usize + orig_s) as usize] *
                                s_weights[s].weights[j];
                        }
                    }

                }
            }
            // TODO use rayon to parallelize this loop?
            // resample image in t direction
            let t_weights = MIPMap::<T>::resample_weights(res.y, res_pow2.y);
            // apply t_weights to zoom in t direction
            for s in 0..res_pow2.x as usize {
                let mut work_data = vec![zero(); res_pow2.y as usize];
                for t in 0..res_pow2.y as usize {
                    work_data[t] = zero();
                    // Compute texel (s,t) in t-zoomed image
                    for j in 0..4 {
                        let mut offset = t_weights[t].first_texel as usize + j;
                        offset = match wrap_mode {
                            WrapMode::Repeat => offset % res.y as usize,
                            WrapMode::Clamp => na::clamp(offset, 0, res.y as usize - 1),
                            WrapMode::Black => offset,
                        };
                        if offset >= 0 && offset < res.y as usize {
                            work_data[t] += img[(offset * res_pow2.x as usize + s) as usize] *
                                            t_weights[t].weights[j];
                        }
                    }
                }
                for t in 0..res_pow2.y as usize {
                    resampled_image[t * res_pow2.x as usize + s] =
                        na::clamp(work_data[t], zero(), one());
                }
            }
            resolution = res_pow2;
        }

        let mut mipmap = MIPMap {
            do_trilinear: do_trilinear,
            max_anisotropy: max_anisotropy,
            wrap_mode: wrap_mode,
            resolution: resolution,
            pyramid: Vec::new(),
            black: zero(),
        };

        // initialize levels of MIPMap for image
        let n_levels = 1 + f32::log2(cmp::max(resolution.x, resolution.y) as f32).log2() as usize;
        // Initialize most detailed level of the pyramid
        let img_data = if resampled_image.len() == 0 {
            img
        } else {
            &resampled_image[..]
        };
        mipmap.pyramid
            .push(BlockedArray::new_from(resolution.x as usize, resolution.y as usize, img_data));
        for i in 1..n_levels {
            // initialize ith level of the pyramid
            let s_res = cmp::max(1, mipmap.pyramid[i - 1].u_size() / 2);
            let t_res = cmp::max(1, mipmap.pyramid[i - 1].v_size() / 2);
            let mut ba = BlockedArray::new(s_res, t_res);
            // Filter 4 texels from finer level of pyramid
            for t in 0..t_res {
                for s in 0..s_res {
                    ba[(s, t)] = (*mipmap.texel(i - 1, 2 * s, 2 * t) +
                                  *mipmap.texel(i - 1, 2 * s + 1, 2 * t) +
                                  *mipmap.texel(i - 1, 2 * s, 2 * t + 1) +
                                  *mipmap.texel(i - 1, 2 * s + 1, 2 * t + 1)) *
                                 0.25;
                }
            }
            mipmap.pyramid.push(ba);
        }
        // initialize EWA filter weights if needed

        mipmap
    }

    pub fn width(&self) -> usize {
        self.resolution.x as usize
    }

    pub fn height(&self) -> usize {
        self.resolution.y as usize
    }

    pub fn levels(&self) -> usize {
        self.pyramid.len()
    }

    pub fn texel(&self, level: usize, s: usize, t: usize) -> &T {
        let l = &self.pyramid[level];
        let (ss, tt) = match self.wrap_mode {
            WrapMode::Repeat => (s % l.u_size(), t % l.v_size()),
            WrapMode::Clamp => (na::clamp(s, 0, l.u_size() - 1), na::clamp(t, 0, l.v_size() - 1)),
            WrapMode::Black => {
                if s < 0 || s >= l.u_size() || t < 0 || t >= l.v_size() {
                    return &self.black;
                }
                (s, t)
            }
        };
        &l[(ss, tt)]
    }

    pub fn lookup(&self, st: &Point2f, width: f32) -> T {
        // Compute MIPMap-level for trilinear filtering
        let level = self.levels() as f32 - 1.0 + width.max(1e-8).log2();
        // Perform trilinear interpolation at appropriate MIPMap level
        if level < 0.0 {
            self.triangle(0, st)
        } else if level >= self.levels() as f32 - 1.0 {
            *self.texel(self.levels() - 1, 0, 0)
        } else {
            let i_level = level.floor();
            let delta = level - i_level;
            lerp(delta,
                 self.triangle(i_level as usize, st),
                 self.triangle(i_level as usize + 1, st))
        }
    }

    pub fn triangle(&self, level: usize, st: &Point2f) -> T {
        let level = na::clamp(level, 0, self.levels() - 1);
        let s = st.x * self.pyramid[level].u_size() as f32 - 0.5;
        let t = st.y * self.pyramid[level].v_size() as f32 - 0.5;
        let s0 = s.floor() as usize;
        let t0 = t.floor() as usize;
        let ds = s - s0 as f32;
        let dt = t - t0 as f32;

        *self.texel(level, s0, t0) * (1.0 - ds) * (1.0 - dt) +
        *self.texel(level, s0, t0 + 1) * (1.0 - ds) * dt +
        *self.texel(level, s0 + 1, t0) * ds * (1.0 - dt) +
        *self.texel(level, s0 + 1, t0 + 1) * ds * dt
    }

    fn resample_weights(old_res: u32, new_res: u32) -> Vec<ResampleWeight> {
        assert!(new_res >= old_res);
        let mut wt = Vec::with_capacity(new_res as usize);
        let filter_width = 2.0;
        let mut w = [0.0; 4];
        for i in 0..new_res {
            // compute image resampling weights for ith texel
            let center = (i as f32 + 0.5) * (old_res as f32 / new_res as f32);
            let first_texel = ((center - filter_width) + 0.5).floor() as u32;
            for j in 0..4 {
                let pos = first_texel as f32 + j as f32 + 0.5;
                w[j] = Self::lanczos((pos - center) / filter_width);
            }
            // Normalize filter weights for texel resampling
            let inv_sum_weights = 1.0 / (w[0] + w[1] + w[2] + w[3]);
            for j in 0..4 {
                w[j] *= inv_sum_weights;
            }
            wt.push(ResampleWeight {
                first_texel: first_texel,
                weights: w,
            });
        }

        wt
    }

    fn lanczos(f: f32) -> f32 {
        0.0
    }
}

struct ResampleWeight {
    pub first_texel: u32,
    pub weights: [f32; 4],
}
<|endoftext|>


<commit_before><commit_msg>Fix comment typos.<commit_after><|endoftext|>


<commit_before><commit_msg>Revert "Implement pipe magic in libimagrt"<commit_after><|endoftext|>


<commit_before><commit_msg>Fix brown-paper-bug (ugh) and make the code more neat.<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #78172 - wesleywiser:close_77062, r=oli-obk<commit_after>// build-pass

fn main() {
    let _ = &[(); usize::MAX];
}
<|endoftext|>


<commit_before><commit_msg>add functions to attach and detach device<commit_after><|endoftext|>


<commit_before>use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use {Future, Wake, Tokens};
use token::AtomicTokens;
use executor::{DEFAULT, Executor};
use slot::Slot;

type Thunk = Box<Future<Item=(), Error=()>>;

struct Forget {
    slot: Slot<(Thunk, Arc<Forget>, Arc<Wake>)>,
    registered: AtomicBool,
    tokens: AtomicTokens,
}

pub fn forget<T: Future>(t: T) {
    let thunk = ThunkFuture { inner: t.boxed() }.boxed();
    let forget = Arc::new(Forget {
        slot: Slot::new(None),
        registered: AtomicBool::new(false),
        tokens: AtomicTokens::all(),
    });
    _forget(thunk, forget.clone(), forget)
}

// FIXME(rust-lang/rust#34416) should just be able to use map/map_err, but that
//                             causes trans to go haywire.
struct ThunkFuture<T, E> {
    inner: Box<Future<Item=T, Error=E>>,
}

impl<T: Send + 'static, E: Send + 'static> Future for ThunkFuture<T, E> {
    type Item = ();
    type Error = ();

    fn poll(&mut self, tokens: &Tokens) -> Option<Result<(), ()>> {
        match self.inner.poll(tokens) {
            Some(Ok(_)) => Some(Ok(())),
            Some(Err(_)) => Some(Err(())),
            None => None,
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        self.inner.schedule(wake)
    }

    fn tailcall(&mut self) -> Option<Box<Future<Item=(), Error=()>>> {
        if let Some(f) = self.inner.tailcall() {
            self.inner = f;
        }
        None
    }
}

fn _forget(mut future: Thunk,
           forget: Arc<Forget>,
           wake: Arc<Wake>) {
    loop {
        // TODO: catch panics here?

        // Note that we need to poll at least once as the wake callback may have
        // received an empty set of tokens, but that's still a valid reason to
        // poll a future.
        if future.poll(&forget.tokens.get_tokens()).is_some() {
            return
        }
        future = match future.tailcall() {
            Some(f) => f,
            None => future,
        };
        if !forget.tokens.any() {
            break
        }
    }

    // Ok, we've seen that there are no tokens which show interest in the
    // future. Schedule interest on the future for when something is ready and
    // then relinquish the future and the forget back to the slot, which will
    // then pick it up once a wake callback has fired.
    future.schedule(&wake);
    forget.slot.try_produce((future, forget.clone(), wake)).ok().unwrap();
}

impl Wake for Forget {
    fn wake(&self, tokens: &Tokens) {
        // First, add all our tokens provided into the shared token set.
        self.tokens.add(tokens);

        // Next, see if we can actually register an `on_full` callback. The
        // `Slot` requires that only one registration happens, and this flag
        // guards that.
        if self.registered.swap(true, Ordering::SeqCst) {
            return
        }

        // If we won the race to register a callback, do so now. Once the slot
        // is resolve we allow another registration **before we poll again**.
        // This allows any future which may be somewhat badly behaved to be
        // compatible with this.
        //
        // TODO: this store of `false` should *probably* be before the
        //       `schedule` call in forget above, need to think it through.
        self.slot.on_full(|slot| {
            let (future, forget, wake) = slot.try_consume().ok().unwrap();
            forget.registered.store(false, Ordering::SeqCst);
            DEFAULT.execute(|| _forget(future, forget, wake));
        });
    }
}
<commit_msg>Catch panics in forget(), but don't do anything<commit_after>use std::panic;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;

use {Future, Wake, Tokens};
use token::AtomicTokens;
use executor::{DEFAULT, Executor};
use slot::Slot;

type Thunk = Box<Future<Item=(), Error=()>>;

struct Forget {
    slot: Slot<(Thunk, Arc<Forget>, Arc<Wake>)>,
    registered: AtomicBool,
    tokens: AtomicTokens,
}

pub fn forget<T: Future>(t: T) {
    let thunk = ThunkFuture { inner: t.boxed() }.boxed();
    let forget = Arc::new(Forget {
        slot: Slot::new(None),
        registered: AtomicBool::new(false),
        tokens: AtomicTokens::all(),
    });
    _forget(thunk, forget.clone(), forget)
}

// FIXME(rust-lang/rust#34416) should just be able to use map/map_err, but that
//                             causes trans to go haywire.
struct ThunkFuture<T, E> {
    inner: Box<Future<Item=T, Error=E>>,
}

impl<T: Send + 'static, E: Send + 'static> Future for ThunkFuture<T, E> {
    type Item = ();
    type Error = ();

    fn poll(&mut self, tokens: &Tokens) -> Option<Result<(), ()>> {
        match self.inner.poll(tokens) {
            Some(Ok(_)) => Some(Ok(())),
            Some(Err(_)) => Some(Err(())),
            None => None,
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        self.inner.schedule(wake)
    }

    fn tailcall(&mut self) -> Option<Box<Future<Item=(), Error=()>>> {
        if let Some(f) = self.inner.tailcall() {
            self.inner = f;
        }
        None
    }
}

fn _forget(mut future: Thunk,
           forget: Arc<Forget>,
           wake: Arc<Wake>) {
    loop {
        // TODO: catch panics here?

        // Note that we need to poll at least once as the wake callback may have
        // received an empty set of tokens, but that's still a valid reason to
        // poll a future.
        let tokens = forget.tokens.get_tokens();
        let result = catch_unwind(move || {
            (future.poll(&tokens), future)
        });
        match result {
            Ok((Some(_), _)) => return,
            Ok((None, f)) => future = f,
            // TODO: do something smarter
            Err(e) => panic::resume_unwind(e),
        }
        future = match future.tailcall() {
            Some(f) => f,
            None => future,
        };
        if !forget.tokens.any() {
            break
        }
    }

    // Ok, we've seen that there are no tokens which show interest in the
    // future. Schedule interest on the future for when something is ready and
    // then relinquish the future and the forget back to the slot, which will
    // then pick it up once a wake callback has fired.
    future.schedule(&wake);
    forget.slot.try_produce((future, forget.clone(), wake)).ok().unwrap();
}

fn catch_unwind<F, U>(f: F) -> thread::Result<U>
    where F: FnOnce() -> U + Send + 'static,
{
    panic::catch_unwind(panic::AssertUnwindSafe(f))
}

impl Wake for Forget {
    fn wake(&self, tokens: &Tokens) {
        // First, add all our tokens provided into the shared token set.
        self.tokens.add(tokens);

        // Next, see if we can actually register an `on_full` callback. The
        // `Slot` requires that only one registration happens, and this flag
        // guards that.
        if self.registered.swap(true, Ordering::SeqCst) {
            return
        }

        // If we won the race to register a callback, do so now. Once the slot
        // is resolve we allow another registration **before we poll again**.
        // This allows any future which may be somewhat badly behaved to be
        // compatible with this.
        //
        // TODO: this store of `false` should *probably* be before the
        //       `schedule` call in forget above, need to think it through.
        self.slot.on_full(|slot| {
            let (future, forget, wake) = slot.try_consume().ok().unwrap();
            forget.registered.store(false, Ordering::SeqCst);
            DEFAULT.execute(|| _forget(future, forget, wake));
        });
    }
}
<|endoftext|>


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

mod flt2dec;
mod dec2flt;
<commit_msg>core/benches/num: Add `from_str/from_str_radix()` benchmarks<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod flt2dec;
mod dec2flt;

use test::Bencher;
use std::str::FromStr;

const ASCII_NUMBERS: [&str; 19] = [
    "0",
    "1",
    "2",
    "43",
    "765",
    "76567",
    "987245987",
    "-4aa32",
    "1786235",
    "8723095",
    "f##5s",
    "83638730",
    "-2345",
    "562aa43",
    "-1",
    "-0",
    "abc",
    "xyz",
    "c0ffee",
];

macro_rules! from_str_bench {
    ($mac:ident, $t:ty) => (
        #[bench]
        fn $mac(b: &mut Bencher) {
            b.iter(|| {
                ASCII_NUMBERS
                    .iter()
                    .cycle()
                    .take(5_000)
                    .filter_map(|s| <($t)>::from_str(s).ok())
                    .max()
            })
        }
    )
}

macro_rules! from_str_radix_bench {
    ($mac:ident, $t:ty, $radix:expr) => (
        #[bench]
        fn $mac(b: &mut Bencher) {
            b.iter(|| {
                ASCII_NUMBERS
                    .iter()
                    .cycle()
                    .take(5_000)
                    .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok())
                    .max()
            })
        }
    )
}

from_str_bench!(bench_u8_from_str, u8);
from_str_radix_bench!(bench_u8_from_str_radix_2, u8, 2);
from_str_radix_bench!(bench_u8_from_str_radix_10, u8, 10);
from_str_radix_bench!(bench_u8_from_str_radix_16, u8, 16);
from_str_radix_bench!(bench_u8_from_str_radix_36, u8, 36);

from_str_bench!(bench_u16_from_str, u16);
from_str_radix_bench!(bench_u16_from_str_radix_2, u16, 2);
from_str_radix_bench!(bench_u16_from_str_radix_10, u16, 10);
from_str_radix_bench!(bench_u16_from_str_radix_16, u16, 16);
from_str_radix_bench!(bench_u16_from_str_radix_36, u16, 36);

from_str_bench!(bench_u32_from_str, u32);
from_str_radix_bench!(bench_u32_from_str_radix_2, u32, 2);
from_str_radix_bench!(bench_u32_from_str_radix_10, u32, 10);
from_str_radix_bench!(bench_u32_from_str_radix_16, u32, 16);
from_str_radix_bench!(bench_u32_from_str_radix_36, u32, 36);

from_str_bench!(bench_u64_from_str, u64);
from_str_radix_bench!(bench_u64_from_str_radix_2, u64, 2);
from_str_radix_bench!(bench_u64_from_str_radix_10, u64, 10);
from_str_radix_bench!(bench_u64_from_str_radix_16, u64, 16);
from_str_radix_bench!(bench_u64_from_str_radix_36, u64, 36);

from_str_bench!(bench_i8_from_str, i8);
from_str_radix_bench!(bench_i8_from_str_radix_2, i8, 2);
from_str_radix_bench!(bench_i8_from_str_radix_10, i8, 10);
from_str_radix_bench!(bench_i8_from_str_radix_16, i8, 16);
from_str_radix_bench!(bench_i8_from_str_radix_36, i8, 36);

from_str_bench!(bench_i16_from_str, i16);
from_str_radix_bench!(bench_i16_from_str_radix_2, i16, 2);
from_str_radix_bench!(bench_i16_from_str_radix_10, i16, 10);
from_str_radix_bench!(bench_i16_from_str_radix_16, i16, 16);
from_str_radix_bench!(bench_i16_from_str_radix_36, i16, 36);

from_str_bench!(bench_i32_from_str, i32);
from_str_radix_bench!(bench_i32_from_str_radix_2, i32, 2);
from_str_radix_bench!(bench_i32_from_str_radix_10, i32, 10);
from_str_radix_bench!(bench_i32_from_str_radix_16, i32, 16);
from_str_radix_bench!(bench_i32_from_str_radix_36, i32, 36);

from_str_bench!(bench_i64_from_str, i64);
from_str_radix_bench!(bench_i64_from_str_radix_2, i64, 2);
from_str_radix_bench!(bench_i64_from_str_radix_10, i64, 10);
from_str_radix_bench!(bench_i64_from_str_radix_16, i64, 16);
from_str_radix_bench!(bench_i64_from_str_radix_36, i64, 36);
<|endoftext|>


<commit_before>//! Blanket impls for Middleware.
//! This is pre-implemented for any function which takes a
//! `Request` and `Response` parameter and returns anything
//! implementing the `ResponseFinalizer` trait. It is also
//! implemented for a tuple of a function and a type `T`.
//! The function must take a `Request`, a `Response` and a
//! `T`, returning anything that implements `ResponseFinalizer`.
//! The data of type `T` will then be shared and available
//! in any request.
//!
//! Please see the examples for usage.

use request::Request;
use response::Response;
use hyper::status::{StatusCode, StatusClass};
use std::fmt::Display;
use hyper::header;
use hyper::net;
use middleware::{Middleware, MiddlewareResult, Halt, Continue};
use serialize::json;
use mimes::{MediaType, get_media_type};
use std::io::Write;

impl Middleware for for<'a> fn(&mut Request, Response<'a>) -> MiddlewareResult<'a> {
    fn invoke<'a, 'b>(&'a self, req: &mut Request<'b, 'a, 'b>, res: Response<'a>) -> MiddlewareResult<'a> {
        (*self)(req, res)
    }
}

impl<T> Middleware for (for <'a> fn(&mut Request, Response<'a>, &T) -> MiddlewareResult<'a>, T)
        where T: Send + Sync + 'static {
    fn invoke<'a, 'b>(&'a self, req: &mut Request<'b, 'a, 'b>, res: Response<'a>) -> MiddlewareResult<'a> {
        let (f, ref data) = *self;
        f(req, res, data)
    }
}

/// This trait provides convenience for translating a number
/// of common return types into a `MiddlewareResult` while
/// also modifying the `Response` as required.
///
/// Please see the examples for some uses.
pub trait ResponseFinalizer<T=net::Fresh> {
    fn respond<'a>(self, Response<'a, T>) -> MiddlewareResult<'a>;
}

impl ResponseFinalizer for () {
    fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
        Ok(Continue(res))
    }
}

// This is impossible?
// impl<'a> ResponseFinalizer for MiddlewareResult<'a> {
//     fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
//         maybe_set_type(&mut res, MediaType::Html);
//         self
//     }
// }

impl ResponseFinalizer for json::Json {
    fn respond<'a>(self, mut res: Response<'a>) -> MiddlewareResult<'a> {
        maybe_set_type(&mut res, MediaType::Json);
        res.send(json::encode(&self).unwrap())
    }
}

impl<'a, S: Display> ResponseFinalizer for &'a [S] {
    fn respond<'c>(self, mut res: Response<'c>) -> MiddlewareResult<'c> {
        maybe_set_type(&mut res, MediaType::Html);
        res.set_status(StatusCode::Ok);
        let mut stream = try!(res.start());
        for ref s in self.iter() {
            // FIXME : This error handling is poor
            match stream.write_fmt(format_args!("{}", s)) {
                Ok(()) => {},
                Err(e) => return stream.bail(format!("Failed to write to stream: {}", e))
            }
        }
        Ok(Halt(stream))
    }
}

macro_rules! dual_impl {
    ($view:ty, $alloc:ty, |$s:ident, $res:ident| $b:block) => (
        impl<'a> ResponseFinalizer for $view {
            #[allow(unused_mut)]
            fn respond<'c>($s, mut $res: Response<'c>) -> MiddlewareResult<'c> $b
        }

        impl ResponseFinalizer for $alloc {
            #[allow(unused_mut)]
            fn respond<'c>($s, mut $res: Response<'c>) -> MiddlewareResult<'c> $b
        }
    )
}

dual_impl!(&'a str,
           String,
            |self, res| {
                maybe_set_type(&mut res, MediaType::Html);

                res.set_status(StatusCode::Ok);
                res.send(self)
            });

dual_impl!((StatusCode, &'static str),
           (StatusCode, String),
            |self, res| {
                maybe_set_type(&mut res, MediaType::Html);
                let (status, message) = self;

                match status.class() {
                    StatusClass::ClientError
                    | StatusClass::ServerError => {
                        res.error(status, message)
                    },
                    _ => {
                        res.set_status(status);
                        res.send(message)
                    }
                }
            });

dual_impl!((u16, &'a str),
           (u16, String),
           |self, res| {
                maybe_set_type(&mut res, MediaType::Html);
                let (status, data) = self;
                res.set_status(StatusCode::from_u16(status));
                res.send(data)
            });

// FIXME: Hyper uses traits for headers, so this needs to be a Vec of
// trait objects. But, a trait object is unable to have Foo + Bar as a bound.
//
// A better/faster solution would be to impl this for tuples,
// where each tuple element implements the Header trait, which would give a
// static dispatch.
// dual_impl!((StatusCode, &'a str, Vec<Box<ResponseHeader>>),
//            (StatusCode, String, Vec<Box<ResponseHeader>>)
//            |self, res| {
//                 let (status, data, headers) = self;

//                 res.origin.status = status;
//                 for header in headers.into_iter() {
//                     res.origin.headers_mut().set(header);
//                 }
//                 maybe_set_type(&mut res, MediaType::Html);
//                 res.send(data);
//                 Ok(Halt)
//             })

fn maybe_set_type(res: &mut Response, ty: MediaType) {
    res.set_header_fallback(|| header::ContentType(get_media_type(ty)));
}
<commit_msg>refactor(middleware): reuse the impl for (StatusCode, String)<commit_after>//! Blanket impls for Middleware.
//! This is pre-implemented for any function which takes a
//! `Request` and `Response` parameter and returns anything
//! implementing the `ResponseFinalizer` trait. It is also
//! implemented for a tuple of a function and a type `T`.
//! The function must take a `Request`, a `Response` and a
//! `T`, returning anything that implements `ResponseFinalizer`.
//! The data of type `T` will then be shared and available
//! in any request.
//!
//! Please see the examples for usage.

use request::Request;
use response::Response;
use hyper::status::{StatusCode, StatusClass};
use std::fmt::Display;
use hyper::header;
use hyper::net;
use middleware::{Middleware, MiddlewareResult, Halt, Continue};
use serialize::json;
use mimes::{MediaType, get_media_type};
use std::io::Write;

impl Middleware for for<'a> fn(&mut Request, Response<'a>) -> MiddlewareResult<'a> {
    fn invoke<'a, 'b>(&'a self, req: &mut Request<'b, 'a, 'b>, res: Response<'a>) -> MiddlewareResult<'a> {
        (*self)(req, res)
    }
}

impl<T> Middleware for (for <'a> fn(&mut Request, Response<'a>, &T) -> MiddlewareResult<'a>, T)
        where T: Send + Sync + 'static {
    fn invoke<'a, 'b>(&'a self, req: &mut Request<'b, 'a, 'b>, res: Response<'a>) -> MiddlewareResult<'a> {
        let (f, ref data) = *self;
        f(req, res, data)
    }
}

/// This trait provides convenience for translating a number
/// of common return types into a `MiddlewareResult` while
/// also modifying the `Response` as required.
///
/// Please see the examples for some uses.
pub trait ResponseFinalizer<T=net::Fresh> {
    fn respond<'a>(self, Response<'a, T>) -> MiddlewareResult<'a>;
}

impl ResponseFinalizer for () {
    fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
        Ok(Continue(res))
    }
}

// This is impossible?
// impl<'a> ResponseFinalizer for MiddlewareResult<'a> {
//     fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
//         maybe_set_type(&mut res, MediaType::Html);
//         self
//     }
// }

impl ResponseFinalizer for json::Json {
    fn respond<'a>(self, mut res: Response<'a>) -> MiddlewareResult<'a> {
        maybe_set_type(&mut res, MediaType::Json);
        res.send(json::encode(&self).unwrap())
    }
}

impl<'a, S: Display> ResponseFinalizer for &'a [S] {
    fn respond<'c>(self, mut res: Response<'c>) -> MiddlewareResult<'c> {
        maybe_set_type(&mut res, MediaType::Html);
        res.set_status(StatusCode::Ok);
        let mut stream = try!(res.start());
        for ref s in self.iter() {
            // FIXME : This error handling is poor
            match stream.write_fmt(format_args!("{}", s)) {
                Ok(()) => {},
                Err(e) => return stream.bail(format!("Failed to write to stream: {}", e))
            }
        }
        Ok(Halt(stream))
    }
}

macro_rules! dual_impl {
    ($view:ty, $alloc:ty, |$s:ident, $res:ident| $b:block) => (
        impl<'a> ResponseFinalizer for $view {
            #[allow(unused_mut)]
            fn respond<'c>($s, mut $res: Response<'c>) -> MiddlewareResult<'c> $b
        }

        impl ResponseFinalizer for $alloc {
            #[allow(unused_mut)]
            fn respond<'c>($s, mut $res: Response<'c>) -> MiddlewareResult<'c> $b
        }
    )
}

dual_impl!(&'static str,
           String,
            |self, res| {
                (StatusCode::Ok, self).respond(res)
            });

dual_impl!((StatusCode, &'static str),
           (StatusCode, String),
            |self, res| {
                maybe_set_type(&mut res, MediaType::Html);
                let (status, message) = self;

                match status.class() {
                    StatusClass::ClientError
                    | StatusClass::ServerError => {
                        res.error(status, message)
                    },
                    _ => {
                        res.set_status(status);
                        res.send(message)
                    }
                }
            });

dual_impl!((u16, &'static str),
           (u16, String),
           |self, res| {
                let (status, message) = self;
                (StatusCode::from_u16(status), message).respond(res)
            });

// FIXME: Hyper uses traits for headers, so this needs to be a Vec of
// trait objects. But, a trait object is unable to have Foo + Bar as a bound.
//
// A better/faster solution would be to impl this for tuples,
// where each tuple element implements the Header trait, which would give a
// static dispatch.
// dual_impl!((StatusCode, &'a str, Vec<Box<ResponseHeader>>),
//            (StatusCode, String, Vec<Box<ResponseHeader>>)
//            |self, res| {
//                 let (status, data, headers) = self;

//                 res.origin.status = status;
//                 for header in headers.into_iter() {
//                     res.origin.headers_mut().set(header);
//                 }
//                 maybe_set_type(&mut res, MediaType::Html);
//                 res.send(data);
//                 Ok(Halt)
//             })

fn maybe_set_type(res: &mut Response, ty: MediaType) {
    res.set_header_fallback(|| header::ContentType(get_media_type(ty)));
}
<|endoftext|>


<commit_before><commit_msg>Reordered suit ranking<commit_after><|endoftext|>


<commit_before><commit_msg>Add collection utility module.<commit_after>//! Collection Utility

/// Clone a vector consisting of item references to
/// a new vector owning cloned items.
#[inline]
pub fn to_owned_vec<T: Clone>(r: &Vec<&T>) -> Vec<T> {
  r.iter().map(|v| (*v).clone()).collect::<Vec<T>>()
}

#[test]
pub fn test() {
  let x = 3; let y = 4;

  let ref_vec : Vec<&usize> = vec![&x, &y];
  let expected: Vec<usize> = vec![x, y];
  assert_eq!(to_owned_vec(&ref_vec), expected);
}<|endoftext|>


<commit_before>//! Enviroment data

use alloc::boxed::Box;

use fs::File;
use path::{Path, PathBuf};
use io::Result;
use string::{String, ToString};
use vec::Vec;

use system::error::{Error, ENOENT};
use system::syscall::sys_chdir;

static mut _args: *mut Vec<&'static str> = 0 as *mut Vec<&'static str>;

pub struct Args {
    i: usize
}

impl Iterator for Args {
    //Yes, this is supposed to be String, do not change it!
    //Only change it if https://doc.rust-lang.org/std/env/struct.Args.html changes from String
    type Item = String;
    fn next(&mut self) -> Option<String> {
        if let Some(arg) = unsafe { (*_args).get(self.i) } {
            self.i += 1;
            Some(arg.to_string())
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = if self.i <= unsafe { (*_args).len() } {
            unsafe { (*_args).len() - self.i }
        } else {
            0
        };
        (len, Some(len))
    }
}

impl ExactSizeIterator for Args {}

/// Arguments
pub fn args() -> Args {
    Args {
        i: 0
    }
}

/// Initialize arguments
pub unsafe fn args_init(args: Vec<&'static str>) {
    _args = Box::into_raw(box args);
}

/// Destroy arguments
pub unsafe fn args_destroy() {
    if _args as usize > 0 {
        drop(Box::from_raw(_args));
    }
}

/// Private function to get the path from a custom location
/// If the custom directory cannot be found, None will be returned
fn get_path_from(location : &str) -> Result<PathBuf> {
    match File::open(dir) {
        Ok(file) => {
            match file.path() {
                Ok(path) => Ok(path),
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

/// Method to return the current directory
pub fn current_dir() -> Result<PathBuf> {
    // Return the current path
    get_path_from("./")
}

/// Method to return the home directory
pub fn home_dir() -> Result<PathBuf> {
    get_path_from("/home/")
}

/// Set the current directory
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> Result<()> {
    let file_result = if path.as_ref().inner.is_empty() || path.as_ref().inner.ends_with('/') {
        File::open(&path.as_ref().inner)
    } else {
        File::open(&(path.as_ref().inner.to_string() + "/"))
    };

    match file_result {
        Ok(file) => {
            match file.path() {
                Ok(path) => {
                    if let Some(path_str) = path.to_str() {
                        let path_c = path_str.to_string() + "\0";
                        match Error::demux(unsafe { sys_chdir(path_c.as_ptr()) }) {
                            Ok(_) => Ok(()),
                            Err(err) => Err(err),
                        }
                    } else {
                        Err(Error::new(ENOENT))
                    }
                }
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

// TODO: Fully implement `env::var()`
pub fn var(_key: &str) -> Result<String> {
    Ok("This is code filler".to_string())
}
<commit_msg>Correct file name<commit_after>//! Enviroment data

use alloc::boxed::Box;

use fs::File;
use path::{Path, PathBuf};
use io::Result;
use string::{String, ToString};
use vec::Vec;

use system::error::{Error, ENOENT};
use system::syscall::sys_chdir;

static mut _args: *mut Vec<&'static str> = 0 as *mut Vec<&'static str>;

pub struct Args {
    i: usize
}

impl Iterator for Args {
    //Yes, this is supposed to be String, do not change it!
    //Only change it if https://doc.rust-lang.org/std/env/struct.Args.html changes from String
    type Item = String;
    fn next(&mut self) -> Option<String> {
        if let Some(arg) = unsafe { (*_args).get(self.i) } {
            self.i += 1;
            Some(arg.to_string())
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = if self.i <= unsafe { (*_args).len() } {
            unsafe { (*_args).len() - self.i }
        } else {
            0
        };
        (len, Some(len))
    }
}

impl ExactSizeIterator for Args {}

/// Arguments
pub fn args() -> Args {
    Args {
        i: 0
    }
}

/// Initialize arguments
pub unsafe fn args_init(args: Vec<&'static str>) {
    _args = Box::into_raw(box args);
}

/// Destroy arguments
pub unsafe fn args_destroy() {
    if _args as usize > 0 {
        drop(Box::from_raw(_args));
    }
}

/// Private function to get the path from a custom location
/// If the custom directory cannot be found, None will be returned
fn get_path_from(location : &str) -> Result<PathBuf> {
    match File::open(location) {
        Ok(file) => {
            match file.path() {
                Ok(path) => Ok(path),
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

/// Method to return the current directory
pub fn current_dir() -> Result<PathBuf> {
    // Return the current path
    get_path_from("./")
}

/// Method to return the home directory
pub fn home_dir() -> Result<PathBuf> {
    get_path_from("/home/")
}

/// Set the current directory
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> Result<()> {
    let file_result = if path.as_ref().inner.is_empty() || path.as_ref().inner.ends_with('/') {
        File::open(&path.as_ref().inner)
    } else {
        File::open(&(path.as_ref().inner.to_string() + "/"))
    };

    match file_result {
        Ok(file) => {
            match file.path() {
                Ok(path) => {
                    if let Some(path_str) = path.to_str() {
                        let path_c = path_str.to_string() + "\0";
                        match Error::demux(unsafe { sys_chdir(path_c.as_ptr()) }) {
                            Ok(_) => Ok(()),
                            Err(err) => Err(err),
                        }
                    } else {
                        Err(Error::new(ENOENT))
                    }
                }
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

// TODO: Fully implement `env::var()`
pub fn var(_key: &str) -> Result<String> {
    Ok("This is code filler".to_string())
}
<|endoftext|>


<commit_before><commit_msg>Adapt tested path<commit_after><|endoftext|>


<commit_before><commit_msg>Implement untested subdivide_once<commit_after><|endoftext|>


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

//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`](boxed/index.html) type is a smart pointer type. There can
//! only be one owner of a `Box`, and the owner can decide to mutate the
//! contents, which live on the heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer
//! type intended for sharing memory within a thread. An `Rc` pointer wraps a
//! type, `T`, and only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using `Box`) is too
//! constraining for an application, and is often paired with the `Cell` or
//! `RefCell` types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`](sync/index.html) type is the threadsafe equivalent of the `Rc`
//! type. It provides all the same functionality of `Rc`, except it requires
//! that the contained type `T` is shareable. Additionally, `Arc<T>` is itself
//! sendable while `Rc<T>` is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.

#![allow(unused_attributes)]
#![unstable(feature = "alloc",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![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/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
#![no_std]
#![needs_allocator]
#![deny(missing_debug_implementations)]

#![cfg_attr(not(test), feature(fn_traits))]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]

#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fundamental)]
#![feature(futures_api)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(needs_allocator)]
#![feature(optin_builtin_traits)]
#![feature(pattern)]
#![feature(pin)]
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
#![feature(rustc_attrs)]
#![feature(specialization)]
#![feature(split_ascii_whitespace)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
#![feature(exact_chunks)]
#![feature(rustc_const_unstable)]
#![feature(const_vec_new)]

// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
#[cfg(test)]
extern crate rand;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

#[unstable(feature = "futures_api",
           reason = "futures in libcore are unstable",
           issue = "50547")]
pub mod task;
// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
#[cfg(test)]
mod boxed_test;
pub mod collections;
#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
pub mod sync;
pub mod rc;
pub mod raw_vec;
pub mod prelude;
pub mod borrow;
pub mod fmt;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;

#[cfg(not(test))]
mod std {
    pub use core::ops;      // RangeFull
}
<commit_msg>liballoc: enable feature(nll) for bootstrap<commit_after>// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`](boxed/index.html) type is a smart pointer type. There can
//! only be one owner of a `Box`, and the owner can decide to mutate the
//! contents, which live on the heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer
//! type intended for sharing memory within a thread. An `Rc` pointer wraps a
//! type, `T`, and only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using `Box`) is too
//! constraining for an application, and is often paired with the `Cell` or
//! `RefCell` types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`](sync/index.html) type is the threadsafe equivalent of the `Rc`
//! type. It provides all the same functionality of `Rc`, except it requires
//! that the contained type `T` is shareable. Additionally, `Arc<T>` is itself
//! sendable while `Rc<T>` is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.

#![allow(unused_attributes)]
#![unstable(feature = "alloc",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![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/",
       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
       test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
#![no_std]
#![needs_allocator]
#![deny(missing_debug_implementations)]

#![cfg_attr(not(test), feature(fn_traits))]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(not(stage0), feature(nll))]
#![cfg_attr(test, feature(test))]

#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fundamental)]
#![feature(futures_api)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(needs_allocator)]
#![feature(optin_builtin_traits)]
#![feature(pattern)]
#![feature(pin)]
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
#![feature(rustc_attrs)]
#![feature(specialization)]
#![feature(split_ascii_whitespace)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
#![feature(exact_chunks)]
#![feature(rustc_const_unstable)]
#![feature(const_vec_new)]

// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
#[cfg(test)]
extern crate rand;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

#[unstable(feature = "futures_api",
           reason = "futures in libcore are unstable",
           issue = "50547")]
pub mod task;
// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
#[cfg(test)]
mod boxed_test;
pub mod collections;
#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
pub mod sync;
pub mod rc;
pub mod raw_vec;
pub mod prelude;
pub mod borrow;
pub mod fmt;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;

#[cfg(not(test))]
mod std {
    pub use core::ops;      // RangeFull
}
<|endoftext|>


<commit_before><commit_msg>lint: Improve ffi-unsafe enum lint warning<commit_after><|endoftext|>