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

//! Lints, aka compiler warnings.
//!
//! A 'lint' check is a kind of miscellaneous constraint that a user _might_
//! want to enforce, but might reasonably want to permit as well, on a
//! module-by-module basis. They contrast with static constraints enforced by
//! other phases of the compiler, which are generally required to hold in order
//! to compile the program at all.
//!
//! Most lints can be written as `LintPass` instances. These run just before
//! translation to LLVM bytecode. The `LintPass`es built into rustc are defined
//! within `builtin.rs`, which has further comments on how to add such a lint.
//! rustc can also load user-defined lint plugins via the plugin mechanism.
//!
//! Some of rustc's lints are defined elsewhere in the compiler and work by
//! calling `add_lint()` on the overall `Session` object. This works when
//! it happens before the main lint pass, which emits the lints stored by
//! `add_lint()`. To emit lints after the main lint pass (from trans, for
//! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
//! in `context.rs`.

pub use self::Level::*;
pub use self::LintSource::*;

use std::hash;
use std::ascii::AsciiExt;
use syntax::codemap::Span;
use rustc_front::visit::FnKind;
use syntax::visit as ast_visit;
use syntax::ast;
use rustc_front::hir;

pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                        raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
                        GatherNodeLevels};

/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
    /// A string identifier for the lint.
    ///
    /// This identifies the lint in attributes and in command-line arguments.
    /// In those contexts it is always lowercase, but this field is compared
    /// in a way which is case-insensitive for ASCII characters. This allows
    /// `declare_lint!()` invocations to follow the convention of upper-case
    /// statics without repeating the name.
    ///
    /// The name is written with underscores, e.g. "unused_imports".
    /// On the command line, underscores become dashes.
    pub name: &'static str,

    /// Default level for the lint.
    pub default_level: Level,

    /// Description of the lint or the issue it detects.
    ///
    /// e.g. "imports that are never used"
    pub desc: &'static str,
}

impl Lint {
    /// Get the lint's name, with ASCII letters converted to lowercase.
    pub fn name_lower(&self) -> String {
        self.name.to_ascii_lowercase()
    }
}

/// Build a `Lint` initializer.
#[macro_export]
macro_rules! lint_initializer {
    ($name:ident, $level:ident, $desc:expr) => (
        ::rustc::lint::Lint {
            name: stringify!($name),
            default_level: ::rustc::lint::$level,
            desc: $desc,
        }
    )
}

/// Declare a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
    // FIXME(#14660): deduplicate
    (pub $name:ident, $level:ident, $desc:expr) => (
        pub static $name: &'static ::rustc::lint::Lint
            = &lint_initializer!($name, $level, $desc);
    );
    ($name:ident, $level:ident, $desc:expr) => (
        static $name: &'static ::rustc::lint::Lint
            = &lint_initializer!($name, $level, $desc);
    );
}

/// Declare a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array { ($( $lint:expr ),*) => (
    {
        static ARRAY: LintArray = &[ $( &$lint ),* ];
        ARRAY
    }
) }

pub type LintArray = &'static [&'static &'static Lint];

pub trait LintPass {
    /// Get descriptions of the lints this `LintPass` object can emit.
    ///
    /// NB: there is no enforcement that the object only emits lints it registered.
    /// And some `rustc` internal `LintPass`es register lints to be emitted by other
    /// parts of the compiler. If you want enforced access restrictions for your
    /// `Lint`, make it a private `static` item in its own module.
    fn get_lints(&self) -> LintArray;
}

/// Trait for types providing lint checks.
///
/// Each `check` method checks a single syntax node, and should not
/// invoke methods recursively (unlike `Visitor`). By default they
/// do nothing.
//
// FIXME: eliminate the duplication with `Visitor`. But this also
// contains a few lint-specific methods with no equivalent in `Visitor`.
pub trait LateLintPass: LintPass {
    fn check_ident(&mut self, _: &LateContext, _: Span, _: ast::Ident) { }
    fn check_crate(&mut self, _: &LateContext, _: &hir::Crate) { }
    fn check_mod(&mut self, _: &LateContext, _: &hir::Mod, _: Span, _: ast::NodeId) { }
    fn check_foreign_item(&mut self, _: &LateContext, _: &hir::ForeignItem) { }
    fn check_item(&mut self, _: &LateContext, _: &hir::Item) { }
    fn check_local(&mut self, _: &LateContext, _: &hir::Local) { }
    fn check_block(&mut self, _: &LateContext, _: &hir::Block) { }
    fn check_stmt(&mut self, _: &LateContext, _: &hir::Stmt) { }
    fn check_arm(&mut self, _: &LateContext, _: &hir::Arm) { }
    fn check_pat(&mut self, _: &LateContext, _: &hir::Pat) { }
    fn check_decl(&mut self, _: &LateContext, _: &hir::Decl) { }
    fn check_expr(&mut self, _: &LateContext, _: &hir::Expr) { }
    fn check_expr_post(&mut self, _: &LateContext, _: &hir::Expr) { }
    fn check_ty(&mut self, _: &LateContext, _: &hir::Ty) { }
    fn check_generics(&mut self, _: &LateContext, _: &hir::Generics) { }
    fn check_fn(&mut self, _: &LateContext,
        _: FnKind, _: &hir::FnDecl, _: &hir::Block, _: Span, _: ast::NodeId) { }
    fn check_trait_item(&mut self, _: &LateContext, _: &hir::TraitItem) { }
    fn check_impl_item(&mut self, _: &LateContext, _: &hir::ImplItem) { }
    fn check_struct_def(&mut self, _: &LateContext,
        _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
    fn check_struct_def_post(&mut self, _: &LateContext,
        _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
    fn check_struct_field(&mut self, _: &LateContext, _: &hir::StructField) { }
    fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
    fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
    fn check_opt_lifetime_ref(&mut self, _: &LateContext, _: Span, _: &Option<hir::Lifetime>) { }
    fn check_lifetime_ref(&mut self, _: &LateContext, _: &hir::Lifetime) { }
    fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
    fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
    // Note that you shouldn't implement both check_mac and check_ast_mac,
    // because then your lint will be called twice. Prefer check_ast_mac.
    fn check_mac(&mut self, _: &LateContext, _: &ast::Mac) { }
    fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
    fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }

    /// Called when entering a syntax node that can have lint attributes such
    /// as `#[allow(...)]`. Called with *all* the attributes of that node.
    fn enter_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }

    /// Counterpart to `enter_lint_attrs`.
    fn exit_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
}

pub trait EarlyLintPass: LintPass {
    fn check_ident(&mut self, _: &EarlyContext, _: Span, _: ast::Ident) { }
    fn check_crate(&mut self, _: &EarlyContext, _: &ast::Crate) { }
    fn check_mod(&mut self, _: &EarlyContext, _: &ast::Mod, _: Span, _: ast::NodeId) { }
    fn check_foreign_item(&mut self, _: &EarlyContext, _: &ast::ForeignItem) { }
    fn check_item(&mut self, _: &EarlyContext, _: &ast::Item) { }
    fn check_local(&mut self, _: &EarlyContext, _: &ast::Local) { }
    fn check_block(&mut self, _: &EarlyContext, _: &ast::Block) { }
    fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
    fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
    fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
    fn check_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
    fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
    fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
    fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
    fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
    fn check_fn(&mut self, _: &EarlyContext,
        _: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
    fn check_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
    fn check_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }
    fn check_struct_def(&mut self, _: &EarlyContext,
        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
    fn check_struct_def_post(&mut self, _: &EarlyContext,
        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
    fn check_struct_field(&mut self, _: &EarlyContext, _: &ast::StructField) { }
    fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
    fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
    fn check_opt_lifetime_ref(&mut self,
                              _: &EarlyContext,
                              _: Span,
                              _: &Option<ast::Lifetime>) { }
    fn check_lifetime_ref(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
    fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
    fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
    fn check_mac(&mut self, _: &EarlyContext, _: &ast::Mac) { }
    fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
    fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }

    /// Called when entering a syntax node that can have lint attributes such
    /// as `#[allow(...)]`. Called with *all* the attributes of that node.
    fn enter_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }

    /// Counterpart to `enter_lint_attrs`.
    fn exit_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
}

/// A lint pass boxed up as a trait object.
pub type EarlyLintPassObject = Box<EarlyLintPass + 'static>;
pub type LateLintPassObject = Box<LateLintPass + 'static>;

/// Identifies a lint known to the compiler.
#[derive(Clone, Copy)]
pub struct LintId {
    // Identity is based on pointer equality of this field.
    lint: &'static Lint,
}

impl PartialEq for LintId {
    fn eq(&self, other: &LintId) -> bool {
        (self.lint as *const Lint) == (other.lint as *const Lint)
    }
}

impl Eq for LintId { }

impl hash::Hash for LintId {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        let ptr = self.lint as *const Lint;
        ptr.hash(state);
    }
}

impl LintId {
    /// Get the `LintId` for a `Lint`.
    pub fn of(lint: &'static Lint) -> LintId {
        LintId {
            lint: lint,
        }
    }

    /// Get the name of the lint.
    pub fn as_str(&self) -> String {
        self.lint.name_lower()
    }
}

/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub enum Level {
    Allow, Warn, Deny, Forbid
}

impl Level {
    /// Convert a level to a lower-case string.
    pub fn as_str(self) -> &'static str {
        match self {
            Allow => "allow",
            Warn => "warn",
            Deny => "deny",
            Forbid => "forbid",
        }
    }

    /// Convert a lower-case string to a level.
    pub fn from_str(x: &str) -> Option<Level> {
        match x {
            "allow" => Some(Allow),
            "warn" => Some(Warn),
            "deny" => Some(Deny),
            "forbid" => Some(Forbid),
            _ => None,
        }
    }
}

/// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum LintSource {
    /// Lint is at the default level as declared
    /// in rustc or a plugin.
    Default,

    /// Lint level was set by an attribute.
    Node(Span),

    /// Lint level was set by a command-line flag.
    CommandLine,
}

pub type LevelSource = (Level, LintSource);

pub mod builtin;

mod context;
<commit_msg>Auto merge of #28506 - Manishearth:no_mac, r=eddyb<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Lints, aka compiler warnings.
//!
//! A 'lint' check is a kind of miscellaneous constraint that a user _might_
//! want to enforce, but might reasonably want to permit as well, on a
//! module-by-module basis. They contrast with static constraints enforced by
//! other phases of the compiler, which are generally required to hold in order
//! to compile the program at all.
//!
//! Most lints can be written as `LintPass` instances. These run just before
//! translation to LLVM bytecode. The `LintPass`es built into rustc are defined
//! within `builtin.rs`, which has further comments on how to add such a lint.
//! rustc can also load user-defined lint plugins via the plugin mechanism.
//!
//! Some of rustc's lints are defined elsewhere in the compiler and work by
//! calling `add_lint()` on the overall `Session` object. This works when
//! it happens before the main lint pass, which emits the lints stored by
//! `add_lint()`. To emit lints after the main lint pass (from trans, for
//! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
//! in `context.rs`.

