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

//! Error Reporting for Anonymous Region Lifetime Errors
//! where both the regions are anonymous.
use hir;
use infer::InferCtxt;
use ty::{self, Region};
use infer::region_inference::RegionResolutionError::*;
use infer::region_inference::RegionResolutionError;
use hir::map as hir_map;
use middle::resolve_lifetime as rl;
use hir::intravisit::{self, Visitor, NestedVisitorMap};

impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
    // This method prints the error message for lifetime errors when both the concerned regions
    // are anonymous.
    // Consider a case where we have
    // fn foo(x: &mut Vec<&u8>, y: &u8)
    //    { x.push(y); }.
    // The example gives
    // fn foo(x: &mut Vec<&u8>, y: &u8) {
    //                    ---      --- these references are declared with different lifetimes...
    //            x.push(y);
    //            ^ ...but data from `y` flows into `x` here
    // It has been extended for the case of structs too.
    // Consider the example
    // struct Ref<'a> { x: &'a u32 }
    // fn foo(mut x: Vec<Ref>, y: Ref) {
    //                   ---      --- these structs are declared with different lifetimes...
    //               x.push(y);
    //               ^ ...but data from `y` flows into `x` here
    // }
    // It will later be extended to trait objects.
    pub fn try_report_anon_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {
        let (span, sub, sup) = match *error {
            ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
            _ => return false, // inapplicable
        };

        // Determine whether the sub and sup consist of both anonymous (elided) regions.
        let (ty1, ty2, scope_def_id_1, scope_def_id_2, bregion1, bregion2) = if
            self.is_suitable_anonymous_region(sup, true).is_some() &&
            self.is_suitable_anonymous_region(sub, true).is_some() {
            if let (Some(anon_reg1), Some(anon_reg2)) =
                (self.is_suitable_anonymous_region(sup, true),
                 self.is_suitable_anonymous_region(sub, true)) {
                let ((def_id1, br1), (def_id2, br2)) = (anon_reg1, anon_reg2);
                let found_arg1 = self.find_anon_type(sup, &br1);
                let found_arg2 = self.find_anon_type(sub, &br2);
                match (found_arg1, found_arg2) {
                    (Some(anonarg_1), Some(anonarg_2)) => {
                        (anonarg_1, anonarg_2, def_id1, def_id2, br1, br2)
                    }
                    _ => {
                        return false;
                    }
                }

            } else {
                return false;
            }
        } else {
            return false; //inapplicable
        };

        let (label1, label2) = if let (Some(sup_arg), Some(sub_arg)) =
            (self.find_arg_with_anonymous_region(sup, sup),
             self.find_arg_with_anonymous_region(sub, sub)) {

            let ((anon_arg1, _, _, is_first1), (anon_arg2, _, _, is_first2)) = (sup_arg, sub_arg);
            if self.is_self_anon(is_first1, scope_def_id_1) ||
               self.is_self_anon(is_first2, scope_def_id_2) {
                return false;
            }

            if self.is_return_type_anon(scope_def_id_1, bregion1) ||
               self.is_return_type_anon(scope_def_id_2, bregion2) {
                return false;
            }

            if anon_arg1 == anon_arg2 {
                (format!(" with one lifetime"), format!(" into the other"))
            } else {
                let span_label_var1 = if let Some(simple_name) = anon_arg1.pat.simple_name() {
                    format!(" from `{}`", simple_name)
                } else {
                    format!("")
                };

                let span_label_var2 = if let Some(simple_name) = anon_arg2.pat.simple_name() {
                    format!(" into `{}`", simple_name)
                } else {
                    format!("")
                };

                (span_label_var1, span_label_var2)
            }
        } else {
            return false;
        };

        struct_span_err!(self.tcx.sess, span, E0623, "lifetime mismatch")
            .span_label(ty1.span,
                        format!("these two types are declared with different lifetimes..."))
            .span_label(ty2.span, format!(""))
            .span_label(span, format!("...but data{} flows{} here", label1, label2))
            .emit();
        return true;

    }

    /// This function calls the `visit_ty` method for the parameters
    /// corresponding to the anonymous regions. The `nested_visitor.found_type`
    /// contains the anonymous type.
    ///
    /// # Arguments
    ///
    /// region - the anonymous region corresponding to the anon_anon conflict
    /// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
    ///
    /// # Example
    /// ```
    /// fn foo(x: &mut Vec<&u8>, y: &u8)
    ///    { x.push(y); }
    /// ```
    /// The function returns the nested type corresponding to the anonymous region
    /// for e.g. `&u8` and Vec<`&u8`.
    pub fn find_anon_type(&self, region: Region<'tcx>, br: &ty::BoundRegion) -> Option<(&hir::Ty)> {
        if let Some(anon_reg) = self.is_suitable_anonymous_region(region, true) {
            let (def_id, _) = anon_reg;
            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
                let ret_ty = self.tcx.type_of(def_id);
                if let ty::TyFnDef(_, _) = ret_ty.sty {
                    if let hir_map::NodeItem(it) = self.tcx.hir.get(node_id) {
                        if let hir::ItemFn(ref fndecl, _, _, _, _, _) = it.node {
                            return fndecl
                                       .inputs
                                       .iter()
                                       .filter_map(|arg| {
                                                       self.find_visitor_found_type(&**arg, br)
                                                   })
                                       .next();
                        }
                    } else if let hir_map::NodeTraitItem(it) = self.tcx.hir.get(node_id) {
                        if let hir::TraitItemKind::Method(ref fndecl, _) = it.node {
                            return fndecl
                                       .decl
                                       .inputs
                                       .iter()
                                       .filter_map(|arg| {
                                                       self.find_visitor_found_type(&**arg, br)
                                                   })
                                       .next();
                        }
                    } else if let hir_map::NodeImplItem(it) = self.tcx.hir.get(node_id) {
                        if let hir::ImplItemKind::Method(ref fndecl, _) = it.node {
                            return fndecl
                                       .decl
                                       .inputs
                                       .iter()
                                       .filter_map(|arg| {
                                                       self.find_visitor_found_type(&**arg, br)
                                                   })
                                       .next();
                        }
                    }
                }
            }
        }
        None
    }

    // This method creates a FindNestedTypeVisitor which returns the type corresponding
    // to the anonymous region.
    fn find_visitor_found_type(&self,
                               arg: &'gcx hir::Ty,
                               br: &ty::BoundRegion)
                               -> Option<(&'gcx hir::Ty)> {
        let mut nested_visitor = FindNestedTypeVisitor {
            infcx: &self,
            hir_map: &self.tcx.hir,
            bound_region: *br,
            found_type: None,
            depth: 1,
        };
        nested_visitor.visit_ty(arg);
        nested_visitor.found_type
    }
}

