<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.

// Detecting language items.
//
// Language items are items that represent concepts intrinsic to the language
// itself. Examples are:
//
// * Traits that specify "kinds"; e.g. "Sync", "Send".
//
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
//
// * Functions called by the compiler itself.

pub use self::LangItem::*;

use hir::def_id::DefId;
use ty::{self, TyCtxt};
use middle::weak_lang_items;
use util::nodemap::FxHashMap;

use syntax::ast;
use syntax::symbol::Symbol;
use hir::itemlikevisit::ItemLikeVisitor;
use hir;

// The actual lang items defined come at the end of this file in one handy table.
// So you probably just want to nip down to the end.
macro_rules! language_item_table {
    (
        $( $variant:ident, $name:expr, $method:ident; )*
    ) => {

enum_from_u32! {
    #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
    pub enum LangItem {
        $($variant,)*
    }
}

impl LangItem {
    fn name(self) -> &'static str {
        match self {
            $( $variant => $name, )*
        }
    }
}

pub struct LanguageItems {
    pub items: Vec<Option<DefId>>,
    pub missing: Vec<LangItem>,
}

impl LanguageItems {
    pub fn new() -> LanguageItems {
        fn foo(_: LangItem) -> Option<DefId> { None }

        LanguageItems {
            items: vec![$(foo($variant)),*],
            missing: Vec::new(),
        }
    }

    pub fn items(&self) -> &[Option<DefId>] {
        &*self.items
    }

    pub fn require(&self, it: LangItem) -> Result<DefId, String> {
        self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
    }

    pub fn fn_trait_kind(&self, id: DefId) -> Option<ty::ClosureKind> {
        match Some(id) {
            x if x == self.fn_trait() => Some(ty::ClosureKind::Fn),
            x if x == self.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
            x if x == self.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
            _ => None
        }
    }

    $(
        #[allow(dead_code)]
        pub fn $method(&self) -> Option<DefId> {
            self.items[$variant as usize]
        }
    )*
}

struct LanguageItemCollector<'a, 'tcx: 'a> {
    items: LanguageItems,

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

    item_refs: FxHashMap<&'static str, usize>,
}

impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        if let Some(value) = extract(&item.attrs) {
            let item_index = self.item_refs.get(&*value.as_str()).cloned();

            if let Some(item_index) = item_index {
                let def_id = self.tcx.hir.local_def_id(item.id);
                self.collect_item(item_index, def_id);
            } else {
                let span = self.tcx.hir.span(item.id);
                span_err!(self.tcx.sess, span, E0522,
                          "definition of an unknown language item: `{}`.",
                          value);
            }
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
        // at present, lang items are always items, not trait items
    }

    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
        // at present, lang items are always items, not impl items
    }
}

impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
    fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> {
        let mut item_refs = FxHashMap();

        $( item_refs.insert($name, $variant as usize); )*

        LanguageItemCollector {
            tcx,
            items: LanguageItems::new(),
            item_refs,
        }
    }

    fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
        // Check for duplicates.
        match self.items.items[item_index] {
            Some(original_def_id) if original_def_id != item_def_id => {
                let name = LangItem::from_u32(item_index as u32).unwrap().name();
                let mut err = match self.tcx.hir.span_if_local(item_def_id) {
                    Some(span) => struct_span_err!(
                        self.tcx.sess,
                        span,
                        E0152,
                        "duplicate lang item found: `{}`.",
                        name),
                    None => self.tcx.sess.struct_err(&format!(
                            "duplicate lang item in crate `{}`: `{}`.",
                            self.tcx.crate_name(item_def_id.krate),
                            name)),
                };
                if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
                    span_note!(&mut err, span,
                               "first defined here.");
                } else {
                    err.note(&format!("first defined in crate `{}`.",
                                      self.tcx.crate_name(original_def_id.krate)));
                }
                err.emit();
            }
            _ => {
                // OK.
            }
        }

        // Matched.
        self.items.items[item_index] = Some(item_def_id);
    }
}

pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
    for attribute in attrs {
        if attribute.check_name("lang") {
            if let Some(value) = attribute.value_str() {
                return Some(value)
            }
        }
    }

    return None;
}

pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
    let mut collector = LanguageItemCollector::new(tcx);
    for &cnum in tcx.crates().iter() {
        for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() {
            collector.collect_item(item_index, def_id);
        }
    }
    tcx.hir.krate().visit_all_item_likes(&mut collector);
    let LanguageItemCollector { mut items, .. } = collector;
    weak_lang_items::check_crate(tcx, &mut items);
    items
}

// End of the macro
    }
}

language_item_table! {
//  Variant name,                    Name,                      Method name;
    CharImplItem,                    "char",                    char_impl;
    StrImplItem,                     "str",                     str_impl;
    SliceImplItem,                   "slice",                   slice_impl;
    ConstPtrImplItem,                "const_ptr",               const_ptr_impl;
    MutPtrImplItem,                  "mut_ptr",                 mut_ptr_impl;
    I8ImplItem,                      "i8",                      i8_impl;
    I16ImplItem,                     "i16",                     i16_impl;
    I32ImplItem,                     "i32",                     i32_impl;
    I64ImplItem,                     "i64",                     i64_impl;
    I128ImplItem,                     "i128",                   i128_impl;
    IsizeImplItem,                   "isize",                   isize_impl;
    U8ImplItem,                      "u8",                      u8_impl;
    U16ImplItem,                     "u16",                     u16_impl;
    U32ImplItem,                     "u32",                     u32_impl;
    U64ImplItem,                     "u64",                     u64_impl;
    U128ImplItem,                    "u128",                    u128_impl;
    UsizeImplItem,                   "usize",                   usize_impl;
    F32ImplItem,                     "f32",                     f32_impl;
    F64ImplItem,                     "f64",                     f64_impl;

    SendTraitLangItem,               "send",                    send_trait;
    SizedTraitLangItem,              "sized",                   sized_trait;
    UnsizeTraitLangItem,             "unsize",                  unsize_trait;
    CopyTraitLangItem,               "copy",                    copy_trait;
    CloneTraitLangItem,              "clone",                   clone_trait;
    SyncTraitLangItem,               "sync",                    sync_trait;
    FreezeTraitLangItem,             "freeze",                  freeze_trait;

    DropTraitLangItem,               "drop",                    drop_trait;

    CoerceUnsizedTraitLangItem,      "coerce_unsized",          coerce_unsized_trait;

    AddTraitLangItem,                "add",                     add_trait;
    SubTraitLangItem,                "sub",                     sub_trait;
    MulTraitLangItem,                "mul",                     mul_trait;
    DivTraitLangItem,                "div",                     div_trait;
    RemTraitLangItem,                "rem",                     rem_trait;
    NegTraitLangItem,                "neg",                     neg_trait;
    NotTraitLangItem,                "not",                     not_trait;
    BitXorTraitLangItem,             "bitxor",                  bitxor_trait;
    BitAndTraitLangItem,             "bitand",                  bitand_trait;
    BitOrTraitLangItem,              "bitor",                   bitor_trait;
    ShlTraitLangItem,                "shl",                     shl_trait;
    ShrTraitLangItem,                "shr",                     shr_trait;
    AddAssignTraitLangItem,          "add_assign",              add_assign_trait;
    SubAssignTraitLangItem,          "sub_assign",              sub_assign_trait;
    MulAssignTraitLangItem,          "mul_assign",              mul_assign_trait;
    DivAssignTraitLangItem,          "div_assign",              div_assign_trait;
    RemAssignTraitLangItem,          "rem_assign",              rem_assign_trait;
    BitXorAssignTraitLangItem,       "bitxor_assign",           bitxor_assign_trait;
    BitAndAssignTraitLangItem,       "bitand_assign",           bitand_assign_trait;
    BitOrAssignTraitLangItem,        "bitor_assign",            bitor_assign_trait;
    ShlAssignTraitLangItem,          "shl_assign",              shl_assign_trait;
    ShrAssignTraitLangItem,          "shr_assign",              shr_assign_trait;
    IndexTraitLangItem,              "index",                   index_trait;
    IndexMutTraitLangItem,           "index_mut",               index_mut_trait;

    UnsafeCellTypeLangItem,          "unsafe_cell",             unsafe_cell_type;

    DerefTraitLangItem,              "deref",                   deref_trait;
    DerefMutTraitLangItem,           "deref_mut",               deref_mut_trait;

    FnTraitLangItem,                 "fn",                      fn_trait;
    FnMutTraitLangItem,              "fn_mut",                  fn_mut_trait;
    FnOnceTraitLangItem,             "fn_once",                 fn_once_trait;

    GeneratorStateLangItem,          "generator_state",         gen_state;
    GeneratorTraitLangItem,          "generator",               gen_trait;

    EqTraitLangItem,                 "eq",                      eq_trait;
    OrdTraitLangItem,                "ord",                     ord_trait;

    // A number of panic-related lang items. The `panic` item corresponds to
    // divide-by-zero and various panic cases with `match`. The
    // `panic_bounds_check` item is for indexing arrays.
    //
    // The `begin_unwind` lang item has a predefined symbol name and is sort of
    // a "weak lang item" in the sense that a crate is not required to have it
    // defined to use it, but a final product is required to define it
    // somewhere. Additionally, there are restrictions on crates that use a weak
    // lang item, but do not have it defined.
    PanicFnLangItem,                 "panic",                   panic_fn;
    PanicBoundsCheckFnLangItem,      "panic_bounds_check",      panic_bounds_check_fn;
    PanicFmtLangItem,                "panic_fmt",               panic_fmt;

    ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
    BoxFreeFnLangItem,               "box_free",                box_free_fn;
    DropInPlaceFnLangItem,             "drop_in_place",           drop_in_place_fn;

    StartFnLangItem,                 "start",                   start_fn;

    EhPersonalityLangItem,           "eh_personality",          eh_personality;
    EhUnwindResumeLangItem,          "eh_unwind_resume",        eh_unwind_resume;
    MSVCTryFilterLangItem,           "msvc_try_filter",         msvc_try_filter;

    OwnedBoxLangItem,                "owned_box",               owned_box;

    PhantomDataItem,                 "phantom_data",            phantom_data;

    NonZeroItem,                     "non_zero",                non_zero;

    DebugTraitLangItem,              "debug_trait",             debug_trait;
}

impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> {
    pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
        self.lang_items().require(lang_item).unwrap_or_else(|msg| {
            self.sess.fatal(&msg)
        })
    }
}
<commit_msg>Derive Debug for LangItem<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Detecting language items.
//
// Language items are items that represent concepts intrinsic to the language
// itself. Examples are:
//
// * Traits that specify "kinds"; e.g. "Sync", "Send".
//
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
//
// * Functions called by the compiler itself.

pub use self::LangItem::*;

use hir::def_id::DefId;
use ty::{self, TyCtxt};
use middle::weak_lang_items;
use util::nodemap::FxHashMap;

use syntax::ast;
use syntax::symbol::Symbol;
use hir::itemlikevisit::ItemLikeVisitor;
use hir;

// The actual lang items defined come at the end of this file in one handy table.
// So you probably just want to nip down to the end.
macro_rules! language_item_table {
    (
        $( $variant:ident, $name:expr, $method:ident; )*
    ) => {

enum_from_u32! {
    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
    pub enum LangItem {
        $($variant,)*
    }
}

impl LangItem {
    fn name(self) -> &'static str {
        match self {
            $( $variant => $name, )*
        }
    }
}

pub struct LanguageItems {
    pub items: Vec<Option<DefId>>,
    pub missing: Vec<LangItem>,
}

impl LanguageItems {
    pub fn new() -> LanguageItems {
        fn foo(_: LangItem) -> Option<DefId> { None }

        LanguageItems {
            items: vec![$(foo($variant)),*],
            missing: Vec::new(),
        }
    }

    pub fn items(&self) -> &[Option<DefId>] {
        &*self.items
    }

    pub fn require(&self, it: LangItem) -> Result<DefId, String> {
        self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
    }

    pub fn fn_trait_kind(&self, id: DefId) -> Option<ty::ClosureKind> {
        match Some(id) {
            x if x == self.fn_trait() => Some(ty::ClosureKind::Fn),
            x if x == self.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
            x if x == self.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
            _ => None
        }
    }

    $(
        #[allow(dead_code)]
        pub fn $method(&self) -> Option<DefId> {
            self.items[$variant as usize]
        }
    )*
}

struct LanguageItemCollector<'a, 'tcx: 'a> {
    items: LanguageItems,

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

    item_refs: FxHashMap<&'static str, usize>,
}

impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        if let Some(value) = extract(&item.attrs) {
            let item_index = self.item_refs.get(&*value.as_str()).cloned();

            if let Some(item_index) = item_index {
                let def_id = self.tcx.hir.local_def_id(item.id);
                self.collect_item(item_index, def_id);
            } else {
                let span = self.tcx.hir.span(item.id);
                span_err!(self.tcx.sess, span, E0522,
                          "definition of an unknown language item: `{}`.",
                          value);
            }
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
        // at present, lang items are always items, not trait items
    }

    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
        // at present, lang items are always items, not impl items
    }
}

impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
    fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> {
        let mut item_refs = FxHashMap();

        $( item_refs.insert($name, $variant as usize); )*

        LanguageItemCollector {
            tcx,
            items: LanguageItems::new(),
            item_refs,
        }
    }

    fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
        // Check for duplicates.
        match self.items.items[item_index] {
            Some(original_def_id) if original_def_id != item_def_id => {
                let name = LangItem::from_u32(item_index as u32).unwrap().name();
                let mut err = match self.tcx.hir.span_if_local(item_def_id) {
                    Some(span) => struct_span_err!(
                        self.tcx.sess,
                        span,
                        E0152,
                        "duplicate lang item found: `{}`.",
                        name),
                    None => self.tcx.sess.struct_err(&format!(
                            "duplicate lang item in crate `{}`: `{}`.",
                            self.tcx.crate_name(item_def_id.krate),
                            name)),
                };
                if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
                    span_note!(&mut err, span,
                               "first defined here.");
                } else {
                    err.note(&format!("first defined in crate `{}`.",
                                      self.tcx.crate_name(original_def_id.krate)));
                }
                err.emit();
            }
            _ => {
                // OK.
            }
        }

        // Matched.
        self.items.items[item_index] = Some(item_def_id);
    }
}

pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
    for attribute in attrs {
        if attribute.check_name("lang") {
            if let Some(value) = attribute.value_str() {
                return Some(value)
            }
        }
    }

    return None;
}

pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
    let mut collector = LanguageItemCollector::new(tcx);
    for &cnum in tcx.crates().iter() {
        for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() {
            collector.collect_item(item_index, def_id);
        }
    }
    tcx.hir.krate().visit_all_item_likes(&mut collector);
    let LanguageItemCollector { mut items, .. } = collector;
    weak_lang_items::check_crate(tcx, &mut items);
    items
}

// End of the macro
    }
}

language_item_table! {
//  Variant name,                    Name,                      Method name;
    CharImplItem,                    "char",                    char_impl;
    StrImplItem,                     "str",                     str_impl;
    SliceImplItem,                   "slice",                   slice_impl;
    ConstPtrImplItem,                "const_ptr",               const_ptr_impl;
    MutPtrImplItem,                  "mut_ptr",                 mut_ptr_impl;
    I8ImplItem,                      "i8",                      i8_impl;
    I16ImplItem,                     "i16",                     i16_impl;
    I32ImplItem,                     "i32",                     i32_impl;
    I64ImplItem,                     "i64",                     i64_impl;
    I128ImplItem,                     "i128",                   i128_impl;
    IsizeImplItem,                   "isize",                   isize_impl;
    U8ImplItem,                      "u8",                      u8_impl;
    U16ImplItem,                     "u16",                     u16_impl;
    U32ImplItem,                     "u32",                     u32_impl;
    U64ImplItem,                     "u64",                     u64_impl;
    U128ImplItem,                    "u128",                    u128_impl;
    UsizeImplItem,                   "usize",                   usize_impl;
    F32ImplItem,                     "f32",                     f32_impl;
    F64ImplItem,                     "f64",                     f64_impl;

    SendTraitLangItem,               "send",                    send_trait;
    SizedTraitLangItem,              "sized",                   sized_trait;
    UnsizeTraitLangItem,             "unsize",                  unsize_trait;
    CopyTraitLangItem,               "copy",                    copy_trait;
    CloneTraitLangItem,              "clone",                   clone_trait;
    SyncTraitLangItem,               "sync",                    sync_trait;
    FreezeTraitLangItem,             "freeze",                  freeze_trait;

    DropTraitLangItem,               "drop",                    drop_trait;

    CoerceUnsizedTraitLangItem,      "coerce_unsized",          coerce_unsized_trait;

    AddTraitLangItem,                "add",                     add_trait;
    SubTraitLangItem,                "sub",                     sub_trait;
    MulTraitLangItem,                "mul",                     mul_trait;
    DivTraitLangItem,                "div",                     div_trait;
    RemTraitLangItem,                "rem",                     rem_trait;
    NegTraitLangItem,                "neg",                     neg_trait;
    NotTraitLangItem,                "not",                     not_trait;
    BitXorTraitLangItem,             "bitxor",                  bitxor_trait;
    BitAndTraitLangItem,             "bitand",                  bitand_trait;
    BitOrTraitLangItem,              "bitor",                   bitor_trait;
    ShlTraitLangItem,                "shl",                     shl_trait;
    ShrTraitLangItem,                "shr",                     shr_trait;
    AddAssignTraitLangItem,          "add_assign",              add_assign_trait;
    SubAssignTraitLangItem,          "sub_assign",              sub_assign_trait;
    MulAssignTraitLangItem,          "mul_assign",              mul_assign_trait;
    DivAssignTraitLangItem,          "div_assign",              div_assign_trait;
    RemAssignTraitLangItem,          "rem_assign",              rem_assign_trait;
    BitXorAssignTraitLangItem,       "bitxor_assign",           bitxor_assign_trait;
    BitAndAssignTraitLangItem,       "bitand_assign",           bitand_assign_trait;
    BitOrAssignTraitLangItem,        "bitor_assign",            bitor_assign_trait;
    ShlAssignTraitLangItem,          "shl_assign",              shl_assign_trait;
    ShrAssignTraitLangItem,          "shr_assign",              shr_assign_trait;
    IndexTraitLangItem,              "index",                   index_trait;
    IndexMutTraitLangItem,           "index_mut",               index_mut_trait;

    UnsafeCellTypeLangItem,          "unsafe_cell",             unsafe_cell_type;

    DerefTraitLangItem,              "deref",                   deref_trait;
    DerefMutTraitLangItem,           "deref_mut",               deref_mut_trait;

    FnTraitLangItem,                 "fn",                      fn_trait;
    FnMutTraitLangItem,              "fn_mut",                  fn_mut_trait;
    FnOnceTraitLangItem,             "fn_once",                 fn_once_trait;

    GeneratorStateLangItem,          "generator_state",         gen_state;
    GeneratorTraitLangItem,          "generator",               gen_trait;

    EqTraitLangItem,                 "eq",                      eq_trait;
    OrdTraitLangItem,                "ord",                     ord_trait;

    // A number of panic-related lang items. The `panic` item corresponds to
    // divide-by-zero and various panic cases with `match`. The
    // `panic_bounds_check` item is for indexing arrays.
    //
    // The `begin_unwind` lang item has a predefined symbol name and is sort of
    // a "weak lang item" in the sense that a crate is not required to have it
    // defined to use it, but a final product is required to define it
    // somewhere. Additionally, there are restrictions on crates that use a weak
    // lang item, but do not have it defined.
    PanicFnLangItem,                 "panic",                   panic_fn;
    PanicBoundsCheckFnLangItem,      "panic_bounds_check",      panic_bounds_check_fn;
    PanicFmtLangItem,                "panic_fmt",               panic_fmt;

    ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
    BoxFreeFnLangItem,               "box_free",                box_free_fn;
    DropInPlaceFnLangItem,             "drop_in_place",           drop_in_place_fn;

    StartFnLangItem,                 "start",                   start_fn;

    EhPersonalityLangItem,           "eh_personality",          eh_personality;
    EhUnwindResumeLangItem,          "eh_unwind_resume",        eh_unwind_resume;
    MSVCTryFilterLangItem,           "msvc_try_filter",         msvc_try_filter;

    OwnedBoxLangItem,                "owned_box",               owned_box;

    PhantomDataItem,                 "phantom_data",            phantom_data;

    NonZeroItem,                     "non_zero",                non_zero;

    DebugTraitLangItem,              "debug_trait",             debug_trait;
}

impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> {
    pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
        self.lang_items().require(lang_item).unwrap_or_else(|msg| {
            self.sess.fatal(&msg)
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>Use event_type enum in r0::room::create_room::InitialStateEvent<commit_after><|endoftext|>


<commit_before><commit_msg>examples: pdate tinydb example (#1288)<commit_after>//! A "tiny database" and accompanying protocol
//!
//! This example shows the usage of shared state amongst all connected clients,
//! namely a database of key/value pairs. Each connected client can send a
//! series of GET/SET commands to query the current value of a key or set the
//! value of a key.
//!
//! This example has a simple protocol you can use to interact with the server.
//! To run, first run this in one terminal window:
//!
//!     cargo run --example tinydb
//!
//! and next in another windows run:
//!
//!     cargo run --example connect 127.0.0.1:8080
//!
//! In the `connect` window you can type in commands where when you hit enter
//! you'll get a response from the server for that command. An example session
//! is:
//!
//!
//!     $ cargo run --example connect 127.0.0.1:8080
//!     GET foo
//!     foo = bar
//!     GET FOOBAR
//!     error: no key FOOBAR
//!     SET FOOBAR my awesome string
//!     set FOOBAR = `my awesome string`, previous: None
//!     SET foo tokio
//!     set foo = `tokio`, previous: Some("bar")
//!     GET foo
//!     foo = tokio
//!
//! Namely you can issue two forms of commands:
//!
//! * `GET $key` - this will fetch the value of `$key` from the database and
//!   return it. The server's database is initially populated with the key `foo`
//!   set to the value `bar`
//! * `SET $key $value` - this will set the value of `$key` to `$value`,
//!   returning the previous value, if any.

#![feature(async_await)]
#![deny(warnings, rust_2018_idioms)]

use std::collections::HashMap;
use std::env;
use std::error::Error;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};

use tokio;
use tokio::codec::{Framed, LinesCodec};
use tokio::net::TcpListener;

use futures::{SinkExt, StreamExt};

/// The in-memory database shared amongst all clients.
///
/// This database will be shared via `Arc`, so to mutate the internal map we're
/// going to use a `Mutex` for interior mutability.
struct Database {
    map: Mutex<HashMap<String, String>>,
}

/// Possible requests our clients can send us
enum Request {
    Get { key: String },
    Set { key: String, value: String },
}

/// Responses to the `Request` commands above
enum Response {
    Value {
        key: String,
        value: String,
    },
    Set {
        key: String,
        value: String,
        previous: Option<String>,
    },
    Error {
        msg: String,
    },
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    // Parse the address we're going to run this server on
    // and set up our TCP listener to accept connections.
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
    let addr = addr.parse::<SocketAddr>()?;
    let mut listener = TcpListener::bind(&addr)?;
    println!("Listening on: {}", addr);

    // Create the shared state of this server that will be shared amongst all
    // clients. We populate the initial database and then create the `Database`
    // structure. Note the usage of `Arc` here which will be used to ensure that
    // each independently spawned client will have a reference to the in-memory
    // database.
    let mut initial_db = HashMap::new();
    initial_db.insert("foo".to_string(), "bar".to_string());
    let db = Arc::new(Database {
        map: Mutex::new(initial_db),
    });

    loop {
        match listener.accept().await {
            Ok((socket, _)) => {
                // After getting a new connection first we see a clone of the database
                // being created, which is creating a new reference for this connected
                // client to use.
                let db = db.clone();

                // Like with other small servers, we'll `spawn` this client to ensure it
                // runs concurrently with all other clients. The `move` keyword is used
                // here to move ownership of our db handle into the async closure.
                tokio::spawn(async move {
                    // Since our protocol is line-based we use `tokio_codecs`'s `LineCodec`
                    // to convert our stream of bytes, `socket`, into a `Stream` of lines
                    // as well as convert our line based responses into a stream of bytes.
                    let mut lines = Framed::new(socket, LinesCodec::new());

                    // Here for every line we get back from the `Framed` decoder,
                    // we parse the request, and if it's valid we generate a response
                    // based on the values in the database.
                    while let Some(result) = lines.next().await {
                        match result {
                            Ok(line) => {
                                let response = handle_request(&line, &db);

                                let response = response.serialize();

                                if let Err(e) = lines.send(response).await {
                                    println!("error on sending response; error = {:?}", e);
                                }
                            }
                            Err(e) => {
                                println!("error on decoding from socket; error = {:?}", e);
                            }
                        }
                    }

                    // The connection will be closed at this point as `lines.next()` has returned `None`.
                });
            }
            Err(e) => println!("error accepting socket; error = {:?}", e),
        }
    }
}

fn handle_request(line: &str, db: &Arc<Database>) -> Response {
    let request = match Request::parse(&line) {
        Ok(req) => req,
        Err(e) => return Response::Error { msg: e },
    };

    let mut db = db.map.lock().unwrap();
    match request {
        Request::Get { key } => match db.get(&key) {
            Some(value) => Response::Value {
                key,
                value: value.clone(),
            },
            None => Response::Error {
                msg: format!("no key {}", key),
            },
        },
        Request::Set { key, value } => {
            let previous = db.insert(key.clone(), value.clone());
            Response::Set {
                key,
                value,
                previous,
            }
        }
    }
}

impl Request {
    fn parse(input: &str) -> Result<Request, String> {
        let mut parts = input.splitn(3, " ");
        match parts.next() {
            Some("GET") => {
                let key = match parts.next() {
                    Some(key) => key,
                    None => return Err(format!("GET must be followed by a key")),
                };
                if parts.next().is_some() {
                    return Err(format!("GET's key must not be followed by anything"));
                }
                Ok(Request::Get {
                    key: key.to_string(),
                })
            }
            Some("SET") => {
                let key = match parts.next() {
                    Some(key) => key,
                    None => return Err(format!("SET must be followed by a key")),
                };
                let value = match parts.next() {
                    Some(value) => value,
                    None => return Err(format!("SET needs a value")),
                };
                Ok(Request::Set {
                    key: key.to_string(),
                    value: value.to_string(),
                })
            }
            Some(cmd) => Err(format!("unknown command: {}", cmd)),
            None => Err(format!("empty input")),
        }
    }
}

impl Response {
    fn serialize(&self) -> String {
        match *self {
            Response::Value { ref key, ref value } => format!("{} = {}", key, value),
            Response::Set {
                ref key,
                ref value,
                ref previous,
            } => format!("set {} = `{}`, previous: {:?}", key, value, previous),
            Response::Error { ref msg } => format!("error: {}", msg),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Refactor & Comment shell::pipe_exec<commit_after><|endoftext|>


<commit_before><commit_msg>auto merge of #8936 : pnkfelix/rust/fsk-issue-2355-testcase, r=alexcrichton<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.

trait I { fn i(&self) -> Self; }

trait A<T:I> {
    fn id(x:T) -> T { x.i() }
}

trait J<T> { fn j(&self) -> Self; }

trait B<T:J<T>> {
    fn id(x:T) -> T { x.j() }
}

trait C {
    fn id<T:J<T>>(x:T) -> T { x.j() }
}

fn main() { }
<|endoftext|>


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

// ignore-windows - this is a unix-specific test

#![feature(process_exec, libc)]

extern crate libc;

use std::env;
use std::io::Error;
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

fn main() {
    if let Some(arg) = env::args().skip(1).next() {
        match &arg[..] {
            "test1" => println!("hello2"),
            "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"),
            "test3" => assert_eq!(env::current_dir().unwrap()
                                      .to_str().unwrap(), "/"),
            "empty" => {}
            _ => panic!("unknown argument: {}", arg),
        }
        return
    }

    let me = env::current_exe().unwrap();

    let output = Command::new(&me).arg("test1").before_exec(|| {
        println!("hello");
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert_eq!(output.stdout, b"hello\nhello2\n");

    let output = Command::new(&me).arg("test2").before_exec(|| {
        env::set_var("FOO", "BAR");
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let output = Command::new(&me).arg("test3").before_exec(|| {
        env::set_current_dir("/").unwrap();
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let output = Command::new(&me).arg("bad").before_exec(|| {
        Err(Error::from_raw_os_error(102))
    }).output().err().unwrap();
    assert_eq!(output.raw_os_error(), Some(102));

    let pid = unsafe { libc::getpid() };
    assert!(pid >= 0);
    let output = Command::new(&me).arg("empty").before_exec(move || {
        let child = unsafe { libc::getpid() };
        assert!(child >= 0);
        assert!(pid != child);
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let mem = Arc::new(AtomicUsize::new(0));
    let mem2 = mem.clone();
    let output = Command::new(&me).arg("empty").before_exec(move || {
        assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0);
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());
    assert_eq!(mem.load(Ordering::SeqCst), 0);
}
<commit_msg>Statically link run-pass/command-before-exec so it passes not just whenever we happen to bootstrap perfectly.<commit_after>// Copyright 2016 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.

// ignore-windows - this is a unix-specific test
// no-prefer-dynamic - this test breaks with dynamic linking as
// some LD_LIBRARY_PATH entries are relative and it cd's to /.

#![feature(process_exec, libc)]

extern crate libc;

use std::env;
use std::io::Error;
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

fn main() {
    if let Some(arg) = env::args().skip(1).next() {
        match &arg[..] {
            "test1" => println!("hello2"),
            "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"),
            "test3" => assert_eq!(env::current_dir().unwrap()
                                      .to_str().unwrap(), "/"),
            "empty" => {}
            _ => panic!("unknown argument: {}", arg),
        }
        return
    }

    let me = env::current_exe().unwrap();

    let output = Command::new(&me).arg("test1").before_exec(|| {
        println!("hello");
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert_eq!(output.stdout, b"hello\nhello2\n");

    let output = Command::new(&me).arg("test2").before_exec(|| {
        env::set_var("FOO", "BAR");
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let output = Command::new(&me).arg("test3").before_exec(|| {
        env::set_current_dir("/").unwrap();
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let output = Command::new(&me).arg("bad").before_exec(|| {
        Err(Error::from_raw_os_error(102))
    }).output().err().unwrap();
    assert_eq!(output.raw_os_error(), Some(102));

    let pid = unsafe { libc::getpid() };
    assert!(pid >= 0);
    let output = Command::new(&me).arg("empty").before_exec(move || {
        let child = unsafe { libc::getpid() };
        assert!(child >= 0);
        assert!(pid != child);
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());

    let mem = Arc::new(AtomicUsize::new(0));
    let mem2 = mem.clone();
    let output = Command::new(&me).arg("empty").before_exec(move || {
        assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0);
        Ok(())
    }).output().unwrap();
    assert!(output.status.success());
    assert!(output.stderr.is_empty());
    assert!(output.stdout.is_empty());
    assert_eq!(mem.load(Ordering::SeqCst), 0);
}
<|endoftext|>


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

#![allow(dead_code)]

use core::prelude::*;

use cmp;
use ffi::CString;
use io;
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
use libc;
use mem;
use ptr;
use sys::os;
use thunk::Thunk;
use time::Duration;

use sys_common::stack::RED_ZONE;
use sys_common::thread::*;

pub type rust_thread = libc::pthread_t;

#[cfg(all(not(target_os = "linux"),
          not(target_os = "macos"),
          not(target_os = "bitrig"),
          not(target_os = "openbsd")))]
pub mod guard {
    pub unsafe fn current() -> usize { 0 }
    pub unsafe fn main() -> usize { 0 }
    pub unsafe fn init() {}
}

#[cfg(any(target_os = "linux",
          target_os = "macos",
          target_os = "bitrig",
          target_os = "openbsd"))]
#[allow(unused_imports)]
pub mod guard {
    use libc::{self, pthread_t};
    use libc::funcs::posix88::mman::mmap;
    use libc::consts::os::posix88::{PROT_NONE,
                                    MAP_PRIVATE,
                                    MAP_ANON,
                                    MAP_FAILED,
                                    MAP_FIXED};
    use mem;
    use ptr;
    use super::{pthread_self, pthread_attr_destroy};
    use sys::os;

    // These are initialized in init() and only read from after
    static mut GUARD_PAGE: usize = 0;

    #[cfg(any(target_os = "macos",
              target_os = "bitrig",
              target_os = "openbsd"))]
    unsafe fn get_stack_start() -> *mut libc::c_void {
        current() as *mut libc::c_void
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    unsafe fn get_stack_start() -> *mut libc::c_void {
        let mut attr: libc::pthread_attr_t = mem::zeroed();
        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
        let mut stackaddr = ptr::null_mut();
        let mut stacksize = 0;
        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
        assert_eq!(pthread_attr_destroy(&mut attr), 0);
        stackaddr
    }

    pub unsafe fn init() {
        let psize = os::page_size();
        let mut stackaddr = get_stack_start();

        // Ensure stackaddr is page aligned! A parent process might
        // have reset RLIMIT_STACK to be non-page aligned. The
        // pthread_attr_getstack() reports the usable stack area
        // stackaddr < stackaddr + stacksize, so if stackaddr is not
        // page-aligned, calculate the fix such that stackaddr <
        // new_page_aligned_stackaddr < stackaddr + stacksize
        let remainder = (stackaddr as usize) % psize;
        if remainder != 0 {
            stackaddr = ((stackaddr as usize) + psize - remainder)
                as *mut libc::c_void;
        }

        // Rellocate the last page of the stack.
        // This ensures SIGBUS will be raised on
        // stack overflow.
        let result = mmap(stackaddr,
                          psize as libc::size_t,
                          PROT_NONE,
                          MAP_PRIVATE | MAP_ANON | MAP_FIXED,
                          -1,
                          0);

        if result != stackaddr || result == MAP_FAILED {
            panic!("failed to allocate a guard page");
        }

        let offset = if cfg!(target_os = "linux") {2} else {1};

        GUARD_PAGE = stackaddr as usize + offset * psize;
    }

    pub unsafe fn main() -> usize {
        GUARD_PAGE
    }

    #[cfg(target_os = "macos")]
    pub unsafe fn current() -> usize {
        extern {
            fn pthread_get_stackaddr_np(thread: pthread_t) -> *mut libc::c_void;
            fn pthread_get_stacksize_np(thread: pthread_t) -> libc::size_t;
        }
        (pthread_get_stackaddr_np(pthread_self()) as libc::size_t -
         pthread_get_stacksize_np(pthread_self())) as usize
    }

    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
    pub unsafe fn current() -> usize {
        #[repr(C)]
        pub struct stack_t {
            ss_sp: *mut libc::c_void,
            ss_size: libc::size_t,
            ss_flags: libc::c_int,
        }
        extern {
            fn pthread_stackseg_np(thread: pthread_t,
                                   sinfo: *mut stack_t) -> libc::c_uint;
        }

        let mut current_stack: stack_t = mem::zeroed();
        assert_eq!(pthread_stackseg_np(pthread_self(), &mut current_stack), 0);

        let extra = if cfg!(target_os = "bitrig") {3} else {1} * os::page_size();
        if pthread_main_np() == 1 {
            // main thread
            current_stack.ss_sp as usize - current_stack.ss_size as usize + extra
        } else {
            // new thread
            current_stack.ss_sp as usize - current_stack.ss_size as usize
        }
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    pub unsafe fn current() -> usize {
        let mut attr: libc::pthread_attr_t = mem::zeroed();
        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
        let mut guardsize = 0;
        assert_eq!(pthread_attr_getguardsize(&attr, &mut guardsize), 0);
        if guardsize == 0 {
            panic!("there is no guard page");
        }
        let mut stackaddr = ptr::null_mut();
        let mut size = 0;
        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
        assert_eq!(pthread_attr_destroy(&mut attr), 0);

        stackaddr as usize + guardsize as usize
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    extern {
        fn pthread_getattr_np(native: libc::pthread_t,
                              attr: *mut libc::pthread_attr_t) -> libc::c_int;
        fn pthread_attr_getguardsize(attr: *const libc::pthread_attr_t,
                                     guardsize: *mut libc::size_t) -> libc::c_int;
        fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
                                 stackaddr: *mut *mut libc::c_void,
                                 stacksize: *mut libc::size_t) -> libc::c_int;
    }
}

pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
    let p = box p;
    let mut native: libc::pthread_t = mem::zeroed();
    let mut attr: libc::pthread_attr_t = mem::zeroed();
    assert_eq!(pthread_attr_init(&mut attr), 0);

    // Reserve room for the red zone, the runtime's stack of last resort.
    let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as usize);
    match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
        0 => {}
        n => {
            assert_eq!(n, libc::EINVAL);
            // EINVAL means |stack_size| is either too small or not a
            // multiple of the system page size.  Because it's definitely
            // >= PTHREAD_STACK_MIN, it must be an alignment issue.
            // Round up to the nearest page and try again.
            let page_size = os::page_size();
            let stack_size = (stack_size + page_size - 1) &
                             (-(page_size as isize - 1) as usize - 1);
            assert_eq!(pthread_attr_setstacksize(&mut attr,
                                                 stack_size as libc::size_t), 0);
        }
    };

    let ret = pthread_create(&mut native, &attr, thread_start,
                             &*p as *const _ as *mut _);
    assert_eq!(pthread_attr_destroy(&mut attr), 0);

    return if ret != 0 {
        Err(io::Error::from_os_error(ret))
    } else {
        mem::forget(p); // ownership passed to pthread_create
        Ok(native)
    };

    #[no_stack_check]
    extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
        start_thread(main);
        0 as *mut _
    }
}

#[cfg(any(target_os = "linux", target_os = "android"))]
pub unsafe fn set_name(name: &str) {
    // pthread_setname_np() since glibc 2.12
    // availability autodetected via weak linkage
    type F = unsafe extern fn(libc::pthread_t, *const libc::c_char)
                              -> libc::c_int;
    extern {
        #[linkage = "extern_weak"]
        static pthread_setname_np: *const ();
    }
    if !pthread_setname_np.is_null() {
        let cname = CString::new(name).unwrap();
        mem::transmute::<*const (), F>(pthread_setname_np)(pthread_self(),
                                                           cname.as_ptr());
    }
}

#[cfg(any(target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "bitrig",
          target_os = "openbsd"))]
pub unsafe fn set_name(name: &str) {
    extern {
        fn pthread_set_name_np(tid: libc::pthread_t, name: *const libc::c_char);
    }
    let cname = CString::new(name).unwrap();
    pthread_set_name_np(pthread_self(), cname.as_ptr());
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
pub unsafe fn set_name(name: &str) {
    extern {
        fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
    }
    let cname = CString::new(name).unwrap();
    pthread_setname_np(cname.as_ptr());
}

pub unsafe fn join(native: rust_thread) {
    assert_eq!(pthread_join(native, ptr::null_mut()), 0);
}

pub unsafe fn detach(native: rust_thread) {
    assert_eq!(pthread_detach(native), 0);
}

pub unsafe fn yield_now() {
    assert_eq!(sched_yield(), 0);
}

pub fn sleep(dur: Duration) {
    unsafe {
        if dur < Duration::zero() {
            return yield_now()
        }
        let seconds = dur.num_seconds();
        let ns = dur - Duration::seconds(seconds);
        let mut ts = libc::timespec {
            tv_sec: seconds as libc::time_t,
            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
        };
        // If we're awoken with a signal then the return value will be -1 and
        // nanosleep will fill in `ts` with the remaining time.
        while dosleep(&mut ts) == -1 {
            assert_eq!(os::errno(), libc::EINTR);
        }
    }

    #[cfg(target_os = "linux")]
    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
        extern {
            fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
                               request: *const libc::timespec,
                               remain: *mut libc::timespec) -> libc::c_int;
        }
        clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
    }
    #[cfg(not(target_os = "linux"))]
    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
        libc::nanosleep(ts, ts)
    }
}

// glibc >= 2.15 has a __pthread_get_minstack() function that returns
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
// storage.  We need that information to avoid blowing up when a small stack
// is created in an application with big thread-local storage requirements.
// See #6233 for rationale and details.
//
// Link weakly to the symbol for compatibility with older versions of glibc.
// Assumes that we've been dynamically linked to libpthread but that is
// currently always the case.  Note that you need to check that the symbol
// is non-null before calling it!
#[cfg(target_os = "linux")]
fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
    type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
    extern {
        #[linkage = "extern_weak"]
        static __pthread_get_minstack: *const ();
    }
    if __pthread_get_minstack.is_null() {
        PTHREAD_STACK_MIN
    } else {
        unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
    }
}

// __pthread_get_minstack() is marked as weak but extern_weak linkage is
// not supported on OS X, hence this kludge...
#[cfg(not(target_os = "linux"))]
fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t {
    PTHREAD_STACK_MIN
}

extern {
    #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
    fn pthread_main_np() -> libc::c_uint;

    fn pthread_self() -> libc::pthread_t;
    fn pthread_create(native: *mut libc::pthread_t,
                      attr: *const libc::pthread_attr_t,
                      f: extern fn(*mut libc::c_void) -> *mut libc::c_void,
                      value: *mut libc::c_void) -> libc::c_int;
    fn pthread_join(native: libc::pthread_t,
                    value: *mut *mut libc::c_void) -> libc::c_int;
    fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
    fn pthread_attr_destroy(attr: *mut libc::pthread_attr_t) -> libc::c_int;
    fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
                                 stack_size: libc::size_t) -> libc::c_int;
    fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
                                   state: libc::c_int) -> libc::c_int;
    fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
    fn sched_yield() -> libc::c_int;
}
<commit_msg>Rollup merge of #23483 - semarie:openbsd-threads, r=alexcrichton<commit_after>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code)]