pub use self::Level::*;
pub use self::LintSource::*;

use std::hash;
use std::ascii::AsciiExt;
use syntax::codemap::Span;
use rustc_front::visit::FnKind;
use syntax::visit as ast_visit;
use syntax::ast;
use rustc_front::hir;

pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                        raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
                        GatherNodeLevels};

/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
    /// A string identifier for the lint.
    ///
    /// This identifies the lint in attributes and in command-line arguments.
    /// In those contexts it is always lowercase, but this field is compared
    /// in a way which is case-insensitive for ASCII characters. This allows
    /// `declare_lint!()` invocations to follow the convention of upper-case
    /// statics without repeating the name.
    ///
    /// The name is written with underscores, e.g. "unused_imports".
    /// On the command line, underscores become dashes.
    pub name: &'static str,

    /// Default level for the lint.
    pub default_level: Level,

    /// Description of the lint or the issue it detects.
    ///
    /// e.g. "imports that are never used"
    pub desc: &'static str,
}

impl Lint {
    /// Get the lint's name, with ASCII letters converted to lowercase.
    pub fn name_lower(&self) -> String {
        self.name.to_ascii_lowercase()
    }
}

/// Build a `Lint` initializer.
#[macro_export]
macro_rules! lint_initializer {
    ($name:ident, $level:ident, $desc:expr) => (
        ::rustc::lint::Lint {
            name: stringify!($name),
            default_level: ::rustc::lint::$level,
            desc: $desc,
        }
    )
}

/// Declare a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
    // FIXME(#14660): deduplicate
    (pub $name:ident, $level:ident, $desc:expr) => (
        pub static $name: &'static ::rustc::lint::Lint
            = &lint_initializer!($name, $level, $desc);
    );
    ($name:ident, $level:ident, $desc:expr) => (
        static $name: &'static ::rustc::lint::Lint
            = &lint_initializer!($name, $level, $desc);
    );
}

/// Declare a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array { ($( $lint:expr ),*) => (
    {
        static ARRAY: LintArray = &[ $( &$lint ),* ];
        ARRAY
    }
) }

pub type LintArray = &'static [&'static &'static Lint];

pub trait LintPass {
    /// Get descriptions of the lints this `LintPass` object can emit.
    ///
    /// NB: there is no enforcement that the object only emits lints it registered.
    /// And some `rustc` internal `LintPass`es register lints to be emitted by other
    /// parts of the compiler. If you want enforced access restrictions for your
    /// `Lint`, make it a private `static` item in its own module.
    fn get_lints(&self) -> LintArray;
}

/// Trait for types providing lint checks.
///
/// Each `check` method checks a single syntax node, and should not
/// invoke methods recursively (unlike `Visitor`). By default they
/// do nothing.
//
// FIXME: eliminate the duplication with `Visitor`. But this also
// contains a few lint-specific methods with no equivalent in `Visitor`.
pub trait LateLintPass: LintPass {
    fn check_ident(&mut self, _: &LateContext, _: Span, _: ast::Ident) { }
    fn check_crate(&mut self, _: &LateContext, _: &hir::Crate) { }
    fn check_mod(&mut self, _: &LateContext, _: &hir::Mod, _: Span, _: ast::NodeId) { }
    fn check_foreign_item(&mut self, _: &LateContext, _: &hir::ForeignItem) { }
    fn check_item(&mut self, _: &LateContext, _: &hir::Item) { }
    fn check_local(&mut self, _: &LateContext, _: &hir::Local) { }
    fn check_block(&mut self, _: &LateContext, _: &hir::Block) { }
    fn check_stmt(&mut self, _: &LateContext, _: &hir::Stmt) { }
    fn check_arm(&mut self, _: &LateContext, _: &hir::Arm) { }
    fn check_pat(&mut self, _: &LateContext, _: &hir::Pat) { }
    fn check_decl(&mut self, _: &LateContext, _: &hir::Decl) { }
    fn check_expr(&mut self, _: &LateContext, _: &hir::Expr) { }
    fn check_expr_post(&mut self, _: &LateContext, _: &hir::Expr) { }
    fn check_ty(&mut self, _: &LateContext, _: &hir::Ty) { }
    fn check_generics(&mut self, _: &LateContext, _: &hir::Generics) { }
    fn check_fn(&mut self, _: &LateContext,
        _: FnKind, _: &hir::FnDecl, _: &hir::Block, _: Span, _: ast::NodeId) { }
    fn check_trait_item(&mut self, _: &LateContext, _: &hir::TraitItem) { }
    fn check_impl_item(&mut self, _: &LateContext, _: &hir::ImplItem) { }
    fn check_struct_def(&mut self, _: &LateContext,
        _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
    fn check_struct_def_post(&mut self, _: &LateContext,
        _: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
    fn check_struct_field(&mut self, _: &LateContext, _: &hir::StructField) { }
    fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
    fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
    fn check_opt_lifetime_ref(&mut self, _: &LateContext, _: Span, _: &Option<hir::Lifetime>) { }
    fn check_lifetime_ref(&mut self, _: &LateContext, _: &hir::Lifetime) { }
    fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
    fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
    fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
    fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }

    /// Called when entering a syntax node that can have lint attributes such
    /// as `#[allow(...)]`. Called with *all* the attributes of that node.
    fn enter_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }

    /// Counterpart to `enter_lint_attrs`.
    fn exit_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
}

pub trait EarlyLintPass: LintPass {
    fn check_ident(&mut self, _: &EarlyContext, _: Span, _: ast::Ident) { }
    fn check_crate(&mut self, _: &EarlyContext, _: &ast::Crate) { }
    fn check_mod(&mut self, _: &EarlyContext, _: &ast::Mod, _: Span, _: ast::NodeId) { }
    fn check_foreign_item(&mut self, _: &EarlyContext, _: &ast::ForeignItem) { }
    fn check_item(&mut self, _: &EarlyContext, _: &ast::Item) { }
    fn check_local(&mut self, _: &EarlyContext, _: &ast::Local) { }
    fn check_block(&mut self, _: &EarlyContext, _: &ast::Block) { }
    fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
    fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
    fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
    fn check_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
    fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
    fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
    fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
    fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
    fn check_fn(&mut self, _: &EarlyContext,
        _: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
    fn check_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
    fn check_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }
    fn check_struct_def(&mut self, _: &EarlyContext,
        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
    fn check_struct_def_post(&mut self, _: &EarlyContext,
        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
    fn check_struct_field(&mut self, _: &EarlyContext, _: &ast::StructField) { }
    fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
    fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
    fn check_opt_lifetime_ref(&mut self,
                              _: &EarlyContext,
                              _: Span,
                              _: &Option<ast::Lifetime>) { }
    fn check_lifetime_ref(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
    fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
    fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
    fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
    fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }

    /// Called when entering a syntax node that can have lint attributes such
    /// as `#[allow(...)]`. Called with *all* the attributes of that node.
    fn enter_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }

    /// Counterpart to `enter_lint_attrs`.
    fn exit_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
}

/// A lint pass boxed up as a trait object.
pub type EarlyLintPassObject = Box<EarlyLintPass + 'static>;
pub type LateLintPassObject = Box<LateLintPass + 'static>;

/// Identifies a lint known to the compiler.
#[derive(Clone, Copy)]
pub struct LintId {
    // Identity is based on pointer equality of this field.
    lint: &'static Lint,
}

impl PartialEq for LintId {
    fn eq(&self, other: &LintId) -> bool {
        (self.lint as *const Lint) == (other.lint as *const Lint)
    }
}

impl Eq for LintId { }

impl hash::Hash for LintId {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        let ptr = self.lint as *const Lint;
        ptr.hash(state);
    }
}

impl LintId {
    /// Get the `LintId` for a `Lint`.
    pub fn of(lint: &'static Lint) -> LintId {
        LintId {
            lint: lint,
        }
    }

    /// Get the name of the lint.
    pub fn as_str(&self) -> String {
        self.lint.name_lower()
    }
}

/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub enum Level {
    Allow, Warn, Deny, Forbid
}

impl Level {
    /// Convert a level to a lower-case string.
    pub fn as_str(self) -> &'static str {
        match self {
            Allow => "allow",
            Warn => "warn",
            Deny => "deny",
            Forbid => "forbid",
        }
    }

    /// Convert a lower-case string to a level.
    pub fn from_str(x: &str) -> Option<Level> {
        match x {
            "allow" => Some(Allow),
            "warn" => Some(Warn),
            "deny" => Some(Deny),
            "forbid" => Some(Forbid),
            _ => None,
        }
    }
}

/// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum LintSource {
    /// Lint is at the default level as declared
    /// in rustc or a plugin.
    Default,

    /// Lint level was set by an attribute.
    Node(Span),

    /// Lint level was set by a command-line flag.
    CommandLine,
}

pub type LevelSource = (Level, LintSource);

pub mod builtin;

mod context;
<|endoftext|>


<commit_before><commit_msg>add new<commit_after>fn insertiong_sort(nl: Vec<i32>, f: &Fn(&i32, &i32) -> bool) -> Vec<i32> {
    let mut head = vec![nl[0]];
    for i in &nl[1..] {
        let thisInd = head.iter().position(|&r| f(r,i)).unwrap();
        if thisInd
    }
}

fn large(a: &i32, b: &i32) -> bool {
    return a > b;
}

fn small(a: &i32, b: &i32) -> bool {
    return a < b;
}
<|endoftext|>


<commit_before><commit_msg>:art: Make it possible to use Attachment and Basic formats<commit_after><|endoftext|>


<commit_before><commit_msg>Implement Blinn-Phong shading<commit_after><|endoftext|>


<commit_before><commit_msg>start keeper<commit_after><|endoftext|>


<commit_before><commit_msg>Fix calculation of cursor position when typing multi-byte characters<commit_after><|endoftext|>


<commit_before><commit_msg>add CodeDeploy integration tests<commit_after>#![cfg(feature = "codedeploy")]

extern crate rusoto;

use rusoto::codedeploy::{CodeDeployClient, ListApplicationsInput};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
fn should_list_applications() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = CodeDeployClient::new(credentials, Region::UsEast1);

    let request = ListApplicationsInput::default();

    match client.list_applications(&request) {
    	Ok(response) => {
    		println!("{:#?}", response);
    		assert!(true)
    	},
    	Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}
<|endoftext|>