// The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the
// anonymous region. The example above would lead to a conflict between
// the two anonymous lifetimes for &u8 in x and y respectively. This visitor
// would be invoked twice, once for each lifetime, and would
// walk the types like &mut Vec<&u8> and &u8 looking for the HIR
// where that lifetime appears. This allows us to highlight the
// specific part of the type in the error message.
struct FindNestedTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
    hir_map: &'a hir::map::Map<'gcx>,
    // The bound_region corresponding to the Refree(freeregion)
    // associated with the anonymous region we are looking for.
    bound_region: ty::BoundRegion,
    // The type where the anonymous lifetime appears
    // for e.g. Vec<`&u8`> and <`&u8`>
    found_type: Option<&'gcx hir::Ty>,
    depth: u32,
}

impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
        NestedVisitorMap::OnlyBodies(&self.hir_map)
    }

    fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
        // Find the index of the anonymous region that was part of the
        // error. We will then search the function parameters for a bound
        // region at the right depth with the same index.
        let br_index = match self.bound_region {
            ty::BrAnon(index) => index,
            _ => return,
        };

        match arg.node {

            hir::TyBareFn(ref fndecl) => {
                self.depth += 1;
                intravisit::walk_ty(self, arg);
                self.depth -= 1;
                return;
            }

            hir::TyRptr(ref lifetime, _) => {
                match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) {
                    // the lifetime of the TyRptr
                    Some(&rl::Region::LateBoundAnon(debuijn_index, anon_index)) => {
                        if debuijn_index.depth == 1 && anon_index == br_index {
                            self.found_type = Some(arg);
                            return; // we can stop visiting now
                        }
                    }
                    Some(&rl::Region::Static) |
                    Some(&rl::Region::EarlyBound(_, _)) |
                    Some(&rl::Region::LateBound(_, _)) |
                    Some(&rl::Region::Free(_, _)) |
                    None => {
                        debug!("no arg found");
                    }
                }
            }
            // Checks if it is of type `hir::TyPath` which corresponds to a struct.
            hir::TyPath(_) => {
                let subvisitor = &mut TyPathVisitor {
                                          infcx: self.infcx,
                                          found_it: false,
                                          bound_region: self.bound_region,
                                          hir_map: self.hir_map,
                                      };
                intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty,
                // this will visit only outermost type
                if subvisitor.found_it {
                    self.found_type = Some(arg);
                }
            }

            _ => {}
        }
        // walk the embedded contents: e.g., if we are visiting `Vec<&Foo>`,
        // go on to visit `&Foo`
        debug!("depth is {:?}", self.depth);
        intravisit::walk_ty(self, arg);

    }
}

// The visitor captures the corresponding `hir::Ty` of the anonymous region
// in the case of structs ie. `hir::TyPath`.
// This visitor would be invoked for each lifetime corresponding to a struct,
// and would walk the types like Vec<Ref> in the above example and Ref looking for the HIR
// where that lifetime appears. This allows us to highlight the
// specific part of the type in the error message.
struct TyPathVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
    hir_map: &'a hir::map::Map<'gcx>,
    found_it: bool,
    bound_region: ty::BoundRegion,
}

impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
        NestedVisitorMap::OnlyBodies(&self.hir_map)
    }

    fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
        let br_index = match self.bound_region {
            ty::BrAnon(index) => index,
            _ => return,
        };

        match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) {
            // the lifetime of the TyPath!
            Some(&rl::Region::LateBoundAnon(debuijn_index, anon_index)) => {
                if debuijn_index.depth == 1 && anon_index == br_index {
                    self.found_it = true;
                }
            }
            Some(&rl::Region::Static) |
            Some(&rl::Region::EarlyBound(_, _)) |
            Some(&rl::Region::LateBound(_, _)) |
            Some(&rl::Region::Free(_, _)) |
            None => {
                debug!("no arg found");
            }
        }
    }

    fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
        // ignore nested types
        //
        // If you have a type like `Foo<'a, &Ty>` we
        // are only interested in the immediate lifetimes ('a).
        //
        // Making `visit_ty` empty will ignore the `&Ty` embedded
        // inside, it will get reached by the outer visitor.
        debug!("`Ty` corresponding to a struct is {:?}", arg);
    }
}
<commit_msg>fixes<commit_after><|endoftext|>


<commit_before>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
extern crate walkdir;

extern crate libimagrt;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, SubCommand};

use libimagrt::runtime::Runtime;

fn help(cmds: Vec<String>) {
    println!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:
    "#);

    for cmd in cmds.iter() {
        println!("\t{}", cmd);
    }

    println!(r#"

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#);
}

fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    let appname = "imag";
    let version = &version!();
    let about   = "imag - the PIM suite for the commandline";
    let mut app = Runtime::get_default_cli_builder(appname, version, about);

    let commands = get_commands();

    for command in commands.iter() {
        let s = SubCommand::with_name(&command[..]);
        app = app.subcommand(s)
    }

    let app = app.arg(Arg::with_name("version")
                      .long("version")
                      .takes_value(false)
                      .required(false)
                      .multiple(false)
                      .help("Get the version of imag"))
                 .arg(Arg::with_name("versions")
                      .long("versions")
                      .takes_value(false)
                      .required(false)
                      .multiple(false)
                      .help("Get the versions of the imag commands"))
                 .arg(Arg::with_name("help")
                      .long("help")
                      .short("h")
                      .takes_value(false)
                      .required(false)
                      .multiple(false)
                      .help("Show help"));

    let matches = app.get_matches();

    if matches.is_present("help") {
        help(get_commands());
        exit(0);
    }

    if matches.is_present("version") {
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        let mut result = vec![];
        for command in commands.iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    matches.subcommand_name()
        .map(|subcommand| {

            let mut subcommand_args = vec![];

            for arg in Runtime::arg_names() {
                matches.value_of(arg)
                    .map(|value| {
                        subcommand_args.push(arg);
                        subcommand_args.push(value);
                    });
            }

            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .arg(subcommand)
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(42));
                    }
                },

                Err(e) => {
                    match e.kind() {
                        ErrorKind::NotFound => {
                            println!("No such command: 'imag-{}'", subcommand);
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1337);
                        }
                    }
                }
            }
        });
}
<commit_msg>Shrink App setup code<commit_after>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
extern crate walkdir;

extern crate libimagrt;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, SubCommand};

use libimagrt::runtime::Runtime;