use core::prelude::*;

use cmp;
use ffi::CString;
use io;
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
use libc;
use mem;
use ptr;
use sys::os;
use thunk::Thunk;
use time::Duration;

use sys_common::stack::RED_ZONE;
use sys_common::thread::*;

pub type rust_thread = libc::pthread_t;

#[cfg(all(not(target_os = "linux"),
          not(target_os = "macos"),
          not(target_os = "bitrig"),
          not(target_os = "openbsd")))]
pub mod guard {
    pub unsafe fn current() -> usize { 0 }
    pub unsafe fn main() -> usize { 0 }
    pub unsafe fn init() {}
}

#[cfg(any(target_os = "linux",
          target_os = "macos",
          target_os = "bitrig",
          target_os = "openbsd"))]
#[allow(unused_imports)]
pub mod guard {
    use libc::{self, pthread_t};
    use libc::funcs::posix88::mman::mmap;
    use libc::consts::os::posix88::{PROT_NONE,
                                    MAP_PRIVATE,
                                    MAP_ANON,
                                    MAP_FAILED,
                                    MAP_FIXED};
    use mem;
    use ptr;
    use super::{pthread_self, pthread_attr_destroy};
    use sys::os;

    // These are initialized in init() and only read from after
    static mut GUARD_PAGE: usize = 0;