<commit_before><commit_msg>Add lib.rs for scrabble-score<commit_after>pub fn score(string: &str) -> usize {
    let mut score: usize = 0;

    for c in string.chars() {
        match c {
            'A' | 'E' | 'I' | 'O' | 'U' | 'L' => score += 1,
            'a' | 'e' | 'i' | 'o' | 'u' | 'l' => score += 1,
            'N' | 'R' | 'S' | 'T' => score += 1,
            'n' | 'r' | 's' | 't' => score += 1,
            'D' | 'G' => score += 2,
            'd' | 'g' => score += 2,
            'B' | 'C' | 'M' | 'P' => score += 3,
            'b' | 'c' | 'm' | 'p' => score += 3,
            'F' | 'H' | 'V' | 'W' | 'Y' => score += 4,
            'f' | 'h' | 'v' | 'w' | 'y' => score += 4,
            'K' => score += 5,
            'k' => score += 5,
            'J' | 'X' => score += 8,
            'j' | 'x' => score += 8,
            'Q' | 'Z' => score += 10,
            'q' | 'z' => score += 10,
            _ => score += 0,
        }
    }

    score
}
<|endoftext|>


<commit_before><commit_msg>Add missing attribute to timeout field<commit_after><|endoftext|>


<commit_before><commit_msg>am ecd5a05f: am bd6acda9: Merge "Fix bugs in grain where values could go out of bounds." into jb-mr1-dev<commit_after><|endoftext|>


<commit_before><commit_msg>am f9678070: Merge "Fix bug in grain." into jb-mr1-dev<commit_after><|endoftext|>


<commit_before><commit_msg>More info when doing backup, restore or clean<commit_after><|endoftext|>


<commit_before>use super::peg::Job;
use super::Variables;

pub fn expand_variables(mut jobs: Vec<Job>, variables: &Variables) -> Vec<Job> {
    for mut job in &mut jobs {
        job.command = expand_string(&job.command, variables);
        job.args = job.args
                      .iter()
                      .map(|original: &String| expand_string(&original, variables))
                      .collect();
    }
    jobs
}

#[inline]
fn expand_string(original: &str, variables: &Variables) -> String {
    if original.starts_with("$") {
        if let Some(value) = variables.get(&original[1..]) {
            value.clone()
        } else {
            String::new()
        }
    } else {
        original.to_string()
    }
}
<commit_msg>Have the user decide when to allocate a String or not<commit_after>use super::peg::Job;
use super::Variables;

pub fn expand_variables(mut jobs: Vec<Job>, variables: &Variables) -> Vec<Job> {
    for mut job in &mut jobs {
        job.command = expand_string(&job.command, variables).to_string();
        job.args = job.args
                      .iter()
                      .map(|original: &String| expand_string(&original, variables).to_string())
                      .collect();
    }
    jobs
}

#[inline]
fn expand_string<'a>(original: &'a str, variables: &'a Variables) -> &'a str {
    if original.starts_with("$") {
        if let Some(value) = variables.get(&original[1..]) {
            &value
        } else {
            ""
        }
    } else {
        original
    }
}
<|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.

/** Task-local reference counted smart pointers

Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
destruction. They are restricted to containing `Owned` types in order to prevent cycles.

*/

use core::libc::{c_void, size_t, malloc, free};
use core::unstable::intrinsics;

struct RcBox<T> {
    value: T,
    count: uint
}

/// Immutable reference counted pointer type
pub struct Rc<T> {
    priv ptr: *mut RcBox<T>,
    priv non_owned: Option<@()> // FIXME: #5601: replace with `#[non_owned]`
}

pub impl<'self, T: Owned> Rc<T> {
    fn new(value: T) -> Rc<T> {
        unsafe {
            let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
            assert!(!ptr::is_null(ptr));
            intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
            Rc{ptr: ptr, non_owned: None}
        }
    }

    #[inline(always)]
    fn borrow(&self) -> &'self T {
        unsafe { cast::transmute_region(&(*self.ptr).value) }
    }
}

#[unsafe_destructor]
impl<T: Owned> Drop for Rc<T> {
    fn finalize(&self) {
        unsafe {
            (*self.ptr).count -= 1;
            if (*self.ptr).count == 0 {
                let mut x = intrinsics::init();
                x <-> *self.ptr;
                free(self.ptr as *c_void)
            }
        }
    }
}

impl<T: Owned> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        unsafe {
            (*self.ptr).count += 1;
            Rc{ptr: self.ptr, non_owned: None}
        }
    }
}

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

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x.borrow(), 5);
    }

    #[test]
    fn test_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x.borrow(), 5);
        assert_eq!(*y.borrow(), 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(~5);
        assert_eq!(**x.borrow(), 5);
    }
}

#[abi = "rust-intrinsic"]
extern "rust-intrinsic" mod rusti {
    fn init<T>() -> T;
}

#[deriving(Eq)]
enum Borrow {
    Mutable,
    Immutable,
    Nothing
}

struct RcMutBox<T> {
    value: T,
    count: uint,
    borrow: Borrow
}

/// Mutable reference counted pointer type
pub struct RcMut<T> {
    priv ptr: *mut RcMutBox<T>,
    priv non_owned: Option<@mut ()> // FIXME: #5601: replace with `#[non_owned]` and `#[non_const]`
}

pub impl<'self, T: Owned> RcMut<T> {
    fn new(value: T) -> RcMut<T> {
        unsafe {
            let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
            assert!(!ptr::is_null(ptr));
            intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
            RcMut{ptr: ptr, non_owned: None}
        }
    }

    /// Fails if there is already a mutable borrow of the box
    #[inline]
    fn with_borrow(&self, f: &fn(&T)) {
        unsafe {
            assert!((*self.ptr).borrow != Mutable);
            let previous = (*self.ptr).borrow;
            (*self.ptr).borrow = Immutable;
            f(cast::transmute_region(&(*self.ptr).value));
            (*self.ptr).borrow = previous;
        }
    }

    /// Fails if there is already a mutable or immutable borrow of the box
    #[inline]
    fn with_mut_borrow(&self, f: &fn(&mut T)) {
        unsafe {
            assert!((*self.ptr).borrow == Nothing);
            (*self.ptr).borrow = Mutable;
            f(cast::transmute_mut_region(&mut (*self.ptr).value));
            (*self.ptr).borrow = Nothing;
        }
    }
}

#[unsafe_destructor]
impl<T: Owned> Drop for RcMut<T> {
    fn finalize(&self) {
        unsafe {
            (*self.ptr).count -= 1;
            if (*self.ptr).count == 0 {
                let mut x = rusti::init();
                x <-> *self.ptr;
                free(self.ptr as *c_void)
            }
        }
    }
}

impl<T: Owned> Clone for RcMut<T> {
    #[inline]
    fn clone(&self) -> RcMut<T> {
        unsafe {
            (*self.ptr).count += 1;
            RcMut{ptr: self.ptr, non_owned: None}
        }
    }
}

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

    #[test]
    fn borrow_many() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |a| {
            assert_eq!(*a, 5);
            do y.with_borrow |b| {
                assert_eq!(*b, 5);
                do x.with_borrow |c| {
                    assert_eq!(*c, 5);
                }
            }
        }
    }

    #[test]
    fn modify() {
        let x = RcMut::new(5);
        let y = x.clone();

        do y.with_mut_borrow |a| {
            assert_eq!(*a, 5);
            *a = 6;
        }

        do x.with_borrow |a| {
            assert_eq!(*a, 6);
        }
    }

    #[test]
    fn release_immutable() {
        let x = RcMut::new(5);
        do x.with_borrow |_| {}
        do x.with_mut_borrow |_| {}
    }

    #[test]
    fn release_mutable() {
        let x = RcMut::new(5);
        do x.with_mut_borrow |_| {}
        do x.with_borrow |_| {}
    }

    #[test]
    #[should_fail]
    fn frozen() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |_| {
            do y.with_mut_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn mutable_dupe() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_mut_borrow |_| {
            do y.with_mut_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn mutable_freeze() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_mut_borrow |_| {
            do y.with_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn restore_freeze() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |_| {
            do x.with_borrow |_| {}
            do y.with_mut_borrow |_| {}
        }
    }
}
<commit_msg>rc: remove the managed pointer workaround<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.

/** Task-local reference counted smart pointers

Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
destruction. They are restricted to containing `Owned` types in order to prevent cycles.

*/

use core::libc::{c_void, size_t, malloc, free};
use core::unstable::intrinsics;

struct RcBox<T> {
    value: T,
    count: uint
}

/// Immutable reference counted pointer type
#[non_owned]
pub struct Rc<T> {
    priv ptr: *mut RcBox<T>,
}

pub impl<'self, T: Owned> Rc<T> {
    fn new(value: T) -> Rc<T> {
        unsafe {
            let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
            assert!(!ptr::is_null(ptr));
            intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
            Rc{ptr: ptr}
        }
    }

    #[inline(always)]
    fn borrow(&self) -> &'self T {
        unsafe { cast::transmute_region(&(*self.ptr).value) }
    }
}

#[unsafe_destructor]
impl<T: Owned> Drop for Rc<T> {
    fn finalize(&self) {
        unsafe {
            (*self.ptr).count -= 1;
            if (*self.ptr).count == 0 {
                let mut x = intrinsics::init();
                x <-> *self.ptr;
                free(self.ptr as *c_void)
            }
        }
    }
}

impl<T: Owned> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        unsafe {
            (*self.ptr).count += 1;
            Rc{ptr: self.ptr}
        }
    }
}

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

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x.borrow(), 5);
    }

    #[test]
    fn test_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x.borrow(), 5);
        assert_eq!(*y.borrow(), 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(~5);
        assert_eq!(**x.borrow(), 5);
    }
}

#[abi = "rust-intrinsic"]
extern "rust-intrinsic" mod rusti {
    fn init<T>() -> T;
}

#[deriving(Eq)]
enum Borrow {
    Mutable,
    Immutable,
    Nothing
}

struct RcMutBox<T> {
    value: T,
    count: uint,
    borrow: Borrow
}

/// Mutable reference counted pointer type
#[non_owned]
#[mutable]
pub struct RcMut<T> {
    priv ptr: *mut RcMutBox<T>,
}

pub impl<'self, T: Owned> RcMut<T> {
    fn new(value: T) -> RcMut<T> {
        unsafe {
            let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
            assert!(!ptr::is_null(ptr));
            intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
            RcMut{ptr: ptr}
        }
    }

    /// Fails if there is already a mutable borrow of the box
    #[inline]
    fn with_borrow(&self, f: &fn(&T)) {
        unsafe {
            assert!((*self.ptr).borrow != Mutable);
            let previous = (*self.ptr).borrow;
            (*self.ptr).borrow = Immutable;
            f(cast::transmute_region(&(*self.ptr).value));
            (*self.ptr).borrow = previous;
        }
    }

    /// Fails if there is already a mutable or immutable borrow of the box
    #[inline]
    fn with_mut_borrow(&self, f: &fn(&mut T)) {
        unsafe {
            assert!((*self.ptr).borrow == Nothing);
            (*self.ptr).borrow = Mutable;
            f(cast::transmute_mut_region(&mut (*self.ptr).value));
            (*self.ptr).borrow = Nothing;
        }
    }
}