fn help(cmds: Vec<String>) {
    println!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:
    "#);

    for cmd in cmds.iter() {
        println!("\t{}", cmd);
    }

    println!(r#"

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#);
}

fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    let appname  = "imag";
    let version  = &version!();
    let about    = "imag - the PIM suite for the commandline";
    let commands = get_commands();
    let r        = Runtime::get_default_cli_builder(appname, version, about);
    let matches  = commands
        .iter()
        .fold(r, |app, cmd| app.subcommand(SubCommand::with_name(cmd)))
        .arg(Arg::with_name("version")
             .long("version")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the version of imag"))
        .arg(Arg::with_name("versions")
             .long("versions")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the versions of the imag commands"))
        .arg(Arg::with_name("help")
             .long("help")
             .short("h")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Show help"))
        .get_matches();

    if matches.is_present("help") {
        help(get_commands());
        exit(0);
    }

    if matches.is_present("version") {
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        let mut result = vec![];
        for command in commands.iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    matches.subcommand_name()
        .map(|subcommand| {

            let mut subcommand_args = vec![];

            for arg in Runtime::arg_names() {
                matches.value_of(arg)
                    .map(|value| {
                        subcommand_args.push(arg);
                        subcommand_args.push(value);
                    });
            }

            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .arg(subcommand)
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(42));
                    }
                },

                Err(e) => {
                    match e.kind() {
                        ErrorKind::NotFound => {
                            println!("No such command: 'imag-{}'", subcommand);
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1337);
                        }
                    }
                }
            }
        });
}
<|endoftext|>


<commit_before><commit_msg>test drop order for locals when a future is dropped part-way through execution<commit_after>// aux-build:arc_wake.rs
// edition:2018
// run-pass

#![allow(unused_variables)]
#![deny(dead_code)]
#![feature(async_await)]

// Test that the drop order for locals in a fn and async fn matches up.
extern crate arc_wake;

use arc_wake::ArcWake;
use std::cell::RefCell;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
use std::task::{Context, Poll};

struct EmptyWaker;

impl ArcWake for EmptyWaker {
    fn wake(self: Arc<Self>) {}
}

#[derive(Debug, Eq, PartialEq)]
enum DropOrder {
    Function,
    Val(&'static str),
}

type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;

struct D(&'static str, DropOrderListPtr);

impl Drop for D {
    fn drop(&mut self) {
        self.1.borrow_mut().push(DropOrder::Val(self.0));
    }
}

struct NeverReady;

impl Future for NeverReady {
    type Output = ();
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        Poll::Pending
    }
}

async fn simple_variable_declaration_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    NeverReady.await;
}

fn simple_variable_declaration_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
}

async fn varable_completely_contained_within_block_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    async {
        let x = D("x", l.clone());
    }
        .await;
    let y = D("y", l.clone());
    NeverReady.await;
}

fn varable_completely_contained_within_block_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    {
        let x = D("x", l.clone());
    }
    let y = D("y", l.clone());
}

async fn variables_moved_into_separate_blocks_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    async move { x }.await;
    async move { y }.await;
    NeverReady.await;
}

fn variables_moved_into_separate_blocks_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    {
        x
    };
    {
        y
    };
}

async fn variables_moved_into_same_block_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    async move {
        x;
        y;
    };
    NeverReady.await;
}

fn variables_moved_into_same_block_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    {
        x;
        y;
    };
    return;
}

async fn move_after_current_await_doesnt_affect_order(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    NeverReady.await;
    async move {
        x;
        y;
    };
}

fn assert_drop_order_after_cancel<Fut: Future<Output = ()>>(
    f: impl FnOnce(DropOrderListPtr) -> Fut,
    g: impl FnOnce(DropOrderListPtr),
) {
    let empty = Arc::new(EmptyWaker);
    let waker = ArcWake::into_waker(empty);
    let mut cx = Context::from_waker(&waker);

    let actual_order = Rc::new(RefCell::new(Vec::new()));
    let mut fut = Box::pin(f(actual_order.clone()));
    let _ = fut.as_mut().poll(&mut cx);
    drop(fut);

    let expected_order = Rc::new(RefCell::new(Vec::new()));
    g(expected_order.clone());
    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
}

fn main() {
    assert_drop_order_after_cancel(
        simple_variable_declaration_async,
        simple_variable_declaration_sync,
    );
    assert_drop_order_after_cancel(
        varable_completely_contained_within_block_async,
        varable_completely_contained_within_block_sync,
    );
    assert_drop_order_after_cancel(
        variables_moved_into_separate_blocks_async,
        variables_moved_into_separate_blocks_sync,
    );
    assert_drop_order_after_cancel(
        variables_moved_into_same_block_async,
        variables_moved_into_same_block_sync,
    );
    assert_drop_order_after_cancel(
        move_after_current_await_doesnt_affect_order,
        simple_variable_declaration_sync,
    );
}
<|endoftext|>


<commit_before><commit_msg>Add possibility to set metadata path<commit_after><|endoftext|>


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

// Test that diagnostic macros are gated by `rustc_diagnostic_macros` feature
// gate

__register_diagnostic!(E0001);
//~^ ERROR macro undefined: '__register_diagnostic!'

fn main() {
    __diagnostic_used!(E0001);
    //~^ ERROR macro undefined: '__diagnostic_used!'
}

__build_diagnostic_array!(DIAGNOSTICS);
//~^ ERROR macro undefined: '__build_diagnostic_array!'
<|endoftext|>


<commit_before><commit_msg>Add a Test for actual split files<commit_after>extern crate livesplit_core;

use livesplit_core::{Time, TimeSpan};
use livesplit_core::comparison::balanced_pb::{BalancedPB, NAME};
use std::fs::File;
use std::io::BufReader;
use livesplit_core::run::parser::livesplit;

fn r(t: Time) -> Time {
    Time::new()
        .with_real_time(
            t.real_time
                .map(|t| TimeSpan::from_seconds(t.total_seconds().floor())),
        )
        .with_game_time(
            t.game_time
                .map(|t| TimeSpan::from_seconds(t.total_seconds().floor())),
        )
}

fn t(r: &str, g: &str) -> Time {
    Time::new()
        .with_real_time(r.parse().ok())
        .with_game_time(g.parse().ok())
}

#[test]
fn balanced_pb() {
    let reader = BufReader::new(File::open("tests/run_files/livesplit1.6_gametime.lss").unwrap());
    let mut run = livesplit::parse(reader, None).unwrap();
    run.comparison_generators_mut().clear();
    run.comparison_generators_mut().push(Box::new(BalancedPB));
    run.regenerate_comparisons();
    let s = run.segments();

    assert_eq!(r(s[0].comparison(NAME)), t("3:11", "3:11"));
    assert_eq!(r(s[1].comparison(NAME)), t("4:24", "4:21"));
    assert_eq!(r(s[2].comparison(NAME)), t("6:38", "6:31"));
    assert_eq!(r(s[3].comparison(NAME)), t("10:34", "10:13"));
    assert_eq!(r(s[4].comparison(NAME)), t("13:05", "12:34"));
    assert_eq!(r(s[5].comparison(NAME)), t("15:02", "14:21"));
    assert_eq!(r(s[6].comparison(NAME)), t("17:50", "16:56"));
    assert_eq!(r(s[7].comparison(NAME)), t("22:42", "21:30"));
    assert_eq!(r(s[8].comparison(NAME)), t("26:20", "24:47"));
    assert_eq!(r(s[9].comparison(NAME)), t("30:24", "28:37"));
    assert_eq!(r(s[10].comparison(NAME)), t("36:51", "34:39"));
    assert_eq!(r(s[11].comparison(NAME)), t("37:56", "35:39"));
    assert_eq!(r(s[12].comparison(NAME)), t("40:01", "37:37"));
}
<|endoftext|>


