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

//! A pass that removes various redundancies in the CFG. It should be
//! called after every significant CFG modification to tidy things
//! up.
//!
//! This pass must also be run before any analysis passes because it removes
//! dead blocks, and some of these can be ill-typed.
//!
//! The cause of that is that typeck lets most blocks whose end is not
//! reachable have an arbitrary return type, rather than having the
//! usual () return type (as a note, typeck's notion of reachability
//! is in fact slightly weaker than MIR CFG reachability - see #31617).
//!
//! A standard example of the situation is:
//! ```rust
//!   fn example() {
//!       let _a: char = { return; };
//!   }
//! ```
//!
//! Here the block (`{ return; }`) has the return type `char`,
//! rather than `()`, but the MIR we naively generate still contains
//! the `_a = ()` write in the unreachable block "after" the return.

use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc::ty::TyCtxt;
use rustc::mir::repr::*;
use rustc::mir::transform::{MirPass, MirSource, Pass};
use rustc::mir::traversal;
use std::fmt;

pub struct SimplifyCfg<'a> { label: &'a str }

impl<'a> SimplifyCfg<'a> {
    pub fn new(label: &'a str) -> Self {
        SimplifyCfg { label: label }
    }
}

impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
        CfgSimplifier::new(mir).simplify();
        remove_dead_blocks(mir);

        // FIXME: Should probably be moved into some kind of pass manager
        mir.basic_blocks_mut().raw.shrink_to_fit();
    }
}

impl<'l> Pass for SimplifyCfg<'l> {
    fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> {
        Some(Box::new(self.label))
    }

    // avoid calling `type_name` - it contains `<'static>`
    fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyCfg".into() }
}

pub struct CfgSimplifier<'a, 'tcx: 'a> {
    basic_blocks: &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
    pred_count: IndexVec<BasicBlock, u32>
}

impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
    fn new(mir: &'a mut Mir<'tcx>) -> Self {
        let mut pred_count = IndexVec::from_elem(0u32, mir.basic_blocks());

        // we can't use mir.predecessors() here because that counts
        // dead blocks, which we don't want to.
        for (_, data) in traversal::preorder(mir) {
            if let Some(ref term) = data.terminator {
                for &tgt in term.successors().iter() {
                    pred_count[tgt] += 1;
                }
            }
        }

        let basic_blocks = mir.basic_blocks_mut();

        CfgSimplifier {
            basic_blocks: basic_blocks,
            pred_count: pred_count
        }
    }

    fn simplify(mut self) {
        loop {
            let mut changed = false;

            for bb in (0..self.basic_blocks.len()).map(BasicBlock::new) {
                if self.pred_count[bb] == 0 {
                    continue
                }

                debug!("simplifying {:?}", bb);

                let mut terminator = self.basic_blocks[bb].terminator.take()
                    .expect("invalid terminator state");

                for successor in terminator.successors_mut() {
                    self.collapse_goto_chain(successor, &mut changed);
                }

                let mut new_stmts = vec![];
                let mut inner_changed = true;
                while inner_changed {
                    inner_changed = false;
                    inner_changed |= self.simplify_branch(&mut terminator);
                    inner_changed |= self.merge_successor(&mut new_stmts, &mut terminator);
                    changed |= inner_changed;
                }

                self.basic_blocks[bb].statements.extend(new_stmts);
                self.basic_blocks[bb].terminator = Some(terminator);

                changed |= inner_changed;
            }

            if !changed { break }
        }
    }

    // Collapse a goto chain starting from `start`
    fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) {
        let mut terminator = match self.basic_blocks[*start] {
            BasicBlockData {
                ref statements,
                terminator: ref mut terminator @ Some(Terminator {
                    kind: TerminatorKind::Goto { .. }, ..
                }), ..
            } if statements.is_empty() => terminator.take(),
            // if `terminator` is None, this means we are in a loop. In that
            // case, let all the loop collapse to its entry.
            _ => return
        };

        let target = match terminator {
            Some(Terminator { kind: TerminatorKind::Goto { ref mut target }, .. }) => {
                self.collapse_goto_chain(target, changed);
                *target
            }
            _ => unreachable!()
        };
        self.basic_blocks[*start].terminator = terminator;

        debug!("collapsing goto chain from {:?} to {:?}", *start, target);

        *changed |= *start != target;
        self.pred_count[target] += 1;
        self.pred_count[*start] -= 1;
        *start = target;
    }

    // merge a block with 1 `goto` predecessor to its parent
    fn merge_successor(&mut self,
                       new_stmts: &mut Vec<Statement<'tcx>>,
                       terminator: &mut Terminator<'tcx>)
                       -> bool
    {
        let target = match terminator.kind {
            TerminatorKind::Goto { target }
                if self.pred_count[target] == 1
                => target,
            _ => return false
        };

        debug!("merging block {:?} into {:?}", target, terminator);
        *terminator = match self.basic_blocks[target].terminator.take() {
            Some(terminator) => terminator,
            None => {
                // unreachable loop - this should not be possible, as we
                // don't strand blocks, but handle it correctly.
                return false
            }
        };
        new_stmts.extend(self.basic_blocks[target].statements.drain(..));
        self.pred_count[target] = 0;

        true
    }

    // turn a branch with all successors identical to a goto
    fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool {
        match terminator.kind {
            TerminatorKind::If { .. } |
            TerminatorKind::Switch { .. } |
            TerminatorKind::SwitchInt { .. } => {},
            _ => return false
        };

        let first_succ = {
            let successors = terminator.successors();
            if let Some(&first_succ) = terminator.successors().get(0) {
                if successors.iter().all(|s| *s == first_succ) {
                    self.pred_count[first_succ] -= (successors.len()-1) as u32;
                    first_succ
                } else {
                    return false
                }
            } else {
                return false
            }
        };

        debug!("simplifying branch {:?}", terminator);
        terminator.kind = TerminatorKind::Goto { target: first_succ };
        true
    }
}

fn remove_dead_blocks(mir: &mut Mir) {
    let mut seen = BitVector::new(mir.basic_blocks().len());
    for (bb, _) in traversal::preorder(mir) {
        seen.insert(bb.index());
    }

    let basic_blocks = mir.basic_blocks_mut();

    let num_blocks = basic_blocks.len();
    let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
    let mut used_blocks = 0;
    for alive_index in seen.iter() {
        replacements[alive_index] = BasicBlock::new(used_blocks);
        if alive_index != used_blocks {
            // Swap the next alive block data with the current available slot. Since alive_index is
            // non-decreasing this is a valid operation.
            basic_blocks.raw.swap(alive_index, used_blocks);
        }
        used_blocks += 1;
    }
    basic_blocks.raw.truncate(used_blocks);

    for block in basic_blocks {
        for target in block.terminator_mut().successors_mut() {
            *target = replacements[target.index()];
        }
    }
}
<commit_msg>SimplifyCfg: simplify the start block<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A pass that removes various redundancies in the CFG. It should be
//! called after every significant CFG modification to tidy things
//! up.
//!
//! This pass must also be run before any analysis passes because it removes
//! dead blocks, and some of these can be ill-typed.
//!
//! The cause of that is that typeck lets most blocks whose end is not
//! reachable have an arbitrary return type, rather than having the
//! usual () return type (as a note, typeck's notion of reachability
//! is in fact slightly weaker than MIR CFG reachability - see #31617).
//!
//! A standard example of the situation is:
//! ```rust
//!   fn example() {
//!       let _a: char = { return; };
//!   }
//! ```
//!
//! Here the block (`{ return; }`) has the return type `char`,
//! rather than `()`, but the MIR we naively generate still contains
//! the `_a = ()` write in the unreachable block "after" the return.

use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc::ty::TyCtxt;
use rustc::mir::repr::*;
use rustc::mir::transform::{MirPass, MirSource, Pass};
use rustc::mir::traversal;
use std::fmt;

pub struct SimplifyCfg<'a> { label: &'a str }

impl<'a> SimplifyCfg<'a> {
    pub fn new(label: &'a str) -> Self {
        SimplifyCfg { label: label }
    }
}

impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
        debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
        CfgSimplifier::new(mir).simplify();
        remove_dead_blocks(mir);

        // FIXME: Should probably be moved into some kind of pass manager
        mir.basic_blocks_mut().raw.shrink_to_fit();
    }
}

impl<'l> Pass for SimplifyCfg<'l> {
    fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> {
        Some(Box::new(self.label))
    }

    // avoid calling `type_name` - it contains `<'static>`
    fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyCfg".into() }
}