#[unsafe_destructor]
impl<T: Owned> Drop for RcMut<T> {
    fn finalize(&self) {
        unsafe {
            (*self.ptr).count -= 1;
            if (*self.ptr).count == 0 {
                let mut x = rusti::init();
                x <-> *self.ptr;
                free(self.ptr as *c_void)
            }
        }
    }
}

impl<T: Owned> Clone for RcMut<T> {
    #[inline]
    fn clone(&self) -> RcMut<T> {
        unsafe {
            (*self.ptr).count += 1;
            RcMut{ptr: self.ptr}
        }
    }
}

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

    #[test]
    fn borrow_many() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |a| {
            assert_eq!(*a, 5);
            do y.with_borrow |b| {
                assert_eq!(*b, 5);
                do x.with_borrow |c| {
                    assert_eq!(*c, 5);
                }
            }
        }
    }

    #[test]
    fn modify() {
        let x = RcMut::new(5);
        let y = x.clone();

        do y.with_mut_borrow |a| {
            assert_eq!(*a, 5);
            *a = 6;
        }

        do x.with_borrow |a| {
            assert_eq!(*a, 6);
        }
    }

    #[test]
    fn release_immutable() {
        let x = RcMut::new(5);
        do x.with_borrow |_| {}
        do x.with_mut_borrow |_| {}
    }

    #[test]
    fn release_mutable() {
        let x = RcMut::new(5);
        do x.with_mut_borrow |_| {}
        do x.with_borrow |_| {}
    }

    #[test]
    #[should_fail]
    fn frozen() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |_| {
            do y.with_mut_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn mutable_dupe() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_mut_borrow |_| {
            do y.with_mut_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn mutable_freeze() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_mut_borrow |_| {
            do y.with_borrow |_| {
            }
        }
    }

    #[test]
    #[should_fail]
    fn restore_freeze() {
        let x = RcMut::new(5);
        let y = x.clone();

        do x.with_borrow |_| {
            do x.with_borrow |_| {}
            do y.with_mut_borrow |_| {}
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>watchmanctl: make audit run on Windows<commit_after><|endoftext|>


<commit_before><commit_msg>Implement !0, !^, and !*<commit_after><|endoftext|>


<commit_before><commit_msg>/src/types/pos.rs: Let me patch it for you.<commit_after><|endoftext|>


<commit_before><commit_msg>Add problem #76<commit_after>use core::hashmap::{ HashMap };

use common::problem::{ Problem };

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

fn count_way(sum: uint) -> uint {
    let mut map = HashMap::new();
    return count_sub(sum, 1, &mut map) - 1;

    fn count_sub(
        sum: uint, min_n: uint, map: &mut HashMap<(uint, uint), uint>
    ) -> uint {
        let mut cnt = 1; // only sum
        for uint::range(min_n, sum / 2 + 1) |k| {
            match map.find(&(sum - k, k)).map(|v| **v) {
                Some(n) => cnt += n,
                None    => {
                    let n = count_sub(sum - k, k, map);
                    map.insert((sum - k, k), n);
                    cnt += n;
                }
            }
        }
        return cnt;
    }
}

fn solve() -> ~str {
    return count_way(100).to_str();
}
<|endoftext|>


<commit_before><commit_msg>Make Hex hashable<commit_after><|endoftext|>


<commit_before><commit_msg>make rsh available as a lib<commit_after>pub mod rsh;

// rexport rsh so that imports aren't rsh::rsh::State
pub use rsh::*;
<|endoftext|>


<commit_before><commit_msg>updated to check/remove dirty file<commit_after><|endoftext|>


<commit_before>// TODO:
//
// panic here or panic there?
//  * catch_unwind is 6x slower than a normal call with panic=abort
//      * can be 3x if we deal with PANIC_COUNT
//  * catch_unwind is 7x slower than a normal call with panic=unwind
//  * perspective, allocation is 20x slower than a noop call
//  * also attributed to the indirect call
//  * data point - wangle deals with C++ exceptions
//
// select() and returning a future back
//  * maybe this is just streams...

mod cell;
mod slot;
mod util;

mod error;
pub use error::{PollError, PollResult, FutureError, FutureResult};

// Primitive futures
mod collect;
mod done;
mod empty;
mod failed;
mod finished;
mod lazy;
mod promise;
pub use collect::{collect, Collect};
pub use done::{done, Done};
pub use empty::{empty, Empty};
pub use failed::{failed, Failed};
pub use finished::{finished, Finished};
pub use lazy::{lazy, Lazy};
pub use promise::{promise, Promise, Complete};

// combinators
mod and_then;
mod chain;
mod flatten;
mod impls;
mod join;
mod map;
mod map_err;
mod or_else;
mod select;
mod then;
pub use and_then::AndThen;
pub use flatten::Flatten;
pub use join::Join;
pub use map::Map;
pub use map_err::MapErr;
pub use or_else::OrElse;
pub use select::Select;
pub use then::Then;

// streams
pub mod stream;

// TODO: Send + 'static is annoying, but required by cancel and_then, document
// TODO: not object safe
//
// FINISH CONDITIONS
//      - poll() return Some
//      - await() is called
//      - schedule() is called
//      - schedule_boxed() is called
//
// BAD:
//      - doing any finish condition after an already called finish condition
//
// WHAT HAPPENS
//      - panic?
pub trait Future: Send + 'static {
    type Item: Send + 'static;
    type Error: Send + 'static;

    fn poll(&mut self) -> Option<PollResult<Self::Item, Self::Error>>;

    // TODO: why is this not drop()
    //       well what if you schedule() then drop, HUH?!
    fn cancel(&mut self);

    fn schedule<F>(&mut self, f: F)
        where F: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static,
              Self: Sized;

    fn schedule_boxed(&mut self, f: Box<Callback<Self::Item, Self::Error>>);

    // TODO: why can't this be in this lib?
    // fn await(&mut self) -> FutureResult<Self::Item, Self::Error>;

    fn boxed(self) -> Box<Future<Item=Self::Item, Error=Self::Error>>
        where Self: Sized
    {
        Box::new(self)
    }

    fn map<F, U>(self, f: F) -> Map<Self, F>
        where F: FnOnce(Self::Item) -> U + Send + 'static,
              U: Send + 'static,
              Self: Sized,
    {
        assert_future::<U, Self::Error, _>(map::new(self, f))
    }

    fn map2<F, U>(self, f: F) -> Box<Future<Item=U, Error=Self::Error>>
        where F: FnOnce(Self::Item) -> U + Send + 'static,
              U: Send + 'static,
              Self: Sized,
    {
        self.then(|r| r.map(f)).boxed()
    }

    fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
        where F: FnOnce(Self::Error) -> E + Send + 'static,
              E: Send + 'static,
              Self: Sized,
    {
        assert_future::<Self::Item, E, _>(map_err::new(self, f))
    }

    fn map_err2<F, E>(self, f: F) -> Box<Future<Item=Self::Item, Error=E>>
        where F: FnOnce(Self::Error) -> E + Send + 'static,
              E: Send + 'static,
              Self: Sized,
    {
        self.then(|res| res.map_err(f)).boxed()
    }

    fn then<F, B>(self, f: F) -> Then<Self, B, F>
        where F: FnOnce(Result<Self::Item, Self::Error>) -> B + Send + 'static,
              B: IntoFuture,
              Self: Sized,
    {
        assert_future::<B::Item, B::Error, _>(then::new(self, f))
    }

    fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
        where F: FnOnce(Self::Item) -> B + Send + 'static,
              B: IntoFuture<Error = Self::Error>,
              Self: Sized,
    {
        assert_future::<B::Item, Self::Error, _>(and_then::new(self, f))
    }

    fn and_then2<F, B>(self, f: F) -> Box<Future<Item=B::Item, Error=Self::Error>>
        where F: FnOnce(Self::Item) -> B + Send + 'static,
              B: IntoFuture<Error = Self::Error>,
              Self: Sized,
    {
        self.then(|res| {
            match res {
                Ok(e) => f(e).into_future().boxed(),
                Err(e) => failed(e).boxed(),
            }
        }).boxed()
    }

    fn or_else<F, B>(self, f: F) -> OrElse<Self, B, F>
        where F: FnOnce(Self::Error) -> B + Send + 'static,
              B: IntoFuture<Item = Self::Item>,
              Self: Sized,
    {
        assert_future::<Self::Item, B::Error, _>(or_else::new(self, f))
    }

    fn or_else2<F, B>(self, f: F) -> Box<Future<Item=B::Item, Error=B::Error>>
        where F: FnOnce(Self::Error) -> B + Send + 'static,
              B: IntoFuture<Item = Self::Item>,
              Self: Sized,
    {
        self.then(|res| {
            match res {
                Ok(e) => finished(e).boxed(),
                Err(e) => f(e).into_future().boxed(),
            }
        }).boxed()
    }

    fn select<B>(self, other: B) -> Select<Self, B::Future>
        where B: IntoFuture<Item=Self::Item, Error=Self::Error>,
              Self: Sized,
    {
        let f = select::new(self, other.into_future());
        assert_future::<Self::Item, Self::Error, _>(f)
    }

    fn join<B>(self, other: B) -> Join<Self, B::Future>
        where B: IntoFuture<Error=Self::Error>,
              Self: Sized,
    {
        let f = join::new(self, other.into_future());
        assert_future::<(Self::Item, B::Item), Self::Error, _>(f)
    }

    fn flatten(self) -> Flatten<Self>
        where Self::Item: IntoFuture,
              <<Self as Future>::Item as IntoFuture>::Error:
                    From<<Self as Future>::Error>,
              Self: Sized
    {
        let f = flatten::new(self);
        assert_future::<<<Self as Future>::Item as IntoFuture>::Item,
                        <<Self as Future>::Item as IntoFuture>::Error,
                        _>(f)
    }

    fn flatten2(self) -> Box<Future<Item=<<Self as Future>::Item as IntoFuture>::Item,
                                    Error=<<Self as Future>::Item as IntoFuture>::Error>>
        where Self::Item: IntoFuture,
              <<Self as Future>::Item as IntoFuture>::Error:
                    From<<Self as Future>::Error>,
              Self: Sized
    {
        self.then(|res| {
            match res {
                Ok(e) => e.into_future().boxed(),
                Err(e) => failed(From::from(e)).boxed(),
            }
        }).boxed()
    }
}

fn assert_future<A, B, F>(t: F) -> F
    where F: Future<Item=A, Error=B>,
          A: Send + 'static,
          B: Send + 'static,
{
    t
}

pub trait Callback<T, E>: Send + 'static {
    fn call(self: Box<Self>, result: PollResult<T, E>);
}

impl<F, T, E> Callback<T, E> for F
    where F: FnOnce(PollResult<T, E>) + Send + 'static
{
    fn call(self: Box<F>, result: PollResult<T, E>) {
        (*self)(result)
    }
}

pub trait IntoFuture: Send + 'static {
    type Future: Future<Item=Self::Item, Error=Self::Error>;
    type Item: Send + 'static;
    type Error: Send + 'static;

    fn into_future(self) -> Self::Future;
}