<commit_before><commit_msg>22 - aliasing<commit_after>struct Point { x: int, y: int, z: int }

fn main() {
    let mut point = Point { x: 0, y: 0, z: 0 };

    {
        let borrowed_point = &point;
        let another_borrow = &point;

        // Data can be accessed via the references and the original owner
        println!("Point has coordinates: ({}, {}, {})",
                 borrowed_point.x, another_borrow.y, point.z);

        // Error! Can't borrow point as mutable because it's currently
        // borrowed as immutable
        //let mutable_borrow = &mut point;
        // TODO ^ Try uncommenting this line

        // Immutable references go out of scope
    }

    {
        let mutable_borrow = &mut point;

        // Change data via mutable reference
        mutable_borrow.x = 5;

        // Error! Can't borrow `point` as immutable because it's currently
        // borrowed as mutable
        //let y = &point.y;
        // TODO ^ Try uncommenting this line

        // Error! Can't print, because println! takes an immutable reference
        //println!("Point Z coordinate is {}", point.z);
        // TODO ^ Try uncommenting this line

        // Mutable reference goes out of scope
    }

    // Immutable references to point are allowed again
    println!("Point now has coordinates: ({}, {}, {})",
             point.x, point.y, point.z);
}
<|endoftext|>


<commit_before><commit_msg>Test for householder<commit_after>use ndarray::*;
use ndarray_linalg::{krylov::*, *};

fn over<A: Scalar + Lapack>(rtol: A::Real) {
    const N: usize = 4;
    let a: Array2<A> = random((N, N * 2));

    // Terminate
    let (q, r) = householder(a.axis_iter(Axis(1)), N, rtol, Strategy::Terminate);
    let a_sub = a.slice(s![.., 0..N]);
    let qc: Array2<A> = conjugate(&q);
    assert_close_l2!(&qc.dot(&q), &Array::eye(N), rtol; "Check Q^H Q = I");
    assert_close_l2!(&q.dot(&r), &a_sub, rtol; "Check A = QR");

    // Skip
    let (q, r) = householder(a.axis_iter(Axis(1)), N, rtol, Strategy::Skip);
    let a_sub = a.slice(s![.., 0..N]);
    let qc: Array2<A> = conjugate(&q);
    assert_close_l2!(&qc.dot(&q), &Array::eye(N), rtol);
    assert_close_l2!(&q.dot(&r), &a_sub, rtol);

    // Full
    let (q, r) = householder(a.axis_iter(Axis(1)), N, rtol, Strategy::Full);
    let qc: Array2<A> = conjugate(&q);
    assert_close_l2!(&qc.dot(&q), &Array::eye(N), rtol);
    assert_close_l2!(&q.dot(&r), &a, rtol);
}

#[test]
fn over_f32() {
    over::<f32>(1e-5);
}
#[test]
fn over_f64() {
    over::<f64>(1e-9);
}
#[test]
fn over_c32() {
    over::<c32>(1e-5);
}
#[test]
fn over_c64() {
    over::<c64>(1e-9);
}

fn full<A: Scalar + Lapack>(rtol: A::Real) {
    const N: usize = 5;
    let a: Array2<A> = random((N, N));
    let (q, r) = householder(a.axis_iter(Axis(1)), N, rtol, Strategy::Terminate);
    let qc: Array2<A> = conjugate(&q);
    assert_close_l2!(&qc.dot(&q), &Array::eye(N), rtol; "Check Q^H Q = I");
    assert_close_l2!(&q.dot(&r), &a, rtol; "Check A = QR");
}

#[test]
fn full_f32() {
    full::<f32>(1e-5);
}
#[test]
fn full_f64() {
    full::<f64>(1e-9);
}
#[test]
fn full_c32() {
    full::<c32>(1e-5);
}
#[test]
fn full_c64() {
    full::<c64>(1e-9);
}

fn half<A: Scalar + Lapack>(rtol: A::Real) {
    const N: usize = 4;
    let a: Array2<A> = random((N, N / 2));
    let (q, r) = householder(a.axis_iter(Axis(1)), N, rtol, Strategy::Terminate);
    let qc: Array2<A> = conjugate(&q);
    assert_close_l2!(&qc.dot(&q), &Array::eye(N / 2), rtol; "Check Q^H Q = I");
    assert_close_l2!(&q.dot(&r), &a, rtol; "Check A = QR");
}

#[test]
fn half_f32() {
    half::<f32>(1e-5);
}
#[test]
fn half_f64() {
    half::<f64>(1e-9);
}
#[test]
fn half_c32() {
    half::<c32>(1e-5);
}
#[test]
fn half_c64() {
    half::<c64>(1e-9);
}
<|endoftext|>


<commit_before><commit_msg>Add test for loading effects.<commit_after>//! Test loading of effect definitions from the disk.

extern crate libfriendship;
extern crate digest;
extern crate serde_json;
extern crate sha2;
extern crate tempdir;
extern crate url;

use std::fs::File;
use std::sync::mpsc::{channel, Receiver, Sender};

use digest::digest_reader;
use sha2::Sha256;
use tempdir::TempDir;
use url::Url;

use libfriendship::{Dispatch, Client};
use libfriendship::dispatch::{OscRouteGraph, OscRenderer, OscResMan};
use libfriendship::render::RefRenderer;
use libfriendship::routing::{adjlist, NodeHandle, DagHandle, Edge, EdgeWeight, EffectMeta, EffectDesc};
use libfriendship::routing::AdjList;

struct MyClient {
    /// Where to send the rendered audio.
    tx: Sender<Vec<f32>>,
}
impl Client for MyClient {
    fn audio_rendered(&mut self, buffer: &[f32], _idx: u64, _num_ch: u8) {
        self.tx.send(buffer.iter().cloned().collect()).unwrap();
    }
}

fn test_setup() -> (Dispatch<RefRenderer>, Receiver<Vec<f32>>) {
    let (tx, rx) = channel();
    let client = Box::new(MyClient{ tx });
    let mut dispatch: Dispatch<RefRenderer> = Dispatch::new();
    dispatch.register_client(client);
    (dispatch, rx)
}