    #[cfg(any(target_os = "macos",
              target_os = "bitrig",
              target_os = "openbsd"))]
    unsafe fn get_stack_start() -> *mut libc::c_void {
        current() as *mut libc::c_void
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    unsafe fn get_stack_start() -> *mut libc::c_void {
        let mut attr: libc::pthread_attr_t = mem::zeroed();
        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
        let mut stackaddr = ptr::null_mut();
        let mut stacksize = 0;
        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
        assert_eq!(pthread_attr_destroy(&mut attr), 0);
        stackaddr
    }

    pub unsafe fn init() {
        let psize = os::page_size();
        let mut stackaddr = get_stack_start();

        // Ensure stackaddr is page aligned! A parent process might
        // have reset RLIMIT_STACK to be non-page aligned. The
        // pthread_attr_getstack() reports the usable stack area
        // stackaddr < stackaddr + stacksize, so if stackaddr is not
        // page-aligned, calculate the fix such that stackaddr <
        // new_page_aligned_stackaddr < stackaddr + stacksize
        let remainder = (stackaddr as usize) % psize;
        if remainder != 0 {
            stackaddr = ((stackaddr as usize) + psize - remainder)
                as *mut libc::c_void;
        }

        // Rellocate the last page of the stack.
        // This ensures SIGBUS will be raised on
        // stack overflow.
        let result = mmap(stackaddr,
                          psize as libc::size_t,
                          PROT_NONE,
                          MAP_PRIVATE | MAP_ANON | MAP_FIXED,
                          -1,
                          0);

        if result != stackaddr || result == MAP_FAILED {
            panic!("failed to allocate a guard page");
        }

        let offset = if cfg!(target_os = "linux") {2} else {1};

        GUARD_PAGE = stackaddr as usize + offset * psize;
    }

    pub unsafe fn main() -> usize {
        GUARD_PAGE
    }

    #[cfg(target_os = "macos")]
    pub unsafe fn current() -> usize {
        extern {
            fn pthread_get_stackaddr_np(thread: pthread_t) -> *mut libc::c_void;
            fn pthread_get_stacksize_np(thread: pthread_t) -> libc::size_t;
        }
        (pthread_get_stackaddr_np(pthread_self()) as libc::size_t -
         pthread_get_stacksize_np(pthread_self())) as usize
    }

    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
    pub unsafe fn current() -> usize {
        #[repr(C)]
        struct stack_t {
            ss_sp: *mut libc::c_void,
            ss_size: libc::size_t,
            ss_flags: libc::c_int,
        }
        extern {
            fn pthread_main_np() -> libc::c_uint;
            fn pthread_stackseg_np(thread: pthread_t,
                                   sinfo: *mut stack_t) -> libc::c_uint;
        }

        let mut current_stack: stack_t = mem::zeroed();
        assert_eq!(pthread_stackseg_np(pthread_self(), &mut current_stack), 0);

        let extra = if cfg!(target_os = "bitrig") {3} else {1} * os::page_size();
        if pthread_main_np() == 1 {
            // main thread
            current_stack.ss_sp as usize - current_stack.ss_size as usize + extra
        } else {
            // new thread
            current_stack.ss_sp as usize - current_stack.ss_size as usize
        }
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    pub unsafe fn current() -> usize {
        let mut attr: libc::pthread_attr_t = mem::zeroed();
        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
        let mut guardsize = 0;
        assert_eq!(pthread_attr_getguardsize(&attr, &mut guardsize), 0);
        if guardsize == 0 {
            panic!("there is no guard page");
        }
        let mut stackaddr = ptr::null_mut();
        let mut size = 0;
        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
        assert_eq!(pthread_attr_destroy(&mut attr), 0);

        stackaddr as usize + guardsize as usize
    }

    #[cfg(any(target_os = "linux", target_os = "android"))]
    extern {
        fn pthread_getattr_np(native: libc::pthread_t,
                              attr: *mut libc::pthread_attr_t) -> libc::c_int;
        fn pthread_attr_getguardsize(attr: *const libc::pthread_attr_t,
                                     guardsize: *mut libc::size_t) -> libc::c_int;
        fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
                                 stackaddr: *mut *mut libc::c_void,
                                 stacksize: *mut libc::size_t) -> libc::c_int;
    }
}

pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
    let p = box p;
    let mut native: libc::pthread_t = mem::zeroed();
    let mut attr: libc::pthread_attr_t = mem::zeroed();
    assert_eq!(pthread_attr_init(&mut attr), 0);

    // Reserve room for the red zone, the runtime's stack of last resort.
    let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as usize);
    match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
        0 => {}
        n => {
            assert_eq!(n, libc::EINVAL);
            // EINVAL means |stack_size| is either too small or not a
            // multiple of the system page size.  Because it's definitely
            // >= PTHREAD_STACK_MIN, it must be an alignment issue.
            // Round up to the nearest page and try again.
            let page_size = os::page_size();
            let stack_size = (stack_size + page_size - 1) &
                             (-(page_size as isize - 1) as usize - 1);
            assert_eq!(pthread_attr_setstacksize(&mut attr,
                                                 stack_size as libc::size_t), 0);
        }
    };

    let ret = pthread_create(&mut native, &attr, thread_start,
                             &*p as *const _ as *mut _);
    assert_eq!(pthread_attr_destroy(&mut attr), 0);

    return if ret != 0 {
        Err(io::Error::from_os_error(ret))
    } else {
        mem::forget(p); // ownership passed to pthread_create
        Ok(native)
    };

    #[no_stack_check]
    extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
        start_thread(main);
        0 as *mut _
    }
}

#[cfg(any(target_os = "linux", target_os = "android"))]
pub unsafe fn set_name(name: &str) {
    // pthread_setname_np() since glibc 2.12
    // availability autodetected via weak linkage
    type F = unsafe extern fn(libc::pthread_t, *const libc::c_char)
                              -> libc::c_int;
    extern {
        #[linkage = "extern_weak"]
        static pthread_setname_np: *const ();
    }
    if !pthread_setname_np.is_null() {
        let cname = CString::new(name).unwrap();
        mem::transmute::<*const (), F>(pthread_setname_np)(pthread_self(),
                                                           cname.as_ptr());
    }
}

#[cfg(any(target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "bitrig",
          target_os = "openbsd"))]
pub unsafe fn set_name(name: &str) {
    extern {
        fn pthread_set_name_np(tid: libc::pthread_t, name: *const libc::c_char);
    }
    let cname = CString::new(name).unwrap();
    pthread_set_name_np(pthread_self(), cname.as_ptr());
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
pub unsafe fn set_name(name: &str) {
    extern {
        fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
    }
    let cname = CString::new(name).unwrap();
    pthread_setname_np(cname.as_ptr());
}

pub unsafe fn join(native: rust_thread) {
    assert_eq!(pthread_join(native, ptr::null_mut()), 0);
}

pub unsafe fn detach(native: rust_thread) {
    assert_eq!(pthread_detach(native), 0);
}

pub unsafe fn yield_now() {
    assert_eq!(sched_yield(), 0);
}

pub fn sleep(dur: Duration) {
    unsafe {
        if dur < Duration::zero() {
            return yield_now()
        }
        let seconds = dur.num_seconds();
        let ns = dur - Duration::seconds(seconds);
        let mut ts = libc::timespec {
            tv_sec: seconds as libc::time_t,
            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
        };
        // If we're awoken with a signal then the return value will be -1 and
        // nanosleep will fill in `ts` with the remaining time.
        while dosleep(&mut ts) == -1 {
            assert_eq!(os::errno(), libc::EINTR);
        }
    }

    #[cfg(target_os = "linux")]
    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
        extern {
            fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
                               request: *const libc::timespec,
                               remain: *mut libc::timespec) -> libc::c_int;
        }
        clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
    }
    #[cfg(not(target_os = "linux"))]
    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
        libc::nanosleep(ts, ts)
    }
}