impl<F: Future> IntoFuture for F {
    type Future = F;
    type Item = F::Item;
    type Error = F::Error;

    fn into_future(self) -> F {
        self
    }
}
<commit_msg>Add some small docs<commit_after>// TODO:
//
// panic here or panic there?
//  * catch_unwind is 6x slower than a normal call with panic=abort
//      * can be 3x if we deal with PANIC_COUNT
//  * catch_unwind is 7x slower than a normal call with panic=unwind
//  * perspective, allocation is 20x slower than a noop call
//  * also attributed to the indirect call
//  * data point - wangle deals with C++ exceptions
//
// select() and returning a future back
//  * maybe this is just streams...

mod cell;
mod slot;
mod util;

mod error;
pub use error::{PollError, PollResult, FutureError, FutureResult};

// Primitive futures
mod collect;
mod done;
mod empty;
mod failed;
mod finished;
mod lazy;
mod promise;
pub use collect::{collect, Collect};
pub use done::{done, Done};
pub use empty::{empty, Empty};
pub use failed::{failed, Failed};
pub use finished::{finished, Finished};
pub use lazy::{lazy, Lazy};
pub use promise::{promise, Promise, Complete};

// combinators
mod and_then;
mod chain;
mod flatten;
mod impls;
mod join;
mod map;
mod map_err;
mod or_else;
mod select;
mod then;
pub use and_then::AndThen;
pub use flatten::Flatten;
pub use join::Join;
pub use map::Map;
pub use map_err::MapErr;
pub use or_else::OrElse;
pub use select::Select;
pub use then::Then;

// streams
pub mod stream;

// TODO: Send + 'static is annoying, but required by cancel and_then, document
// TODO: not object safe
//
// FINISH CONDITIONS
//      - poll() return Some
//      - await() is called
//      - schedule() is called
//      - schedule_boxed() is called
//
// BAD:
//      - doing any finish condition after an already called finish condition
//
// WHAT HAPPENS
//      - panic?
pub trait Future: Send + 'static {
    type Item: Send + 'static;
    type Error: Send + 'static;

    // returns None - you can keep calling this, future is not consumed
    // returns Some - future becomes consumed
    //
    // If future is consumed then this returns `Some` of a panicked error.
    //
    // TODO: why does this actually exist?
    fn poll(&mut self) -> Option<PollResult<Self::Item, Self::Error>>;

    // - If future is not consumes, causes future calls to poll() and schedule()
    //   to return immediately with Canceled
    // - If future is consumed via poll(), does nothing, but causes future
    //   poll()/schedule() invocations to return immediately with Canceled
    // - If future is consumed via schedule(), arranges to have the callback
    //   called "as soon as possible" with a resolution. That resolution may be
    //   Canceled, or it may be anything else (depending on how the race plays
    //   out).
    //
    // Canceling a canceled future doesn't do much, shouldn't panic either.
    //
    // FAQ:
    //
    // Q: Why is this not drop?
    // A: How to differentiate drop() vs cancel() then drop()
    fn cancel(&mut self);

    // Contract: the closure `f` is guaranteed to get called
    //
    // - If future is consumed, `f` is immediately called with a "panicked"
    //   result.
    // - If future is not consumd, arranges `f` to be called with the resolved
    //   value. May be called earlier if `cancel` is called.
    //
    // This function will "consume" the future.
    fn schedule<F>(&mut self, f: F)
        where F: FnOnce(PollResult<Self::Item, Self::Error>) + Send + 'static,
              Self: Sized;

    // Impl detail, just do this as:
    //
    //      self.schedule(|r| f.call(r))
    fn schedule_boxed(&mut self, f: Box<Callback<Self::Item, Self::Error>>);

    // TODO: why can't this be in this lib?
    //
    // Seems not very useful if we can't provide it.
    // fn await(&mut self) -> FutureResult<Self::Item, Self::Error>;

    fn boxed(self) -> Box<Future<Item=Self::Item, Error=Self::Error>>
        where Self: Sized
    {
        Box::new(self)
    }

    fn map<F, U>(self, f: F) -> Map<Self, F>
        where F: FnOnce(Self::Item) -> U + Send + 'static,
              U: Send + 'static,
              Self: Sized,
    {
        assert_future::<U, Self::Error, _>(map::new(self, f))
    }

    fn map2<F, U>(self, f: F) -> Box<Future<Item=U, Error=Self::Error>>
        where F: FnOnce(Self::Item) -> U + Send + 'static,
              U: Send + 'static,
              Self: Sized,
    {
        self.then(|r| r.map(f)).boxed()
    }

    fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
        where F: FnOnce(Self::Error) -> E + Send + 'static,
              E: Send + 'static,
              Self: Sized,
    {
        assert_future::<Self::Item, E, _>(map_err::new(self, f))
    }

    fn map_err2<F, E>(self, f: F) -> Box<Future<Item=Self::Item, Error=E>>
        where F: FnOnce(Self::Error) -> E + Send + 'static,
              E: Send + 'static,
              Self: Sized,
    {
        self.then(|res| res.map_err(f)).boxed()
    }

    fn then<F, B>(self, f: F) -> Then<Self, B, F>
        where F: FnOnce(Result<Self::Item, Self::Error>) -> B + Send + 'static,
              B: IntoFuture,
              Self: Sized,
    {
        assert_future::<B::Item, B::Error, _>(then::new(self, f))
    }

    fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
        where F: FnOnce(Self::Item) -> B + Send + 'static,
              B: IntoFuture<Error = Self::Error>,
              Self: Sized,
    {
        assert_future::<B::Item, Self::Error, _>(and_then::new(self, f))
    }

    fn and_then2<F, B>(self, f: F) -> Box<Future<Item=B::Item, Error=Self::Error>>
        where F: FnOnce(Self::Item) -> B + Send + 'static,
              B: IntoFuture<Error = Self::Error>,
              Self: Sized,
    {
        self.then(|res| {
            match res {
                Ok(e) => f(e).into_future().boxed(),
                Err(e) => failed(e).boxed(),
            }
        }).boxed()
    }

    fn or_else<F, B>(self, f: F) -> OrElse<Self, B, F>
        where F: FnOnce(Self::Error) -> B + Send + 'static,
              B: IntoFuture<Item = Self::Item>,
              Self: Sized,
    {
        assert_future::<Self::Item, B::Error, _>(or_else::new(self, f))
    }

    fn or_else2<F, B>(self, f: F) -> Box<Future<Item=B::Item, Error=B::Error>>
        where F: FnOnce(Self::Error) -> B + Send + 'static,
              B: IntoFuture<Item = Self::Item>,
              Self: Sized,
    {
        self.then(|res| {
            match res {
                Ok(e) => finished(e).boxed(),
                Err(e) => f(e).into_future().boxed(),
            }
        }).boxed()
    }

    fn select<B>(self, other: B) -> Select<Self, B::Future>
        where B: IntoFuture<Item=Self::Item, Error=Self::Error>,
              Self: Sized,
    {
        let f = select::new(self, other.into_future());
        assert_future::<Self::Item, Self::Error, _>(f)
    }

    fn join<B>(self, other: B) -> Join<Self, B::Future>
        where B: IntoFuture<Error=Self::Error>,
              Self: Sized,
    {
        let f = join::new(self, other.into_future());
        assert_future::<(Self::Item, B::Item), Self::Error, _>(f)
    }

    fn flatten(self) -> Flatten<Self>
        where Self::Item: IntoFuture,
              <<Self as Future>::Item as IntoFuture>::Error:
                    From<<Self as Future>::Error>,
              Self: Sized
    {
        let f = flatten::new(self);
        assert_future::<<<Self as Future>::Item as IntoFuture>::Item,
                        <<Self as Future>::Item as IntoFuture>::Error,
                        _>(f)
    }

    fn flatten2(self) -> Box<Future<Item=<<Self as Future>::Item as IntoFuture>::Item,
                                    Error=<<Self as Future>::Item as IntoFuture>::Error>>
        where Self::Item: IntoFuture,
              <<Self as Future>::Item as IntoFuture>::Error:
                    From<<Self as Future>::Error>,
              Self: Sized
    {
        self.then(|res| {
            match res {
                Ok(e) => e.into_future().boxed(),
                Err(e) => failed(From::from(e)).boxed(),
            }
        }).boxed()
    }
}

fn assert_future<A, B, F>(t: F) -> F
    where F: Future<Item=A, Error=B>,
          A: Send + 'static,
          B: Send + 'static,
{
    t
}

pub trait Callback<T, E>: Send + 'static {
    fn call(self: Box<Self>, result: PollResult<T, E>);
}

impl<F, T, E> Callback<T, E> for F
    where F: FnOnce(PollResult<T, E>) + Send + 'static
{
    fn call(self: Box<F>, result: PollResult<T, E>) {
        (*self)(result)
    }
}

pub trait IntoFuture: Send + 'static {
    type Future: Future<Item=Self::Item, Error=Self::Error>;
    type Item: Send + 'static;
    type Error: Send + 'static;

    fn into_future(self) -> Self::Future;
}

impl<F: Future> IntoFuture for F {
    type Future = F;
    type Item = F::Item;
    type Error = F::Error;

    fn into_future(self) -> F {
        self
    }
}
<|endoftext|>


<commit_before><commit_msg>Use trailing commas consistently<commit_after><|endoftext|>


<commit_before><commit_msg>chg to work<commit_after><|endoftext|>


<commit_before><commit_msg>added segmented sieve test<commit_after><|endoftext|>


<commit_before><commit_msg>Remove obsolete license attribute<commit_after><|endoftext|>


<commit_before><commit_msg>Adding color documentation.<commit_after><|endoftext|>


<commit_before><commit_msg>added comment prefixes such that the documentation is built correctly<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary mutability on writer<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>A hack to support StrBuf.<commit_after><|endoftext|>


<commit_before><commit_msg>mpm: use toml assertion<commit_after><|endoftext|>


<commit_before><commit_msg>Details<commit_after><|endoftext|>


<commit_before><commit_msg>Rename TermType to TermKind<commit_after><|endoftext|>


<commit_before>import std._io.stdio_reader;
import std._str;
import std.map;
import std.map.hashmap;

fn new_str_hash[V]() -> map.hashmap[str,V] {
    let map.hashfn[str] hasher = _str.hash;
    let map.eqfn[str] eqer = _str.eq;
    ret map.mk_hashmap[str,V](hasher, eqer);
}

type reader = obj {
              fn is_eof() -> bool;
              fn curr() -> char;
              fn next() -> char;
              fn bump();
              fn get_curr_pos() -> tup(str,uint,uint);
              fn get_keywords() -> hashmap[str,token.token];
              fn get_reserved() -> hashmap[str,()];
};