fn create_multby2() -> EffectDesc {
    let mult_hnd = NodeHandle::new_node(DagHandle::toplevel(), 1);
    let mult_data = adjlist::NodeData::Effect(
        EffectMeta::new("Multiply".to_string(), None, [Url::parse("primitive:///Multiply").unwrap()].iter().cloned())
    );
    let const_hnd = NodeHandle::new_node(DagHandle::toplevel(), 2);
    let const_data = adjlist::NodeData::Effect(
        EffectMeta::new("Constant".to_string(), None, [Url::parse("primitive:///Constant?value=5").unwrap()].iter().cloned())
    );

    let nodes = [(mult_hnd, mult_data), (const_hnd, const_data)];

    let edge_in = Edge::new_from_null(mult_hnd, EdgeWeight::new(0, 0, 0, 0));
    let edge_out = Edge::new_to_null(mult_hnd, EdgeWeight::new(1, 0, 1, 0));
    let edge_const = Edge::new(const_hnd, mult_hnd, EdgeWeight::new(1, 0, 2, 0)).unwrap();

    let edges = [edge_in, edge_out, edge_const];

    let list = AdjList {
        nodes: nodes.iter().cloned().collect(),
        edges: edges.iter().cloned().collect(),
    };
    let meta = EffectMeta::new("MulBy2".to_string(), None, Vec::new().into_iter());
    EffectDesc::new(meta, list)
}

#[test]
fn load_multby2() {
    let (mut dispatch, rx) = test_setup();
    let dir = TempDir::new("libfriendship").unwrap();
    let mulby2_desc = create_multby2();

    // Add the temp dir as a search dir
    dispatch.dispatch(
        OscResMan::AddDir((), (dir.path().to_str().unwrap().to_string(),)).into()
    ).unwrap();

    // Write the effect definition to file
    let mulby2_path = dir.path().join("mulby2.fnd");
    let mulby2_file = File::create(mulby2_path.clone()).unwrap();
    serde_json::to_writer(mulby2_file, &mulby2_desc).unwrap();

    // Determine the hash of our file
    let mut mulby2_file = File::open(mulby2_path).unwrap();
    let hash_result = digest_reader::<Sha256>(&mut mulby2_file).unwrap();
    let mut sha: [u8; 32] = Default::default();
    sha.copy_from_slice(hash_result.as_slice());

    // Create the MulBy2 node (id=1)
    let mul_hnd = NodeHandle::new_node(DagHandle::toplevel(), 1);
    dispatch.dispatch(OscRouteGraph::AddNode((), (mul_hnd, adjlist::NodeData::Effect(
        EffectMeta::new("MulBy2".to_string(), Some(sha), [].iter().cloned())
    ))).into()).unwrap();
    // Connect MulBy2 output to master output.
    dispatch.dispatch(OscRouteGraph::AddEdge((), (Edge::new_to_null(mul_hnd, EdgeWeight::new(1, 0, 0, 0)),)).into()).unwrap();

    // Create Constant node (id=2)
    let const_hnd = NodeHandle::new_node(DagHandle::toplevel(), 2);
    dispatch.dispatch(OscRouteGraph::AddNode((), (const_hnd, adjlist::NodeData::Effect(
        EffectMeta::new("Constant".to_string(), None, [Url::parse("primitive:///Constant?value=0.5").unwrap()].iter().cloned())
    ))).into()).unwrap();
    // Route constant output to mul input
    dispatch.dispatch(OscRouteGraph::AddEdge((), (Edge::new(const_hnd, mul_hnd, EdgeWeight::new(1, 0, 0, 0)).unwrap(),)).into()).unwrap();

    // Read some data from ch=0.
    // This should be 0.5*5 = [2.5, 2.5, 2.5, 2.5]
    dispatch.dispatch(
        OscRenderer::RenderRange((), (0, 4, 1))
    .into()).unwrap();
    let rendered = rx.recv().unwrap();
    assert_eq!(rendered, vec![2.5f32, 2.5f32, 2.5f32, 2.5f32]);
}

<|endoftext|>


<commit_before><commit_msg>Fix menu example<commit_after><|endoftext|>


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

use dom::bindings::codegen::Bindings::FormDataBinding;
use dom::bindings::codegen::Bindings::FormDataBinding::FormDataMethods;
use dom::bindings::codegen::InheritTypes::FileCast;
use dom::bindings::codegen::UnionTypes::FileOrString::{FileOrString, eFile, eString};
use dom::bindings::error::{Fallible};
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::trace::Traceable;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::blob::Blob;
use dom::file::File;
use dom::htmlformelement::HTMLFormElement;
use servo_util::str::DOMString;
use std::cell::RefCell;
use std::collections::hashmap::HashMap;

#[deriving(Clone)]
#[jstraceable]
#[must_root]
pub enum FormDatum {
    StringData(DOMString),
    FileData(JS<File>)
}

#[jstraceable]
#[must_root]
pub struct FormData {
    data: Traceable<RefCell<HashMap<DOMString, Vec<FormDatum>>>>,
    reflector_: Reflector,
    global: GlobalField,
    form: Option<JS<HTMLFormElement>>
}

impl FormData {
    fn new_inherited(form: Option<JSRef<HTMLFormElement>>, global: &GlobalRef) -> FormData {
        FormData {
            data: Traceable::new(RefCell::new(HashMap::new())),
            reflector_: Reflector::new(),
            global: GlobalField::from_rooted(global),
            form: form.map(|f| JS::from_rooted(f)),
        }
    }

    pub fn new(form: Option<JSRef<HTMLFormElement>>, global: &GlobalRef) -> Temporary<FormData> {
        reflect_dom_object(box FormData::new_inherited(form, global),
                           global, FormDataBinding::Wrap)
    }

    pub fn Constructor(global: &GlobalRef, form: Option<JSRef<HTMLFormElement>>) -> Fallible<Temporary<FormData>> {
        Ok(FormData::new(form, global))
    }
}

impl<'a> FormDataMethods for JSRef<'a, FormData> {
    #[allow(unrooted_must_root)]
    fn Append(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
        let file = FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
        self.data.deref().borrow_mut().insert_or_update_with(name.clone(), vec!(file.clone()),
                                        |_k, v| {v.push(file.clone());});
    }

    fn Append_(self, name: DOMString, value: DOMString) {
        self.data.deref().borrow_mut().insert_or_update_with(name, vec!(StringData(value.clone())),
                                        |_k, v| {v.push(StringData(value.clone()));});
    }

    fn Delete(self, name: DOMString) {
        self.data.deref().borrow_mut().remove(&name);
    }

    fn Get(self, name: DOMString) -> Option<FileOrString> {
        if self.data.deref().borrow().contains_key_equiv(&name) {
            match (*self.data.deref().borrow())[name][0].clone() {
                StringData(ref s) => Some(eString(s.clone())),
                FileData(ref f) => {
                    Some(eFile(f.clone()))
                }
            }
        } else {
            None
        }
    }

    fn Has(self, name: DOMString) -> bool {
        self.data.deref().borrow().contains_key_equiv(&name)
    }
    #[allow(unrooted_must_root)]
    fn Set(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
        let file = FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
        self.data.deref().borrow_mut().insert(name, vec!(file));
    }