pub struct CfgSimplifier<'a, 'tcx: 'a> {
    basic_blocks: &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
    pred_count: IndexVec<BasicBlock, u32>
}

impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
    fn new(mir: &'a mut Mir<'tcx>) -> Self {
        let mut pred_count = IndexVec::from_elem(0u32, mir.basic_blocks());

        // we can't use mir.predecessors() here because that counts
        // dead blocks, which we don't want to.
        pred_count[START_BLOCK] = 1;

        for (_, data) in traversal::preorder(mir) {
            if let Some(ref term) = data.terminator {
                for &tgt in term.successors().iter() {
                    pred_count[tgt] += 1;
                }
            }
        }

        let basic_blocks = mir.basic_blocks_mut();

        CfgSimplifier {
            basic_blocks: basic_blocks,
            pred_count: pred_count
        }
    }

    fn simplify(mut self) {
        loop {
            let mut changed = false;

            for bb in (0..self.basic_blocks.len()).map(BasicBlock::new) {
                if self.pred_count[bb] == 0 {
                    continue
                }

                debug!("simplifying {:?}", bb);

                let mut terminator = self.basic_blocks[bb].terminator.take()
                    .expect("invalid terminator state");

                for successor in terminator.successors_mut() {
                    self.collapse_goto_chain(successor, &mut changed);
                }

                let mut new_stmts = vec![];
                let mut inner_changed = true;
                while inner_changed {
                    inner_changed = false;
                    inner_changed |= self.simplify_branch(&mut terminator);
                    inner_changed |= self.merge_successor(&mut new_stmts, &mut terminator);
                    changed |= inner_changed;
                }

                self.basic_blocks[bb].statements.extend(new_stmts);
                self.basic_blocks[bb].terminator = Some(terminator);

                changed |= inner_changed;
            }

            if !changed { break }
        }
    }

    // Collapse a goto chain starting from `start`
    fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) {
        let mut terminator = match self.basic_blocks[*start] {
            BasicBlockData {
                ref statements,
                terminator: ref mut terminator @ Some(Terminator {
                    kind: TerminatorKind::Goto { .. }, ..
                }), ..
            } if statements.is_empty() => terminator.take(),
            // if `terminator` is None, this means we are in a loop. In that
            // case, let all the loop collapse to its entry.
            _ => return
        };

        let target = match terminator {
            Some(Terminator { kind: TerminatorKind::Goto { ref mut target }, .. }) => {
                self.collapse_goto_chain(target, changed);
                *target
            }
            _ => unreachable!()
        };
        self.basic_blocks[*start].terminator = terminator;

        debug!("collapsing goto chain from {:?} to {:?}", *start, target);

        *changed |= *start != target;
        self.pred_count[target] += 1;
        self.pred_count[*start] -= 1;
        *start = target;
    }

    // merge a block with 1 `goto` predecessor to its parent
    fn merge_successor(&mut self,
                       new_stmts: &mut Vec<Statement<'tcx>>,
                       terminator: &mut Terminator<'tcx>)
                       -> bool
    {
        let target = match terminator.kind {
            TerminatorKind::Goto { target }
                if self.pred_count[target] == 1
                => target,
            _ => return false
        };

        debug!("merging block {:?} into {:?}", target, terminator);
        *terminator = match self.basic_blocks[target].terminator.take() {
            Some(terminator) => terminator,
            None => {
                // unreachable loop - this should not be possible, as we
                // don't strand blocks, but handle it correctly.
                return false
            }
        };
        new_stmts.extend(self.basic_blocks[target].statements.drain(..));
        self.pred_count[target] = 0;

        true
    }

    // turn a branch with all successors identical to a goto
    fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool {
        match terminator.kind {
            TerminatorKind::If { .. } |
            TerminatorKind::Switch { .. } |
            TerminatorKind::SwitchInt { .. } => {},
            _ => return false
        };

        let first_succ = {
            let successors = terminator.successors();
            if let Some(&first_succ) = terminator.successors().get(0) {
                if successors.iter().all(|s| *s == first_succ) {
                    self.pred_count[first_succ] -= (successors.len()-1) as u32;
                    first_succ
                } else {
                    return false
                }
            } else {
                return false
            }
        };

        debug!("simplifying branch {:?}", terminator);
        terminator.kind = TerminatorKind::Goto { target: first_succ };
        true
    }
}

fn remove_dead_blocks(mir: &mut Mir) {
    let mut seen = BitVector::new(mir.basic_blocks().len());
    for (bb, _) in traversal::preorder(mir) {
        seen.insert(bb.index());
    }

    let basic_blocks = mir.basic_blocks_mut();

    let num_blocks = basic_blocks.len();
    let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
    let mut used_blocks = 0;
    for alive_index in seen.iter() {
        replacements[alive_index] = BasicBlock::new(used_blocks);
        if alive_index != used_blocks {
            // Swap the next alive block data with the current available slot. Since alive_index is
            // non-decreasing this is a valid operation.
            basic_blocks.raw.swap(alive_index, used_blocks);
        }
        used_blocks += 1;
    }
    basic_blocks.raw.truncate(used_blocks);

    for block in basic_blocks {
        for target in block.terminator_mut().successors_mut() {
            *target = replacements[target.index()];
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Improve the u8 vector dump so that it doesn't represent non-existent bytes<commit_after><|endoftext|>


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

#![feature(core_intrinsics)]

use std::intrinsics;

const SWAPPED_U8: u8 = unsafe { intrinsics::bswap(0x12_u8) };
const SWAPPED_U16: u16 = unsafe { intrinsics::bswap(0x12_34_u16) };
const SWAPPED_I32: i32 = unsafe { intrinsics::bswap(0x12_34_56_78_i32) };

fn main() {
    assert_eq!(SWAPPED_U8, 0x12);
    assert_eq!(SWAPPED_U16, 0x34_12);
    assert_eq!(SWAPPED_I32, 0x78_56_34_12);
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #75886 - erikdesjardins:index, r=nikic<commit_after>// min-llvm-version: 11.0.0
// compile-flags: -O
// ignore-debug: the debug assertions get in the way
#![crate_type = "lib"]

// Make sure no bounds checks are emitted when slicing or indexing
// with an index from `position()` or `rposition()`.

// CHECK-LABEL: @position_slice_to_no_bounds_check
#[no_mangle]
pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
        &s[..idx]
    } else {
        s
    }
}

// CHECK-LABEL: @position_slice_from_no_bounds_check
#[no_mangle]
pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
        &s[idx..]
    } else {
        s
    }
}

// CHECK-LABEL: @position_index_no_bounds_check
#[no_mangle]
pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
        s[idx]
    } else {
        42
    }
}
// CHECK-LABEL: @rposition_slice_to_no_bounds_check
#[no_mangle]
pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
        &s[..idx]
    } else {
        s
    }
}

// CHECK-LABEL: @rposition_slice_from_no_bounds_check
#[no_mangle]
pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
        &s[idx..]
    } else {
        s
    }
}

// CHECK-LABEL: @rposition_index_no_bounds_check
#[no_mangle]
pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
        s[idx]
    } else {
        42
    }
}
<|endoftext|>


<commit_before><commit_msg>Add Rust code for proverb case<commit_after>pub fn build_proverb(text: Vec<&str>) -> String {
    let mut result = String::new();
    let mut iter = text.iter().peekable();

    let last = if text.len() < 3 { "" } else { "horseshoe " };

    while let Some(c) = iter.next() {
        if let Some(n) = iter.peek() {
            result += &format!("For want of a {} the {} was lost.\n", c, n);
        } else {
            result += &format!("And all for the want of a {}nail.", last);
        }
    }

    result
}
<|endoftext|>


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

use prelude::*;
use fmt::{self, Write, FlagV1};

struct PadAdapter<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    on_newline: bool,
}

impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
    fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
        PadAdapter {
            fmt: fmt,
            on_newline: false,
        }
    }
}

impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
    fn write_str(&mut self, mut s: &str) -> fmt::Result {
        while !s.is_empty() {
            if self.on_newline {
                try!(self.fmt.write_str("    "));
            }

            let split = match s.find('\n') {
                Some(pos) => {
                    self.on_newline = true;
                    pos + 1
                }
                None => {
                    self.on_newline = false;
                    s.len()
                }
            };
            try!(self.fmt.write_str(&s[..split]));
            s = &s[split..];
        }

        Ok(())
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_struct` method.
#[must_use]
pub struct DebugStruct<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
                                -> DebugStruct<'a, 'b> {
    let result = fmt.write_str(name);
    DebugStruct {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
    /// Adds a new field to the generated struct output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
        self.result = self.result.and_then(|_| {
            let prefix = if self.has_fields {
                ","
            } else {
                " {"
            };

            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
            } else {
                write!(self.fmt, "{} {}: {:?}", prefix, name, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Consumes the `DebugStruct`, finishing output and returning any error
    /// encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        if self.has_fields {
            self.result = self.result.and_then(|_| {
                if self.is_pretty() {
                    self.fmt.write_str("\n}")
                } else {
                    self.fmt.write_str(" }")
                }
            });
        }
        self.result
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_tuple` method.
#[must_use]
pub struct DebugTuple<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
    let result = fmt.write_str(name);
    DebugTuple {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
    /// Adds a new field to the generated tuple struct output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
        self.result = self.result.and_then(|_| {
            let (prefix, space) = if self.has_fields {
                (",", " ")
            } else {
                ("(", "")
            };

            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
            } else {
                write!(self.fmt, "{}{}{:?}", prefix, space, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Consumes the `DebugTuple`, finishing output and returning any error
    /// encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        if self.has_fields {
            self.result = self.result.and_then(|_| {
                if self.is_pretty() {
                    self.fmt.write_str("\n)")
                } else {
                    self.fmt.write_str(")")
                }
            });
        }
        self.result
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

struct DebugInner<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

impl<'a, 'b: 'a> DebugInner<'a, 'b> {
    fn entry(&mut self, entry: &fmt::Debug) {
        self.result = self.result.and_then(|_| {
            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                let prefix = if self.has_fields { "," } else { "" };
                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
            } else {
                let prefix = if self.has_fields { ", " } else { "" };
                write!(self.fmt, "{}{:?}", prefix, entry)
            }
        });

        self.has_fields = true;
    }

    pub fn finish(&mut self) {
        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
        self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_set` method.
#[must_use]
pub struct DebugSet<'a, 'b: 'a> {
    inner: DebugInner<'a, 'b>,
}

pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
    let result = write!(fmt, "{{");
    DebugSet {
        inner: DebugInner {
            fmt: fmt,
            result: result,
            has_fields: false,
        }
    }
}

impl<'a, 'b: 'a> DebugSet<'a, 'b> {
    /// Adds a new entry to the set output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
        self.inner.entry(entry);
        self
    }

    /// Adds the contents of an iterator of entries to the set output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
            where D: fmt::Debug, I: IntoIterator<Item=D> {
        for entry in entries {
            self.entry(&entry);
        }
        self
    }

    /// Consumes the `DebugSet`, finishing output and returning any error
    /// encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        self.inner.finish();
        self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_list` method.
#[must_use]
pub struct DebugList<'a, 'b: 'a> {
    inner: DebugInner<'a, 'b>,
}

pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
    let result = write!(fmt, "[");
    DebugList {
        inner: DebugInner {
            fmt: fmt,
            result: result,
            has_fields: false,
        }
    }
}

impl<'a, 'b: 'a> DebugList<'a, 'b> {
    /// Adds a new entry to the list output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
        self.inner.entry(entry);
        self
    }

    /// Adds the contents of an iterator of entries to the list output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
            where D: fmt::Debug, I: IntoIterator<Item=D> {
        for entry in entries {
            self.entry(&entry);
        }
        self
    }

    /// Consumes the `DebugSet`, finishing output and returning any error
    /// encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        self.inner.finish();
        self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_map` method.
#[must_use]
pub struct DebugMap<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
    let result = write!(fmt, "{{");
    DebugMap {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugMap<'a, 'b> {
    /// Adds a new entry to the map output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
        self.result = self.result.and_then(|_| {
            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                let prefix = if self.has_fields { "," } else { "" };
                fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
            } else {
                let prefix = if self.has_fields { ", " } else { "" };
                write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Adds the contents of an iterator of entries to the map output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
            where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item=(K, V)> {
        for (k, v) in entries {
            self.entry(&k, &v);
        }
        self
    }

    /// Consumes the `DebugMap`, finishing output and returning any error
    /// encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
        self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}
<commit_msg>Fix finish docs<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use prelude::*;
use fmt::{self, Write, FlagV1};

struct PadAdapter<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    on_newline: bool,
}

impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
    fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
        PadAdapter {
            fmt: fmt,
            on_newline: false,
        }
    }
}

impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
    fn write_str(&mut self, mut s: &str) -> fmt::Result {
        while !s.is_empty() {
            if self.on_newline {
                try!(self.fmt.write_str("    "));
            }

            let split = match s.find('\n') {
                Some(pos) => {
                    self.on_newline = true;
                    pos + 1
                }
                None => {
                    self.on_newline = false;
                    s.len()
                }
            };
            try!(self.fmt.write_str(&s[..split]));
            s = &s[split..];
        }

        Ok(())
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_struct` method.
#[must_use]
pub struct DebugStruct<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
                                -> DebugStruct<'a, 'b> {
    let result = fmt.write_str(name);
    DebugStruct {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
    /// Adds a new field to the generated struct output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
        self.result = self.result.and_then(|_| {
            let prefix = if self.has_fields {
                ","
            } else {
                " {"
            };

            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
            } else {
                write!(self.fmt, "{} {}: {:?}", prefix, name, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Finishes output and returns any error encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        if self.has_fields {
            self.result = self.result.and_then(|_| {
                if self.is_pretty() {
                    self.fmt.write_str("\n}")
                } else {
                    self.fmt.write_str(" }")
                }
            });
        }
        self.result
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_tuple` method.
#[must_use]
pub struct DebugTuple<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
    let result = fmt.write_str(name);
    DebugTuple {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
    /// Adds a new field to the generated tuple struct output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
        self.result = self.result.and_then(|_| {
            let (prefix, space) = if self.has_fields {
                (",", " ")
            } else {
                ("(", "")
            };

            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
            } else {
                write!(self.fmt, "{}{}{:?}", prefix, space, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Finishes output and returns any error encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        if self.has_fields {
            self.result = self.result.and_then(|_| {
                if self.is_pretty() {
                    self.fmt.write_str("\n)")
                } else {
                    self.fmt.write_str(")")
                }
            });
        }
        self.result
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

struct DebugInner<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

impl<'a, 'b: 'a> DebugInner<'a, 'b> {
    fn entry(&mut self, entry: &fmt::Debug) {
        self.result = self.result.and_then(|_| {
            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                let prefix = if self.has_fields { "," } else { "" };
                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
            } else {
                let prefix = if self.has_fields { ", " } else { "" };
                write!(self.fmt, "{}{:?}", prefix, entry)
            }
        });

        self.has_fields = true;
    }

    pub fn finish(&mut self) {
        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
        self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_set` method.
#[must_use]
pub struct DebugSet<'a, 'b: 'a> {
    inner: DebugInner<'a, 'b>,
}

pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
    let result = write!(fmt, "{{");
    DebugSet {
        inner: DebugInner {
            fmt: fmt,
            result: result,
            has_fields: false,
        }
    }
}

impl<'a, 'b: 'a> DebugSet<'a, 'b> {
    /// Adds a new entry to the set output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
        self.inner.entry(entry);
        self
    }

    /// Adds the contents of an iterator of entries to the set output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
            where D: fmt::Debug, I: IntoIterator<Item=D> {
        for entry in entries {
            self.entry(&entry);
        }
        self
    }

    /// Finishes output and returns any error encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        self.inner.finish();
        self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_list` method.
#[must_use]
pub struct DebugList<'a, 'b: 'a> {
    inner: DebugInner<'a, 'b>,
}

pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
    let result = write!(fmt, "[");
    DebugList {
        inner: DebugInner {
            fmt: fmt,
            result: result,
            has_fields: false,
        }
    }
}

impl<'a, 'b: 'a> DebugList<'a, 'b> {
    /// Adds a new entry to the list output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
        self.inner.entry(entry);
        self
    }

    /// Adds the contents of an iterator of entries to the list output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
            where D: fmt::Debug, I: IntoIterator<Item=D> {
        for entry in entries {
            self.entry(&entry);
        }
        self
    }

    /// Finishes output and returns any error encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        self.inner.finish();
        self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
    }
}

/// A struct to help with `fmt::Debug` implementations.
///
/// Constructed by the `Formatter::debug_map` method.
#[must_use]
pub struct DebugMap<'a, 'b: 'a> {
    fmt: &'a mut fmt::Formatter<'b>,
    result: fmt::Result,
    has_fields: bool,
}

pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
    let result = write!(fmt, "{{");
    DebugMap {
        fmt: fmt,
        result: result,
        has_fields: false,
    }
}

impl<'a, 'b: 'a> DebugMap<'a, 'b> {
    /// Adds a new entry to the map output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
        self.result = self.result.and_then(|_| {
            if self.is_pretty() {
                let mut writer = PadAdapter::new(self.fmt);
                let prefix = if self.has_fields { "," } else { "" };
                fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
            } else {
                let prefix = if self.has_fields { ", " } else { "" };
                write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
            }
        });

        self.has_fields = true;
        self
    }

    /// Adds the contents of an iterator of entries to the map output.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
            where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item=(K, V)> {
        for (k, v) in entries {
            self.entry(&k, &v);
        }
        self
    }

    /// Finishes output and returns any error encountered.
    #[unstable(feature = "debug_builders", reason = "method was just created")]
    pub fn finish(&mut self) -> fmt::Result {
        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
        self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
    }

    fn is_pretty(&self) -> bool {
        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
    }
}
<|endoftext|>


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

use borrow_check::borrow_set::BorrowData;
use borrow_check::error_reporting::UseSpans;
use borrow_check::nll::region_infer::Cause;
use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
use rustc::ty::{Region, TyCtxt};
use rustc::mir::{FakeReadCause, Location, Operand, Place, StatementKind, TerminatorKind};
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;
use syntax_pos::symbol::Symbol;

mod find_use;

pub(in borrow_check) enum BorrowExplanation<'tcx> {
    UsedLater(LaterUseKind, Span),
    UsedLaterInLoop(LaterUseKind, Span),
    UsedLaterWhenDropped(Span, Symbol, bool),
    MustBeValidFor(Region<'tcx>),
    Unexplained,
}

#[derive(Clone, Copy)]
pub(in borrow_check) enum LaterUseKind {
    ClosureCapture,
    Call,
    FakeLetRead,
    Other,
}

impl<'tcx> BorrowExplanation<'tcx> {
    pub(in borrow_check) fn emit<'cx, 'gcx>(
        &self,
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        err: &mut DiagnosticBuilder<'_>,
        borrow_desc: String,
    ) {
        match *self {
            BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
                let message = borrow_desc + match later_use_kind {
                    LaterUseKind::ClosureCapture => "borrow later captured here by closure",
                    LaterUseKind::Call =>  "borrow later used by call",
                    LaterUseKind::FakeLetRead => "borrow later stored here",
                    LaterUseKind::Other => "borrow later used here",
                };
                err.span_label(var_or_use_span, message);
            },
            BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
                let message = borrow_desc + match later_use_kind {
                    LaterUseKind::ClosureCapture => {
                        "borrow captured here by closure, in later iteration of loop"
                    },
                    LaterUseKind::Call =>  "borrow used by call, in later iteration of loop",
                    LaterUseKind::FakeLetRead => "borrow later stored here",
                    LaterUseKind::Other => "borrow used here, in later iteration of loop",
                };
                err.span_label(var_or_use_span, message);
            },
            BorrowExplanation::UsedLaterWhenDropped(span, local_name, should_note_order) => {
                err.span_label(
                    span,
                    format!(
                        "{}borrow later used here, when `{}` is dropped",
                        borrow_desc,
                        local_name,
                    ),
                );

                if should_note_order {
                    err.note(
                        "values in a scope are dropped \
                         in the opposite order they are defined",
                    );
                }
            },
            BorrowExplanation::MustBeValidFor(region) => {
                tcx.note_and_explain_free_region(
                    err,
                    &(borrow_desc + "borrowed value must be valid for "),
                    region,
                    "...",
                );
            },
            _ => {},
        }
    }
}

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Returns structured explanation for *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// # Parameters
    ///
    /// - `borrow`: the borrow in question
    /// - `context`: where the borrow occurs
    /// - `kind_place`: if Some, this describes the statement that triggered the error.
    ///   - first half is the kind of write, if any, being performed
    ///   - second half is the place being accessed
    ///
    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
    pub(in borrow_check) fn explain_why_borrow_contains_point(
        &self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        kind_place: Option<(WriteKind, &Place<'tcx>)>,
    ) -> BorrowExplanation<'tcx> {
        debug!(
            "find_why_borrow_contains_point(context={:?}, borrow={:?})",
            context, borrow,
        );

        let regioncx = &self.nonlexical_regioncx;
        let mir = self.mir;
        let tcx = self.infcx.tcx;

        let borrow_region_vid = regioncx.to_region_vid(borrow.region);
        debug!(
            "explain_why_borrow_contains_point: borrow_region_vid={:?}",
            borrow_region_vid
        );

        let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, context.loc);
        debug!(
            "explain_why_borrow_contains_point: region_sub={:?}",
            region_sub
        );

         match find_use::find(mir, regioncx, tcx, region_sub, context.loc) {
            Some(Cause::LiveVar(local, location)) => {
                let span = mir.source_info(location).span;
                let spans = self.move_spans(&Place::Local(local), location)
                    .or_else(|| self.borrow_spans(span, location));

                if self.is_borrow_location_in_loop(context.loc) {
                    let later_use = self.later_use_kind(spans, location);
                    BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1)
                } else {
                    // Check if the location represents a `FakeRead`, and adapt the error
                    // message to the `FakeReadCause` it is from: in particular,
                    // the ones inserted in optimized `let var = <expr>` patterns.
                    let later_use = self.later_use_kind(spans, location);
                    BorrowExplanation::UsedLater(later_use.0, later_use.1)
                }
            }

            Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name {
                Some(local_name) => {
                    let mut should_note_order = false;
                    if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
                        if let Place::Local(borrowed_local) = place {
                            let dropped_local_scope = mir.local_decls[local].visibility_scope;
                            let borrowed_local_scope =
                                mir.local_decls[*borrowed_local].visibility_scope;

                            if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope)
                                && local != *borrowed_local
                            {
                                should_note_order = true;
                            }
                        }
                    }

                    BorrowExplanation::UsedLaterWhenDropped(
                        mir.source_info(location).span,
                        *local_name,
                        should_note_order
                    )
                },

                None => BorrowExplanation::Unexplained,
            },

            None => if let Some(region) = regioncx.to_error_region(region_sub) {
                BorrowExplanation::MustBeValidFor(region)
            } else {
                BorrowExplanation::Unexplained
            },
        }
    }

    /// Check if a borrow location is within a loop.
    fn is_borrow_location_in_loop(
        &self,
        borrow_location: Location,
    ) -> bool {
        let mut visited_locations = Vec::new();
        let mut pending_locations = vec![ borrow_location ];
        debug!("is_in_loop: borrow_location={:?}", borrow_location);

        while let Some(location) = pending_locations.pop() {
            debug!("is_in_loop: location={:?} pending_locations={:?} visited_locations={:?}",
                   location, pending_locations, visited_locations);
            if location == borrow_location && visited_locations.contains(&borrow_location) {
                // We've managed to return to where we started (and this isn't the start of the
                // search).
                debug!("is_in_loop: found!");
                return true;
            }

            // Skip locations we've been.
            if visited_locations.contains(&location) { continue; }

            let block = &self.mir.basic_blocks()[location.block];
            if location.statement_index ==  block.statements.len() {
                // Add start location of the next blocks to pending locations.
                match block.terminator().kind {
                    TerminatorKind::Goto { target } => {
                        pending_locations.push(target.start_location());
                    },
                    TerminatorKind::SwitchInt { ref targets, .. } => {
                        for target in targets {
                            pending_locations.push(target.start_location());
                        }
                    },
                    TerminatorKind::Drop { target, unwind, .. } |
                    TerminatorKind::DropAndReplace { target, unwind, .. } |
                    TerminatorKind::Assert { target, cleanup: unwind, .. } |
                    TerminatorKind::Yield { resume: target, drop: unwind, .. } |
                    TerminatorKind::FalseUnwind { real_target: target, unwind, .. } => {
                        pending_locations.push(target.start_location());
                        if let Some(unwind) = unwind {
                            pending_locations.push(unwind.start_location());
                        }
                    },
                    TerminatorKind::Call { ref destination, cleanup, .. } => {
                        if let Some((_, destination)) = destination {
                            pending_locations.push(destination.start_location());
                        }
                        if let Some(cleanup) = cleanup {
                            pending_locations.push(cleanup.start_location());
                        }
                    },
                    TerminatorKind::FalseEdges { real_target, ref imaginary_targets, .. } => {
                        pending_locations.push(real_target.start_location());
                        for target in imaginary_targets {
                            pending_locations.push(target.start_location());
                        }
                    },
                    _ => {},
                }
            } else {
                // Add the next statement to pending locations.
                pending_locations.push(location.successor_within_block());
            }

            // Keep track of where we have visited.
            visited_locations.push(location);
        }

        false
    }

    fn later_use_kind(&self, use_spans: UseSpans, location: Location) -> (LaterUseKind, Span) {
        use self::LaterUseKind::*;

        let block = &self.mir.basic_blocks()[location.block];
        match use_spans {
            UseSpans::ClosureUse { var_span, .. } => (LaterUseKind::ClosureCapture, var_span),
            UseSpans::OtherUse(span) => {
                (if let Some(stmt) = block.statements.get(location.statement_index) {
                    match stmt.kind {
                        StatementKind::FakeRead(FakeReadCause::ForLet, _) => FakeLetRead,
                        _ => Other,
                    }
                } else {
                    assert_eq!(location.statement_index, block.statements.len());
                    match block.terminator().kind {
                        TerminatorKind::Call { ref func, from_hir_call: true, .. } => {
                            // Just point to the function, to reduce the chance
                            // of overlapping spans.
                            let function_span = match func {
                                Operand::Constant(c) => c.span,
                                Operand::Copy(Place::Local(l)) | Operand::Move(Place::Local(l)) => {
                                    let local_decl = &self.mir.local_decls[*l];
                                    if local_decl.name.is_none() {
                                        local_decl.source_info.span
                                    } else {
                                        span
                                    }
                                },
                                _ => span,
                            };
                            return (Call, function_span);
                        },
                        _ => Other,
                    }
                }, span)
            }
        }
    }
}
<commit_msg>Fix `debug!` to reflect rename of `explain_why_borrow_contains_point`.<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use borrow_check::borrow_set::BorrowData;
use borrow_check::error_reporting::UseSpans;
use borrow_check::nll::region_infer::Cause;
use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
use rustc::ty::{Region, TyCtxt};
use rustc::mir::{FakeReadCause, Location, Operand, Place, StatementKind, TerminatorKind};
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;
use syntax_pos::symbol::Symbol;

mod find_use;

pub(in borrow_check) enum BorrowExplanation<'tcx> {
    UsedLater(LaterUseKind, Span),
    UsedLaterInLoop(LaterUseKind, Span),
    UsedLaterWhenDropped(Span, Symbol, bool),
    MustBeValidFor(Region<'tcx>),
    Unexplained,
}

#[derive(Clone, Copy)]
pub(in borrow_check) enum LaterUseKind {
    ClosureCapture,
    Call,
    FakeLetRead,
    Other,
}

impl<'tcx> BorrowExplanation<'tcx> {
    pub(in borrow_check) fn emit<'cx, 'gcx>(
        &self,
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        err: &mut DiagnosticBuilder<'_>,
        borrow_desc: String,
    ) {
        match *self {
            BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
                let message = borrow_desc + match later_use_kind {
                    LaterUseKind::ClosureCapture => "borrow later captured here by closure",
                    LaterUseKind::Call =>  "borrow later used by call",
                    LaterUseKind::FakeLetRead => "borrow later stored here",
                    LaterUseKind::Other => "borrow later used here",
                };
                err.span_label(var_or_use_span, message);
            },
            BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
                let message = borrow_desc + match later_use_kind {
                    LaterUseKind::ClosureCapture => {
                        "borrow captured here by closure, in later iteration of loop"
                    },
                    LaterUseKind::Call =>  "borrow used by call, in later iteration of loop",
                    LaterUseKind::FakeLetRead => "borrow later stored here",
                    LaterUseKind::Other => "borrow used here, in later iteration of loop",
                };
                err.span_label(var_or_use_span, message);
            },
            BorrowExplanation::UsedLaterWhenDropped(span, local_name, should_note_order) => {
                err.span_label(
                    span,
                    format!(
                        "{}borrow later used here, when `{}` is dropped",
                        borrow_desc,
                        local_name,
                    ),
                );

                if should_note_order {
                    err.note(
                        "values in a scope are dropped \
                         in the opposite order they are defined",
                    );
                }
            },
            BorrowExplanation::MustBeValidFor(region) => {
                tcx.note_and_explain_free_region(
                    err,
                    &(borrow_desc + "borrowed value must be valid for "),
                    region,
                    "...",
                );
            },
            _ => {},
        }
    }
}

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Returns structured explanation for *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// # Parameters
    ///
    /// - `borrow`: the borrow in question
    /// - `context`: where the borrow occurs
    /// - `kind_place`: if Some, this describes the statement that triggered the error.
    ///   - first half is the kind of write, if any, being performed
    ///   - second half is the place being accessed
    ///
    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
    pub(in borrow_check) fn explain_why_borrow_contains_point(
        &self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        kind_place: Option<(WriteKind, &Place<'tcx>)>,
    ) -> BorrowExplanation<'tcx> {
        debug!(
            "explain_why_borrow_contains_point(context={:?}, borrow={:?})",
            context, borrow,
        );

        let regioncx = &self.nonlexical_regioncx;
        let mir = self.mir;
        let tcx = self.infcx.tcx;

        let borrow_region_vid = regioncx.to_region_vid(borrow.region);
        debug!(
            "explain_why_borrow_contains_point: borrow_region_vid={:?}",
            borrow_region_vid
        );

        let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, context.loc);
        debug!(
            "explain_why_borrow_contains_point: region_sub={:?}",
            region_sub
        );

         match find_use::find(mir, regioncx, tcx, region_sub, context.loc) {
            Some(Cause::LiveVar(local, location)) => {
                let span = mir.source_info(location).span;
                let spans = self.move_spans(&Place::Local(local), location)
                    .or_else(|| self.borrow_spans(span, location));

                if self.is_borrow_location_in_loop(context.loc) {
                    let later_use = self.later_use_kind(spans, location);
                    BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1)
                } else {
                    // Check if the location represents a `FakeRead`, and adapt the error
                    // message to the `FakeReadCause` it is from: in particular,
                    // the ones inserted in optimized `let var = <expr>` patterns.
                    let later_use = self.later_use_kind(spans, location);
                    BorrowExplanation::UsedLater(later_use.0, later_use.1)
                }
            }

            Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name {
                Some(local_name) => {
                    let mut should_note_order = false;
                    if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
                        if let Place::Local(borrowed_local) = place {
                            let dropped_local_scope = mir.local_decls[local].visibility_scope;
                            let borrowed_local_scope =
                                mir.local_decls[*borrowed_local].visibility_scope;

                            if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope)
                                && local != *borrowed_local
                            {
                                should_note_order = true;
                            }
                        }
                    }

                    BorrowExplanation::UsedLaterWhenDropped(
                        mir.source_info(location).span,
                        *local_name,
                        should_note_order
                    )
                },

                None => BorrowExplanation::Unexplained,
            },

            None => if let Some(region) = regioncx.to_error_region(region_sub) {
                BorrowExplanation::MustBeValidFor(region)
            } else {
                BorrowExplanation::Unexplained
            },
        }
    }

    /// Check if a borrow location is within a loop.
    fn is_borrow_location_in_loop(
        &self,
        borrow_location: Location,
    ) -> bool {
        let mut visited_locations = Vec::new();
        let mut pending_locations = vec![ borrow_location ];
        debug!("is_in_loop: borrow_location={:?}", borrow_location);

        while let Some(location) = pending_locations.pop() {
            debug!("is_in_loop: location={:?} pending_locations={:?} visited_locations={:?}",
                   location, pending_locations, visited_locations);
            if location == borrow_location && visited_locations.contains(&borrow_location) {
                // We've managed to return to where we started (and this isn't the start of the
                // search).
                debug!("is_in_loop: found!");
                return true;
            }

            // Skip locations we've been.
            if visited_locations.contains(&location) { continue; }

            let block = &self.mir.basic_blocks()[location.block];
            if location.statement_index ==  block.statements.len() {
                // Add start location of the next blocks to pending locations.
                match block.terminator().kind {
                    TerminatorKind::Goto { target } => {
                        pending_locations.push(target.start_location());
                    },
                    TerminatorKind::SwitchInt { ref targets, .. } => {
                        for target in targets {
                            pending_locations.push(target.start_location());
                        }
                    },
                    TerminatorKind::Drop { target, unwind, .. } |
                    TerminatorKind::DropAndReplace { target, unwind, .. } |
                    TerminatorKind::Assert { target, cleanup: unwind, .. } |
                    TerminatorKind::Yield { resume: target, drop: unwind, .. } |
                    TerminatorKind::FalseUnwind { real_target: target, unwind, .. } => {
                        pending_locations.push(target.start_location());
                        if let Some(unwind) = unwind {
                            pending_locations.push(unwind.start_location());
                        }
                    },
                    TerminatorKind::Call { ref destination, cleanup, .. } => {
                        if let Some((_, destination)) = destination {
                            pending_locations.push(destination.start_location());
                        }
                        if let Some(cleanup) = cleanup {
                            pending_locations.push(cleanup.start_location());
                        }
                    },
                    TerminatorKind::FalseEdges { real_target, ref imaginary_targets, .. } => {
                        pending_locations.push(real_target.start_location());
                        for target in imaginary_targets {
                            pending_locations.push(target.start_location());
                        }
                    },
                    _ => {},
                }
            } else {
                // Add the next statement to pending locations.
                pending_locations.push(location.successor_within_block());
            }

            // Keep track of where we have visited.
            visited_locations.push(location);
        }

        false
    }

    fn later_use_kind(&self, use_spans: UseSpans, location: Location) -> (LaterUseKind, Span) {
        use self::LaterUseKind::*;

        let block = &self.mir.basic_blocks()[location.block];
        match use_spans {
            UseSpans::ClosureUse { var_span, .. } => (LaterUseKind::ClosureCapture, var_span),
            UseSpans::OtherUse(span) => {
                (if let Some(stmt) = block.statements.get(location.statement_index) {
                    match stmt.kind {
                        StatementKind::FakeRead(FakeReadCause::ForLet, _) => FakeLetRead,
                        _ => Other,
                    }
                } else {
                    assert_eq!(location.statement_index, block.statements.len());
                    match block.terminator().kind {
                        TerminatorKind::Call { ref func, from_hir_call: true, .. } => {
                            // Just point to the function, to reduce the chance
                            // of overlapping spans.
                            let function_span = match func {
                                Operand::Constant(c) => c.span,
                                Operand::Copy(Place::Local(l)) | Operand::Move(Place::Local(l)) => {
                                    let local_decl = &self.mir.local_decls[*l];
                                    if local_decl.name.is_none() {
                                        local_decl.source_info.span
                                    } else {
                                        span
                                    }
                                },
                                _ => span,
                            };
                            return (Call, function_span);
                        },
                        _ => Other,
                    }
                }, span)
            }
        }
    }
}
<|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.

#![allow(non_snake_case)]

register_diagnostic!(E0001, r##"
    This error suggests that the expression arm corresponding to the noted pattern
    will never be reached as for all possible values of the expression being matched,
    one of the preceeding patterns will match.

    This means that perhaps some of the preceeding patterns are too general, this
    one is too specific or the ordering is incorrect.
"##)

register_diagnostics!(
    E0002,
    E0003,
    E0004,
    E0005,
    E0006,
    E0007,
    E0008,
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0019,
    E0020,
    E0021,
    E0022,
    E0023,
    E0024,
    E0025,
    E0026,
    E0027,
    E0028,
    E0029,
    E0030,
    E0031,
    E0032,
    E0033,
    E0034,
    E0035,
    E0036,
    E0038,
    E0039,
    E0040,
    E0041,
    E0042,
    E0043,
    E0044,
    E0045,
    E0046,
    E0047,
    E0048,
    E0049,
    E0050,
    E0051,
    E0052,
    E0053,
    E0054,
    E0055,
    E0056,
    E0057,
    E0058,
    E0059,
    E0060,
    E0061,
    E0062,
    E0063,
    E0066,
    E0067,
    E0068,
    E0069,
    E0070,
    E0071,
    E0072,
    E0073,
    E0074,
    E0075,
    E0076,
    E0077,
    E0078,
    E0079,
    E0080,
    E0081,
    E0082,
    E0083,
    E0084,
    E0085,
    E0086,
    E0087,
    E0088,
    E0089,
    E0090,
    E0091,
    E0092,
    E0093,
    E0094,
    E0095,
    E0096,
    E0097,
    E0098,
    E0099,
    E0100,
    E0101,
    E0102,
    E0103,
    E0104,
    E0105,
    E0106,
    E0107,
    E0108,
    E0109,
    E0110,
    E0113,
    E0114,
    E0115,
    E0116,
    E0117,
    E0118,
    E0119,
    E0120,
    E0121,
    E0122,
    E0124,
    E0125,
    E0126,
    E0127,
    E0128,
    E0129,
    E0130,
    E0131,
    E0132,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0140,
    E0141,
    E0142,
    E0143,
    E0144,
    E0145,
    E0146,
    E0147,
    E0148,
    E0151,
    E0152,
    E0153,
    E0154,
    E0155,
    E0156,
    E0157,
    E0158,
    E0159,
    E0160,
    E0161
)
<commit_msg>Drop a few unused diagnostic codes<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.

#![allow(non_snake_case)]

register_diagnostic!(E0001, r##"
    This error suggests that the expression arm corresponding to the noted pattern
    will never be reached as for all possible values of the expression being matched,
    one of the preceeding patterns will match.

    This means that perhaps some of the preceeding patterns are too general, this
    one is too specific or the ordering is incorrect.
"##)

register_diagnostics!(
    E0002,
    E0003,
    E0004,
    E0005,
    E0006,
    E0007,
    E0008,
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0019,
    E0020,
    E0021,
    E0022,
    E0023,
    E0024,
    E0025,
    E0026,
    E0027,
    E0028,
    E0029,
    E0030,
    E0031,
    E0032,
    E0033,
    E0034,
    E0035,
    E0036,
    E0038,
    E0039,
    E0040,
    E0041,
    E0042,
    E0043,
    E0044,
    E0045,
    E0046,
    E0047,
    E0048,
    E0049,
    E0050,
    E0051,
    E0052,
    E0053,
    E0054,
    E0055,
    E0056,
    E0057,
    E0058,
    E0059,
    E0060,
    E0061,
    E0062,
    E0063,
    E0066,
    E0067,
    E0068,
    E0069,
    E0070,
    E0071,
    E0072,
    E0073,
    E0074,
    E0075,
    E0076,
    E0077,
    E0078,
    E0079,
    E0080,
    E0081,
    E0082,
    E0083,
    E0084,
    E0085,
    E0086,
    E0087,
    E0088,
    E0089,
    E0090,
    E0091,
    E0092,
    E0093,
    E0094,
    E0100,
    E0101,
    E0102,
    E0103,
    E0104,
    E0105,
    E0106,
    E0107,
    E0108,
    E0109,
    E0110,
    E0113,
    E0114,
    E0115,
    E0116,
    E0117,
    E0118,
    E0119,
    E0120,
    E0121,
    E0122,
    E0124,
    E0125,
    E0126,
    E0127,
    E0128,
    E0129,
    E0130,
    E0131,
    E0132,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0140,
    E0141,
    E0143,
    E0144,
    E0145,
    E0146,
    E0147,
    E0148,
    E0151,
    E0152,
    E0153,
    E0154,
    E0155,
    E0156,
    E0157,
    E0158,
    E0159,
    E0161
)
<|endoftext|>


<commit_before><commit_msg>add mount::mount<commit_after>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

extern crate libc;

use self::libc::c_char;
use self::libc::c_void;
use self::libc::c_ulong;
use self::libc::c_int;
use std::ptr;
use std::ffi::CString;
use strerror::getStrError;

//////////////////////////////////////////////////////////////////
pub struct MountInfo<'a> {
    source:     &'a str,
    target:     &'a str,
    filesystem: &'a str
}

pub fn mount(mi: &MountInfo) -> Result<(), String> {
    let c_source = CString::new(mi.source).unwrap();
    let source_raw = c_source.into_raw();
    let c_target = CString::new(mi.target).unwrap();
    let target_raw = c_target.into_raw();
    let c_filesystem = CString::new(mi.filesystem).unwrap();
    let filesystem_raw = c_filesystem.into_raw();
    let flags: c_ulong = 0;
    let data: *const c_void = ptr::null();
    let mut result: c_int = 0;
    unsafe {
        result = libc::mount(source_raw,
                             target_raw,
                             filesystem_raw,
                             flags,
                             data);
    }
    match result {
        0  => Ok(()),
        -1 => Err(getStrError()),
        _  => Err("Unexpected error in mount::mount!".to_string()),
    }
}
/*
pub unsafe extern fn mount(src: *const c_char,
                           target: *const c_char,
                           fstype: *const c_char,
                           flags: c_ulong,
                           data: *const c_void)
                           -> c_int
*/
pub fn umount(mi: &MountInfo) -> Result<(), String> {
    //
    //TODO
    //
    Ok(())
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[test]
fn test_mount_01() {
    let mi = MountInfo{source: "/dev/sdb1",
                       target: "/mnt/temp",
                       filesystem: "ext4"};
    let res = mount(&mi);
    //assert_eq!(false, i.verify_label(".*ANC.*"));
}

#[test]
#[ignore]
fn test_mount_02() {
    let mi = MountInfo{source: "/dev/sdb1",
                       target: "/mnt/temp",
                       filesystem: "ext4"};
    let res = umount(&mi);
    //assert_eq!(false, i.verify_label(".*ANC.*"));
}
//////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before><commit_msg>respond to ping with pong<commit_after><|endoftext|>


<commit_before><commit_msg>Fix echo asdf >> asdf (#300)<commit_after><|endoftext|>


<commit_before><commit_msg>:art: Make to skip serializing if a property is none.<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix<commit_after><|endoftext|>


<commit_before><commit_msg>epoll_ctl<commit_after><|endoftext|>


<commit_before><commit_msg>Correction for 0x5 opcode and more tests<commit_after><|endoftext|>


<commit_before><commit_msg>move tuple stuff into separate module<commit_after>use super::{ NifEnv, NifTerm, NifError };
use super::{ c_int };

use std::mem;

extern crate ruster_unsafe;
use ruster_unsafe::{ ERL_NIF_TERM };

pub fn get_tuple<'a>(env: &'a NifEnv, term: NifTerm) -> Result<Vec<NifTerm<'a>>, NifError> {
    let mut arity: c_int = 0;
    let mut array_ptr: *const ERL_NIF_TERM = unsafe { mem::uninitialized() };
    let success = unsafe { ruster_unsafe::enif_get_tuple(env.env, term.term,
                                                         &mut arity as *mut c_int,
                                                         &mut array_ptr as *mut *const ERL_NIF_TERM) };
    if success != 1 {
        return Err(NifError::BadArg);
    }
    let term_array = unsafe { ::std::slice::from_raw_parts(array_ptr, arity as usize) };
    Ok(term_array.iter().map(|x| { NifTerm::new(env, *x) }).collect::<Vec<NifTerm>>())
}

#[macro_export]
macro_rules! decode_term_array_to_tuple {
    (@count ()) => { 0 };
    (@count ($_i:ty, $($rest:tt)*)) => { 1 + decode_term_array_to_tuple!(@count ($($rest)*)) };
    (@accum $_env:expr, $_list:expr, $_num:expr, ($(,)*) -> ($($body:tt)*)) => {
        decode_term_array_to_tuple!(@as_expr ($($body)*))
    };
    (@accum $env:expr, $list:expr, $num:expr, ($head:ty, $($tail:tt)*) -> ($($body:tt)*)) => {
        decode_term_array_to_tuple!(@accum $env, $list, ($num+1), ($($tail)*) -> ($($body)* decode_term_array_to_tuple!(@decode_arg $env, $head, $list[$num]),))
    };
    (@as_expr $e:expr) => {$e};
    (@decode_arg $env:expr, $typ:ty, $val:expr) => {
        match $crate::decode_type::<$typ>($val, $env) {
            Ok(val) => val,
            Err(val) => return Err(val),
        }
    };
    ($env:expr, $terms:expr, ($($typs:ty),*)) => {
        {
            let decoder: &Fn(&NifEnv, &[NifTerm]) -> Result<($($typs),*), NifError> = &|env, terms| {
                let num_expr: usize = decode_term_array_to_tuple!(@count ($($typs,)*));
                if $terms.len() != num_expr {
                    Err($crate::NifError::BadArg)
                } else {
                    Ok(decode_term_array_to_tuple!(@accum $env, $terms, 0, ($($typs),*,) -> ()))
                }
            };
            decoder($env, $terms)
        }
    }
}

#[macro_export]
macro_rules! decode_tuple {
    ($env:expr, $term:expr, ($($typs:ty),*)) => {
        {
            let terms = try!($crate::get_tuple($env, $term));
            decode_term_array_to_tuple!($env, &terms[..], ($($typs),*))
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add dummy compilation test in replacement for examples<commit_after>//! This file contains a single test that is
//!  compiled but not run, just to ensure that
//!  the GL symbols are defined

extern crate gl;
extern crate libc;

#[test]
#[ignore]
fn test() {
	gl::Clear(gl::COLOR_BUFFER_BIT);
	let _: libc::c_uint = gl::CreateProgram();
	gl::CompileShader(5);
}

<|endoftext|>


<commit_before><commit_msg>video.edit method<commit_after><|endoftext|>


<commit_before><commit_msg>add video permission to get and search<commit_after><|endoftext|>


<commit_before>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

<commit_msg>Implement Debug for Configuration<commit_after>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;

use std::fmt::Debug;
use std::fmt::Formatter;
use std::fmt::Error;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

impl Debug for Configuration {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Configuration (verbose: {}, debugging: {}, rtp: {}, store path: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp(),
            self.store_path_str()
            )
    }

}

<|endoftext|>


<commit_before>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;

use std::fmt::Debug;
use std::fmt::Formatter;
use std::fmt::Error;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        let rtp = rtp_path(config);

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(&rtp) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp,
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> String {
    String::from(config.cli_matches.value_of("rtp").unwrap_or("~/.imag/store/"))
}

fn fetch_config(rtp: &String) -> Option<Cfg> {
    from_file(Path::new(&(rtp.clone() + "/config"))).ok()
}

impl Debug for Configuration {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Configuration (verbose: {}, debugging: {}, rtp: {}, store path: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp(),
            self.store_path_str()
            )
    }

}

<commit_msg>Configuration::new() should use default values<commit_after>extern crate clap;

use cli::CliConfig;

use std::path::Path;
use config::reader::from_file;
use config::types::Config as Cfg;

use std::fmt::Debug;
use std::fmt::Formatter;
use std::fmt::Error;

pub struct Configuration {
    pub rtp         : String,
    pub store_sub   : String,
    pub verbose     : bool,
    pub debugging   : bool,
}

impl Configuration {

    pub fn new(config: &CliConfig) -> Configuration {
        use std::env::home_dir;

        let rtp = rtp_path(config).or(default_path());

        let mut verbose     = false;
        let mut debugging   = false;
        let mut store_sub   = String::from("/store");

        if let Some(cfg) = fetch_config(rtp.clone()) {
            if let Some(v) = cfg.lookup_boolean("verbose") {
                verbose = v;
            }
            if let Some(d) = cfg.lookup_boolean("debug") {
                debugging = d;
            }
            if let Some(s) = cfg.lookup_str("store") {
                store_sub = String::from(s);
            }
        }

        Configuration {
            verbose: verbose,
            debugging: debugging,
            store_sub: store_sub,
            rtp: rtp.unwrap_or(String::from("/tmp/")),
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.verbose
    }

    pub fn is_debugging(&self) -> bool {
        self.debugging
    }

    pub fn store_path_str(&self) -> String {
        format!("{}{}", self.rtp, self.store_sub)
    }

    pub fn get_rtp(&self) -> String {
        self.rtp.clone()
    }

}

fn rtp_path(config: &CliConfig) -> Option<String> {
    config.cli_matches.value_of("rtp")
                      .and_then(|s| Some(String::from(s)))
}

fn fetch_config(rtp: Option<String>) -> Option<Cfg> {
    rtp.and_then(|r| from_file(Path::new(&(r.clone() + "/config"))).ok())
}

fn default_path() -> Option<String> {
    use std::env::home_dir;

    home_dir().and_then(|mut buf| {
        buf.push("/.imag");
        buf.to_str().map(|s| String::from(s))
    })

}

impl Debug for Configuration {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Configuration (verbose: {}, debugging: {}, rtp: {}, store path: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp(),
            self.store_path_str()
            )
    }

}

<|endoftext|>


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

use std::error::Error;

use dbus;
use dbus::arg::{ArgType, Iter, IterAppend, RefArg, Variant};
use dbus::stdintf::org_freedesktop_dbus::PropertiesPropertiesChanged;
use dbus::tree::{MTFn, MethodErr, PropInfo};
use dbus::Connection;
use dbus::SignalArgs;

use devicemapper::DmError;

use super::super::stratis::{ErrorEnum, StratisError};

use super::types::{DbusErrorEnum, TData};

pub const STRATIS_BASE_PATH: &str = "/org/storage/stratis1";
pub const STRATIS_BASE_SERVICE: &str = "org.storage.stratis1";

/// Convert a tuple as option to an Option type
pub fn tuple_to_option<T>(value: (bool, T)) -> Option<T> {
    if value.0 {
        Some(value.1)
    } else {
        None
    }
}

/// Get the next argument off the bus
pub fn get_next_arg<'a, T>(iter: &mut Iter<'a>, loc: u16) -> Result<T, MethodErr>
where
    T: dbus::arg::Get<'a> + dbus::arg::Arg,
{
    if iter.arg_type() == ArgType::Invalid {
        return Err(MethodErr::no_arg());
    };
    let value: T = iter.read::<T>().map_err(|_| MethodErr::invalid_arg(&loc))?;
    Ok(value)
}

/// Translates an engine error to the (errorcode, string) tuple that Stratis
/// D-Bus methods return.
pub fn engine_to_dbus_err_tuple(err: &StratisError) -> (u16, String) {
    let error = match *err {
        StratisError::Error(_) => DbusErrorEnum::INTERNAL_ERROR,
        StratisError::Engine(ref e, _) => match *e {
            ErrorEnum::Error => DbusErrorEnum::ERROR,
            ErrorEnum::AlreadyExists => DbusErrorEnum::ALREADY_EXISTS,
            ErrorEnum::Busy => DbusErrorEnum::BUSY,
            ErrorEnum::Invalid => DbusErrorEnum::ERROR,
            ErrorEnum::NotFound => DbusErrorEnum::NOTFOUND,
        },
        StratisError::Io(_) => DbusErrorEnum::IO_ERROR,
        StratisError::Nix(_) => DbusErrorEnum::NIX_ERROR,
        StratisError::Uuid(_)
        | StratisError::Utf8(_)
        | StratisError::Serde(_)
        | StratisError::DM(_)
        | StratisError::Dbus(_)
        | StratisError::Udev(_) => DbusErrorEnum::INTERNAL_ERROR,
    };
    let description = match *err {
        StratisError::DM(DmError::Core(ref err)) => err.to_string(),
        ref err => err.description().to_owned(),
    };
    (error.into(), description)
}

/// Convenience function to get the error value for "OK"
pub fn msg_code_ok() -> u16 {
    DbusErrorEnum::OK.into()
}

/// Convenience function to get the error string for "OK"
pub fn msg_string_ok() -> String {
    DbusErrorEnum::OK.get_error_string().to_owned()
}

/// Get the UUID for an object path.
pub fn get_uuid(i: &mut IterAppend, p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    let object_path = p.path.get_name();
    let path = p.tree
        .get(object_path)
        .expect("implicit argument must be in tree");

    let data = path.get_data()
        .as_ref()
        .ok_or_else(|| MethodErr::failed(&format!("no data for object path {}", object_path)))?;

    i.append(format!("{}", data.uuid.simple()));
    Ok(())
}

/// Get the parent object path for an object path.
pub fn get_parent(i: &mut IterAppend, p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    let object_path = p.path.get_name();
    let path = p.tree
        .get(object_path)
        .expect("implicit argument must be in tree");

    let data = path.get_data()
        .as_ref()
        .ok_or_else(|| MethodErr::failed(&format!("no data for object path {}", object_path)))?;

    i.append(data.parent.clone());
    Ok(())
}

/// Place a property changed signal on the D-Bus.
pub fn prop_changed_dispatch<T: 'static>(
    conn: &Connection,
    prop_name: &str,
    new_value: T,
    path: &dbus::Path,
) -> Result<(), ()>
where
    T: RefArg,
{
    let mut prop_changed: PropertiesPropertiesChanged = Default::default();
    prop_changed
        .changed_properties
        .insert(prop_name.into(), Variant(Box::new(new_value)));

    conn.send(prop_changed.to_emit_message(path))?;

    Ok(())
}
<commit_msg>Map Engine errors to DbusErrorEnum::ERROR instead of INTERNAL_ERROR<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::error::Error;

use dbus;
use dbus::arg::{ArgType, Iter, IterAppend, RefArg, Variant};
use dbus::stdintf::org_freedesktop_dbus::PropertiesPropertiesChanged;
use dbus::tree::{MTFn, MethodErr, PropInfo};
use dbus::Connection;
use dbus::SignalArgs;

use devicemapper::DmError;

use super::super::stratis::{ErrorEnum, StratisError};

use super::types::{DbusErrorEnum, TData};

pub const STRATIS_BASE_PATH: &str = "/org/storage/stratis1";
pub const STRATIS_BASE_SERVICE: &str = "org.storage.stratis1";

/// Convert a tuple as option to an Option type
pub fn tuple_to_option<T>(value: (bool, T)) -> Option<T> {
    if value.0 {
        Some(value.1)
    } else {
        None
    }
}

/// Get the next argument off the bus
pub fn get_next_arg<'a, T>(iter: &mut Iter<'a>, loc: u16) -> Result<T, MethodErr>
where
    T: dbus::arg::Get<'a> + dbus::arg::Arg,
{
    if iter.arg_type() == ArgType::Invalid {
        return Err(MethodErr::no_arg());
    };
    let value: T = iter.read::<T>().map_err(|_| MethodErr::invalid_arg(&loc))?;
    Ok(value)
}

/// Translates an engine error to the (errorcode, string) tuple that Stratis
/// D-Bus methods return.
pub fn engine_to_dbus_err_tuple(err: &StratisError) -> (u16, String) {
    let error = match *err {
        StratisError::Error(_) => DbusErrorEnum::ERROR,
        StratisError::Engine(ref e, _) => match *e {
            ErrorEnum::Error => DbusErrorEnum::ERROR,
            ErrorEnum::AlreadyExists => DbusErrorEnum::ALREADY_EXISTS,
            ErrorEnum::Busy => DbusErrorEnum::BUSY,
            ErrorEnum::Invalid => DbusErrorEnum::ERROR,
            ErrorEnum::NotFound => DbusErrorEnum::NOTFOUND,
        },
        StratisError::Io(_) => DbusErrorEnum::IO_ERROR,
        StratisError::Nix(_) => DbusErrorEnum::NIX_ERROR,
        StratisError::Uuid(_)
        | StratisError::Utf8(_)
        | StratisError::Serde(_)
        | StratisError::DM(_)
        | StratisError::Dbus(_)
        | StratisError::Udev(_) => DbusErrorEnum::ERROR,
    };
    let description = match *err {
        StratisError::DM(DmError::Core(ref err)) => err.to_string(),
        ref err => err.description().to_owned(),
    };
    (error.into(), description)
}

/// Convenience function to get the error value for "OK"
pub fn msg_code_ok() -> u16 {
    DbusErrorEnum::OK.into()
}

/// Convenience function to get the error string for "OK"
pub fn msg_string_ok() -> String {
    DbusErrorEnum::OK.get_error_string().to_owned()
}

/// Get the UUID for an object path.
pub fn get_uuid(i: &mut IterAppend, p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    let object_path = p.path.get_name();
    let path = p.tree
        .get(object_path)
        .expect("implicit argument must be in tree");

    let data = path.get_data()
        .as_ref()
        .ok_or_else(|| MethodErr::failed(&format!("no data for object path {}", object_path)))?;

    i.append(format!("{}", data.uuid.simple()));
    Ok(())
}

/// Get the parent object path for an object path.
pub fn get_parent(i: &mut IterAppend, p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    let object_path = p.path.get_name();
    let path = p.tree
        .get(object_path)
        .expect("implicit argument must be in tree");

    let data = path.get_data()
        .as_ref()
        .ok_or_else(|| MethodErr::failed(&format!("no data for object path {}", object_path)))?;

    i.append(data.parent.clone());
    Ok(())
}

/// Place a property changed signal on the D-Bus.
pub fn prop_changed_dispatch<T: 'static>(
    conn: &Connection,
    prop_name: &str,
    new_value: T,
    path: &dbus::Path,
) -> Result<(), ()>
where
    T: RefArg,
{
    let mut prop_changed: PropertiesPropertiesChanged = Default::default();
    prop_changed
        .changed_properties
        .insert(prop_name.into(), Variant(Box::new(new_value)));

    conn.send(prop_changed.to_emit_message(path))?;

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>add possible moves app<commit_after>use combustion::board::Board;

use std::env;
use std::process::exit;

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        println!("Error: exactly one argument required. Exiting...");
        exit(1);
    }

    let board = Board::from_fen(&args[1]).unwrap();

    for mv in &board.legal_moves().unwrap() {
        println!("{}", mv);
    }
}
<|endoftext|>