fn new_reader(stdio_reader rdr, str filename) -> reader
{
    obj reader(stdio_reader rdr,
               str filename,
               mutable char c,
               mutable char n,
               mutable uint line,
               mutable uint col,
               hashmap[str,token.token] keywords,
               hashmap[str,()] reserved)
        {
            fn is_eof() -> bool {
                ret c == (-1) as char;
            }

            fn get_curr_pos() -> tup(str,uint,uint) {
                ret tup(filename, line, col);
            }

            fn curr() -> char {
                ret c;
            }

            fn next() -> char {
                ret n;
            }

            fn bump() {
                c = n;

                if (c == (-1) as char) {
                    ret;
                }

                if (c == '\n') {
                    line += 1u;
                    col = 0u;
                } else {
                    col += 1u;
                }

                n = rdr.getc() as char;
            }

            fn get_keywords() -> hashmap[str,token.token] {
                ret keywords;
            }

            fn get_reserved() -> hashmap[str,()] {
                ret reserved;
            }
        }

    auto keywords = new_str_hash[token.token]();
    auto reserved = new_str_hash[()]();

    keywords.insert("mod", token.MOD());
    keywords.insert("use", token.USE());
    keywords.insert("meta", token.META());
    keywords.insert("auth", token.AUTH());

    keywords.insert("syntax", token.SYNTAX());

    keywords.insert("if", token.IF());
    keywords.insert("else", token.ELSE());
    keywords.insert("while", token.WHILE());
    keywords.insert("do", token.DO());
    keywords.insert("alt", token.ALT());
    keywords.insert("case", token.CASE());

    keywords.insert("for", token.FOR());
    keywords.insert("each", token.EACH());
    keywords.insert("put", token.PUT());
    keywords.insert("ret", token.RET());
    keywords.insert("be", token.BE());

    ret reader(rdr, filename, rdr.getc() as char, rdr.getc() as char,
               1u, 1u, keywords, reserved);
}

fn in_range(char c, char lo, char hi) -> bool {
    ret lo <= c && c <= hi;
}

fn is_alpha(char c) -> bool {
    ret in_range(c, 'a', 'z') ||
        in_range(c, 'A', 'Z');
}

fn is_dec_digit(char c) -> bool {
    ret in_range(c, '0', '9');
}

fn is_hex_digit(char c) -> bool {
    ret in_range(c, '0', '9') ||
        in_range(c, 'a', 'f') ||
        in_range(c, 'A', 'F');
}

fn is_bin_digit(char c) -> bool {
    ret c == '0' || c == '1';
}