// glibc >= 2.15 has a __pthread_get_minstack() function that returns
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
// storage.  We need that information to avoid blowing up when a small stack
// is created in an application with big thread-local storage requirements.
// See #6233 for rationale and details.
//
// Link weakly to the symbol for compatibility with older versions of glibc.
// Assumes that we've been dynamically linked to libpthread but that is
// currently always the case.  Note that you need to check that the symbol
// is non-null before calling it!
#[cfg(target_os = "linux")]
fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
    type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
    extern {
        #[linkage = "extern_weak"]
        static __pthread_get_minstack: *const ();
    }
    if __pthread_get_minstack.is_null() {
        PTHREAD_STACK_MIN
    } else {
        unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
    }
}

// __pthread_get_minstack() is marked as weak but extern_weak linkage is
// not supported on OS X, hence this kludge...
#[cfg(not(target_os = "linux"))]
fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t {
    PTHREAD_STACK_MIN
}

extern {
    fn pthread_self() -> libc::pthread_t;
    fn pthread_create(native: *mut libc::pthread_t,
                      attr: *const libc::pthread_attr_t,
                      f: extern fn(*mut libc::c_void) -> *mut libc::c_void,
                      value: *mut libc::c_void) -> libc::c_int;
    fn pthread_join(native: libc::pthread_t,
                    value: *mut *mut libc::c_void) -> libc::c_int;
    fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
    fn pthread_attr_destroy(attr: *mut libc::pthread_attr_t) -> libc::c_int;
    fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
                                 stack_size: libc::size_t) -> libc::c_int;
    fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
                                   state: libc::c_int) -> libc::c_int;
    fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
    fn sched_yield() -> libc::c_int;
}
<|endoftext|>


<commit_before><commit_msg>Addition of completed joiner tutorial program<commit_after>use std::rand::random;
use std::str;
use std::os;
use std::io::File;
use std::io;

fn main(){
	let args: ~[~str] = os::args();

    if args.len() != 3 {
        println("please list your two files");
    }

    else {
    	let file1 = &args[1];
    	let file2 = &args[2];
    	let path1 = Path::new(file1.clone());
    	let path2 = Path::new(file2.clone());
    	let msg1_file = File::open(&path1);
    	let msg2_file = File::open(&path2);

    	match (msg1_file, msg2_file) {
			(Some(mut msg1), Some(mut msg2)) => {
				let msg_bytes1: ~[u8] = msg1.read_to_end();
				let msg_bytes2: ~[u8] = msg2.read_to_end();

				let decoded = xor(msg_bytes1,msg_bytes2);
				let s = str::from_utf8(decoded);
				println(s);

			}

			(_,_) => {fail!("bad files");}
    	}
	}

}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}<|endoftext|>


<commit_before><commit_msg>Don't forget the test.<commit_after>use hotel::test_dcrypto::TestDcrypto;
use hotel::crypto::dcrypto;
#[allow(unused_imports)]
use hotel::crypto::dcrypto::{Dcrypto, DcryptoClient, DcryptoEngine};

pub unsafe fn run_dcrypto() {
    let r = static_init_test_dcrypto();
    dcrypto::DCRYPTO.set_client(r);
    r.run();
}

unsafe fn static_init_test_dcrypto() -> &'static mut TestDcrypto<'static> {
    static_init!(
        TestDcrypto<'static>,
        TestDcrypto::new(&dcrypto::DCRYPTO)
    )
}
<|endoftext|>


<commit_before><commit_msg>Check that getcwd does not error<commit_after>// ignore-windows: TODO the windows hook is not done yet

fn main() {
    std::env::current_dir().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>added statement parser<commit_after><|endoftext|>


<commit_before><commit_msg>Unit test for the new implicit borrow and deref within the guard expressions of matches (activated only when using new NLL mode).<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.

//revisions: ast mir
//[mir] compile-flags: -Z borrowck=mir

#![feature(rustc_attrs)]

// Here is arielb1's basic example from rust-lang/rust#27282
// that AST borrowck is flummoxed by:

fn should_reject_destructive_mutate_in_guard() {
    match Some(&4) {
        None => {},
        ref mut foo if {
            (|| { let bar = foo; bar.take() })();
            //[mir]~^ ERROR cannot move out of borrowed content [E0507]
            false } => { },
        Some(s) => std::process::exit(*s),
    }
}

// Here below is a case that needs to keep working: we only use the
// binding via immutable-borrow in the guard, and we mutate in the arm
// body.
fn allow_mutate_in_arm_body() {
    match Some(&4) {
        None => {},
        ref mut foo if foo.is_some() && false => { foo.take(); () }
        Some(s) => std::process::exit(*s),
    }
}

// Here below is a case that needs to keep working: we only use the
// binding via immutable-borrow in the guard, and we move into the arm
// body.
fn allow_move_into_arm_body() {
    match Some(&4) {
        None => {},
        mut foo if foo.is_some() && false => { foo.take(); () }
        Some(s) => std::process::exit(*s),
    }
}

// Since this is a compile-fail test that is explicitly encoding the
// different behavior of AST- vs MIR-borrowck where AST-borrowck does
// not error, we need to use rustc_error to placate the test harness
// that wants *some* error to occur.
#[rustc_error]
fn main() { //[ast]~ ERROR compilation successful
    should_reject_destructive_mutate_in_guard();
    allow_mutate_in_arm_body();
    allow_move_into_arm_body();
}
<|endoftext|>


<commit_before><commit_msg>Test that we can call unboxed closures with the sugar now. Fixes #16929.<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

use std::ops::FnMut;

fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
    box move |y| { x + y }
}

pub fn main() {
    let mut adder = make_adder(3);
    let z = (*adder)(2);
    println!("{}", z);
    assert_eq!(z, 5);
}

<|endoftext|>


<commit_before><commit_msg>Add async search example<commit_after>extern crate tokio_core;
extern crate ldap;

use tokio_core::reactor::{Core, Handle};
use ldap::Ldap;

pub fn main() {
    let addr = "127.0.0.1:389".parse().unwrap();

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let ldap = core.run(Ldap::connect(&addr, &handle)).unwrap();
    let bind = core.run(ldap.simple_bind("cn=root,dc=plabs".to_string(), "asdf".to_string()));

    let search_results = core.run(ldap.search("dc=plabs".to_string(),
                                  ldap::Scope::WholeSubtree,
                                  ldap::DerefAliases::Never,
                                  false,
                                  "(objectClass=*)".to_string()));

    println!("Search Results: {:?}", search_results)
}
<|endoftext|>


<commit_before><commit_msg>Add test<commit_after>#![feature(extern_types)]

extern {
    pub type ExternType;
}

impl ExternType {
    pub fn f(&self) {

    }
}

// @has 'intra_link_extern_type/foreigntype.ExternType.html'
// @has 'intra_link_extern_type/fn.links_to_extern_type.html' \
// 'href="../intra_link_extern_type/foreigntype.ExternType.html#method.f"'
/// See also [ExternType::f]
pub fn links_to_extern_type() {
}
<|endoftext|>


<commit_before>#![feature(phase)]

#[phase(link, plugin)]
extern crate gfx;
extern crate glfw;

static VERTEX_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    attribute vec2 a_Pos;
    varying vec4 v_Color;
    void main() {
        v_Color = vec4(a_Pos+0.5, 0.0, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 a_Pos;
    out vec4 v_Color;
    void main() {
        v_Color = vec4(a_Pos+0.5, 0.0, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    varying vec4 v_Color;
    void main() {
        gl_FragColor = v_Color;
    }
"
GLSL_150: b"
    #version 150 core
    in vec4 v_Color;
    out vec4 o_Color;
    void main() {
        o_Color = v_Color;
    }
"
};

#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = gfx::glfw::WindowBuilder::new(&glfw)
        .title("Hello this is window")
        .try_modern_context_hints()
        .create()
        .expect("Failed to create GLFW window.");

    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    // spawn render task
    let (renderer, mut device) = {
        let (platform, provider) = gfx::glfw::Platform::new(window.render_context(), &glfw);
        gfx::start(platform, provider, 1).unwrap()
    };

    // spawn game task
    spawn(proc() {
        let mut renderer = renderer;
        let program = renderer.create_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone());
        let frame = gfx::Frame::new();
        let mut env = gfx::Environment::new();
        env.add_uniform("color", gfx::ValueF32Vec([0.1, 0.1, 0.1, 0.1]));
        let env = renderer.create_environment(env);
        let state = gfx::DrawState::new();
        let mesh = {
            let data = vec![-0.5f32, -0.5, 0.5, -0.5, 0.0, 0.5];
            let buf = renderer.create_buffer(Some(data));
            gfx::mesh::Builder::new(buf)
                .add("a_Pos", 2, gfx::mesh::F32)
                .complete(3)
        };
        while !renderer.should_finish() {
            let cdata = gfx::ClearData {
                color: Some(gfx::Color([0.3, 0.3, 0.3, 1.0])),
                depth: None,
                stencil: None,
            };
            renderer.clear(cdata, frame);
            renderer.draw(&mesh, gfx::mesh::VertexSlice(0, 3), frame, program, env, state).unwrap();
            renderer.end_frame();
            for err in renderer.iter_errors() {
                println!("Renderer error: {}", err);
            }
        }
    });

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) => {
                    window.set_should_close(true);
                },
                _ => {},
            }
        }
        device.update();
    }
    device.close();
}
<commit_msg>Use crate_name for example<commit_after>#![feature(phase)]
#![crate_name = "triangle"]

