<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::{Context, MirBorrowckCtxt};
use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
use dataflow::BorrowData;
use rustc::mir::{Local, Location, Mir};
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use util::liveness::{self, DefUse, LivenessMode};

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Adds annotations to `err` explaining *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// [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(
        &mut self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        err: &mut DiagnosticBuilder<'_>,
    ) {
        if let Some(regioncx) = &self.nonlexical_regioncx {
            let mir = self.mir;

            if self.nonlexical_cause_info.is_none() {
                self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
            }

            let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
            if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
                match *cause.root_cause() {
                    Cause::LiveVar(local, location) => {
                        match find_regular_use(&mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                err.span_label(
                                    mir.source_info(p).span,
                                    format!("borrow later used here"),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a LiveVar"
                                );
                            }
                        }
                    }

                    Cause::DropVar(local, location) => {
                        match find_drop_use(&mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                let local_name = &mir.local_decls[local].name.unwrap();

                                err.span_label(
                                    mir.source_info(p).span,
                                    format!(
                                        "borrow later used here, when `{}` is dropped",
                                        local_name
                                    ),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a DropVar"
                                );
                            }
                        }
                    }

                    Cause::UniversalRegion(region_vid) => {
                        if let Some(region) = regioncx.to_error_region(region_vid) {
                            self.tcx.note_and_explain_free_region(
                                err,
                                "borrowed value must be valid for ",
                                region,
                                "...",
                            );
                        }
                    }

                    _ => {}
                }
            }
        }
    }
}

fn find_regular_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: true,
            include_drops: false,
        },
    };

    uf.find()
}

fn find_drop_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: false,
            include_drops: true,
        },
    };

    uf.find()
}

struct UseFinder<'gcx, 'tcx> {
    mir: &'gcx Mir<'gcx>,
    regioncx: &'tcx RegionInferenceContext<'tcx>,
    borrow: &'tcx BorrowData<'tcx>,
    start_point: Location,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> {
    fn find(&mut self) -> Option<Location> {
        let mut stack = vec![];
        let mut visited = FxHashSet();

        stack.push(self.start_point);
        while let Some(p) = stack.pop() {
            if !self.regioncx.region_contains_point(self.borrow.region, p) {
                continue;
            }

            if !visited.insert(p) {
                continue;
            }

            let block_data = &self.mir[p.block];
            let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index));

            if used {
                return Some(p);
            } else if !defined {
                if p.statement_index < block_data.statements.len() {
                    stack.push(Location {
                        statement_index: p.statement_index + 1,
                        ..p
                    });
                } else {
                    stack.extend(
                        block_data
                            .terminator()
                            .successors()
                            .iter()
                            .map(|&basic_block| Location {
                                statement_index: 0,
                                block: basic_block,
                            }),
                    );
                }
            }
        }

        None
    }

    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) {
        let mut visitor = DefUseVisitor {
            defined: false,
            used: false,
            local: self.local,
            liveness_mode: self.liveness_mode,
        };

        thing.apply(location, &mut visitor);

        (visitor.defined, visitor.used)
    }
}

struct DefUseVisitor {
    defined: bool,
    used: bool,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'tcx> Visitor<'tcx> for DefUseVisitor {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
        if local == self.local {
            match liveness::categorize(context, self.liveness_mode) {
                Some(DefUse::Def) => self.defined = true,
                Some(DefUse::Use) => self.used = true,
                None => (),
            }
        }
    }
}
<commit_msg>mir is already a reference<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::{Context, MirBorrowckCtxt};
use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
use dataflow::BorrowData;
use rustc::mir::{Local, Location, Mir};
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use util::liveness::{self, DefUse, LivenessMode};

impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
    /// Adds annotations to `err` explaining *why* the borrow contains the
    /// point from `context`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// [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(
        &mut self,
        context: Context,
        borrow: &BorrowData<'tcx>,
        err: &mut DiagnosticBuilder<'_>,
    ) {
        if let Some(regioncx) = &self.nonlexical_regioncx {
            let mir = self.mir;

            if self.nonlexical_cause_info.is_none() {
                self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
            }

            let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
            if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
                match *cause.root_cause() {
                    Cause::LiveVar(local, location) => {
                        match find_regular_use(mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                err.span_label(
                                    mir.source_info(p).span,
                                    format!("borrow later used here"),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a LiveVar"
                                );
                            }
                        }
                    }

                    Cause::DropVar(local, location) => {
                        match find_drop_use(mir, regioncx, borrow, location, local) {
                            Some(p) => {
                                let local_name = mir.local_decls[local].name.unwrap();

                                err.span_label(
                                    mir.source_info(p).span,
                                    format!(
                                        "borrow later used here, when `{}` is dropped",
                                        local_name
                                    ),
                                );
                            }

                            None => {
                                span_bug!(
                                    mir.source_info(context.loc).span,
                                    "Cause should end in a DropVar"
                                );
                            }
                        }
                    }

                    Cause::UniversalRegion(region_vid) => {
                        if let Some(region) = regioncx.to_error_region(region_vid) {
                            self.tcx.note_and_explain_free_region(
                                err,
                                "borrowed value must be valid for ",
                                region,
                                "...",
                            );
                        }
                    }

                    _ => {}
                }
            }
        }
    }
}

fn find_regular_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: true,
            include_drops: false,
        },
    };

    uf.find()
}

fn find_drop_use<'gcx, 'tcx>(
    mir: &'gcx Mir,
    regioncx: &'tcx RegionInferenceContext,
    borrow: &'tcx BorrowData,
    start_point: Location,
    local: Local,
) -> Option<Location> {
    let mut uf = UseFinder {
        mir,
        regioncx,
        borrow,
        start_point,
        local,
        liveness_mode: LivenessMode {
            include_regular_use: false,
            include_drops: true,
        },
    };

    uf.find()
}

struct UseFinder<'gcx, 'tcx> {
    mir: &'gcx Mir<'gcx>,
    regioncx: &'tcx RegionInferenceContext<'tcx>,
    borrow: &'tcx BorrowData<'tcx>,
    start_point: Location,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> {
    fn find(&mut self) -> Option<Location> {
        let mut stack = vec![];
        let mut visited = FxHashSet();

        stack.push(self.start_point);
        while let Some(p) = stack.pop() {
            if !self.regioncx.region_contains_point(self.borrow.region, p) {
                continue;
            }

            if !visited.insert(p) {
                continue;
            }

            let block_data = &self.mir[p.block];
            let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index));

            if used {
                return Some(p);
            } else if !defined {
                if p.statement_index < block_data.statements.len() {
                    stack.push(Location {
                        statement_index: p.statement_index + 1,
                        ..p
                    });
                } else {
                    stack.extend(
                        block_data
                            .terminator()
                            .successors()
                            .iter()
                            .map(|&basic_block| Location {
                                statement_index: 0,
                                block: basic_block,
                            }),
                    );
                }
            }
        }

        None
    }

    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) {
        let mut visitor = DefUseVisitor {
            defined: false,
            used: false,
            local: self.local,
            liveness_mode: self.liveness_mode,
        };

        thing.apply(location, &mut visitor);

        (visitor.defined, visitor.used)
    }
}

struct DefUseVisitor {
    defined: bool,
    used: bool,
    local: Local,
    liveness_mode: LivenessMode,
}