fn is_whitespace(char c) -> bool {
    ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

fn consume_any_whitespace(reader rdr) {
    while (is_whitespace(rdr.curr())) {
        rdr.bump();
    }
    be consume_any_line_comment(rdr);
}

fn consume_any_line_comment(reader rdr) {
    if (rdr.curr() == '/') {
        if (rdr.next() == '/') {
            while (rdr.curr() != '\n') {
                rdr.bump();
            }
            // Restart whitespace munch.
            be consume_any_whitespace(rdr);
        }
    }
}

fn next_token(reader rdr) -> token.token {
    auto accum_str = "";
    auto accum_int = 0;

    consume_any_whitespace(rdr);

    if (rdr.is_eof()) { ret token.EOF(); }

    auto c = rdr.curr();

    if (is_alpha(c)) {
        while (is_alpha(rdr.curr())) {
            c = rdr.curr();
            accum_str += (c as u8);
            rdr.bump();
        }
        ret token.IDENT(accum_str);
    }

    if (is_dec_digit(c)) {
        if (c == '0') {
            log "fixme: leading zero";
            fail;
        } else {
            while (is_dec_digit(c)) {
                c = rdr.curr();
                accum_int *= 10;
                accum_int += (c as int) - ('0' as int);
                rdr.bump();
            }
            ret token.LIT_INT(accum_int);
        }
    }

    fn op_or_opeq(reader rdr, token.op op) -> token.token {
        rdr.bump();
        if (rdr.next() == '=') {
            rdr.bump();
            ret token.OPEQ(op);
        } else {
            ret token.OP(op);
        }
    }

    alt (c) {
        // One-byte tokens.
        case (';') { rdr.bump(); ret token.SEMI(); }
        case (',') { rdr.bump(); ret token.COMMA(); }
        case ('.') { rdr.bump(); ret token.DOT(); }
        case ('(') { rdr.bump(); ret token.LPAREN(); }
        case (')') { rdr.bump(); ret token.RPAREN(); }
        case ('{') { rdr.bump(); ret token.LBRACE(); }
        case ('}') { rdr.bump(); ret token.RBRACE(); }
        case ('[') { rdr.bump(); ret token.LBRACKET(); }
        case (']') { rdr.bump(); ret token.RBRACKET(); }
        case ('@') { rdr.bump(); ret token.AT(); }
        case ('#') { rdr.bump(); ret token.POUND(); }

        // Multi-byte tokens.
        case ('=') {
            if (rdr.next() == '=') {
                rdr.bump();
                rdr.bump();
                ret token.OP(token.EQEQ());
            } else {
                rdr.bump();
                ret token.OP(token.EQ());
            }
        }

        case ('\'') {
            rdr.bump();
            auto c2 = rdr.curr();
            if (c2 == '\\') {
                alt (rdr.next()) {
                    case ('n') { rdr.bump(); c2 = '\n'; }
                    case ('r') { rdr.bump(); c2 = '\r'; }
                    case ('t') { rdr.bump(); c2 = '\t'; }
                    case ('\\') { rdr.bump(); c2 = '\\'; }
                    case ('\'') { rdr.bump(); c2 = '\''; }
                    // FIXME: unicode numeric escapes.
                    case (c2) {
                        log "unknown character escape";
                        log c2;
                        fail;
                    }
                }
            }

            if (rdr.next() != '\'') {
                log "unterminated character constant";
                fail;
            }
            rdr.bump();
            rdr.bump();
            ret token.LIT_CHAR(c2);
        }

        case ('"') {
            rdr.bump();
            // FIXME: general utf8-consumption support.
            while (rdr.curr() != '"') {
                alt (rdr.curr()) {
                    case ('\\') {
                        alt (rdr.next()) {
                            case ('n') { rdr.bump(); accum_str += '\n' as u8; }
                            case ('r') { rdr.bump(); accum_str += '\r' as u8; }
                            case ('t') { rdr.bump(); accum_str += '\t' as u8; }
                            case ('\\') { rdr.bump(); accum_str += '\\' as u8; }
                            case ('"') { rdr.bump(); accum_str += '"' as u8; }
                            // FIXME: unicode numeric escapes.
                            case (c2) {
                                log "unknown string escape";
                                log c2;
                                fail;
                            }
                        }
                    }
                    case (_) {
                        accum_str += rdr.curr() as u8;
                    }
                }
                rdr.bump();
            }
            rdr.bump();
            ret token.LIT_STR(accum_str);
        }

        case ('-') {
            if (rdr.next() == '>') {
                rdr.bump();
                rdr.bump();
                ret token.RARROW();
            } else {
                ret op_or_opeq(rdr, token.MINUS());
            }
        }

        case ('&') {
            if (rdr.next() == '&') {
                rdr.bump();
                rdr.bump();
                ret token.OP(token.ANDAND());
            } else {
                ret op_or_opeq(rdr, token.AND());
            }
        }

        case ('+') {
            ret op_or_opeq(rdr, token.PLUS());
        }

        case ('*') {
            ret op_or_opeq(rdr, token.STAR());
        }

        case ('/') {
            ret op_or_opeq(rdr, token.STAR());
        }

        case ('!') {
            ret op_or_opeq(rdr, token.NOT());
        }

        case ('^') {
            ret op_or_opeq(rdr, token.CARET());
        }

        case ('%') {
            ret op_or_opeq(rdr, token.PERCENT());
        }

    }

    log "lexer stopping at ";
    log c;
    ret token.EOF();
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Whitespace shuffle in rustc's lexer to fit 78-column rule and put out burning tinderbox.<commit_after>import std._io.stdio_reader;
import std._str;
import std.map;
import std.map.hashmap;

fn new_str_hash[V]() -> map.hashmap[str,V] {
    let map.hashfn[str] hasher = _str.hash;
    let map.eqfn[str] eqer = _str.eq;
    ret map.mk_hashmap[str,V](hasher, eqer);
}

type reader = obj {
              fn is_eof() -> bool;
              fn curr() -> char;
              fn next() -> char;
              fn bump();
              fn get_curr_pos() -> tup(str,uint,uint);
              fn get_keywords() -> hashmap[str,token.token];
              fn get_reserved() -> hashmap[str,()];
};

fn new_reader(stdio_reader rdr, str filename) -> reader
{
    obj reader(stdio_reader rdr,
               str filename,
               mutable char c,
               mutable char n,
               mutable uint line,
               mutable uint col,
               hashmap[str,token.token] keywords,
               hashmap[str,()] reserved)
        {
            fn is_eof() -> bool {
                ret c == (-1) as char;
            }

            fn get_curr_pos() -> tup(str,uint,uint) {
                ret tup(filename, line, col);
            }

            fn curr() -> char {
                ret c;
            }

            fn next() -> char {
                ret n;
            }

            fn bump() {
                c = n;

                if (c == (-1) as char) {
                    ret;
                }

                if (c == '\n') {
                    line += 1u;
                    col = 0u;
                } else {
                    col += 1u;
                }

                n = rdr.getc() as char;
            }

            fn get_keywords() -> hashmap[str,token.token] {
                ret keywords;
            }

            fn get_reserved() -> hashmap[str,()] {
                ret reserved;
            }
        }

    auto keywords = new_str_hash[token.token]();
    auto reserved = new_str_hash[()]();

    keywords.insert("mod", token.MOD());
    keywords.insert("use", token.USE());
    keywords.insert("meta", token.META());
    keywords.insert("auth", token.AUTH());

    keywords.insert("syntax", token.SYNTAX());

    keywords.insert("if", token.IF());
    keywords.insert("else", token.ELSE());
    keywords.insert("while", token.WHILE());
    keywords.insert("do", token.DO());
    keywords.insert("alt", token.ALT());
    keywords.insert("case", token.CASE());

    keywords.insert("for", token.FOR());
    keywords.insert("each", token.EACH());
    keywords.insert("put", token.PUT());
    keywords.insert("ret", token.RET());
    keywords.insert("be", token.BE());

    ret reader(rdr, filename, rdr.getc() as char, rdr.getc() as char,
               1u, 1u, keywords, reserved);
}

fn in_range(char c, char lo, char hi) -> bool {
    ret lo <= c && c <= hi;
}

fn is_alpha(char c) -> bool {
    ret in_range(c, 'a', 'z') ||
        in_range(c, 'A', 'Z');
}

fn is_dec_digit(char c) -> bool {
    ret in_range(c, '0', '9');
}

fn is_hex_digit(char c) -> bool {
    ret in_range(c, '0', '9') ||
        in_range(c, 'a', 'f') ||
        in_range(c, 'A', 'F');
}

fn is_bin_digit(char c) -> bool {
    ret c == '0' || c == '1';
}

fn is_whitespace(char c) -> bool {
    ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

fn consume_any_whitespace(reader rdr) {
    while (is_whitespace(rdr.curr())) {
        rdr.bump();
    }
    be consume_any_line_comment(rdr);
}

fn consume_any_line_comment(reader rdr) {
    if (rdr.curr() == '/') {
        if (rdr.next() == '/') {
            while (rdr.curr() != '\n') {
                rdr.bump();
            }
            // Restart whitespace munch.
            be consume_any_whitespace(rdr);
        }
    }
}

fn next_token(reader rdr) -> token.token {
    auto accum_str = "";
    auto accum_int = 0;

    consume_any_whitespace(rdr);

    if (rdr.is_eof()) { ret token.EOF(); }

    auto c = rdr.curr();

    if (is_alpha(c)) {
        while (is_alpha(rdr.curr())) {
            c = rdr.curr();
            accum_str += (c as u8);
            rdr.bump();
        }
        ret token.IDENT(accum_str);
    }

    if (is_dec_digit(c)) {
        if (c == '0') {
            log "fixme: leading zero";
            fail;
        } else {
            while (is_dec_digit(c)) {
                c = rdr.curr();
                accum_int *= 10;
                accum_int += (c as int) - ('0' as int);
                rdr.bump();
            }
            ret token.LIT_INT(accum_int);
        }
    }

    fn op_or_opeq(reader rdr, token.op op) -> token.token {
        rdr.bump();
        if (rdr.next() == '=') {
            rdr.bump();
            ret token.OPEQ(op);
        } else {
            ret token.OP(op);
        }
    }

    alt (c) {
        // One-byte tokens.
        case (';') { rdr.bump(); ret token.SEMI(); }
        case (',') { rdr.bump(); ret token.COMMA(); }
        case ('.') { rdr.bump(); ret token.DOT(); }
        case ('(') { rdr.bump(); ret token.LPAREN(); }
        case (')') { rdr.bump(); ret token.RPAREN(); }
        case ('{') { rdr.bump(); ret token.LBRACE(); }
        case ('}') { rdr.bump(); ret token.RBRACE(); }
        case ('[') { rdr.bump(); ret token.LBRACKET(); }
        case (']') { rdr.bump(); ret token.RBRACKET(); }
        case ('@') { rdr.bump(); ret token.AT(); }
        case ('#') { rdr.bump(); ret token.POUND(); }

        // Multi-byte tokens.
        case ('=') {
            if (rdr.next() == '=') {
                rdr.bump();
                rdr.bump();
                ret token.OP(token.EQEQ());
            } else {
                rdr.bump();
                ret token.OP(token.EQ());
            }
        }

        case ('\'') {
            rdr.bump();
            auto c2 = rdr.curr();
            if (c2 == '\\') {
                alt (rdr.next()) {
                    case ('n') { rdr.bump(); c2 = '\n'; }
                    case ('r') { rdr.bump(); c2 = '\r'; }
                    case ('t') { rdr.bump(); c2 = '\t'; }
                    case ('\\') { rdr.bump(); c2 = '\\'; }
                    case ('\'') { rdr.bump(); c2 = '\''; }
                    // FIXME: unicode numeric escapes.
                    case (c2) {
                        log "unknown character escape";
                        log c2;
                        fail;
                    }
                }
            }

            if (rdr.next() != '\'') {
                log "unterminated character constant";
                fail;
            }
            rdr.bump();
            rdr.bump();
            ret token.LIT_CHAR(c2);
        }

        case ('"') {
            rdr.bump();
            // FIXME: general utf8-consumption support.
            while (rdr.curr() != '"') {
                alt (rdr.curr()) {
                    case ('\\') {
                        alt (rdr.next()) {
                            case ('n') {
                                rdr.bump();
                                accum_str += '\n' as u8;
                            }
                            case ('r') {
                                rdr.bump();
                                accum_str += '\r' as u8;
                            }
                            case ('t') {
                                rdr.bump();
                                accum_str += '\t' as u8;
                            }
                            case ('\\') {
                                rdr.bump();
                                accum_str += '\\' as u8;
                            }
                            case ('"') {
                                rdr.bump();
                                accum_str += '"' as u8;
                            }
                            // FIXME: unicode numeric escapes.
                            case (c2) {
                                log "unknown string escape";
                                log c2;
                                fail;
                            }
                        }
                    }
                    case (_) {
                        accum_str += rdr.curr() as u8;
                    }
                }
                rdr.bump();
            }
            rdr.bump();
            ret token.LIT_STR(accum_str);
        }

        case ('-') {
            if (rdr.next() == '>') {
                rdr.bump();
                rdr.bump();
                ret token.RARROW();
            } else {
                ret op_or_opeq(rdr, token.MINUS());
            }
        }

        case ('&') {
            if (rdr.next() == '&') {
                rdr.bump();
                rdr.bump();
                ret token.OP(token.ANDAND());
            } else {
                ret op_or_opeq(rdr, token.AND());
            }
        }

        case ('+') {
            ret op_or_opeq(rdr, token.PLUS());
        }

        case ('*') {
            ret op_or_opeq(rdr, token.STAR());
        }

        case ('/') {
            ret op_or_opeq(rdr, token.STAR());
        }

        case ('!') {
            ret op_or_opeq(rdr, token.NOT());
        }

        case ('^') {
            ret op_or_opeq(rdr, token.CARET());
        }

        case ('%') {
            ret op_or_opeq(rdr, token.PERCENT());
        }

    }

    log "lexer stopping at ";
    log c;
    ret token.EOF();
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before><commit_msg>Range was not properly defined<commit_after><|endoftext|>


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

// Check that extern crate declarations are excluded from glob imports.

#![feature(core)]
extern crate core;

mod T {
    use super::*;
}

fn main() {
    use T::core; //~ ERROR unresolved import `T::core`
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #83806 - JohnTitor:issue-51446, r=estebank<commit_after>// Regression test for #51446.
// check-pass

trait Foo {
    type Item;
    fn get(&self) -> Self::Item;
}

fn blah<T, F>(x: T, f: F) -> B<T::Item, impl Fn(T::Item)>
where
    T: Foo,
    F: Fn(T::Item),
{
    B { x: x.get(), f }
}

pub struct B<T, F>
where
    F: Fn(T),
{
    pub x: T,
    pub f: F,
}

impl Foo for i32 {
    type Item = i32;
    fn get(&self) -> i32 {
        *self
    }
}

fn main() {
    let _ = blah(0, |_| ());
}
<|endoftext|>


<commit_before><commit_msg>added missing file, and inter-node links added<commit_after>use std::num;
use std::num::*;

use syntax::parse;
use syntax::ast;
use syntax::ast_map;
use syntax::visit;
use syntax::oldvisit;
use syntax::oldvisit::*;
use syntax::oldvisit::{Visitor, fn_kind};
use syntax::codemap;
use rustc::{front, metadata, driver, middle};
use rustc::middle::mem_categorization::ast_node;
use rustc::middle::ty;

use std::hashmap;
use codemaput::*;

pub struct RFindCtx {
     crate: @ast::Crate,
     tycx: middle::ty::ctxt,
     sess: driver::session::Session,
     ca: driver::driver::CrateAnalysis
}

<|endoftext|>


<commit_before><commit_msg>added tree example<commit_after>use std::fmt::Debug;
use std::collections::VecDeque;

#[derive(Debug)]
struct NodeInfo<'a,T: 'a + Debug> {
    depth: u32,
    iter: &'a Tree<T>,
}

impl<'a,T: 'a + Debug> NodeInfo<'a,T> {
    fn new(t: u32, it: &'a Tree<T>) -> Self { NodeInfo { depth: t, iter: it, } }
}

#[derive(Debug)]
struct Tree<T:Debug> {
  data: T,
  children: Vec<Tree<T>>,
}

impl<T:Debug> Tree<T> {
  fn new(t: T, c: Vec<Tree<T>>) -> Self { Tree { data: t, children: c, } }
  fn leaf(t: T) -> Self { Tree { data: t, children: vec![], } }
}

// Note that path elements are listed backwards (right-to-left) because we pop
// them off the end.
fn seek_path<T:Debug>(t: &Tree<T>, mut path: Vec<usize>) -> &Tree<T> {
  if let Some(index) = path.pop() {
    seek_path(&t.children[index], path)
  } else {
    t
  }
}

fn print_tree<T:Debug>(t: &Tree<T>) {
    let mut q: VecDeque<NodeInfo<T>> = VecDeque::new();
    let mut depth_old: u32 = 0;

    q.push_back(NodeInfo::new(depth_old, t));

    while let Some(mut u) = q.pop_front() {
        if u.depth > depth_old {
            println!("{:?}", u.iter.data);
            print!(" ");
        }
        else {
            print!("{:?}", u.iter.data);
            print!(" ");
        }

        depth_old = u.depth;
        u.depth += 1;

        for kid in u.iter.children.iter() {
            q.push_back(NodeInfo::new(u.depth, kid));
        }
    }

    println!("");
}

fn main() {
    let t = Tree::new("a", vec![Tree::leaf("b"),
                                Tree::leaf("c"),
                                Tree::new("d", vec![Tree::leaf("e")])]);
    print_tree(&t);

    println!["{:?}", seek_path(&t, vec![0usize])];
    println!["{:?}", seek_path(&t, vec![2usize])];
    println!["{:?}", seek_path(&t, vec![0usize, 2usize])];
}
<|endoftext|>


<commit_before><commit_msg>Switched the intersect algorithm to one that works<commit_after><|endoftext|>


<commit_before><commit_msg>Remove denig: it is not a macro.<commit_after><|endoftext|>


<commit_before><commit_msg>*This* is the proof-of-concept code.<commit_after>extern crate "interleave_jit" as ellell;

use ellell::{Context, Module, Builder, Position, ExecutionEngine, Value};

fn main() {
    let ctxt = Context::new();
    let module = Module::in_context(&ctxt, "incremeters");
    {
        let mut builder = Builder::in_context(&ctxt);

        // void myfunction(i8*);
        let target_type = ctxt.int_type(8);
        let pointer_type = ctxt.pointer_type(target_type);
        let void = ctxt.void_type();
        let function_type = ctxt.function_type(void, &[pointer_type], false);
        let func = module.add_function("increment_i8", function_type);

        // Create a basic block inside the function we just created
        let bb = ctxt.append_bb(func, "entry");
        // Generate code at the end of the new basic block
        builder.position(Position::EndOf(bb));

        let params = func.function_params().collect::<Vec<_>>();
        let load = builder.build_load(params[0]);
        let one = Value::const_int(&target_type, 1, false);
        let result = builder.build_add(load, one);
        builder.build_store(result, params[0]);
        builder.build_ret_void();
        module.dump();
    }

    let ee = ExecutionEngine::new(module);
    let the_function = ee.get_function("increment_i8").expect("No function named \"increment_i8\"");
    let the_function = unsafe {
        std::mem::transmute::<extern "C" fn() -> (),
                              extern "C" fn(*mut i8) -> ()>(the_function)
    };
    println!("&increment_i8 = {:?}", the_function as *const ());

    let mut the_value: i8 = 0;
    println!("x = {}", the_value);
    println!("increment_i8(&x)");
    the_function(&mut the_value as *mut _);
    println!("x = {}", the_value);
    assert_eq!(the_value, 1);
}
<|endoftext|>


<commit_before><commit_msg>test for correct drops<commit_after><|endoftext|>


<commit_before><commit_msg>Implement simple SMTP parser<commit_after>
fn ascii_upcase(ascii: u8) -> u8 {
    if ascii >= b'a' && ascii <= b'z' {
        ascii - b'a' + b'A'
    } else {
        ascii
    }
}

#[test]
fn test_ascii_upcase() {
    assert!(ascii_upcase(b'E') == b'E');
    assert!(ascii_upcase(b'e') == b'E');
}

fn ascii_upcase_compare(str: &[u8], against: &[u8]) -> bool {
    str.len() == against.len() &&
    str.iter().zip(against.iter()).all(|(&a,&b)| ascii_upcase(a) == ascii_upcase(b))
}

#[test]
fn test_ascii_upcase_compare() {
    assert!(ascii_upcase_compare(b"ehlo", b"EHLO") == true);
    assert!(ascii_upcase_compare(b"EHLO", b"EHLO") == true);
    assert!(ascii_upcase_compare(b"bHLO", b"EHLO") == false);
    assert!(ascii_upcase_compare(b"EHLO ", b"EHLO") == false);
}

#[deriving(PartialEq, Eq)]
enum SmtpCommand {
    Ehlo,
    Helo,
    Mail,
    Rcpt,
    Data,
    Unknown
}

pub fn parse_line(line: &[u8]) -> SmtpCommand {
    if line.len() >= 4 {
        let cmd = line.slice(0, 4);

        if ascii_upcase_compare(cmd, b"EHLO") {
            Ehlo
        }
        else if ascii_upcase_compare(cmd, b"HELO") {
            Helo
        }
        else if ascii_upcase_compare(cmd, b"MAIL") {
            Mail
        }
        else if ascii_upcase_compare(cmd, b"RCPT") {
            Rcpt
        }
        else if ascii_upcase_compare(cmd, b"DATA") {
           Data
        }
        else {
            Unknown
        }
    }
    else {
        Unknown
    }
}

#[test]
fn test_parse_commands() {
    assert!(parse_line(b"ehlo mail.ntecs.de\r\n") == Ehlo);
    assert!(parse_line(b"helo mail.ntecs.de\r\n") == Helo);
    assert!(parse_line(b"DATA\r\n") == Data);
}
<|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.

/*!

Higher level communication abstractions.

*/

#[allow(missing_doc)];

use std::comm::{GenericChan, GenericSmartChan, GenericPort};
use std::comm::{Chan, Port, Peekable};
use std::comm;

/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<T, U> {
    priv chan: Chan<T>,
    priv port: Port<U>,
}

// Allow these methods to be used without import:
impl<T:Send,U:Send> DuplexStream<T, U> {
    pub fn send(&self, x: T) {
        self.chan.send(x)
    }
    pub fn try_send(&self, x: T) -> bool {
        self.chan.try_send(x)
    }
    pub fn recv(&self, ) -> U {
        self.port.recv()
    }
    pub fn try_recv(&self) -> Option<U> {
        self.port.try_recv()
    }
    pub fn peek(&self) -> bool {
        self.port.peek()
    }
}

impl<T:Send,U:Send> GenericChan<T> for DuplexStream<T, U> {
    fn send(&self, x: T) {
        self.chan.send(x)
    }
}

impl<T:Send,U:Send> GenericSmartChan<T> for DuplexStream<T, U> {
    fn try_send(&self, x: T) -> bool {
        self.chan.try_send(x)
    }
}

impl<T:Send,U:Send> GenericPort<U> for DuplexStream<T, U> {
    fn recv(&self) -> U {
        self.port.recv()
    }

    fn try_recv(&self) -> Option<U> {
        self.port.try_recv()
    }
}

impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
    fn peek(&self) -> bool {
        self.port.peek()
    }
}

/// Creates a bidirectional stream.
pub fn DuplexStream<T:Send,U:Send>()
    -> (DuplexStream<T, U>, DuplexStream<U, T>)
{
    let (p1, c2) = comm::stream();
    let (p2, c1) = comm::stream();
    (DuplexStream {
        chan: c1,
        port: p1
    },
     DuplexStream {
         chan: c2,
         port: p2
     })
}

#[cfg(test)]
mod test {
    use comm::DuplexStream;

    #[test]
    pub fn DuplexStream1() {
        let (left, right) = DuplexStream();

        left.send(~"abc");
        right.send(123);

        assert!(left.recv() == 123);
        assert!(right.recv() == ~"abc");
    }
}
<commit_msg>Rendezvous stream for synchronous channel messaging<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Higher level communication abstractions.

*/

#[allow(missing_doc)];

use std::comm::{GenericChan, GenericSmartChan, GenericPort};
use std::comm::{Chan, Port, Peekable};
use std::comm;

/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<T, U> {
    priv chan: Chan<T>,
    priv port: Port<U>,
}

// Allow these methods to be used without import:
impl<T:Send,U:Send> DuplexStream<T, U> {
    pub fn send(&self, x: T) {
        self.chan.send(x)
    }
    pub fn try_send(&self, x: T) -> bool {
        self.chan.try_send(x)
    }
    pub fn recv(&self, ) -> U {
        self.port.recv()
    }
    pub fn try_recv(&self) -> Option<U> {
        self.port.try_recv()
    }
    pub fn peek(&self) -> bool {
        self.port.peek()
    }
}

impl<T:Send,U:Send> GenericChan<T> for DuplexStream<T, U> {
    fn send(&self, x: T) {
        self.chan.send(x)
    }
}

impl<T:Send,U:Send> GenericSmartChan<T> for DuplexStream<T, U> {
    fn try_send(&self, x: T) -> bool {
        self.chan.try_send(x)
    }
}

impl<T:Send,U:Send> GenericPort<U> for DuplexStream<T, U> {
    fn recv(&self) -> U {
        self.port.recv()
    }

    fn try_recv(&self) -> Option<U> {
        self.port.try_recv()
    }
}

impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
    fn peek(&self) -> bool {
        self.port.peek()
    }
}

/// Creates a bidirectional stream.
pub fn DuplexStream<T:Send,U:Send>()
    -> (DuplexStream<T, U>, DuplexStream<U, T>)
{
    let (p1, c2) = comm::stream();
    let (p2, c1) = comm::stream();
    (DuplexStream {
        chan: c1,
        port: p1
    },
     DuplexStream {
         chan: c2,
         port: p2
     })
}

/// An extension of `pipes::stream` that provides synchronous message sending.
pub struct SyncChan<T> { priv duplex_stream: DuplexStream<T, ()> }
/// An extension of `pipes::stream` that acknowledges each message received.
pub struct SyncPort<T> { priv duplex_stream: DuplexStream<(), T> }

impl<T: Send> GenericChan<T> for SyncChan<T> {
    fn send(&self, val: T) {
        assert!(self.try_send(val), "SyncChan.send: receiving port closed");
    }
}

impl<T: Send> GenericSmartChan<T> for SyncChan<T> {
    /// Sends a message, or report if the receiver has closed the connection before receiving.
    fn try_send(&self, val: T) -> bool {
        self.duplex_stream.try_send(val) && self.duplex_stream.try_recv().is_some()
    }
}

impl<T: Send> GenericPort<T> for SyncPort<T> {
    fn recv(&self) -> T {
        self.try_recv().expect("SyncPort.recv: sending channel closed")
    }

    fn try_recv(&self) -> Option<T> {
        do self.duplex_stream.try_recv().map_move |val| {
            self.duplex_stream.try_send(());
            val
        }
    }
}

impl<T: Send> Peekable<T> for SyncPort<T> {
    fn peek(&self) -> bool {
        self.duplex_stream.peek()
    }
}

/// Creates a stream whose channel, upon sending a message, blocks until the message is received.
pub fn rendezvous<T: Send>() -> (SyncPort<T>, SyncChan<T>) {
    let (chan_stream, port_stream) = DuplexStream();
    (SyncPort { duplex_stream: port_stream }, SyncChan { duplex_stream: chan_stream })
}

#[cfg(test)]
mod test {
    use comm::{DuplexStream, rendezvous};
    use std::rt::test::run_in_newsched_task;
    use std::task::spawn_unlinked;

    #[test]
    pub fn DuplexStream1() {
        let (left, right) = DuplexStream();

        left.send(~"abc");
        right.send(123);

        assert!(left.recv() == 123);
        assert!(right.recv() == ~"abc");
    }

    #[test]
    pub fn basic_rendezvous_test() {
        let (port, chan) = rendezvous();

        do spawn {
            chan.send("abc");
        }

        assert!(port.recv() == "abc");
    }

    #[test]
    fn recv_a_lot() {
        // Rendezvous streams should be able to handle any number of messages being sent
        do run_in_newsched_task {
            let (port, chan) = rendezvous();
            do spawn {
                do 1000000.times { chan.send(()) }
            }
            do 1000000.times { port.recv() }
        }
    }

    #[test]
    fn send_and_fail_and_try_recv() {
        let (port, chan) = rendezvous();
        do spawn_unlinked {
            chan.duplex_stream.send(()); // Can't access this field outside this module
            fail!()
        }
        port.recv()
    }

    #[test]
    fn try_send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        do spawn_unlinked {
            port.duplex_stream.recv();
            fail!()
        }
        chan.try_send(());
    }

    #[test]
    #[should_fail]
    fn send_and_recv_then_fail_before_ack() {
        let (port, chan) = rendezvous();
        do spawn_unlinked {
            port.duplex_stream.recv();
            fail!()
        }
        chan.send(());
    }
}
<|endoftext|>


<commit_before><commit_msg>Problem 33<commit_after>fn gcd(a: int, b: int) -> int {
    match (a, b) {
        (0, b) => b,
        (a, b) => gcd(b%a, a)
    }
}

fn coprime(a: int, b: int) -> bool {
    gcd(a, b) == 1
}

fn main() {
    assert!(coprime(13, 27));
    assert!(!coprime(20536, 7826));
}

<|endoftext|>