    fn Set_(self, name: DOMString, value: DOMString) {
        self.data.deref().borrow_mut().insert(name, vec!(StringData(value)));
    }
}

impl Reflectable for FormData {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }
}

trait PrivateFormDataHelpers{
  fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File>;
}

impl PrivateFormDataHelpers for FormData {
    fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File> {
        let global = self.global.root();
        let f: Option<JSRef<File>> = FileCast::to_ref(value);
        let name = filename.unwrap_or(f.map(|inner| inner.name.clone()).unwrap_or("blob".to_string()));
        File::new(&global.root_ref(), value, name)
    }
}
<commit_msg>Remove Traceable from formdata.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::FormDataBinding;
use dom::bindings::codegen::Bindings::FormDataBinding::FormDataMethods;
use dom::bindings::codegen::InheritTypes::FileCast;
use dom::bindings::codegen::UnionTypes::FileOrString::{FileOrString, eFile, eString};
use dom::bindings::error::{Fallible};
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::blob::Blob;
use dom::file::File;
use dom::htmlformelement::HTMLFormElement;
use servo_util::str::DOMString;
use std::cell::RefCell;
use std::collections::hashmap::HashMap;

#[deriving(Clone)]
#[jstraceable]
#[must_root]
pub enum FormDatum {
    StringData(DOMString),
    FileData(JS<File>)
}

#[jstraceable]
#[must_root]
pub struct FormData {
    data: RefCell<HashMap<DOMString, Vec<FormDatum>>>,
    reflector_: Reflector,
    global: GlobalField,
    form: Option<JS<HTMLFormElement>>
}

impl FormData {
    fn new_inherited(form: Option<JSRef<HTMLFormElement>>, global: &GlobalRef) -> FormData {
        FormData {
            data: RefCell::new(HashMap::new()),
            reflector_: Reflector::new(),
            global: GlobalField::from_rooted(global),
            form: form.map(|f| JS::from_rooted(f)),
        }
    }

    pub fn new(form: Option<JSRef<HTMLFormElement>>, global: &GlobalRef) -> Temporary<FormData> {
        reflect_dom_object(box FormData::new_inherited(form, global),
                           global, FormDataBinding::Wrap)
    }

    pub fn Constructor(global: &GlobalRef, form: Option<JSRef<HTMLFormElement>>) -> Fallible<Temporary<FormData>> {
        Ok(FormData::new(form, global))
    }
}

impl<'a> FormDataMethods for JSRef<'a, FormData> {
    #[allow(unrooted_must_root)]
    fn Append(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
        let file = FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
        self.data.borrow_mut().insert_or_update_with(name.clone(), vec!(file.clone()),
                                        |_k, v| {v.push(file.clone());});
    }

    fn Append_(self, name: DOMString, value: DOMString) {
        self.data.borrow_mut().insert_or_update_with(name, vec!(StringData(value.clone())),
                                        |_k, v| {v.push(StringData(value.clone()));});
    }

    fn Delete(self, name: DOMString) {
        self.data.borrow_mut().remove(&name);
    }

    fn Get(self, name: DOMString) -> Option<FileOrString> {
        if self.data.borrow().contains_key_equiv(&name) {
            match (*self.data.borrow())[name][0].clone() {
                StringData(ref s) => Some(eString(s.clone())),
                FileData(ref f) => {
                    Some(eFile(f.clone()))
                }
            }
        } else {
            None
        }
    }

    fn Has(self, name: DOMString) -> bool {
        self.data.borrow().contains_key_equiv(&name)
    }
    #[allow(unrooted_must_root)]
    fn Set(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
        let file = FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
        self.data.borrow_mut().insert(name, vec!(file));
    }

    fn Set_(self, name: DOMString, value: DOMString) {
        self.data.borrow_mut().insert(name, vec!(StringData(value)));
    }
}

impl Reflectable for FormData {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }
}

trait PrivateFormDataHelpers{
  fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File>;
}

impl PrivateFormDataHelpers for FormData {
    fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File> {
        let global = self.global.root();
        let f: Option<JSRef<File>> = FileCast::to_ref(value);
        let name = filename.unwrap_or(f.map(|inner| inner.name.clone()).unwrap_or("blob".to_string()));
        File::new(&global.root_ref(), value, name)
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: gap buffer<commit_after><|endoftext|>


<commit_before>use std::path::PathBuf;

use git2::{Index, Repository};
use toml::Value;

use libimagerror::into::IntoError;
use libimagerror::trace::MapErrTrace;
use libimagstore::hook::error::CustomData;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;
use libimagutil::debug_result::*;

use vcs::git::action::StoreAction;
use vcs::git::result::Result;
use vcs::git::error::{MapErrInto, GitHookErrorKind as GHEK};

/// Runtime object for git hook implementations.
///
/// Contains some utility functionality to hold the repository and the configuration for the hooks.
pub struct Runtime {
    repository: Option<Repository>,
    config: Option<Value>,
}

impl Runtime {

    /// Build a `Runtime` object, pass the store path to build the `Repository` instance the
    /// `Runtime` has to contain.
    ///
    /// If the building of the `Repository` fails, this function `trace_error()`s the error and
    /// returns a `Runtime` object that does _not_ contain a `Repository`.
    pub fn new(storepath: &PathBuf) -> Runtime {
        Runtime {
            repository: Repository::open(storepath).map_err_trace().ok(),
            config: None,
        }
    }

    /// Set the configuration for the `Runtime`. Always returns `Ok(())`.
    pub fn set_config(&mut self, cfg: &Value) -> Result<()> {
        self.config = Some(cfg.clone());
        Ok(())
    }

    /// Check whether the `Runtime` has a `Repository`
    pub fn has_repository(&self) -> bool {
        self.repository.is_some()
    }

    /// Check whether the `Runtime` has a configuration
    pub fn has_config(&self) -> bool {
        self.config.is_some()
    }

    /// Get the the config value by reference or get an `Err()` which can be returned to the callee
    /// of the Hook.
    ///
    /// The `action` Argument is required in case of `Err()` so the error message can be build
    /// correctly.
    pub fn config_value_or_err(&self, action: &StoreAction) -> HookResult<&Value> {
        self.config
            .as_ref()
            .ok_or(GHEK::NoConfigError.into_error())
            .map_err_into(GHEK::ConfigError)
            .map_err(Box::new)
            .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e))
            .map_err(|e| e.with_custom_data(CustomData::default().aborting(false)))
            .map_dbg_err(|_| {
                format!("[GIT {} HOOK]: Couldn't get Value object from config", action.uppercase())
            })
    }