#[phase(link, plugin)]
extern crate gfx;
extern crate glfw;

static VERTEX_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    attribute vec2 a_Pos;
    varying vec4 v_Color;
    void main() {
        v_Color = vec4(a_Pos+0.5, 0.0, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
GLSL_150: b"
    #version 150 core
    in vec2 a_Pos;
    out vec4 v_Color;
    void main() {
        v_Color = vec4(a_Pos+0.5, 0.0, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120
    varying vec4 v_Color;
    void main() {
        gl_FragColor = v_Color;
    }
"
GLSL_150: b"
    #version 150 core
    in vec4 v_Color;
    out vec4 o_Color;
    void main() {
        o_Color = v_Color;
    }
"
};

#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = gfx::glfw::WindowBuilder::new(&glfw)
        .title("Hello this is window")
        .try_modern_context_hints()
        .create()
        .expect("Failed to create GLFW window.");

    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    // spawn render task
    let (renderer, mut device) = {
        let (platform, provider) = gfx::glfw::Platform::new(window.render_context(), &glfw);
        gfx::start(platform, provider, 1).unwrap()
    };

    // spawn game task
    spawn(proc() {
        let mut renderer = renderer;
        let program = renderer.create_program(
            VERTEX_SRC.clone(),
            FRAGMENT_SRC.clone());
        let frame = gfx::Frame::new();
        let mut env = gfx::Environment::new();
        env.add_uniform("color", gfx::ValueF32Vec([0.1, 0.1, 0.1, 0.1]));
        let env = renderer.create_environment(env);
        let state = gfx::DrawState::new();
        let mesh = {
            let data = vec![-0.5f32, -0.5, 0.5, -0.5, 0.0, 0.5];
            let buf = renderer.create_buffer(Some(data));
            gfx::mesh::Builder::new(buf)
                .add("a_Pos", 2, gfx::mesh::F32)
                .complete(3)
        };
        while !renderer.should_finish() {
            let cdata = gfx::ClearData {
                color: Some(gfx::Color([0.3, 0.3, 0.3, 1.0])),
                depth: None,
                stencil: None,
            };
            renderer.clear(cdata, frame);
            renderer.draw(&mesh, gfx::mesh::VertexSlice(0, 3), frame, program, env, state).unwrap();
            renderer.end_frame();
            for err in renderer.iter_errors() {
                println!("Renderer error: {}", err);
            }
        }
    });

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) => {
                    window.set_should_close(true);
                },
                _ => {},
            }
        }
        device.update();
    }
    device.close();
}
<|endoftext|>


<commit_before><commit_msg>languages/rust/rust-book/3-chapter/35-code.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Test binops move semantics<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.

// Test that move restrictions are enforced on overloaded binary operations

fn double_move<T: Add<T, ()>>(x: T) {
    x
    +
    x;  //~ ERROR: use of moved value
}

fn move_then_borrow<T: Add<T, ()> + Clone>(x: T) {
    x
    +
    x.clone();  //~ ERROR: use of moved value
}

fn move_borrowed<T: Add<T, ()>>(x: T, mut y: T) {
    let m = &x;
    let n = &mut y;

    x  //~ ERROR: cannot move out of `x` because it is borrowed
    +
    y;  //~ ERROR: cannot move out of `y` because it is borrowed
}

fn illegal_dereference<T: Add<T, ()>>(mut x: T, y: T) {
    let m = &mut x;
    let n = &y;

    *m  //~ ERROR: cannot move out of dereference of `&mut`-pointer
    +
    *n;  //~ ERROR: cannot move out of dereference of `&`-pointer
}

struct Foo;

impl<'a, 'b> Add<&'b Foo, ()> for &'a mut Foo {
    fn add(self, _: &Foo) {}
}

impl<'a, 'b> Add<&'b mut Foo, ()> for &'a Foo {
    fn add(self, _: &mut Foo) {}
}

fn mut_plus_immut() {
    let mut f = Foo;

    &mut f
    +
    &f;  //~ ERROR: cannot borrow `f` as immutable because it is also borrowed as mutable
}

fn immut_plus_mut() {
    let mut f = Foo;

    &f
    +
    &mut f;  //~ ERROR: cannot borrow `f` as mutable because it is also borrowed as immutable
}

fn main() {}
<|endoftext|>


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

use prelude::v1::*;

use cell::UnsafeCell;
use sys::sync as ffi;

pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }

pub const RWLOCK_INIT: RWLock = RWLock {
    inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
};

unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}