impl<'tcx> Visitor<'tcx> for DefUseVisitor {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
        if local == self.local {
            match liveness::categorize(context, self.liveness_mode) {
                Some(DefUse::Def) => self.defined = true,
                Some(DefUse::Use) => self.used = true,
                None => (),
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright © 2017, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate bragi;
extern crate iron_test;
extern crate serde_json;
use super::BragiHandler;
use super::get_value;

pub fn bragi_stops_test(es_wrapper: ::ElasticSearchWrapper) {
    let bragi = BragiHandler::new(format!("{}/munin", es_wrapper.host()));

    // ******************************************
    // we the OSM dataset, three-cities bano dataset and a stop file
    // the current dataset are thus (load order matters):
    // - osm_fixture.osm.pbf
    // - bano-three_cities
    // - stops.txt
    // ******************************************
    let osm2mimir = concat!(env!("OUT_DIR"), "/../../../osm2mimir");
    info!("Launching {}", osm2mimir);
    ::launch_and_assert(osm2mimir,
                        vec!["--input=./tests/fixtures/osm_fixture.osm.pbf".into(),
                             "--level=8".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    info!("Launching {}", bano2mimir);
    ::launch_and_assert(bano2mimir,
                        vec!["--input=./tests/fixtures/bano-three_cities.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    info!("Launching {}", stops2mimir);
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops.txt".into(),
                             "--dataset=dataset1".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    stop_attached_to_admin_test(&bragi);
    stop_no_admin_test(&bragi);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    info!("Launching {}", stops2mimir);
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops_dataset2.txt".into(),
                             "--dataset=dataset2".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    stop_filtred_by_dataset_test(&bragi);
}

fn stop_attached_to_admin_test(bragi: &BragiHandler) {
    // with this query we should find only one response, a stop
    let response = bragi.get("/autocomplete?q=14 juillet");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();

    assert_eq!(get_value(stop, "type"), "public_transport:stop_area");
    assert_eq!(get_value(stop, "label"), "14 Juillet");
    assert_eq!(get_value(stop, "name"), "14 Juillet");
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");
    assert_eq!(get_value(stop, "citycode"), "77487");

    // this stop area is in the boundary of the admin 'Vaux-le-Pénil',
    // it should have been associated to it
    assert_eq!(get_value(stop, "city"), "Vaux-le-Pénil");
    let admins = stop.get("administrative_regions").and_then(|a| a.as_array());
    assert_eq!(admins.map(|a| a.len()).unwrap_or(0), 1);
}

fn stop_no_admin_test(bragi: &BragiHandler) {
    // we query another stop, but this one is outside the range of an admin,
    // we should get the stop, but with no admin attached to it
    let response = bragi.get("/autocomplete?q=Far west station");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();

    assert_eq!(get_value(stop, "type"), "public_transport:stop_area");
    assert_eq!(get_value(stop, "label"), "Far west station");
    assert_eq!(get_value(stop, "name"), "Far west station");
    assert_eq!(get_value(stop, "id"), "stop_area:SA:station_no_city");
    assert_eq!(get_value(stop, "city"), "");
    let admins = stop.get("administrative_regions").and_then(|a| a.as_array());
    assert_eq!(admins.map(|a| a.len()).unwrap_or(0), 0);
}

fn stop_filtered_by_dataset_test(bragi: &BragiHandler) {
    // Search stops on all aliases
    let response = bragi.get("/autocomplete?q=14 juillet");
    assert_eq!(response.len(), 2);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");

    let stop = response.last().unwrap();
    assert_eq!(get_value(stop, "id"),
               "stop_area:SA:second_station:dataset2");

    // filter by dataset1
    let response = bragi.get("/autocomplete?q=14 juillet&pt_dataset=dataset1");

    assert_eq!(response.len(), 1);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");
    // filter by dataset2
    let response = bragi.get("/autocomplete?q=14 juillet&pt_dataset=dataset2");

    assert_eq!(response.len(), 1);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"),
               "stop_area:SA:second_station:dataset2");
}
<commit_msg>rename function<commit_after>// Copyright © 2017, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate bragi;
extern crate iron_test;
extern crate serde_json;
use super::BragiHandler;
use super::get_value;

pub fn bragi_stops_test(es_wrapper: ::ElasticSearchWrapper) {
    let bragi = BragiHandler::new(format!("{}/munin", es_wrapper.host()));

    // ******************************************
    // we the OSM dataset, three-cities bano dataset and a stop file
    // the current dataset are thus (load order matters):
    // - osm_fixture.osm.pbf
    // - bano-three_cities
    // - stops.txt
    // ******************************************
    let osm2mimir = concat!(env!("OUT_DIR"), "/../../../osm2mimir");
    info!("Launching {}", osm2mimir);
    ::launch_and_assert(osm2mimir,
                        vec!["--input=./tests/fixtures/osm_fixture.osm.pbf".into(),
                             "--level=8".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let bano2mimir = concat!(env!("OUT_DIR"), "/../../../bano2mimir");
    info!("Launching {}", bano2mimir);
    ::launch_and_assert(bano2mimir,
                        vec!["--input=./tests/fixtures/bano-three_cities.csv".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    info!("Launching {}", stops2mimir);
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops.txt".into(),
                             "--dataset=dataset1".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    stop_attached_to_admin_test(&bragi);
    stop_no_admin_test(&bragi);

    let stops2mimir = concat!(env!("OUT_DIR"), "/../../../stops2mimir");
    info!("Launching {}", stops2mimir);
    ::launch_and_assert(stops2mimir,
                        vec!["--input=./tests/fixtures/stops_dataset2.txt".into(),
                             "--dataset=dataset2".into(),
                             format!("--connection-string={}", es_wrapper.host())],
                        &es_wrapper);

    stop_filtered_by_dataset_test(&bragi);
}

fn stop_attached_to_admin_test(bragi: &BragiHandler) {
    // with this query we should find only one response, a stop
    let response = bragi.get("/autocomplete?q=14 juillet");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();

    assert_eq!(get_value(stop, "type"), "public_transport:stop_area");
    assert_eq!(get_value(stop, "label"), "14 Juillet");
    assert_eq!(get_value(stop, "name"), "14 Juillet");
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");
    assert_eq!(get_value(stop, "citycode"), "77487");

    // this stop area is in the boundary of the admin 'Vaux-le-Pénil',
    // it should have been associated to it
    assert_eq!(get_value(stop, "city"), "Vaux-le-Pénil");
    let admins = stop.get("administrative_regions").and_then(|a| a.as_array());
    assert_eq!(admins.map(|a| a.len()).unwrap_or(0), 1);
}

fn stop_no_admin_test(bragi: &BragiHandler) {
    // we query another stop, but this one is outside the range of an admin,
    // we should get the stop, but with no admin attached to it
    let response = bragi.get("/autocomplete?q=Far west station");
    assert_eq!(response.len(), 1);
    let stop = response.first().unwrap();

    assert_eq!(get_value(stop, "type"), "public_transport:stop_area");
    assert_eq!(get_value(stop, "label"), "Far west station");
    assert_eq!(get_value(stop, "name"), "Far west station");
    assert_eq!(get_value(stop, "id"), "stop_area:SA:station_no_city");
    assert_eq!(get_value(stop, "city"), "");
    let admins = stop.get("administrative_regions").and_then(|a| a.as_array());
    assert_eq!(admins.map(|a| a.len()).unwrap_or(0), 0);
}

fn stop_filtered_by_dataset_test(bragi: &BragiHandler) {
    // Search stops on all aliases
    let response = bragi.get("/autocomplete?q=14 juillet");
    assert_eq!(response.len(), 2);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");

    let stop = response.last().unwrap();
    assert_eq!(get_value(stop, "id"),
               "stop_area:SA:second_station:dataset2");

    // filter by dataset1
    let response = bragi.get("/autocomplete?q=14 juillet&pt_dataset=dataset1");

    assert_eq!(response.len(), 1);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"), "stop_area:SA:second_station");
    // filter by dataset2
    let response = bragi.get("/autocomplete?q=14 juillet&pt_dataset=dataset2");

    assert_eq!(response.len(), 1);

    let stop = response.first().unwrap();
    assert_eq!(get_value(stop, "id"),
               "stop_area:SA:second_station:dataset2");
}
<|endoftext|>


<commit_before>use rm::linalg::Matrix;
use rm::linalg::Vector;
use rm::learning::SupModel;
use rm::learning::lin_reg::LinRegressor;
use libnum::abs;

#[test]
fn test_optimized_regression() {
    let mut lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 1, vec![2.0, 3.0, 4.0]);
    let targets = Vector::new(vec![5.0, 6.0, 7.0]);

    lin_mod.train_with_optimization(&inputs, &targets);

    let _ = lin_mod.parameters().unwrap();
}

#[test]
fn test_regression() {
    let mut lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 1, vec![2.0, 3.0, 4.0]);
    let targets = Vector::new(vec![5.0, 6.0, 7.0]);

    lin_mod.train(&inputs, &targets).unwrap();

    let parameters = lin_mod.parameters().unwrap();

    let err_1 = abs(parameters[0] - 3.0);
    let err_2 = abs(parameters[1] - 1.0);

    assert!(err_1 < 1e-8);
    assert!(err_2 < 1e-8);
}

#[test]
#[should_panic]
fn test_no_train_params() {
    let lin_mod = LinRegressor::default();

    let _ = lin_mod.parameters().unwrap();
}

#[test]
#[should_panic]
fn test_no_train_predict() {
    let lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);

    let _ = lin_mod.predict(&inputs).unwrap();
}

#[cfg(feature = "datasets")]
#[test]
fn test_regression_datasets_trees() {
    use rm::datasets::trees;
    let trees = trees::load();

    let mut lin_mod = LinRegressor::default();
    lin_mod.train(&trees.data(), &trees.target()).unwrap();
    let params = lin_mod.parameters().unwrap();
    assert_eq!(params, &Vector::new(vec![-57.98765891838409, 4.708160503017506, 0.3392512342447438]));

    let predicted = lin_mod.predict(&trees.data()).unwrap();
    let expected = vec![4.837659653793278, 4.55385163347481, 4.816981265588826, 15.874115228921276,
                        19.869008437727473, 21.018326956518717, 16.192688074961563, 19.245949183164257,
                        21.413021404689726, 20.187581283767756, 22.015402271048487, 21.468464618616007,
                        21.468464618616007, 20.50615412980805, 23.954109686181766, 27.852202904652785,
                        31.583966481344966, 33.806481916796706, 30.60097760433255, 28.697035014921106,
                        34.388184394951004, 36.008318964043994, 35.38525970948079, 41.76899799551756,
                        44.87770231764652, 50.942867757643015, 52.223751092491256, 53.42851282520877,
                        53.899328875510534, 53.899328875510534, 68.51530482306926];
    assert_eq!(predicted, Vector::new(expected));
}

#[test]
fn test_train_no_data() {
    let inputs = Matrix::new(0, 1, vec![]);
    let targets = Vector::new(vec![]);

    let mut lin_mod = LinRegressor::default();
    let res = lin_mod.train(&inputs, &targets);

    assert!(res.is_err());
}
<commit_msg>ignore nondeterministically failing test for the moment<commit_after>use rm::linalg::Matrix;
use rm::linalg::Vector;
use rm::learning::SupModel;
use rm::learning::lin_reg::LinRegressor;
use libnum::abs;

#[test]
fn test_optimized_regression() {
    let mut lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 1, vec![2.0, 3.0, 4.0]);
    let targets = Vector::new(vec![5.0, 6.0, 7.0]);

    lin_mod.train_with_optimization(&inputs, &targets);

    let _ = lin_mod.parameters().unwrap();
}

#[test]
fn test_regression() {
    let mut lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 1, vec![2.0, 3.0, 4.0]);
    let targets = Vector::new(vec![5.0, 6.0, 7.0]);

    lin_mod.train(&inputs, &targets).unwrap();

    let parameters = lin_mod.parameters().unwrap();

    let err_1 = abs(parameters[0] - 3.0);
    let err_2 = abs(parameters[1] - 1.0);

    assert!(err_1 < 1e-8);
    assert!(err_2 < 1e-8);
}

#[test]
#[should_panic]
fn test_no_train_params() {
    let lin_mod = LinRegressor::default();

    let _ = lin_mod.parameters().unwrap();
}

#[test]
#[should_panic]
fn test_no_train_predict() {
    let lin_mod = LinRegressor::default();
    let inputs = Matrix::new(3, 2, vec![1.0, 2.0, 1.0, 3.0, 1.0, 4.0]);

    let _ = lin_mod.predict(&inputs).unwrap();
}

#[cfg(feature = "datasets")]
#[test]
fn test_regression_datasets_trees() {
    use rm::datasets::trees;
    let trees = trees::load();

    let mut lin_mod = LinRegressor::default();
    lin_mod.train(&trees.data(), &trees.target()).unwrap();
    let params = lin_mod.parameters().unwrap();
    assert_eq!(params, &Vector::new(vec![-57.98765891838409, 4.708160503017506, 0.3392512342447438]));

    let predicted = lin_mod.predict(&trees.data()).unwrap();
    let expected = vec![4.837659653793278, 4.55385163347481, 4.816981265588826, 15.874115228921276,
                        19.869008437727473, 21.018326956518717, 16.192688074961563, 19.245949183164257,
                        21.413021404689726, 20.187581283767756, 22.015402271048487, 21.468464618616007,
                        21.468464618616007, 20.50615412980805, 23.954109686181766, 27.852202904652785,
                        31.583966481344966, 33.806481916796706, 30.60097760433255, 28.697035014921106,
                        34.388184394951004, 36.008318964043994, 35.38525970948079, 41.76899799551756,
                        44.87770231764652, 50.942867757643015, 52.223751092491256, 53.42851282520877,
                        53.899328875510534, 53.899328875510534, 68.51530482306926];
    assert_eq!(predicted, Vector::new(expected));
}

#[test]
#[ignore = "FIXME #183 fails nondeterministically"]
fn test_train_no_data() {
    let inputs = Matrix::new(0, 1, vec![]);
    let targets = Vector::new(vec![]);

    let mut lin_mod = LinRegressor::default();
    let res = lin_mod.train(&inputs, &targets);

    assert!(res.is_err());
}
<|endoftext|>


<commit_before>extern crate antidote;
extern crate bytes;
extern crate fallible_iterator;
extern crate futures_cpupool;
extern crate phf;
extern crate postgres_protocol;
extern crate postgres_shared;
extern crate tokio_codec;
extern crate tokio_io;
extern crate void;

#[macro_use]
extern crate futures;
#[macro_use]
extern crate log;
#[macro_use]
extern crate state_machine_future;

use bytes::Bytes;
use futures::{Async, Future, Poll, Stream};
use postgres_shared::rows::RowIndex;
use std::error::Error as StdError;
use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering};
use tokio_io::{AsyncRead, AsyncWrite};

#[doc(inline)]
pub use postgres_shared::stmt::Column;
#[doc(inline)]
pub use postgres_shared::{params, types};
#[doc(inline)]
pub use postgres_shared::{CancelData, Notification};

pub use builder::*;
pub use error::*;
use proto::CancelFuture;
pub use tls::*;
use types::{FromSql, ToSql, Type};

mod builder;
pub mod error;
mod proto;
mod tls;

fn next_statement() -> String {
    static ID: AtomicUsize = AtomicUsize::new(0);
    format!("s{}", ID.fetch_add(1, Ordering::SeqCst))
}

fn next_portal() -> String {
    static ID: AtomicUsize = AtomicUsize::new(0);
    format!("p{}", ID.fetch_add(1, Ordering::SeqCst))
}

pub fn cancel_query<S, T>(stream: S, tls_mode: T, cancel_data: CancelData) -> CancelQuery<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    CancelQuery(CancelFuture::new(stream, tls_mode, cancel_data))
}

pub struct Client(proto::Client);

impl Client {
    pub fn prepare(&mut self, query: &str) -> Prepare {
        self.prepare_typed(query, &[])
    }

    pub fn prepare_typed(&mut self, query: &str, param_types: &[Type]) -> Prepare {
        Prepare(self.0.prepare(next_statement(), query, param_types))
    }

    pub fn execute(&mut self, statement: &Statement, params: &[&ToSql]) -> Execute {
        Execute(self.0.execute(&statement.0, params))
    }

    pub fn query(&mut self, statement: &Statement, params: &[&ToSql]) -> Query {
        Query(self.0.query(&statement.0, params))
    }

    pub fn bind(&mut self, statement: &Statement, params: &[&ToSql]) -> Bind {
        Bind(self.0.bind(&statement.0, next_portal(), params))
    }

    pub fn query_portal(&mut self, portal: &Portal, max_rows: i32) -> QueryPortal {
        QueryPortal(self.0.query_portal(&portal.0, max_rows))
    }

    pub fn copy_in<S>(&mut self, statement: &Statement, params: &[&ToSql], stream: S) -> CopyIn<S>
    where
        S: Stream,
        S::Item: AsRef<[u8]>,
        // FIXME error type?
        S::Error: Into<Box<StdError + Sync + Send>>,
    {
        CopyIn(self.0.copy_in(&statement.0, params, stream))
    }

    pub fn copy_out(&mut self, statement: &Statement, params: &[&ToSql]) -> CopyOut {
        CopyOut(self.0.copy_out(&statement.0, params))
    }

    pub fn transaction<T>(&mut self, future: T) -> Transaction<T>
    where
        T: Future,
        // FIXME error type?
        T::Error: From<Error>,
    {
        Transaction(proto::TransactionFuture::new(self.0.clone(), future))
    }

    pub fn batch_execute(&mut self, query: &str) -> BatchExecute {
        BatchExecute(self.0.batch_execute(query))
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Connection<S>(proto::Connection<S>);

impl<S> Connection<S>
where
    S: AsyncRead + AsyncWrite,
{
    pub fn cancel_data(&self) -> CancelData {
        self.0.cancel_data()
    }

    pub fn parameter(&self, name: &str) -> Option<&str> {
        self.0.parameter(name)
    }

    pub fn poll_message(&mut self) -> Poll<Option<AsyncMessage>, Error> {
        self.0.poll_message()
    }
}

impl<S> Future for Connection<S>
where
    S: AsyncRead + AsyncWrite,
{
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}

pub enum AsyncMessage {
    Notice(DbError),
    Notification(Notification),
    #[doc(hidden)]
    __NonExhaustive,
}

#[must_use = "futures do nothing unless polled"]
pub struct CancelQuery<S, T>(proto::CancelFuture<S, T>)
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>;

impl<S, T> Future for CancelQuery<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Connect<S, T>(proto::ConnectFuture<S, T>)
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>;

impl<S, T> Future for Connect<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    type Item = (Client, Connection<T::Stream>);
    type Error = Error;

    fn poll(&mut self) -> Poll<(Client, Connection<T::Stream>), Error> {
        let (client, connection) = try_ready!(self.0.poll());

        Ok(Async::Ready((Client(client), Connection(connection))))
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Prepare(proto::PrepareFuture);

impl Future for Prepare {
    type Item = Statement;
    type Error = Error;

    fn poll(&mut self) -> Poll<Statement, Error> {
        let statement = try_ready!(self.0.poll());

        Ok(Async::Ready(Statement(statement)))
    }
}

pub struct Statement(proto::Statement);

impl Statement {
    pub fn params(&self) -> &[Type] {
        self.0.params()
    }

    pub fn columns(&self) -> &[Column] {
        self.0.columns()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Execute(proto::ExecuteFuture);

impl Future for Execute {
    type Item = u64;
    type Error = Error;

    fn poll(&mut self) -> Poll<u64, Error> {
        self.0.poll()
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct Query(proto::QueryStream<proto::Statement>);

impl Stream for Query {
    type Item = Row;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Row>, Error> {
        match self.0.poll() {
            Ok(Async::Ready(Some(row))) => Ok(Async::Ready(Some(Row(row)))),
            Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Bind(proto::BindFuture);

impl Future for Bind {
    type Item = Portal;
    type Error = Error;

    fn poll(&mut self) -> Poll<Portal, Error> {
        match self.0.poll() {
            Ok(Async::Ready(portal)) => Ok(Async::Ready(Portal(portal))),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct QueryPortal(proto::QueryStream<proto::Portal>);

impl Stream for QueryPortal {
    type Item = Row;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Row>, Error> {
        match self.0.poll() {
            Ok(Async::Ready(Some(row))) => Ok(Async::Ready(Some(Row(row)))),
            Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

pub struct Portal(proto::Portal);

#[must_use = "futures do nothing unless polled"]
pub struct CopyIn<S>(proto::CopyInFuture<S>)
where
    S: Stream,
    S::Item: AsRef<[u8]>,
    S::Error: Into<Box<StdError + Sync + Send>>;

impl<S> Future for CopyIn<S>
where
    S: Stream<Item = Vec<u8>>,
    S::Error: Into<Box<StdError + Sync + Send>>,
{
    type Item = u64;
    type Error = Error;

    fn poll(&mut self) -> Poll<u64, Error> {
        self.0.poll()
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct CopyOut(proto::CopyOutStream);

impl Stream for CopyOut {
    type Item = Bytes;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, Error> {
        self.0.poll()
    }
}

pub struct Row(proto::Row);

impl Row {
    pub fn columns(&self) -> &[Column] {
        self.0.columns()
    }

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

    pub fn get<'a, I, T>(&'a self, idx: I) -> T
    where
        I: RowIndex + fmt::Debug,
        T: FromSql<'a>,
    {
        self.0.get(idx)
    }

    pub fn try_get<'a, I, T>(&'a self, idx: I) -> Result<Option<T>, Error>
    where
        I: RowIndex,
        T: FromSql<'a>,
    {
        self.0.try_get(idx)
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Transaction<T>(proto::TransactionFuture<T, T::Item, T::Error>)
where
    T: Future,
    T::Error: From<Error>;

impl<T> Future for Transaction<T>
where
    T: Future,
    T::Error: From<Error>,
{
    type Item = T::Item;
    type Error = T::Error;

    fn poll(&mut self) -> Poll<T::Item, T::Error> {
        self.0.poll()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct BatchExecute(proto::SimpleQueryFuture);

impl Future for BatchExecute {
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}
<commit_msg>Fix CopyIn Future bound<commit_after>extern crate antidote;
extern crate bytes;
extern crate fallible_iterator;
extern crate futures_cpupool;
extern crate phf;
extern crate postgres_protocol;
extern crate postgres_shared;
extern crate tokio_codec;
extern crate tokio_io;
extern crate void;

#[macro_use]
extern crate futures;
#[macro_use]
extern crate log;
#[macro_use]
extern crate state_machine_future;

use bytes::Bytes;
use futures::{Async, Future, Poll, Stream};
use postgres_shared::rows::RowIndex;
use std::error::Error as StdError;
use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering};
use tokio_io::{AsyncRead, AsyncWrite};

#[doc(inline)]
pub use postgres_shared::stmt::Column;
#[doc(inline)]
pub use postgres_shared::{params, types};
#[doc(inline)]
pub use postgres_shared::{CancelData, Notification};

pub use builder::*;
pub use error::*;
use proto::CancelFuture;
pub use tls::*;
use types::{FromSql, ToSql, Type};

mod builder;
pub mod error;
mod proto;
mod tls;

fn next_statement() -> String {
    static ID: AtomicUsize = AtomicUsize::new(0);
    format!("s{}", ID.fetch_add(1, Ordering::SeqCst))
}

fn next_portal() -> String {
    static ID: AtomicUsize = AtomicUsize::new(0);
    format!("p{}", ID.fetch_add(1, Ordering::SeqCst))
}

pub fn cancel_query<S, T>(stream: S, tls_mode: T, cancel_data: CancelData) -> CancelQuery<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    CancelQuery(CancelFuture::new(stream, tls_mode, cancel_data))
}

pub struct Client(proto::Client);

impl Client {
    pub fn prepare(&mut self, query: &str) -> Prepare {
        self.prepare_typed(query, &[])
    }

    pub fn prepare_typed(&mut self, query: &str, param_types: &[Type]) -> Prepare {
        Prepare(self.0.prepare(next_statement(), query, param_types))
    }

    pub fn execute(&mut self, statement: &Statement, params: &[&ToSql]) -> Execute {
        Execute(self.0.execute(&statement.0, params))
    }

    pub fn query(&mut self, statement: &Statement, params: &[&ToSql]) -> Query {
        Query(self.0.query(&statement.0, params))
    }

    pub fn bind(&mut self, statement: &Statement, params: &[&ToSql]) -> Bind {
        Bind(self.0.bind(&statement.0, next_portal(), params))
    }

    pub fn query_portal(&mut self, portal: &Portal, max_rows: i32) -> QueryPortal {
        QueryPortal(self.0.query_portal(&portal.0, max_rows))
    }

    pub fn copy_in<S>(&mut self, statement: &Statement, params: &[&ToSql], stream: S) -> CopyIn<S>
    where
        S: Stream,
        S::Item: AsRef<[u8]>,
        // FIXME error type?
        S::Error: Into<Box<StdError + Sync + Send>>,
    {
        CopyIn(self.0.copy_in(&statement.0, params, stream))
    }

    pub fn copy_out(&mut self, statement: &Statement, params: &[&ToSql]) -> CopyOut {
        CopyOut(self.0.copy_out(&statement.0, params))
    }

    pub fn transaction<T>(&mut self, future: T) -> Transaction<T>
    where
        T: Future,
        // FIXME error type?
        T::Error: From<Error>,
    {
        Transaction(proto::TransactionFuture::new(self.0.clone(), future))
    }

    pub fn batch_execute(&mut self, query: &str) -> BatchExecute {
        BatchExecute(self.0.batch_execute(query))
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Connection<S>(proto::Connection<S>);

impl<S> Connection<S>
where
    S: AsyncRead + AsyncWrite,
{
    pub fn cancel_data(&self) -> CancelData {
        self.0.cancel_data()
    }

    pub fn parameter(&self, name: &str) -> Option<&str> {
        self.0.parameter(name)
    }

    pub fn poll_message(&mut self) -> Poll<Option<AsyncMessage>, Error> {
        self.0.poll_message()
    }
}

impl<S> Future for Connection<S>
where
    S: AsyncRead + AsyncWrite,
{
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}

pub enum AsyncMessage {
    Notice(DbError),
    Notification(Notification),
    #[doc(hidden)]
    __NonExhaustive,
}

#[must_use = "futures do nothing unless polled"]
pub struct CancelQuery<S, T>(proto::CancelFuture<S, T>)
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>;

impl<S, T> Future for CancelQuery<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Connect<S, T>(proto::ConnectFuture<S, T>)
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>;

impl<S, T> Future for Connect<S, T>
where
    S: AsyncRead + AsyncWrite,
    T: TlsMode<S>,
{
    type Item = (Client, Connection<T::Stream>);
    type Error = Error;

    fn poll(&mut self) -> Poll<(Client, Connection<T::Stream>), Error> {
        let (client, connection) = try_ready!(self.0.poll());

        Ok(Async::Ready((Client(client), Connection(connection))))
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Prepare(proto::PrepareFuture);

impl Future for Prepare {
    type Item = Statement;
    type Error = Error;

    fn poll(&mut self) -> Poll<Statement, Error> {
        let statement = try_ready!(self.0.poll());

        Ok(Async::Ready(Statement(statement)))
    }
}

pub struct Statement(proto::Statement);

impl Statement {
    pub fn params(&self) -> &[Type] {
        self.0.params()
    }

    pub fn columns(&self) -> &[Column] {
        self.0.columns()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Execute(proto::ExecuteFuture);

impl Future for Execute {
    type Item = u64;
    type Error = Error;

    fn poll(&mut self) -> Poll<u64, Error> {
        self.0.poll()
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct Query(proto::QueryStream<proto::Statement>);

impl Stream for Query {
    type Item = Row;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Row>, Error> {
        match self.0.poll() {
            Ok(Async::Ready(Some(row))) => Ok(Async::Ready(Some(Row(row)))),
            Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Bind(proto::BindFuture);

impl Future for Bind {
    type Item = Portal;
    type Error = Error;

    fn poll(&mut self) -> Poll<Portal, Error> {
        match self.0.poll() {
            Ok(Async::Ready(portal)) => Ok(Async::Ready(Portal(portal))),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct QueryPortal(proto::QueryStream<proto::Portal>);

impl Stream for QueryPortal {
    type Item = Row;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Row>, Error> {
        match self.0.poll() {
            Ok(Async::Ready(Some(row))) => Ok(Async::Ready(Some(Row(row)))),
            Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
            Ok(Async::NotReady) => Ok(Async::NotReady),
            Err(e) => Err(e),
        }
    }
}

pub struct Portal(proto::Portal);

#[must_use = "futures do nothing unless polled"]
pub struct CopyIn<S>(proto::CopyInFuture<S>)
where
    S: Stream,
    S::Item: AsRef<[u8]>,
    S::Error: Into<Box<StdError + Sync + Send>>;

impl<S> Future for CopyIn<S>
where
    S: Stream,
    S::Item: AsRef<[u8]>,
    S::Error: Into<Box<StdError + Sync + Send>>,
{
    type Item = u64;
    type Error = Error;

    fn poll(&mut self) -> Poll<u64, Error> {
        self.0.poll()
    }
}

#[must_use = "streams do nothing unless polled"]
pub struct CopyOut(proto::CopyOutStream);

impl Stream for CopyOut {
    type Item = Bytes;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<Bytes>, Error> {
        self.0.poll()
    }
}

pub struct Row(proto::Row);

impl Row {
    pub fn columns(&self) -> &[Column] {
        self.0.columns()
    }

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

    pub fn get<'a, I, T>(&'a self, idx: I) -> T
    where
        I: RowIndex + fmt::Debug,
        T: FromSql<'a>,
    {
        self.0.get(idx)
    }

    pub fn try_get<'a, I, T>(&'a self, idx: I) -> Result<Option<T>, Error>
    where
        I: RowIndex,
        T: FromSql<'a>,
    {
        self.0.try_get(idx)
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct Transaction<T>(proto::TransactionFuture<T, T::Item, T::Error>)
where
    T: Future,
    T::Error: From<Error>;

impl<T> Future for Transaction<T>
where
    T: Future,
    T::Error: From<Error>,
{
    type Item = T::Item;
    type Error = T::Error;

    fn poll(&mut self) -> Poll<T::Item, T::Error> {
        self.0.poll()
    }
}

#[must_use = "futures do nothing unless polled"]
pub struct BatchExecute(proto::SimpleQueryFuture);

impl Future for BatchExecute {
    type Item = ();
    type Error = Error;

    fn poll(&mut self) -> Poll<(), Error> {
        self.0.poll()
    }
}
<|endoftext|>


<commit_before>use bytes::{Buf, BufMut};
use futures::{Future, Poll};
use std::error::Error;
use std::io::{self, Read, Write};
use tokio_io::{AsyncRead, AsyncWrite};

use proto;

pub struct Socket(pub(crate) proto::Socket);

impl Read for Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl AsyncRead for Socket {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        self.0.prepare_uninitialized_buffer(buf)
    }

    fn read_buf<B>(&mut self, buf: &mut B) -> Poll<usize, io::Error>
    where
        B: BufMut,
    {
        self.0.read_buf(buf)
    }
}

impl Write for Socket {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl AsyncWrite for Socket {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.0.shutdown()
    }

    fn write_buf<B>(&mut self, buf: &mut B) -> Poll<usize, io::Error>
    where
        B: Buf,
    {
        self.0.write_buf(buf)
    }
}

pub trait TlsConnect {
    fn connect(
        &self,
        domain: &str,
        socket: Socket,
    ) -> Box<Future<Item = Box<TlsStream>, Error = Box<Error + Sync + Send>> + Sync + Send>;
}

pub trait TlsStream: 'static + Sync + Send + AsyncRead + AsyncWrite {
    /// Returns the data associated with the `tls-unique` channel binding type as described in
    /// [RFC 5929], if supported.
    ///
    /// An implementation only needs to support at most one of this or `tls_server_end_point`.
    ///
    /// [RFC 5929]: https://tools.ietf.org/html/rfc5929
    fn tls_unique(&self) -> Option<Vec<u8>> {
        None
    }

    /// Returns the data associated with the `tls-server-end-point` channel binding type as
    /// described in [RFC 5929], if supported.
    ///
    /// An implementation only needs to support at most one of this or `tls_unique`.
    ///
    /// [RFC 5929]: https://tools.ietf.org/html/rfc5929
    fn tls_server_end_point(&self) -> Option<Vec<u8>> {
        None
    }
}

impl TlsStream for proto::Socket {}
<commit_msg>Make TlsConnect Sync and Send<commit_after>use bytes::{Buf, BufMut};
use futures::{Future, Poll};
use std::error::Error;
use std::io::{self, Read, Write};
use tokio_io::{AsyncRead, AsyncWrite};

use proto;

pub struct Socket(pub(crate) proto::Socket);

impl Read for Socket {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl AsyncRead for Socket {
    unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
        self.0.prepare_uninitialized_buffer(buf)
    }

    fn read_buf<B>(&mut self, buf: &mut B) -> Poll<usize, io::Error>
    where
        B: BufMut,
    {
        self.0.read_buf(buf)
    }
}

impl Write for Socket {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl AsyncWrite for Socket {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.0.shutdown()
    }

    fn write_buf<B>(&mut self, buf: &mut B) -> Poll<usize, io::Error>
    where
        B: Buf,
    {
        self.0.write_buf(buf)
    }
}

pub trait TlsConnect: Sync + Send {
    fn connect(
        &self,
        domain: &str,
        socket: Socket,
    ) -> Box<Future<Item = Box<TlsStream>, Error = Box<Error + Sync + Send>> + Sync + Send>;
}

pub trait TlsStream: 'static + Sync + Send + AsyncRead + AsyncWrite {
    /// Returns the data associated with the `tls-unique` channel binding type as described in
    /// [RFC 5929], if supported.
    ///
    /// An implementation only needs to support at most one of this or `tls_server_end_point`.
    ///
    /// [RFC 5929]: https://tools.ietf.org/html/rfc5929
    fn tls_unique(&self) -> Option<Vec<u8>> {
        None
    }

    /// Returns the data associated with the `tls-server-end-point` channel binding type as
    /// described in [RFC 5929], if supported.
    ///
    /// An implementation only needs to support at most one of this or `tls_unique`.
    ///
    /// [RFC 5929]: https://tools.ietf.org/html/rfc5929
    fn tls_server_end_point(&self) -> Option<Vec<u8>> {
        None
    }
}

impl TlsStream for proto::Socket {}
<|endoftext|>


<commit_before>use env::{Environment, Point};
use loans_in_scope::{Loan, LoansInScope};
use nll_repr::repr;
use std::error::Error;
use std::fmt;

pub fn borrow_check(env: &Environment, loans_in_scope: &LoansInScope) -> Result<(), Box<Error>> {
    let mut result: Result<(), Box<Error>> = Ok(());
    loans_in_scope.walk(env, |point, opt_action, loans| {
        let borrowck = BorrowCheck { env, point, loans };
        if let Some(action) = opt_action {
            if let Err(e) = borrowck.check_action(action) {
                if !action.should_have_error {
                    result = Err(e);
                }
            } else if action.should_have_error {
                result = Err(Box::new(BorrowError::no_error(point)));
            }
        }
    });

    result
}

struct BorrowCheck<'cx> {
    env: &'cx Environment<'cx>,
    point: Point,
    loans: &'cx [&'cx Loan<'cx>],
}

impl<'cx> BorrowCheck<'cx> {
    fn check_action(&self, action: &repr::Action) -> Result<(), Box<Error>> {
        log!("check_action({:?}) at {:?}", action, self.point);
        match action.kind {
            repr::ActionKind::Init(ref a, ref bs) => {
                self.check_write(a)?;
                for b in bs {
                    self.check_read(b)?;
                }
            }
            repr::ActionKind::Assign(ref a, ref b) => {
                self.check_write(a)?;
                self.check_read(b)?;
            }
            repr::ActionKind::Borrow(ref a, _, repr::BorrowKind::Shared, ref b) => {
                self.check_write(a)?;
                self.check_read(b)?;
            }
            repr::ActionKind::Borrow(ref a, _, repr::BorrowKind::Mut, ref b) => {
                self.check_write(a)?;
                self.check_write(b)?;
            }
            repr::ActionKind::Constraint(_) => {}
            repr::ActionKind::Use(ref p) => {
                self.check_read(p)?;
            }
            repr::ActionKind::Drop(ref p) => {
                self.check_move(p)?;
            }
            repr::ActionKind::StorageDead(p) => {
                self.check_storage_dead(p)?;
            }
            repr::ActionKind::Noop => {}
        }

        Ok(())
    }

    /// Cannot write to a path `p` if:
    /// - the path `p` is frozen by one of the loans
    ///   - see `frozen_by_borrow_of()`
    ///   - this covers writing to `a` (or `a.b`) when `a.b` is borrowed
    /// - some prefix of `p` is borrowed.
    ///   - this covers writing to `a.b.c` when `a.b` is borrowed
    fn check_write(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_write of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        let prefixes = path.prefixes();
        for loan in self.loans {
            // If you have borrowed `a.b`, this prevents writes to `a`
            // or `a.b`:
            let frozen_paths = self.frozen_by_borrow_of(&loan.path);
            if frozen_paths.contains(&path) {
                return Err(Box::new(BorrowError::for_write(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }

            // If you have borrowed `a.b`, this prevents writes to
            // `a.b.c`:
            if prefixes.contains(&loan.path) {
                return Err(Box::new(BorrowError::for_write(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }
        }
        Ok(())
    }

    /// Cannot read from a path `a.b.c` if:
    /// - the exact path `a.b.c` is borrowed mutably;
    /// - some subpath `a.b.c.d` is borrowed mutably;
    /// - some prefix of `a.b` is borrowed mutably.
    fn check_read(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_read of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        let path_prefixes = path.prefixes();
        for loan in self.loans {
            match loan.kind {
                repr::BorrowKind::Shared => continue,
                repr::BorrowKind::Mut => {}
            }

            if {
                // `a.b.c` or `a.b` is borrowed
                path_prefixes.contains(&loan.path) ||

                    // `a.b.c.d` is borrowed
                    loan.path.prefixes().contains(&path)
            } {
                return Err(Box::new(BorrowError::for_read(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }
        }
        Ok(())
    }

    /// Cannot move from a path `p` if:
    /// - `p` is borrowed;
    /// - some subpath `p.foo` is borrowed;
    /// - some prefix of `p` is borrowed.
    ///
    /// Note that this is stricter than both *writes* and
    /// *storage-dead*. In particular, you **can** write to a variable
    /// `x` that contains an `&mut` value when `*x` is borrowed, but
    /// you **cannot** move `x`. This is because moving it would make
    /// the `&mut` available in the new location, but writing (and
    /// storage-dead) both kill it forever.
    fn check_move(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_move of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        let path_prefixes = path.prefixes();
        for loan in self.loans {
            if {
                // accessing `a.b.c` is illegal if `a.b.c` or `a.b` is
                // borrowed...
                path_prefixes.contains(&loan.path) ||

                    // ...or `a.b.c.d` is borrowed
                    loan.path.prefixes().contains(&path)
            } {
                return Err(Box::new(BorrowError::for_move(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }
        }
        Ok(())
    }

    /// Cannot free a local variable `var` if:
    /// - data interior to `var` is borrowed.
    ///
    /// In particular, having something like `*var` borrowed is ok.
    fn check_storage_dead(&self, var: repr::Variable) -> Result<(), Box<Error>> {
        log!(
            "check_storage_dead of {:?} at {:?} with loans={:#?}",
            var,
            self.point,
            self.loans
        );
        for loan in self.loans {
            if let Some(loan_var) = self.invalidated_by_dead_storage(&loan.path) {
                if var == loan_var {
                    return Err(Box::new(BorrowError::for_storage_dead(
                        self.point,
                        var,
                        &loan.path,
                        loan.point,
                    )));
                }
            }
        }
        Ok(())
    }

    /// If `path` is borrowed, returns a vector of paths which -- if
    /// moved or if the storage went away -- would invalidate this
    /// reference.
    fn invalidated_by_dead_storage(&self, mut path: &repr::Path) -> Option<repr::Variable> {
        loop {
            match *path {
                repr::Path::Base(v) => return Some(v),
                repr::Path::Extension(ref base_path, field_name) => {
                    match *self.env.path_ty(base_path) {
                        // If you borrow `*r`, you can drop the
                        // reference `r` without invalidating that
                        // memory.
                        repr::Ty::Ref(_, _, _) => {
                            assert_eq!(field_name, repr::FieldName::star());
                            return None;
                        }

                        repr::Ty::Unit |
                        repr::Ty::Struct(..) => {
                            path = base_path;
                        }

                        repr::Ty::Bound(..) => panic!("unexpected bound type"),
                    }
                }
            }
        }
    }

    /// If `path` is mutably borrowed, returns a vector of paths which -- if
    /// moved or if the storage went away -- would invalidate this
    /// reference.
    fn frozen_by_borrow_of<'a>(&self, mut path: &'a repr::Path) -> Vec<&'a repr::Path> {
        let mut result = vec![];
        loop {
            result.push(path);
            match *path {
                repr::Path::Base(_) => return result,
                repr::Path::Extension(ref base_path, field_name) => {
                    match *self.env.path_ty(base_path) {
                        // If you borrowed `*r`, writing to `r` does
                        // not actually affect the memory at `*r`, so
                        // we can stop iterating backwards now.
                        repr::Ty::Ref(_, _, _) => {
                            assert_eq!(field_name, repr::FieldName::star());
                            return result;
                        }

                        // If you have borrowed `a.b`, then writing to
                        // `a` would overwrite `a.b`, which is
                        // disallowed.
                        repr::Ty::Struct(..) => {
                            path = base_path;
                        }

                        repr::Ty::Unit => panic!("unit has no fields"),
                        repr::Ty::Bound(..) => panic!("unexpected bound type"),
                    }
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct BorrowError {
    description: String,
}

impl BorrowError {
    fn no_error(point: Point) -> Self {
        BorrowError {
            description: format!("point {:?} had no error, but should have", point),
        }
    }

    fn for_move(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot move {:?} because {:?} is borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_read(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot read {:?} because {:?} is mutably borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_write(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot write {:?} because {:?} is borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_storage_dead(
        point: Point,
        var: repr::Variable,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot kill storage for {:?} \
                 because {:?} is borrowed (at point `{:?}`)",
                point,
                var,
                loan_path,
                loan_point
            ),
        }
    }
}

impl Error for BorrowError {
    fn description(&self) -> &str {
        &self.description
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl fmt::Display for BorrowError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.description)
    }
}
<commit_msg>consolidate treatment of write and storage-dead using helper<commit_after>use env::{Environment, Point};
use loans_in_scope::{Loan, LoansInScope};
use nll_repr::repr;
use std::error::Error;
use std::fmt;

pub fn borrow_check(env: &Environment, loans_in_scope: &LoansInScope) -> Result<(), Box<Error>> {
    let mut result: Result<(), Box<Error>> = Ok(());
    loans_in_scope.walk(env, |point, opt_action, loans| {
        let borrowck = BorrowCheck { env, point, loans };
        if let Some(action) = opt_action {
            if let Err(e) = borrowck.check_action(action) {
                if !action.should_have_error {
                    result = Err(e);
                }
            } else if action.should_have_error {
                result = Err(Box::new(BorrowError::no_error(point)));
            }
        }
    });

    result
}

struct BorrowCheck<'cx> {
    env: &'cx Environment<'cx>,
    point: Point,
    loans: &'cx [&'cx Loan<'cx>],
}

impl<'cx> BorrowCheck<'cx> {
    fn check_action(&self, action: &repr::Action) -> Result<(), Box<Error>> {
        log!("check_action({:?}) at {:?}", action, self.point);
        match action.kind {
            repr::ActionKind::Init(ref a, ref bs) => {
                self.check_write(a)?;
                for b in bs {
                    self.check_read(b)?;
                }
            }
            repr::ActionKind::Assign(ref a, ref b) => {
                self.check_write(a)?;
                self.check_read(b)?;
            }
            repr::ActionKind::Borrow(ref a, _, repr::BorrowKind::Shared, ref b) => {
                self.check_write(a)?;
                self.check_read(b)?;
            }
            repr::ActionKind::Borrow(ref a, _, repr::BorrowKind::Mut, ref b) => {
                self.check_write(a)?;
                self.check_write(b)?;
            }
            repr::ActionKind::Constraint(_) => {}
            repr::ActionKind::Use(ref p) => {
                self.check_read(p)?;
            }
            repr::ActionKind::Drop(ref p) => {
                self.check_move(p)?;
            }
            repr::ActionKind::StorageDead(p) => {
                self.check_storage_dead(p)?;
            }
            repr::ActionKind::Noop => {}
        }

        Ok(())
    }

    /// Cannot write to a path `p` if:
    /// - the path `p` is frozen by one of the loans
    ///   - see `frozen_by_borrow_of()`
    ///   - this covers writing to `a` (or `a.b`) when `a.b` is borrowed
    /// - some prefix of `p` is borrowed.
    ///   - this covers writing to `a.b.c` when `a.b` is borrowed
    fn check_write(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_write of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        if let Some(loan) = self.find_loan_that_freezes(path) {
            return Err(Box::new(BorrowError::for_write(
                self.point,
                path,
                &loan.path,
                loan.point,
            )));
        }
        Ok(())
    }

    /// Cannot read from a path `a.b.c` if:
    /// - the exact path `a.b.c` is borrowed mutably;
    /// - some subpath `a.b.c.d` is borrowed mutably;
    /// - some prefix of `a.b` is borrowed mutably.
    fn check_read(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_read of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        let path_prefixes = path.prefixes();
        for loan in self.loans {
            match loan.kind {
                repr::BorrowKind::Shared => continue,
                repr::BorrowKind::Mut => {}
            }

            if {
                // `a.b.c` or `a.b` is borrowed
                path_prefixes.contains(&loan.path) ||

                    // `a.b.c.d` is borrowed
                    loan.path.prefixes().contains(&path)
            } {
                return Err(Box::new(BorrowError::for_read(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }
        }
        Ok(())
    }

    /// Cannot move from a path `p` if:
    /// - `p` is borrowed;
    /// - some subpath `p.foo` is borrowed;
    /// - some prefix of `p` is borrowed.
    ///
    /// Note that this is stricter than both *writes* and
    /// *storage-dead*. In particular, you **can** write to a variable
    /// `x` that contains an `&mut` value when `*x` is borrowed, but
    /// you **cannot** move `x`. This is because moving it would make
    /// the `&mut` available in the new location, but writing (and
    /// storage-dead) both kill it forever.
    fn check_move(&self, path: &repr::Path) -> Result<(), Box<Error>> {
        log!(
            "check_move of {:?} at {:?} with loans={:#?}",
            path,
            self.point,
            self.loans
        );
        let path_prefixes = path.prefixes();
        for loan in self.loans {
            if {
                // accessing `a.b.c` is illegal if `a.b.c` or `a.b` is
                // borrowed...
                path_prefixes.contains(&loan.path) ||

                    // ...or `a.b.c.d` is borrowed
                    loan.path.prefixes().contains(&path)
            } {
                return Err(Box::new(BorrowError::for_move(
                    self.point,
                    path,
                    &loan.path,
                    loan.point,
                )));
            }
        }
        Ok(())
    }

    /// Cannot free a local variable `var` if:
    /// - data interior to `var` is borrowed.
    ///
    /// In particular, having something like `*var` borrowed is ok.
    fn check_storage_dead(&self, var: repr::Variable) -> Result<(), Box<Error>> {
        log!(
            "check_storage_dead of {:?} at {:?} with loans={:#?}",
            var,
            self.point,
            self.loans
        );
        if let Some(loan) = self.find_loan_that_freezes(&repr::Path::Base(var)) {
            return Err(Box::new(BorrowError::for_storage_dead(
                self.point,
                var,
                &loan.path,
                loan.point,
            )));
        }
        Ok(())
    }

    /// Helper for `check_write` and `check_storage_dead`: finds if
    /// there is a loan that "freezes" the given path -- that is, a
    /// loan that would make modifying the `path` (or freeing it)
    /// illegal. This is slightly more permissive than the rules
    /// around move and reads, precisely because overwriting or
    /// freeing `path` makes the previous value unavailable from that
    /// point on.
    fn find_loan_that_freezes(&self, path: &repr::Path) -> Option<&Loan> {
        let prefixes = path.prefixes();
        self.loans.iter().cloned().find(|loan| {
            // If you have borrowed `a.b`, this prevents writes to `a`
            // or `a.b`:
            let frozen_paths = self.frozen_by_borrow_of(&loan.path);
            frozen_paths.contains(&path) ||

                // If you have borrowed `a.b`, this prevents writes to
                // `a.b.c`:
                prefixes.contains(&loan.path)
        })
    }

    /// If `path` is mutably borrowed, returns a vector of paths which -- if
    /// moved or if the storage went away -- would invalidate this
    /// reference.
    fn frozen_by_borrow_of<'a>(&self, mut path: &'a repr::Path) -> Vec<&'a repr::Path> {
        let mut result = vec![];
        loop {
            result.push(path);
            match *path {
                repr::Path::Base(_) => return result,
                repr::Path::Extension(ref base_path, field_name) => {
                    match *self.env.path_ty(base_path) {
                        // If you borrowed `*r`, writing to `r` does
                        // not actually affect the memory at `*r`, so
                        // we can stop iterating backwards now.
                        repr::Ty::Ref(_, _, _) => {
                            assert_eq!(field_name, repr::FieldName::star());
                            return result;
                        }

                        // If you have borrowed `a.b`, then writing to
                        // `a` would overwrite `a.b`, which is
                        // disallowed.
                        repr::Ty::Struct(..) => {
                            path = base_path;
                        }

                        repr::Ty::Unit => panic!("unit has no fields"),
                        repr::Ty::Bound(..) => panic!("unexpected bound type"),
                    }
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct BorrowError {
    description: String,
}

impl BorrowError {
    fn no_error(point: Point) -> Self {
        BorrowError {
            description: format!("point {:?} had no error, but should have", point),
        }
    }

    fn for_move(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot move {:?} because {:?} is borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_read(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot read {:?} because {:?} is mutably borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_write(
        point: Point,
        path: &repr::Path,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot write {:?} because {:?} is borrowed (at point `{:?}`)",
                point,
                path,
                loan_path,
                loan_point
            ),
        }
    }

    fn for_storage_dead(
        point: Point,
        var: repr::Variable,
        loan_path: &repr::Path,
        loan_point: Point,
    ) -> Self {
        BorrowError {
            description: format!(
                "point {:?} cannot kill storage for {:?} \
                 because {:?} is borrowed (at point `{:?}`)",
                point,
                var,
                loan_path,
                loan_point
            ),
        }
    }
}

impl Error for BorrowError {
    fn description(&self) -> &str {
        &self.description
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl fmt::Display for BorrowError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}", self.description)
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove commented-out function<commit_after><|endoftext|>


<commit_before><commit_msg>convert string to permission<commit_after><|endoftext|>


<commit_before>//! To run a LOGO program, run:
//!     cargo run --example logo_interpreter -- .\examples\my_logo_program.txt

extern crate turtle;

use turtle::Turtle;
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::Path;

fn main() {
    let mut turtle = Turtle::new();
    turtle.set_speed(4);

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

    if args.len() == 2 {
        let source= parse_source(&parse_file(&args[1]));
        parse_string(&source, &mut turtle);
    }
    else {
        println!("Pass in a LOGO command txt file.");
    }
}

fn parse_string(source: &str, turtle: &mut Turtle) {
    let ops: Vec<&str> = source.split(' ').collect();

    let mut ins_pointer = 0;

    while let Some(op) = ops.get(ins_pointer) {
        match *op {
            "fd" | "forward" => if let Some(dist) = ops.get(ins_pointer + 1) {
                let dist: f64 = dist.parse().unwrap();
                turtle.forward(dist as f64);
                ins_pointer += 1;
            },
            "bk" | "back" => if let Some(dist) = ops.get(ins_pointer + 1) {
                let dist: f64 = dist.parse().unwrap();
                turtle.backward(dist as f64);
                ins_pointer += 1;
            },
            "lt" | "left" => if let Some(dist) = ops.get(ins_pointer + 1) {
                let dist: f64 = dist.parse().unwrap();
                turtle.left(dist as f64);
                ins_pointer += 1;
            },
            "rt" | "right" => if let Some(dist) = ops.get(ins_pointer + 1) {
                let dist: f64 = dist.parse().unwrap();
                turtle.right(dist as f64);
                ins_pointer += 1;
            },
            _ => println!("command: {}", op),
        }
        ins_pointer += 1;
    }
}

fn parse_file(file_name: &str) -> String {
    let path = Path::new(file_name);
    let mut file = match File::open(&path) {
        Err(why) => {
            println!("FILE ERROR");
            panic!("Error: {}", why);
        },
        Ok(file) => file,
    };
    let mut text = String::new();
    match file.read_to_string(&mut text) {
        Ok(_) => {},
        Err(why) => {
            println!("READ ERROR");
            panic!("Error: {}", why);
        },
    };
    text
}

fn parse_source(source: &str) -> String {
    // Transform the single string to a vector of strings by splitting at whitespaces.
    let src: Vec<&str> = source.split_whitespace().collect();
    // Join the Vector to form a single String with even spaces.
    let src = src.join(" ").to_string();
    src
}<commit_msg>Re-do the LOGO interpreter<commit_after>//! To run a LOGO program, run:
//!     cargo run --example logo_interpreter -- .\examples\my_logo_program.txt

extern crate turtle;

use turtle::Turtle;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::collections::VecDeque;

fn main() {
    let mut turtle = Turtle::new();

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

    if args.len() != 2 {
        println!("No file provided");
        return
    }

    let path = &args[1];
    let file = File::open(path).expect("Could not open provided program");
    let mut reader = BufReader::new(file);
    loop {
        let mut buffer = String::new();
        let read_bytes = reader.read_line(&mut buffer)
            .expect("Unable read input from stdin");
        if read_bytes == 0 {
            // Reached EOF, stop interpreter
            break;
        }

        let mut cmd_args = buffer.split_whitespace().collect();
        handle_command(&mut turtle, &mut cmd_args);
    }
}

fn handle_command(turtle: &mut Turtle, args: &mut VecDeque<&str>) {
    if args.is_empty() {
        return;
    }
    // We already checked if args is empty, so we can unwrap here without fear
    match args.pop_front().unwrap() {
        "fd" | "forward" => {
            let distance = parse_distance(args.pop_front()
                .expect("Expected a distance value after fd/forward command"));
            turtle.forward(distance)
        },
        "bk" | "back" => {
            let distance = parse_distance(args.pop_front()
                .expect("Expect a distance value after bk/back command"));
            turtle.backward(distance)
        },
        "lt" | "left" => {
            let distance = parse_distance(args.pop_front()
                .expect("Expect a distance value after lt/left command"));
            turtle.left(distance)
        }
        "rt" | "right" => {
            let distance = parse_distance(args.pop_front()
                .expect("Expect a distance value after rt/right command"));
            turtle.right(distance)
        }
        _ => unimplemented!(), //TODO: a couple more commands (no need to do everything)
    }
    // Parse any remaining commands on this line
    handle_command(turtle, args);
}

fn parse_distance(s: &str) -> f64 {
    let dist: f64 = s.parse().unwrap();
    dist
}<|endoftext|>


<commit_before><commit_msg>fix(core): CMat is marked as Send<commit_after><|endoftext|>


<commit_before><commit_msg>fixed signature verification<commit_after><|endoftext|>


<commit_before><commit_msg>Added Day9 B<commit_after><|endoftext|>


<commit_before>use sqlite::{Connection, Statement, State};
use std::mem;

use streamer::{Config, Result};
use streamer::platform::{self, Platform, Profile};
use streamer::system::{Event, EventKind, Job};

pub struct Output {
    #[allow(dead_code)]
    connection: Connection,
    arrivals: Statement<'static>,
    profiles: Statement<'static>,
}

impl Output {
    pub fn new(platform: &platform::Thermal, config: &Config) -> Result<Self> {
        use sql::prelude::*;

        let connection = ok!(Connection::open(path!(@unchecked config,
                                                    "an output file is required")));
        ok!(connection.execute("
            PRAGMA journal_mode = MEMORY;
            PRAGMA synchronous = OFF;
        "));
        ok!(connection.execute(
            ok!(create_table("arrivals").if_not_exists().columns(&[
                "time".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(
            ok!(create_table("profiles").if_not_exists().columns(&[
                "time".float().not_null(), "component_id".integer().not_null(),
                "power".float().not_null(), "temperature".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(ok!(delete_from("arrivals").compile())));
        ok!(connection.execute(ok!(delete_from("profiles").compile())));
        let arrivals = {
            let statement = ok!(connection.prepare(
                ok!(insert_into("arrivals").columns(&["time"]).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        let units = platform.elements().len();
        let profiles = {
            let statement = ok!(connection.prepare(
                ok!(insert_into("profiles").columns(&[
                    "time", "component_id", "power", "temperature",
                ]).batch(units).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        Ok(Output { connection: connection, arrivals: arrivals, profiles: profiles })
    }

    pub fn next(&mut self, event: &Event, &(ref power, ref temperature): &(Profile, Profile))
                -> Result<()> {

        ok!(self.connection.execute("BEGIN TRANSACTION"));
        if let &EventKind::Arrived(ref job) = &event.kind {
            ok!(self.write_arrival(job));
        }
        ok!(self.write_profile(power, temperature));
        ok!(self.connection.execute("END TRANSACTION"));
        Ok(())
    }

    fn write_arrival(&mut self, job: &Job) -> Result<()> {
        let statement = &mut self.arrivals;
        ok!(statement.reset());
        ok!(statement.bind(1, job.arrival));
        if State::Done != ok!(statement.next()) {
            raise!("failed to write into the database");
        }
        Ok(())
    }

    fn write_profile(&mut self, power: &Profile, temperature: &Profile) -> Result<()> {
        let &Profile { units, steps, time, time_step, data: ref power } = power;
        let &Profile { data: ref temperature, .. } = temperature;
        let statement = &mut self.profiles;
        for i in 0..steps {
            let time = time + (i as f64) * time_step;
            ok!(statement.reset());
            let mut k = 0;
            for j in 0..units {
                ok!(statement.bind(k + 1, time));
                ok!(statement.bind(k + 2, j as i64));
                ok!(statement.bind(k + 3, power[i * units + j]));
                ok!(statement.bind(k + 4, temperature[i * units + j]));
                k += 4;
            }
            if State::Done != ok!(statement.next()) {
                raise!("failed to write into the database");
            }
        }
        Ok(())
    }
}
<commit_msg>Make a cosmetic adjustment<commit_after>use sqlite::{Connection, Statement, State};
use std::mem;

use streamer::{Config, Result};
use streamer::platform::{self, Platform, Profile};
use streamer::system::{Event, EventKind, Job};

pub struct Output {
    #[allow(dead_code)]
    connection: Connection,
    arrivals: Statement<'static>,
    profiles: Statement<'static>,
}

impl Output {
    pub fn new(platform: &platform::Thermal, config: &Config) -> Result<Self> {
        use sql::prelude::*;

        let connection = ok!(Connection::open(path!(@unchecked config,
                                                    "an output file is required")));
        ok!(connection.execute("
            PRAGMA journal_mode = MEMORY;
            PRAGMA synchronous = OFF;
        "));
        ok!(connection.execute(
            ok!(create_table("arrivals").if_not_exists().columns(&[
                "time".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(
            ok!(create_table("profiles").if_not_exists().columns(&[
                "time".float().not_null(), "component_id".integer().not_null(),
                "power".float().not_null(), "temperature".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(ok!(delete_from("arrivals").compile())));
        ok!(connection.execute(ok!(delete_from("profiles").compile())));
        let arrivals = {
            let statement = ok!(connection.prepare(
                ok!(insert_into("arrivals").columns(&["time"]).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        let profiles = {
            let units = platform.elements().len();
            let statement = ok!(connection.prepare(
                ok!(insert_into("profiles").columns(&[
                    "time", "component_id", "power", "temperature",
                ]).batch(units).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        Ok(Output { connection: connection, arrivals: arrivals, profiles: profiles })
    }

    pub fn next(&mut self, event: &Event, &(ref power, ref temperature): &(Profile, Profile))
                -> Result<()> {

        ok!(self.connection.execute("BEGIN TRANSACTION"));
        if let &EventKind::Arrived(ref job) = &event.kind {
            ok!(self.write_arrival(job));
        }
        ok!(self.write_profile(power, temperature));
        ok!(self.connection.execute("END TRANSACTION"));
        Ok(())
    }

    fn write_arrival(&mut self, job: &Job) -> Result<()> {
        let statement = &mut self.arrivals;
        ok!(statement.reset());
        ok!(statement.bind(1, job.arrival));
        if State::Done != ok!(statement.next()) {
            raise!("failed to write into the database");
        }
        Ok(())
    }

    fn write_profile(&mut self, power: &Profile, temperature: &Profile) -> Result<()> {
        let &Profile { units, steps, time, time_step, data: ref power } = power;
        let &Profile { data: ref temperature, .. } = temperature;
        let statement = &mut self.profiles;
        for i in 0..steps {
            let time = time + (i as f64) * time_step;
            ok!(statement.reset());
            let mut k = 0;
            for j in 0..units {
                ok!(statement.bind(k + 1, time));
                ok!(statement.bind(k + 2, j as i64));
                ok!(statement.bind(k + 3, power[i * units + j]));
                ok!(statement.bind(k + 4, temperature[i * units + j]));
                k += 4;
            }
            if State::Done != ok!(statement.next()) {
                raise!("failed to write into the database");
            }
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::env;

use chars::display;
use chars::human_names;

fn main() {
    let args = env::args()
        .skip(1)
        .flat_map(|argument| human_names::from_arg(argument.as_ref()));
    for c in args {
        display::describe(c);
    }
}
<commit_msg>Display helpful message when there’s no results<commit_after>use std::env;

use chars::display;
use chars::human_names;

fn main() {
    let args = env::args().skip(1);
    for argument in args {
        let results = human_names::from_arg(argument.as_ref());
        if results.is_empty() {
            eprintln!("No results for “{}”.", argument);
        } else {
            for c in results {
                display::describe(c);
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Low-level bindings to libm

#![cfg(target_os = "linux")]

extern crate linux_api;

use linux_api::{c_double, c_float};

#[link(name = "m")] //For -lm
extern {

    ///Rounds to an integer value in c_double format
    ///
    ///If you want an integer format, use lrint instead
    pub fn nearbyint(x: c_double) -> c_double;

    ///Rounds to an integer value in c_float format
    ///
    ///If you want an integer format, use lrintf instead
    pub fn nearbyintf(x: c_float) -> c_float;

    ///Rounds to an integer value in c_double format
    ///
    ///If you want an integer format, use lrint instead
    pub fn rint(x: c_double) -> c_double;

    ///Rounds to an integer value in c_float format
    ///
    ///If you want an integer format, use lrintf instead
    pub fn rintf(x: c_float) -> c_float;

}

#[cfg(test)]
#[allow(unused_assignments)] // Unsafe functions
mod test {

    use super::*;

    #[test]
    fn test_rint() {

        let value = 246.246f64;

        let mut result = 0f64;

        unsafe { result = rint(value); }

        assert_eq!(246.0f64, result);
    }

    #[test]
    fn test_rintf() {

        let value = 2543637.536f32;

        let mut result = 0f32;

        unsafe { result = rintf(value); }

        assert_eq!(2543638.0f32, result);
    }

    #[test]
    fn test_nearbyint() {

        let value = 246.246f64;

        let mut result = 0f64;

        unsafe { result = nearbyint(value); }

        assert_eq!(246.0f64, result);
    }

    #[test]
    fn test_nearbyintf() {

        let value = 2543637.536f32;

        let mut result = 0f32;

        unsafe { result = nearbyintf(value); }

        assert_eq!(2543638.0f32, result);
    }

}
<commit_msg>Add integral rounding functions<commit_after>//! Low-level bindings to libm

#![cfg(target_os = "linux")]

extern crate linux_api;

use linux_api::{c_double, c_float,
                c_long, c_longlong};

#[link(name = "m")] //For -lm
extern {

    ///Rounds to an integer value in c_double format
    ///
    ///If you want an integer format, use lrint instead
    pub fn nearbyint(x: c_double) -> c_double;

    ///Rounds to an integer value in c_float format
    ///
    ///If you want an integer format, use lrintf instead
    pub fn nearbyintf(x: c_float) -> c_float;

    ///Rounds to an integer value in c_double format
    ///
    ///If you want an integer format, use lrint instead
    pub fn rint(x: c_double) -> c_double;

    ///Rounds to an integer value in c_float format
    ///
    ///If you want an integer format, use lrintf instead
    pub fn rintf(x: c_float) -> c_float;

    ///Rounds a c_double to the nearest c_long
    pub fn lrint(x: c_double) -> c_long;

    ///Rounds a c_float to the nearest c_long
    pub fn lrintf(x: c_float) -> c_long;

    ///Rounds a c_double to the nearest c_longlong
    pub fn llrint(x: c_double) -> c_longlong;

    ///Rounds a c_float to the nearest c_longlong
    pub fn llrintf(x: c_float) -> c_longlong;

}

#[cfg(test)]
#[allow(unused_assignments)] // Unsafe functions
mod test {

    extern crate linux_api;

    use linux_api::{c_long, c_longlong};

    use super::*;

    #[test]
    fn test_rint() {

        let value = 246.246f64;

        let mut result = 0f64;

        unsafe { result = rint(value); }

        assert_eq!(246.0f64, result);
    }

    #[test]
    fn test_rintf() {

        let value = 2543637.536f32;

        let mut result = 0f32;

        unsafe { result = rintf(value); }

        assert_eq!(2543638.0f32, result);
    }

    #[test]
    fn test_nearbyint() {

        let value = 246.246f64;

        let mut result = 0f64;

        unsafe { result = nearbyint(value); }

        assert_eq!(246.0f64, result);
    }

    #[test]
    fn test_nearbyintf() {

        let value = 2543637.536f32;

        let mut result = 0f32;

        unsafe { result = nearbyintf(value); }

        assert_eq!(2543638.0f32, result);
    }

    #[test]
    fn test_lrint() {

        let value = 2464326.432f64;

        let mut result: c_long = 0;

        unsafe { result = lrint(value); }

        assert_eq!(2464326, result);

    }

    #[test]
    fn test_lrintf() {

        let value = 2464326.432f32;

        let mut result: c_long = 0;

        unsafe { result = lrintf(value); }

        assert_eq!(2464326, result);

    }

    #[test]
    fn test_llrint() {

        let value = 46873283884.432f64;

        let mut result: c_longlong = 0;

        unsafe { result = llrint(value); }

        assert_eq!(46873283884, result);

    }

    #[test]
    fn test_llrintf() {

        let value = 4687328.9732f32;

        let mut result: c_longlong = 0;

        unsafe { result = llrintf(value); }

        assert_eq!(4687329, result);

    }

}
<|endoftext|>