    /// Get the `Repository` object from the `Runtime` or an `Err()` that can be returned to the
    /// callee of the Hook.
    ///
    /// The `action` Argument is required in case of `Err()` so the error message can be build
    /// correctly.
    pub fn repository(&self, action: &StoreAction) -> HookResult<&Repository> {
        use vcs::git::error::MapIntoHookError;

        debug!("[GIT {} HOOK]: Getting repository", action.uppercase());
        self.repository
            .as_ref()
            .ok_or(GHEK::MkRepo.into_error())
            .map_err_into(GHEK::RepositoryError)
            .map_into_hook_error()
            .map_dbg_err(|_| format!("[GIT {} HOOK]: Couldn't fetch Repository", action.uppercase()))
            .map_dbg(|_| format!("[GIT {} HOOK]: Repository object fetched", action.uppercase()))
    }

    /// Ensure that the branch that is put in the configuration file is checked out, if any.
    pub fn ensure_cfg_branch_is_checked_out(&self, action: &StoreAction) -> HookResult<()> {
        use vcs::git::config::ensure_branch;
        use vcs::git::config::do_checkout_ensure_branch;

        debug!("[GIT {} HOOK]: Ensuring branch checkout", action.uppercase());
        let head = try!(self
                        .repository(action)
                        .and_then(|r| {
                            debug!("[GIT {} HOOK]: Repository fetched, getting head", action.uppercase());
                            r.head()
                                .map_dbg_err_str("Couldn't fetch HEAD")
                                .map_dbg_err(|e| format!("\tbecause = {:?}", e))
                                .map_err_into(GHEK::HeadFetchError)
                                .map_err(|e| e.into())
                        }));
        debug!("[GIT {} HOOK]: HEAD fetched", action.uppercase());

        // TODO: Fail if not on branch? hmmh... I'm not sure
        if !head.is_branch() {
            debug!("[GIT {} HOOK]: HEAD is not a branch", action.uppercase());
            return Err(GHEK::NotOnBranch.into_error().into());
        }
        debug!("[GIT {} HOOK]: HEAD is a branch", action.uppercase());

        // Check out appropriate branch ... or fail
        match ensure_branch(self.config.as_ref()) {
            Ok(Some(s)) => {
                debug!("[GIT {} HOOK]: We have to ensure branch: {}", action.uppercase(), s);
                match head.name().map(|name| {
                    debug!("[GIT {} HOOK]: {} == {}", action.uppercase(), name, s);
                    name == s
                }) {
                    Some(b) => {
                        if b {
                            debug!("[GIT {} HOOK]: Branch already checked out.", action.uppercase());
                            Ok(())
                        } else {
                            debug!("[GIT {} HOOK]: Branch not checked out.", action.uppercase());

                            if !do_checkout_ensure_branch(self.config.as_ref()) {
                                Err(GHEK::RepositoryWrongBranchError.into_error())
                                    .map_err_into(GHEK::RepositoryError)
                            } else {
                                // Else try to check out the branch...
                                unimplemented!()
                            }
                        }
                    },

                    None => Err(GHEK::RepositoryBranchNameFetchingError.into_error())
                        .map_err_into(GHEK::RepositoryBranchError)
                        .map_err_into(GHEK::RepositoryError),
                }
            },
            Ok(None) => {
                debug!("[GIT {} HOOK]: No branch to checkout", action.uppercase());
                Ok(())
            },

            Err(e) => Err(e).map_err_into(GHEK::RepositoryError),
        }
        .map_err(Box::new)
        .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e))
        .map_dbg(|_| format!("[GIT {} HOOK]: Branch checked out", action.uppercase()))
    }

    /// Check whether the WD is "dirty" - whether there is a diff to the repository
    /// This function returns false if there is no `Repository` object in the `Runtime`
    pub fn repo_is_dirty(&self, index: &Index) -> bool {
        match self.repository.as_ref() {
            Some(repo) => {
                repo.diff_index_to_workdir(Some(index), None)
                    .map_dbg_str("Fetched diff: Index <-> WD")
                    .map_dbg_err_str("Failed to fetch diff: Index <-> WD")
                    .map(|diff| diff.deltas().count() != 0)
                    .unwrap_or(false)
            },

            None => {
                debug!("No repository: Cannot fetch diff: Index <-> WD");
                false
            }
        }

    }

}

<commit_msg>Revert "Add helper fn to check whether the repository WD is dirty"<commit_after>use std::path::PathBuf;

use git2::Repository;
use toml::Value;

use libimagerror::into::IntoError;
use libimagerror::trace::MapErrTrace;
use libimagstore::hook::error::CustomData;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;
use libimagutil::debug_result::*;

use vcs::git::action::StoreAction;
use vcs::git::result::Result;
use vcs::git::error::{MapErrInto, GitHookErrorKind as GHEK};

/// Runtime object for git hook implementations.
///
/// Contains some utility functionality to hold the repository and the configuration for the hooks.
pub struct Runtime {
    repository: Option<Repository>,
    config: Option<Value>,
}

impl Runtime {

    /// Build a `Runtime` object, pass the store path to build the `Repository` instance the
    /// `Runtime` has to contain.
    ///
    /// If the building of the `Repository` fails, this function `trace_error()`s the error and
    /// returns a `Runtime` object that does _not_ contain a `Repository`.
    pub fn new(storepath: &PathBuf) -> Runtime {
        Runtime {
            repository: Repository::open(storepath).map_err_trace().ok(),
            config: None,
        }
    }

    /// Set the configuration for the `Runtime`. Always returns `Ok(())`.
    pub fn set_config(&mut self, cfg: &Value) -> Result<()> {
        self.config = Some(cfg.clone());
        Ok(())
    }

    /// Check whether the `Runtime` has a `Repository`
    pub fn has_repository(&self) -> bool {
        self.repository.is_some()
    }

    /// Check whether the `Runtime` has a configuration
    pub fn has_config(&self) -> bool {
        self.config.is_some()
    }