impl RWLock {
    #[inline]
    pub unsafe fn read(&self) {
        let r = ffi::pthread_rwlock_rdlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn try_read(&self) -> bool {
        ffi::pthread_rwlock_tryrdlock(self.inner.get()) == 0
    }
    #[inline]
    pub unsafe fn write(&self) {
        let r = ffi::pthread_rwlock_wrlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn try_write(&self) -> bool {
        ffi::pthread_rwlock_trywrlock(self.inner.get()) == 0
    }
    #[inline]
    pub unsafe fn read_unlock(&self) {
        let r = ffi::pthread_rwlock_unlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn write_unlock(&self) { self.read_unlock() }
    #[inline]
    pub unsafe fn destroy(&self) {
        let r = ffi::pthread_rwlock_destroy(self.inner.get());
        // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
        // rwlock that was just initialized with
        // ffi::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
        // or pthread_rwlock_init() is called, this behaviour no longer occurs.
        if cfg!(target_os = "dragonfly") {
            debug_assert!(r == 0 || r == libc::EINVAL);
        } else {
            debug_assert_eq!(r, 0);
        }
    }
}
<commit_msg>std: Always check for EDEADLK in rwlocks on unix<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use prelude::v1::*;

use libc;
use cell::UnsafeCell;
use sys::sync as ffi;

pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }

pub const RWLOCK_INIT: RWLock = RWLock {
    inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
};

unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}

impl RWLock {
    #[inline]
    pub unsafe fn read(&self) {
        let r = ffi::pthread_rwlock_rdlock(self.inner.get());

        // According to the pthread_rwlock_rdlock spec, this function **may**
        // fail with EDEADLK if a deadlock is detected. On the other hand
        // pthread mutexes will *never* return EDEADLK if they are initialized
        // as the "fast" kind (which ours always are). As a result, a deadlock
        // situation may actually return from the call to pthread_rwlock_rdlock
        // instead of blocking forever (as mutexes and Windows rwlocks do). Note
        // that not all unix implementations, however, will return EDEADLK for
        // their rwlocks.
        //
        // We roughly maintain the deadlocking behavior by panicking to ensure
        // that this lock acquisition does not succeed.
        if r == libc::EDEADLK {
            panic!("rwlock read lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
        }
    }
    #[inline]
    pub unsafe fn try_read(&self) -> bool {
        ffi::pthread_rwlock_tryrdlock(self.inner.get()) == 0
    }
    #[inline]
    pub unsafe fn write(&self) {
        let r = ffi::pthread_rwlock_wrlock(self.inner.get());
        // see comments above for why we check for EDEADLK
        if r == libc::EDEADLK {
            panic!("rwlock write lock would result in deadlock");
        } else {
            debug_assert_eq!(r, 0);
        }
    }
    #[inline]
    pub unsafe fn try_write(&self) -> bool {
        ffi::pthread_rwlock_trywrlock(self.inner.get()) == 0
    }
    #[inline]
    pub unsafe fn read_unlock(&self) {
        let r = ffi::pthread_rwlock_unlock(self.inner.get());
        debug_assert_eq!(r, 0);
    }
    #[inline]
    pub unsafe fn write_unlock(&self) { self.read_unlock() }
    #[inline]
    pub unsafe fn destroy(&self) {
        let r = ffi::pthread_rwlock_destroy(self.inner.get());
        // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
        // rwlock that was just initialized with
        // ffi::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
        // or pthread_rwlock_init() is called, this behaviour no longer occurs.
        if cfg!(target_os = "dragonfly") {
            debug_assert!(r == 0 || r == libc::EINVAL);
        } else {
            debug_assert_eq!(r, 0);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test whether Store::is_borrowed() works as expected<commit_after><|endoftext|>


<commit_before><commit_msg>Replace "\" with "/" in entry paths before extracting<commit_after><|endoftext|>


<commit_before><commit_msg>Reset digest after use<commit_after><|endoftext|>


<commit_before><commit_msg>Use concise hash_replay method and reset digest after use<commit_after><|endoftext|>


<commit_before><commit_msg>debug_assert to ensure that from_raw_parts is only used properly aligned<commit_after><|endoftext|>


<commit_before><commit_msg>start new<commit_after>fn sum_vec(nums: &Vec<i32>) -> i32 {
    let mut result = 0;
    for i in nums {
        result += *i;
    }
    result
}

fn check_sub_array_sum(nums: Vec<i32>, k: i32) -> bool {
    let length = nums.len();
    if length <= 1 {
        return false;
    }

    if sum_vec(&nums) == 0 {
        return true;
    }

    if k == 0 {
        return false;
    }

    if length >= 2 && k > 0 {
        return true;
    }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>day 11<commit_after>use std::io::{Cursor, Read};

const A: u8 = 'a' as u8;
const Z: u8 = 'z' as u8;

// forbidden characters
const I: u8 = 'i' as u8;
const L: u8 = 'l' as u8;
const O: u8 = 'o' as u8;

const FORBIDDEN: [u8; 3] = [I, L, O];

fn main() {
    let input = "vzbxkghb";
    // Uncomment for part 2
    // let input = "vzbxxyzz";

    let mut pass: [u8; 8] = {
        let mut cur = Cursor::new(input);
        let mut buff = [0; 8];
        cur.read(&mut buff).expect("Could not read &'static str from Cursor");

        buff
    };

    // Uncomment for part 2
    // increment(&mut pass);

    while !is_valid(&pass) {
        if !check_forbidden_chars(&pass) {
            increment_forbidden_char(&mut pass);
            continue
        }

        increment(&mut pass);

        if pass == [A, A, A, A, A, A, A, A] {
            panic!("No valid password found");
        }
    }

    let pass = String::from_utf8(Vec::from(pass.as_ref())).expect("Could not convert to utf-8");

    println!("{}", pass);
}

fn is_valid(pass: &[u8; 8]) -> bool {
    check_increasing_sequence(pass) && check_forbidden_chars(pass) && check_pairs(pass)
}

fn increment(pass: &mut [u8; 8]) {
    for i in (0..8).rev() {
        if pass[i] == Z {
            if i == 0 {
                for j in 0..8 { pass[j] = A }
            }
            pass[i] = A;
        } else {
            pass[i] += 1;
            break;
        }
    }
}

fn increment_forbidden_char(pass: &mut [u8; 8]) {
    for i in (0..8).rev() {
        if FORBIDDEN.contains(&pass[i]) {
            pass[i] += 1;
            for j in (i + 1)..8 { pass[j] = A }
            break;
        }
    }
}

fn check_increasing_sequence(pass: &[u8; 8]) -> bool {
    for i in 0..6 {
        if pass[i + 1] == (pass[i] + 1) && pass[i + 2] == (pass[i] + 2) {
            return true
        }
    }

    false
}

fn check_forbidden_chars(pass: &[u8; 8]) -> bool {
    for c in pass.iter() {
        if FORBIDDEN.contains(c) {
            return false
        }
    }

    true
}

fn check_pairs(pass: &[u8; 8]) -> bool {
    let mut pair_1 = 0;
    let mut pair_2 = 0;

    let mut second_loop_start = 0;

    for i in 0..5 {
        if pass[i] == pass[i + 1] {
            pair_1 = pass[i];
            second_loop_start = i + 2;
            break
        }
    }

    if pair_1 == 0 {
        return false
    }

    for i in second_loop_start..7 {
        if pass[i] == pass[i + 1] {
            pair_2 = pass[i];
            break
        }
    }

    if pair_2 == 0 {
        return false
    }

    pair_1 != pair_2
}

#[cfg(test)]
mod tests {
    use super::{A, Z, I, L, O};

    const B: u8 = 'b' as u8;

    #[test]
    fn increment_simple() {
        let mut input = [A, A, A, A, A, A, A, A];
        super::increment(&mut input);

        assert_eq!([A, A, A, A, A, A, A, B], input);
    }

    #[test]
    fn increment_not_so_simple() {
        let mut input = [A, A, A, A, A, A, A, Z];
        super::increment(&mut input);

        assert_eq!([A, A, A, A, A, A, B, A], input);
    }

    #[test]
    fn increment_complicated() {
        let mut input = [Z, Z, Z, Z, Z, Z, Z, Z];
        super::increment(&mut input);

        assert_eq!([A, A, A, A, A, A, A, A], input);
    }

    #[test]
    fn has_increasing_sequence_at_beginning() {
        let input = [A, A + 1, A + 2, A, A, A, A, A];
        assert!(super::check_increasing_sequence(&input));
    }

    #[test]
    fn has_increasing_sequence_at_end() {
        let input = [A, A, A, A, A, A, A + 1, A + 2];
        assert!(super::check_increasing_sequence(&input));
    }

    #[test]
    fn has_increasing_sequence_at_middle() {
        let input = [A, A, A, A + 1, A + 2, A, A, A];
        assert!(super::check_increasing_sequence(&input));
    }

    #[test]
    fn doesnt_has_increasing_sequence_should_fail() {
        let input = [A, Z, A, Z, A, Z, A, Z];
        assert!( ! super::check_increasing_sequence(&input));
    }

    #[test]
    fn has_forbidden_chars_should_fail() {
        let input = [A, I, A, A, A, A, A, A];
        assert!( ! super::check_forbidden_chars(&input));

        let input = [A, A, A, L, A, A, A, A];
        assert!( ! super::check_forbidden_chars(&input));

        let input = [A, A, A, A, A, A, O, A];
        assert!( ! super::check_forbidden_chars(&input));
    }

    #[test]
    fn has_multiple_forbdden_chars_should_fail() {
        let input = [A, I, A, L, A, O, A, A];
        assert!( ! super::check_forbidden_chars(&input));
    }

    #[test]
    fn doesnt_has_forbidden_chars() {
        let input = [A, Z, A, Z, A, Z, A, Z];
        assert!(super::check_forbidden_chars(&input));
    }

    #[test]
    fn has_two_different_pairs_at_begenning() {
        let input = [A, A, B, B, A, Z, A, Z];
        assert!(super::check_pairs(&input));
    }

    #[test]
    fn has_two_different_pairs_at_end() {
        let input = [A, Z, A, Z, A, A, B, B];
        assert!(super::check_pairs(&input));
    }

    #[test]
    fn has_two_different_pairs_at_middle() {
        let input = [A, Z, A, A, B, B, A, Z];
        assert!(super::check_pairs(&input));
    }

    #[test]
    fn has_two_different_pairs_at_sides() {
        let input = [A, A, Z, Z, Z, Z, B, B];
        assert!(super::check_pairs(&input));
    }

    #[test]
    fn doesnt_has_two_different_pairs_should_fail() {
        let input = [A, Z, A, Z, A, Z, A, Z];
        assert!( ! super::check_pairs(&input));
    }

    #[test]
    fn has_two_equal_pairs_should_fail() {
        let input = [A, A, A, Z, A, A, A, Z];
        assert!( ! super::check_pairs(&input));
    }

    #[test]
    fn has_only_one_pair_should_fail() {
        let input = [A, A, Z, A, Z, A, Z, A];
        assert!( ! super::check_pairs(&input));
    }

    #[test]
    fn increment_forbidden() {
        let mut input = [A, A, A, I, B, Z, B, B];
        super::increment_forbidden_char(&mut input);

        assert_eq!([A, A, A, I + 1, A, A, A, A], input);
    }
}
<|endoftext|>


<commit_before><commit_msg>added brainfuck maco, need to add dep to cargo<commit_after><|endoftext|>


<commit_before><commit_msg>Create card_points.rs<commit_after>use card::Card;

#[derive(Debug, PartialEq)]
pub struct CardPoints {
    card: Card,
    points: i32
}

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

	use card::*;

    #[test]
    fn equality() {
    	let card = Card { suit: Suit::Heart, rank: Rank::Ace };
    	assert_eq!(CardPoints { card: card, points: 1 }, CardPoints { card: card, points: 1 });
    }
}
<|endoftext|>


<commit_before><commit_msg>create the sandbox in the main thread<commit_after><|endoftext|>


<commit_before><commit_msg>DenseVector: Indexing unset values now panics, and more docs.<commit_after><|endoftext|>


<commit_before>// Extended attribute support

#[cfg(target_os = "macos")] mod xattr_darwin;
#[cfg(target_os = "macos")] pub use self::xattr_darwin::Attribute;

#[cfg(target_os = "linux")] mod xattr_linux;
#[cfg(target_os = "linux")] pub use self::xattr_linux::Attribute;

#[cfg(not(any(target_os = "macos", target_os = "linux")))] use std::old_io as io;
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
#[derive(Clone)]
pub struct Attribute;

#[cfg(not(any(target_os = "macos", target_os = "linux")))]
impl Attribute {

    /// Getter for name
    pub fn name(&self) -> &str {
        unimplemented!()
    }

    /// Getter for size
    pub fn size(&self) -> usize {
        unimplemented!()
    }

    /// Lists the extended attributes. Follows symlinks like `metadata`
    pub fn list(_: &Path) -> io::IoResult<Vec<Attribute>> {
        Ok(Vec::new())
    }

    /// Lists the extended attributes. Does not follow symlinks like `symlink_metadata`
    pub fn llist(_: &Path) -> io::IoResult<Vec<Attribute>> {
        Ok(Vec::new())
    }

    pub fn feature_implemented() -> bool { false }
}

// Git support

#[cfg(feature="git")] mod git;
#[cfg(feature="git")] pub use self::git::Git;

#[cfg(not(feature="git"))] pub struct Git;
#[cfg(not(feature="git"))] use std::old_path::posix::Path;
#[cfg(not(feature="git"))]
impl Git {
    pub fn scan(_: &Path) -> Result<Git, ()> {
        Err(())
    }

    pub fn status(&self, _: &Path) -> String {
        panic!("Tried to access a Git repo without Git support!");
    }

    pub fn dir_status(&self, path: &Path) -> String {
        self.status(path)
    }
}
<commit_msg>fix compile errors if git support is disabled<commit_after>// Extended attribute support

#[cfg(target_os = "macos")] mod xattr_darwin;
#[cfg(target_os = "macos")] pub use self::xattr_darwin::Attribute;

#[cfg(target_os = "linux")] mod xattr_linux;
#[cfg(target_os = "linux")] pub use self::xattr_linux::Attribute;

#[cfg(not(any(target_os = "macos", target_os = "linux")))] use std::old_io as io;
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
#[derive(Clone)]
pub struct Attribute;

#[cfg(not(any(target_os = "macos", target_os = "linux")))]
impl Attribute {

    /// Getter for name
    pub fn name(&self) -> &str {
        unimplemented!()
    }

    /// Getter for size
    pub fn size(&self) -> usize {
        unimplemented!()
    }

    /// Lists the extended attributes. Follows symlinks like `metadata`
    pub fn list(_: &Path) -> io::IoResult<Vec<Attribute>> {
        Ok(Vec::new())
    }

    /// Lists the extended attributes. Does not follow symlinks like `symlink_metadata`
    pub fn llist(_: &Path) -> io::IoResult<Vec<Attribute>> {
        Ok(Vec::new())
    }

    pub fn feature_implemented() -> bool { false }
}

// Git support

#[cfg(feature="git")] mod git;
#[cfg(feature="git")] pub use self::git::Git;

#[cfg(not(feature="git"))] pub struct Git;
#[cfg(not(feature="git"))] use std::path::Path;
#[cfg(not(feature="git"))] use file::fields;
#[cfg(not(feature="git"))]
impl Git {
    pub fn scan(_: &Path) -> Result<Git, ()> {
        Err(())
    }

    pub fn status(&self, _: &Path) -> fields::Git {
        panic!("Tried to access a Git repo without Git support!");
    }

    pub fn dir_status(&self, path: &Path) -> fields::Git {
        self.status(path)
    }
}
<|endoftext|>