    /// Get the the config value by reference or get an `Err()` which can be returned to the callee
    /// of the Hook.
    ///
    /// The `action` Argument is required in case of `Err()` so the error message can be build
    /// correctly.
    pub fn config_value_or_err(&self, action: &StoreAction) -> HookResult<&Value> {
        self.config
            .as_ref()
            .ok_or(GHEK::NoConfigError.into_error())
            .map_err_into(GHEK::ConfigError)
            .map_err(Box::new)
            .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e))
            .map_err(|e| e.with_custom_data(CustomData::default().aborting(false)))
            .map_dbg_err(|_| {
                format!("[GIT {} HOOK]: Couldn't get Value object from config", action.uppercase())
            })
    }

    /// Get the `Repository` object from the `Runtime` or an `Err()` that can be returned to the
    /// callee of the Hook.
    ///
    /// The `action` Argument is required in case of `Err()` so the error message can be build
    /// correctly.
    pub fn repository(&self, action: &StoreAction) -> HookResult<&Repository> {
        use vcs::git::error::MapIntoHookError;

        debug!("[GIT {} HOOK]: Getting repository", action.uppercase());
        self.repository
            .as_ref()
            .ok_or(GHEK::MkRepo.into_error())
            .map_err_into(GHEK::RepositoryError)
            .map_into_hook_error()
            .map_dbg_err(|_| format!("[GIT {} HOOK]: Couldn't fetch Repository", action.uppercase()))
            .map_dbg(|_| format!("[GIT {} HOOK]: Repository object fetched", action.uppercase()))
    }

    /// Ensure that the branch that is put in the configuration file is checked out, if any.
    pub fn ensure_cfg_branch_is_checked_out(&self, action: &StoreAction) -> HookResult<()> {
        use vcs::git::config::ensure_branch;
        use vcs::git::config::do_checkout_ensure_branch;

        debug!("[GIT {} HOOK]: Ensuring branch checkout", action.uppercase());
        let head = try!(self
                        .repository(action)
                        .and_then(|r| {
                            debug!("[GIT {} HOOK]: Repository fetched, getting head", action.uppercase());
                            r.head()
                                .map_dbg_err_str("Couldn't fetch HEAD")
                                .map_dbg_err(|e| format!("\tbecause = {:?}", e))
                                .map_err_into(GHEK::HeadFetchError)
                                .map_err(|e| e.into())
                        }));
        debug!("[GIT {} HOOK]: HEAD fetched", action.uppercase());

        // TODO: Fail if not on branch? hmmh... I'm not sure
        if !head.is_branch() {
            debug!("[GIT {} HOOK]: HEAD is not a branch", action.uppercase());
            return Err(GHEK::NotOnBranch.into_error().into());
        }
        debug!("[GIT {} HOOK]: HEAD is a branch", action.uppercase());

        // Check out appropriate branch ... or fail
        match ensure_branch(self.config.as_ref()) {
            Ok(Some(s)) => {
                debug!("[GIT {} HOOK]: We have to ensure branch: {}", action.uppercase(), s);
                match head.name().map(|name| {
                    debug!("[GIT {} HOOK]: {} == {}", action.uppercase(), name, s);
                    name == s
                }) {
                    Some(b) => {
                        if b {
                            debug!("[GIT {} HOOK]: Branch already checked out.", action.uppercase());
                            Ok(())
                        } else {
                            debug!("[GIT {} HOOK]: Branch not checked out.", action.uppercase());

                            if !do_checkout_ensure_branch(self.config.as_ref()) {
                                Err(GHEK::RepositoryWrongBranchError.into_error())
                                    .map_err_into(GHEK::RepositoryError)
                            } else {
                                // Else try to check out the branch...
                                unimplemented!()
                            }
                        }
                    },

                    None => Err(GHEK::RepositoryBranchNameFetchingError.into_error())
                        .map_err_into(GHEK::RepositoryBranchError)
                        .map_err_into(GHEK::RepositoryError),
                }
            },
            Ok(None) => {
                debug!("[GIT {} HOOK]: No branch to checkout", action.uppercase());
                Ok(())
            },

            Err(e) => Err(e).map_err_into(GHEK::RepositoryError),
        }
        .map_err(Box::new)
        .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e))
        .map_dbg(|_| format!("[GIT {} HOOK]: Branch checked out", action.uppercase()))
    }

}

<|endoftext|>


<commit_before>use std::path::PathBuf;

use git2::{Repository, Signature};

use libimagerror::into::IntoError;
use libimagerror::trace::trace_error;

use vcs::git::result::Result;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::config::{author_name, author_mail, committer_name, committer_mail};

struct Person<'a> {
    pub name: &'a str,
    pub mail: &'a str,
}

impl<'a> Person<'a> {
    fn new(name: &'a str, mail: &'a str) -> Person<'a> {
        Person { name: name, mail: mail }
    }
}

struct Runtime<'a> {
    pub repository: Option<Repository>,
    pub author: Option<Person<'a>>,
    pub committer: Option<Person<'a>>,
}

impl<'a> Runtime<'a> {

    pub fn new(storepath: &PathBuf) -> Runtime<'a> {
        Runtime {
            repository: match Repository::open(storepath) {
                Ok(r) => Some(r),
                Err(e) => {
                    trace_error(&e);
                    None
                },
            },

            author: None,
            committer: None,
        }
    }

    pub fn configure(&mut self, config: &Value) -> Result<()> {
        author_name(cfg)
            .and_then(|n| author_email(cfg).map(|m| Person::new(n, m)))
            .and_then(|author| {
                committer_name(cfg)
                    .and_then(|n| committer_email(cfg).map(|m| (author, Person::new(n, m))))
            })
            .map(|(author, committer)| {
                self.author = Some(author);
                self.committer = Some(committer);
            })
    }

    pub fn new_committer_sig(&self) -> Option<Result<Signature>> {
        self.committer
            .as_ref()
            .map(|c| {
                Signature::now(c.name, c.mail)
                    .map_err(|e| GHEK::MkSignature.into_error_with_cause(Box::new(e)))
            })
    }

}

<commit_msg>Add Runtime::repository()<commit_after>use std::path::PathBuf;

use git2::{Repository, Signature};

use libimagerror::into::IntoError;
use libimagerror::trace::trace_error;

use vcs::git::result::Result;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::config::{author_name, author_mail, committer_name, committer_mail};

struct Person<'a> {
    pub name: &'a str,
    pub mail: &'a str,
}

impl<'a> Person<'a> {
    fn new(name: &'a str, mail: &'a str) -> Person<'a> {
        Person { name: name, mail: mail }
    }
}

struct Runtime<'a> {
    pub repository: Option<Repository>,
    pub author: Option<Person<'a>>,
    pub committer: Option<Person<'a>>,
}

impl<'a> Runtime<'a> {

    pub fn new(storepath: &PathBuf) -> Runtime<'a> {
        Runtime {
            repository: match Repository::open(storepath) {
                Ok(r) => Some(r),
                Err(e) => {
                    trace_error(&e);
                    None
                },
            },

            author: None,
            committer: None,
        }
    }

    pub fn configure(&mut self, config: &Value) -> Result<()> {
        author_name(cfg)
            .and_then(|n| author_email(cfg).map(|m| Person::new(n, m)))
            .and_then(|author| {
                committer_name(cfg)
                    .and_then(|n| committer_email(cfg).map(|m| (author, Person::new(n, m))))
            })
            .map(|(author, committer)| {
                self.author = Some(author);
                self.committer = Some(committer);
            })
    }

    pub fn new_committer_sig(&self) -> Option<Result<Signature>> {
        self.committer
            .as_ref()
            .map(|c| {
                Signature::now(c.name, c.mail)
                    .map_err(|e| GHEK::MkSignature.into_error_with_cause(Box::new(e)))
            })
    }

    pub fn repository(&self) -> Result<&Repository> {
        self.repository.as_ref().ok_or(GHEK::MkRepo.into_error())
    }

}

<|endoftext|>