<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::{StoreError, StoreErrorKind};
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId(PathBuf);

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        self.0
    }

}

impl Deref for StoreId {
    type Target = PathBuf;

    fn deref(&self) -> &PathBuf {
        &self.0
    }

}

impl From<PathBuf> for StoreId {

    fn from(pb: PathBuf) -> StoreId {
        StoreId(pb)
    }

}

impl From<String> for StoreId {

    fn from(string: String) -> StoreId {
        StoreId(string.into())
    }

}

impl AsRef<Path> for StoreId {

    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }

}

impl Borrow<Path> for StoreId {

    fn borrow(&self) -> &Path {
        self.0.borrow()
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        StoreId(self)
    }
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(StoreError::new(StoreErrorKind::StorePathLacksVersion, None));
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<commit_msg>Shorten type names in import<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::{StoreError as SE, StoreErrorKind as SEK};
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId(PathBuf);

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        self.0
    }

}

impl Deref for StoreId {
    type Target = PathBuf;

    fn deref(&self) -> &PathBuf {
        &self.0
    }

}

impl From<PathBuf> for StoreId {

    fn from(pb: PathBuf) -> StoreId {
        StoreId(pb)
    }

}

impl From<String> for StoreId {

    fn from(string: String) -> StoreId {
        StoreId(string.into())
    }

}

impl AsRef<Path> for StoreId {

    fn as_ref(&self) -> &Path {
        self.0.as_ref()
    }

}

impl Borrow<Path> for StoreId {

    fn borrow(&self) -> &Path {
        self.0.borrow()
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        StoreId(self)
    }
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SE::new(SEK::StorePathLacksVersion, None));
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<|endoftext|>


<commit_before><commit_msg>Fix(ignore): fix windows issue with line endings<commit_after><|endoftext|>


<commit_before>#![feature(rustc_private)]
#![feature(once_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]
// warn on rustc internal lints
#![deny(rustc::internal)]

// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_interface;
extern crate rustc_middle;

use rustc_interface::interface;
use rustc_middle::ty::TyCtxt;
use rustc_tools_util::VersionInfo;

use std::borrow::Cow;
use std::env;
use std::lazy::SyncLazy;
use std::ops::Deref;
use std::panic;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};

/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
fn arg_value<'a, T: Deref<Target = str>>(
    args: &'a [T],
    find_arg: &str,
    pred: impl Fn(&str) -> bool,
) -> Option<&'a str> {
    let mut args = args.iter().map(Deref::deref);
    while let Some(arg) = args.next() {
        let mut arg = arg.splitn(2, '=');
        if arg.next() != Some(find_arg) {
            continue;
        }

        match arg.next().or_else(|| args.next()) {
            Some(v) if pred(v) => return Some(v),
            _ => {},
        }
    }
    None
}

#[test]
fn test_arg_value() {
    let args = &["--bar=bar", "--foobar", "123", "--foo"];

    assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
    assert_eq!(arg_value(args, "--bar", |_| false), None);
    assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
    assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
    assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None);
    assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None);
    assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123"));
    assert_eq!(arg_value(args, "--foo", |_| true), None);
}

struct DefaultCallbacks;
impl rustc_driver::Callbacks for DefaultCallbacks {}

struct ClippyCallbacks;
impl rustc_driver::Callbacks for ClippyCallbacks {
    fn config(&mut self, config: &mut interface::Config) {
        let previous = config.register_lints.take();
        config.register_lints = Some(Box::new(move |sess, mut lint_store| {
            // technically we're ~guaranteed that this is none but might as well call anything that
            // is there already. Certainly it can't hurt.
            if let Some(previous) = &previous {
                (previous)(sess, lint_store);
            }

            let conf = clippy_lints::read_conf(&[], &sess);
            clippy_lints::register_plugins(&mut lint_store, &sess, &conf);
            clippy_lints::register_pre_expansion_lints(&mut lint_store);
            clippy_lints::register_renamed(&mut lint_store);
        }));

        // FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
        // run on the unoptimized MIR. On the other hand this results in some false negatives. If
        // MIR passes can be enabled / disabled separately, we should figure out, what passes to
        // use for Clippy.
        config.opts.debugging_opts.mir_opt_level = 0;
    }
}

fn display_help() {
    println!(
        "\
Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
        --rustc              Pass all args to rustc
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

You can use tool lints to allow or deny lints from your code, eg.:

    #[allow(clippy::needless_lifetimes)]
"
    );
}

const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new";

static ICE_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = SyncLazy::new(|| {
    let hook = panic::take_hook();
    panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL)));
    hook
});

fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
    // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace
    (*ICE_HOOK)(info);

    // Separate the output with an empty line
    eprintln!();

    let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
        rustc_errors::ColorConfig::Auto,
        None,
        false,
        false,
        None,
        false,
    ));
    let handler = rustc_errors::Handler::with_emitter(true, None, emitter);

    // a .span_bug or .bug call has already printed what
    // it wants to print.
    if !info.payload().is::<rustc_errors::ExplicitBug>() {
        let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
        handler.emit_diagnostic(&d);
    }

    let version_info = rustc_tools_util::get_version_info!();

    let xs: Vec<Cow<'static, str>> = vec![
        "the compiler unexpectedly panicked. this is a bug.".into(),
        format!("we would appreciate a bug report: {}", bug_report_url).into(),
        format!("Clippy version: {}", version_info).into(),
    ];

    for note in &xs {
        handler.note_without_error(&note);
    }

    // If backtraces are enabled, also print the query stack
    let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0");

    let num_frames = if backtrace { None } else { Some(2) };

    TyCtxt::try_print_query_stack(&handler, num_frames);
}

fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
    home.and_then(|home| {
        toolchain.map(|toolchain| {
            let mut path = PathBuf::from(home);
            path.push("toolchains");
            path.push(toolchain);
            path
        })
    })
}

pub fn main() {
    rustc_driver::init_rustc_env_logger();
    SyncLazy::force(&ICE_HOOK);
    exit(rustc_driver::catch_with_exit_code(move || {
        let mut orig_args: Vec<String> = env::args().collect();

        // Get the sysroot, looking from most specific to this invocation to the least:
        // - command line
        // - runtime environment
        //    - SYSROOT
        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
        // - sysroot from rustc in the path
        // - compile-time environment
        //    - SYSROOT
        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
        let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
        let have_sys_root_arg = sys_root_arg.is_some();
        let sys_root = sys_root_arg
            .map(PathBuf::from)
            .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
            .or_else(|| {
                let home = std::env::var("RUSTUP_HOME")
                    .or_else(|_| std::env::var("MULTIRUST_HOME"))
                    .ok();
                let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
                    .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
                    .ok();
                toolchain_path(home, toolchain)
            })
            .or_else(|| {
                Command::new("rustc")
                    .arg("--print")
                    .arg("sysroot")
                    .output()
                    .ok()
                    .and_then(|out| String::from_utf8(out.stdout).ok())
                    .map(|s| PathBuf::from(s.trim()))
            })
            .or_else(|| option_env!("SYSROOT").map(PathBuf::from))
            .or_else(|| {
                let home = option_env!("RUSTUP_HOME")
                    .or(option_env!("MULTIRUST_HOME"))
                    .map(ToString::to_string);
                let toolchain = option_env!("RUSTUP_TOOLCHAIN")
                    .or(option_env!("MULTIRUST_TOOLCHAIN"))
                    .map(ToString::to_string);
                toolchain_path(home, toolchain)
            })
            .map(|pb| pb.to_string_lossy().to_string())
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");

        // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
        // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
        // uses
        if let Some(pos) = orig_args.iter().position(|arg| arg == "--rustc") {
            orig_args.remove(pos);
            orig_args[0] = "rustc".to_string();

            // if we call "rustc", we need to pass --sysroot here as well
            let mut args: Vec<String> = orig_args.clone();
            if !have_sys_root_arg {
                args.extend(vec!["--sysroot".into(), sys_root]);
            };

            return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
        }

        if orig_args.iter().any(|a| a == "--version" || a == "-V") {
            let version_info = rustc_tools_util::get_version_info!();
            println!("{}", version_info);
            exit(0);
        }

        // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
        // We're invoking the compiler programmatically, so we ignore this/
        let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref());

        if wrapper_mode {
            // we still want to be able to invoke it normally though
            orig_args.remove(1);
        }

        if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) {
            display_help();
            exit(0);
        }

        // this conditional check for the --sysroot flag is there so users can call
        // `clippy_driver` directly
        // without having to pass --sysroot or anything
        let mut args: Vec<String> = orig_args.clone();
        if !have_sys_root_arg {
            args.extend(vec!["--sysroot".into(), sys_root]);
        };

        let mut no_deps = false;
        let clippy_args = env::var("CLIPPY_ARGS")
            .unwrap_or_default()
            .split("__CLIPPY_HACKERY__")
            .filter_map(|s| match s {
                "" => None,
                "--no-deps" => {
                    no_deps = true;
                    None
                },
                _ => Some(s.to_string()),
            })
            .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
            .collect::<Vec<String>>();

        // this check ensures that dependencies are built but not linted and the final
        // crate is linted but not built
        let clippy_disabled = env::var("CLIPPY_TESTS").map_or(false, |val| val != "true")
            || arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some()
            || no_deps && env::var("CARGO_PRIMARY_PACKAGE").is_err();

        if !clippy_disabled {
            args.extend(clippy_args);
        }
        let mut clippy = ClippyCallbacks;
        let mut default = DefaultCallbacks;
        let callbacks: &mut (dyn rustc_driver::Callbacks + Send) =
            if clippy_disabled { &mut default } else { &mut clippy };
        rustc_driver::RunCompiler::new(&args, callbacks).run()
    }))
}
<commit_msg>Apply suggestion regarding clippy_enabled bool<commit_after>#![feature(rustc_private)]
#![feature(once_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]
// warn on rustc internal lints
#![deny(rustc::internal)]

// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_interface;
extern crate rustc_middle;

use rustc_interface::interface;
use rustc_middle::ty::TyCtxt;
use rustc_tools_util::VersionInfo;

use std::borrow::Cow;
use std::env;
use std::lazy::SyncLazy;
use std::ops::Deref;
use std::panic;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};

/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
fn arg_value<'a, T: Deref<Target = str>>(
    args: &'a [T],
    find_arg: &str,
    pred: impl Fn(&str) -> bool,
) -> Option<&'a str> {
    let mut args = args.iter().map(Deref::deref);
    while let Some(arg) = args.next() {
        let mut arg = arg.splitn(2, '=');
        if arg.next() != Some(find_arg) {
            continue;
        }

        match arg.next().or_else(|| args.next()) {
            Some(v) if pred(v) => return Some(v),
            _ => {},
        }
    }
    None
}

#[test]
fn test_arg_value() {
    let args = &["--bar=bar", "--foobar", "123", "--foo"];

    assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
    assert_eq!(arg_value(args, "--bar", |_| false), None);
    assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
    assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
    assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None);
    assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None);
    assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123"));
    assert_eq!(arg_value(args, "--foo", |_| true), None);
}

struct DefaultCallbacks;
impl rustc_driver::Callbacks for DefaultCallbacks {}

struct ClippyCallbacks;
impl rustc_driver::Callbacks for ClippyCallbacks {
    fn config(&mut self, config: &mut interface::Config) {
        let previous = config.register_lints.take();
        config.register_lints = Some(Box::new(move |sess, mut lint_store| {
            // technically we're ~guaranteed that this is none but might as well call anything that
            // is there already. Certainly it can't hurt.
            if let Some(previous) = &previous {
                (previous)(sess, lint_store);
            }

            let conf = clippy_lints::read_conf(&[], &sess);
            clippy_lints::register_plugins(&mut lint_store, &sess, &conf);
            clippy_lints::register_pre_expansion_lints(&mut lint_store);
            clippy_lints::register_renamed(&mut lint_store);
        }));

        // FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
        // run on the unoptimized MIR. On the other hand this results in some false negatives. If
        // MIR passes can be enabled / disabled separately, we should figure out, what passes to
        // use for Clippy.
        config.opts.debugging_opts.mir_opt_level = 0;
    }
}

fn display_help() {
    println!(
        "\
Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
        --rustc              Pass all args to rustc
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

You can use tool lints to allow or deny lints from your code, eg.:

    #[allow(clippy::needless_lifetimes)]
"
    );
}

const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new";

static ICE_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = SyncLazy::new(|| {
    let hook = panic::take_hook();
    panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL)));
    hook
});

fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
    // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace
    (*ICE_HOOK)(info);

    // Separate the output with an empty line
    eprintln!();

    let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
        rustc_errors::ColorConfig::Auto,
        None,
        false,
        false,
        None,
        false,
    ));
    let handler = rustc_errors::Handler::with_emitter(true, None, emitter);

    // a .span_bug or .bug call has already printed what
    // it wants to print.
    if !info.payload().is::<rustc_errors::ExplicitBug>() {
        let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
        handler.emit_diagnostic(&d);
    }

    let version_info = rustc_tools_util::get_version_info!();

    let xs: Vec<Cow<'static, str>> = vec![
        "the compiler unexpectedly panicked. this is a bug.".into(),
        format!("we would appreciate a bug report: {}", bug_report_url).into(),
        format!("Clippy version: {}", version_info).into(),
    ];

    for note in &xs {
        handler.note_without_error(&note);
    }

    // If backtraces are enabled, also print the query stack
    let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0");

    let num_frames = if backtrace { None } else { Some(2) };

    TyCtxt::try_print_query_stack(&handler, num_frames);
}

fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
    home.and_then(|home| {
        toolchain.map(|toolchain| {
            let mut path = PathBuf::from(home);
            path.push("toolchains");
            path.push(toolchain);
            path
        })
    })
}

#[allow(clippy::too_many_lines)]
pub fn main() {
    rustc_driver::init_rustc_env_logger();
    SyncLazy::force(&ICE_HOOK);
    exit(rustc_driver::catch_with_exit_code(move || {
        let mut orig_args: Vec<String> = env::args().collect();

        // Get the sysroot, looking from most specific to this invocation to the least:
        // - command line
        // - runtime environment
        //    - SYSROOT
        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
        // - sysroot from rustc in the path
        // - compile-time environment
        //    - SYSROOT
        //    - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
        let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
        let have_sys_root_arg = sys_root_arg.is_some();
        let sys_root = sys_root_arg
            .map(PathBuf::from)
            .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
            .or_else(|| {
                let home = std::env::var("RUSTUP_HOME")
                    .or_else(|_| std::env::var("MULTIRUST_HOME"))
                    .ok();
                let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
                    .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
                    .ok();
                toolchain_path(home, toolchain)
            })
            .or_else(|| {
                Command::new("rustc")
                    .arg("--print")
                    .arg("sysroot")
                    .output()
                    .ok()
                    .and_then(|out| String::from_utf8(out.stdout).ok())
                    .map(|s| PathBuf::from(s.trim()))
            })
            .or_else(|| option_env!("SYSROOT").map(PathBuf::from))
            .or_else(|| {
                let home = option_env!("RUSTUP_HOME")
                    .or(option_env!("MULTIRUST_HOME"))
                    .map(ToString::to_string);
                let toolchain = option_env!("RUSTUP_TOOLCHAIN")
                    .or(option_env!("MULTIRUST_TOOLCHAIN"))
                    .map(ToString::to_string);
                toolchain_path(home, toolchain)
            })
            .map(|pb| pb.to_string_lossy().to_string())
            .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");

        // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
        // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
        // uses
        if let Some(pos) = orig_args.iter().position(|arg| arg == "--rustc") {
            orig_args.remove(pos);
            orig_args[0] = "rustc".to_string();

            // if we call "rustc", we need to pass --sysroot here as well
            let mut args: Vec<String> = orig_args.clone();
            if !have_sys_root_arg {
                args.extend(vec!["--sysroot".into(), sys_root]);
            };

            return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
        }

        if orig_args.iter().any(|a| a == "--version" || a == "-V") {
            let version_info = rustc_tools_util::get_version_info!();
            println!("{}", version_info);
            exit(0);
        }

        // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
        // We're invoking the compiler programmatically, so we ignore this/
        let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref());

        if wrapper_mode {
            // we still want to be able to invoke it normally though
            orig_args.remove(1);
        }

        if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) {
            display_help();
            exit(0);
        }

        // this conditional check for the --sysroot flag is there so users can call
        // `clippy_driver` directly
        // without having to pass --sysroot or anything
        let mut args: Vec<String> = orig_args.clone();
        if !have_sys_root_arg {
            args.extend(vec!["--sysroot".into(), sys_root]);
        };

        let mut no_deps = false;
        let clippy_args = env::var("CLIPPY_ARGS")
            .unwrap_or_default()
            .split("__CLIPPY_HACKERY__")
            .filter_map(|s| match s {
                "" => None,
                "--no-deps" => {
                    no_deps = true;
                    None
                },
                _ => Some(s.to_string()),
            })
            .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
            .collect::<Vec<String>>();

        // this check ensures that dependencies are built but not linted and the final
        // crate is linted but not built
        let clippy_tests_set = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true");
        let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some();
        let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok();

        let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package));
        if clippy_enabled {
            args.extend(clippy_args);
        }

        let mut clippy = ClippyCallbacks;
        let mut default = DefaultCallbacks;
        let callbacks: &mut (dyn rustc_driver::Callbacks + Send) =
            if clippy_enabled { &mut clippy } else { &mut default };

        rustc_driver::RunCompiler::new(&args, callbacks).run()
    }))
}
<|endoftext|>


<commit_before><commit_msg>Fields in m.receipt are optional.<commit_after><|endoftext|>


<commit_before>#![allow(dead_code)]
extern crate rand;

pub struct World {
	size: u64,
}

impl World {
	// enmine();
	// calc_neighbors()
}

pub struct Chunk {
	mines: [u16;16], // mines
	vis: [u16;16], // visibility
	nhb: [u64;16], // neighbors
}

impl Chunk {
	pub fn new() -> Chunk {
		Chunk {
			mines: [0;16],
			vis: [0;16],
			nhb: [0;16],
		}
	}

	pub fn click (&mut self, row: u8, col: u8) {
		if (row < 15) & (col < 15) {
			self.vis[row as usize] = self.vis[row as usize] | (1u16 << (15-col));
		}
	}

	pub fn is_clicked (&self, row: u8, col: u8) -> bool {
		if (row < 15) & (col < 15) {
			(self.vis[row as usize] & (1u16 << (15-col))) == (1u16 << (15-col))
		}
		else { false }
	}
}

#[test]
fn test_chunk_construct() {
	let c = Chunk::new();
	for i in 0..15 { assert_eq!(c.mines[i], 0); }
	for i in 0..15 { assert_eq!(c.vis[i], 0); }
	for i in 0..15 { assert_eq!(c.nhb[i], 0); }
}

#[test]
fn test_chunk_click() {
	let mut c = Chunk::new();
	c.click(0, 2);
	assert_eq!(c.vis[0], 8192);
}

#[test]
fn test_chunk_is_clicked() {
	let mut vec = Vec::new();
	let mut c = Chunk::new();
	for _ in 0..15 { vec.push((rand::random::<u8>()%15, rand::random::<u8>()%15)); }
	for i in &vec { c.click(i.0, i.1); };
	for i in &vec { assert!(c.is_clicked(i.0, i.1)); }
}

<commit_msg>Started chunk creation implementation<commit_after>#![allow(dead_code)]
extern crate rand;
use std::collections::HashMap;

const MIN_M: u8 = 16;
const MAX_M: u8 = 64;

pub struct World {
	allocated: u64,
	activated: u64,
	board: HashMap<(i32,i32),Chunk>,
}

impl World {
	pub fn new() -> World {
		World {
			allocated: 0,
			activated: 0,
			board: HashMap::new(),
		}
	}

	fn chunk_create(&mut self, x: i32, y: i32) {
		// TODO: add current chunk, surrounding chunks if not exist
		//		 calculate neighbors for current chunk
		//		 increment size
	}

	fn chunk_add(&mut self, x: i32, y: i32) {
		self.board.insert((x,y), Chunk::new());
	}

	fn calc_neighbors(&mut self) {}
}

enum ChunkStat {
	Mined,
	Neighbored,
	Won,
}

pub struct Chunk {
	stat: ChunkStat, // status
	mines: [u16;16], // mines
	vis: [u16;16], // visibility
	nhb: [u64;16], // neighbors
}

impl Chunk {
	pub fn new() -> Chunk {
		let mut c = Chunk {
			stat: ChunkStat::Mined,
			mines: [0;16],
			vis: [0;16],
			nhb: [0;16],
		};

		for _ in 1..(rand::random::<u8>()%(MAX_M-MIN_M)+MIN_M) {
			// duplicate entries are not of consequence.
			c.enmine(rand::random::<u8>()%16, rand::random::<u8>()%16);
		}

		return c;
	}

	fn enmine(&mut self, row: u8, col: u8) {
		if (row < 15) & (col < 15) {
			self.mines[row as usize] = self.mines[row as usize] | (1u16 << (15-col));
		}
	}

	pub fn click (&mut self, row: u8, col: u8) {
		if (row < 15) & (col < 15) {
			self.vis[row as usize] = self.vis[row as usize] | (1u16 << (15-col));
		}
	}

	pub fn is_clicked (&self, row: u8, col: u8) -> bool {
		if (row < 15) & (col < 15) {
			(self.vis[row as usize] & (1u16 << (15-col))) == (1u16 << (15-col))
		}
		else { false }
	}
}
<|endoftext|>


<commit_before>use std::sys;
use std::libc;
use std::num::One;
use std::ptr;
use glcore::*;
use nalgebra::traits::homogeneous::ToHomogeneous;
use nalgebra::traits::indexable::Indexable;
use nalgebra::adaptors::transform::Transform;
use nalgebra::adaptors::rotmat::Rotmat;
use nalgebra::mat::{Mat3, Mat4};
use nalgebra::vec::Vec3;

type Transform3d = Transform<Rotmat<Mat3<f64>>, Vec3<f64>>;
type Scale3d     = Mat3<GLfloat>;

pub enum Geometry
{ VerticesTriangles(~[Vec3<f32>], ~[(GLuint, GLuint, GLuint)]) }

pub struct GeometryIndices
{
  priv offset:         uint,
  priv size:           i32,
  priv element_buffer: GLuint,
  priv normal_buffer:  GLuint,
  priv vertex_buffer:  GLuint
}

impl GeometryIndices
{
  pub fn new(offset:         uint,
             size:           i32,
             element_buffer: GLuint,
             normal_buffer:  GLuint,
             vertex_buffer:  GLuint) -> GeometryIndices
  {
    GeometryIndices {
      offset:         offset,
      size:           size,
      element_buffer: element_buffer,
      normal_buffer:  normal_buffer,
      vertex_buffer:  vertex_buffer
    }
  }
}

pub struct Object
{
  priv scale:     Scale3d,
  priv transform: Transform3d,
  priv color:     Vec3<f32>,
  priv igeometry: GeometryIndices,
  priv geometry:  Option<Geometry>
}

impl Object
{
  pub fn new(igeometry: GeometryIndices,
             r:    f32,
             g:    f32,
             b:    f32,
             sx:   GLfloat,
             sy:   GLfloat,
             sz:   GLfloat,
             geometry: Option<Geometry>) -> Object
  {
    Object {
      scale:     Mat3::new( [
                              sx, 0.0, 0.0,
                              0.0, sy, 0.0,
                              0.0, 0.0, sz,
                            ] ),
      transform: One::one(),
      igeometry: igeometry,
      geometry:  geometry,
      color:     Vec3::new([r, g, b])
    }
  }

  pub fn upload(&self,
                pos_attrib:                u32,
                normal_attrib:             u32,
                color_location:            i32,
                transform_location:        i32,
                scale_location:            i32,
                normal_transform_location: i32)
  {
    let formated_transform:  Mat4<f64> = self.transform.to_homogeneous();
    let formated_ntransform: Mat3<f64> = self.transform.submat().submat();

    // we convert the matrix elements and do the transposition at the same time
    let transform_glf = Mat4::new ([
      formated_transform.at((0, 0)) as GLfloat,
      formated_transform.at((1, 0)) as GLfloat,
      formated_transform.at((2, 0)) as GLfloat,
      formated_transform.at((3, 0)) as GLfloat,

      formated_transform.at((0, 1)) as GLfloat,
      formated_transform.at((1, 1)) as GLfloat,
      formated_transform.at((2, 1)) as GLfloat,
      formated_transform.at((3, 1)) as GLfloat,

      formated_transform.at((0, 2)) as GLfloat,
      formated_transform.at((1, 2)) as GLfloat,
      formated_transform.at((2, 2)) as GLfloat,
      formated_transform.at((3, 2)) as GLfloat,

      formated_transform.at((0, 3)) as GLfloat,
      formated_transform.at((1, 3)) as GLfloat,
      formated_transform.at((2, 3)) as GLfloat,
      formated_transform.at((3, 3)) as GLfloat,
    ]);

    let ntransform_glf = Mat3::new ([
      formated_ntransform.at((0, 0)) as GLfloat,
      formated_ntransform.at((1, 0)) as GLfloat,
      formated_ntransform.at((2, 0)) as GLfloat,
      formated_ntransform.at((0, 1)) as GLfloat,
      formated_ntransform.at((1, 1)) as GLfloat,
      formated_ntransform.at((2, 1)) as GLfloat,
      formated_ntransform.at((0, 2)) as GLfloat,
      formated_ntransform.at((1, 2)) as GLfloat,
      formated_ntransform.at((2, 2)) as GLfloat,
    ]);

    unsafe {
      glUniformMatrix4fv(transform_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&transform_glf.mij[0]));

      glUniformMatrix3fv(normal_transform_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&ntransform_glf.mij[0]));

      glUniformMatrix3fv(scale_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&self.scale.mij[0]));

      glUniform3f(color_location, self.color.at[0], self.color.at[1], self.color.at[2]);

      // FIXME: we should not switch the buffers if the last drawn shape uses the same.
      glBindBuffer(GL_ARRAY_BUFFER, self.igeometry.vertex_buffer);
      glVertexAttribPointer(pos_attrib,
                            3,
                            GL_FLOAT,
                            GL_FALSE,
                            3 * sys::size_of::<GLfloat>() as GLsizei,
                            ptr::null());

      glBindBuffer(GL_ARRAY_BUFFER, self.igeometry.normal_buffer);
      glVertexAttribPointer(normal_attrib,
                            3,
                            GL_FLOAT,
                            GL_FALSE,
                            3 * sys::size_of::<GLfloat>() as GLsizei,
                            ptr::null());

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.igeometry.element_buffer);
      glDrawElements(GL_TRIANGLES,
                     self.igeometry.size,
                     GL_UNSIGNED_INT,
                     self.igeometry.offset * sys::size_of::<GLuint>() as *libc::c_void);
    }
  }

  pub fn transformation<'r>(&'r mut self) -> &'r mut Transform3d
  { &mut self.transform }

  pub fn set_color(@mut self, r: f32, g: f32, b: f32) -> @mut Object
  {
    self.color.at[0] = r;
    self.color.at[1] = g;
    self.color.at[2] = b;

    self
  }
}
<commit_msg>Add accessors to objects geometry.<commit_after>use std::sys;
use std::libc;
use std::num::One;
use std::ptr;
use glcore::*;
use nalgebra::traits::homogeneous::ToHomogeneous;
use nalgebra::traits::indexable::Indexable;
use nalgebra::adaptors::transform::Transform;
use nalgebra::adaptors::rotmat::Rotmat;
use nalgebra::mat::{Mat3, Mat4};
use nalgebra::vec::Vec3;

type Transform3d = Transform<Rotmat<Mat3<f64>>, Vec3<f64>>;
type Scale3d     = Mat3<GLfloat>;

pub enum Geometry
{ VerticesTriangles(~[Vec3<f32>], ~[(GLuint, GLuint, GLuint)]) }

pub struct GeometryIndices
{
  priv offset:         uint,
  priv size:           i32,
  priv element_buffer: GLuint,
  priv normal_buffer:  GLuint,
  priv vertex_buffer:  GLuint
}

impl GeometryIndices
{
  pub fn new(offset:         uint,
             size:           i32,
             element_buffer: GLuint,
             normal_buffer:  GLuint,
             vertex_buffer:  GLuint) -> GeometryIndices
  {
    GeometryIndices {
      offset:         offset,
      size:           size,
      element_buffer: element_buffer,
      normal_buffer:  normal_buffer,
      vertex_buffer:  vertex_buffer
    }
  }
}

pub struct Object
{
  priv scale:     Scale3d,
  priv transform: Transform3d,
  priv color:     Vec3<f32>,
  priv igeometry: GeometryIndices,
  priv geometry:  Option<Geometry>
}

impl Object
{
  pub fn new(igeometry: GeometryIndices,
             r:    f32,
             g:    f32,
             b:    f32,
             sx:   GLfloat,
             sy:   GLfloat,
             sz:   GLfloat,
             geometry: Option<Geometry>) -> Object
  {
    Object {
      scale:     Mat3::new( [
                              sx, 0.0, 0.0,
                              0.0, sy, 0.0,
                              0.0, 0.0, sz,
                            ] ),
      transform: One::one(),
      igeometry: igeometry,
      geometry:  geometry,
      color:     Vec3::new([r, g, b])
    }
  }

  pub fn upload(&self,
                pos_attrib:                u32,
                normal_attrib:             u32,
                color_location:            i32,
                transform_location:        i32,
                scale_location:            i32,
                normal_transform_location: i32)
  {
    let formated_transform:  Mat4<f64> = self.transform.to_homogeneous();
    let formated_ntransform: Mat3<f64> = self.transform.submat().submat();

    // we convert the matrix elements and do the transposition at the same time
    let transform_glf = Mat4::new ([
      formated_transform.at((0, 0)) as GLfloat,
      formated_transform.at((1, 0)) as GLfloat,
      formated_transform.at((2, 0)) as GLfloat,
      formated_transform.at((3, 0)) as GLfloat,

      formated_transform.at((0, 1)) as GLfloat,
      formated_transform.at((1, 1)) as GLfloat,
      formated_transform.at((2, 1)) as GLfloat,
      formated_transform.at((3, 1)) as GLfloat,

      formated_transform.at((0, 2)) as GLfloat,
      formated_transform.at((1, 2)) as GLfloat,
      formated_transform.at((2, 2)) as GLfloat,
      formated_transform.at((3, 2)) as GLfloat,

      formated_transform.at((0, 3)) as GLfloat,
      formated_transform.at((1, 3)) as GLfloat,
      formated_transform.at((2, 3)) as GLfloat,
      formated_transform.at((3, 3)) as GLfloat,
    ]);

    let ntransform_glf = Mat3::new ([
      formated_ntransform.at((0, 0)) as GLfloat,
      formated_ntransform.at((1, 0)) as GLfloat,
      formated_ntransform.at((2, 0)) as GLfloat,
      formated_ntransform.at((0, 1)) as GLfloat,
      formated_ntransform.at((1, 1)) as GLfloat,
      formated_ntransform.at((2, 1)) as GLfloat,
      formated_ntransform.at((0, 2)) as GLfloat,
      formated_ntransform.at((1, 2)) as GLfloat,
      formated_ntransform.at((2, 2)) as GLfloat,
    ]);

    unsafe {
      glUniformMatrix4fv(transform_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&transform_glf.mij[0]));

      glUniformMatrix3fv(normal_transform_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&ntransform_glf.mij[0]));

      glUniformMatrix3fv(scale_location,
                         1,
                         GL_FALSE,
                         ptr::to_unsafe_ptr(&self.scale.mij[0]));

      glUniform3f(color_location, self.color.at[0], self.color.at[1], self.color.at[2]);

      // FIXME: we should not switch the buffers if the last drawn shape uses the same.
      glBindBuffer(GL_ARRAY_BUFFER, self.igeometry.vertex_buffer);
      glVertexAttribPointer(pos_attrib,
                            3,
                            GL_FLOAT,
                            GL_FALSE,
                            3 * sys::size_of::<GLfloat>() as GLsizei,
                            ptr::null());

      glBindBuffer(GL_ARRAY_BUFFER, self.igeometry.normal_buffer);
      glVertexAttribPointer(normal_attrib,
                            3,
                            GL_FLOAT,
                            GL_FALSE,
                            3 * sys::size_of::<GLfloat>() as GLsizei,
                            ptr::null());

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.igeometry.element_buffer);
      glDrawElements(GL_TRIANGLES,
                     self.igeometry.size,
                     GL_UNSIGNED_INT,
                     self.igeometry.offset * sys::size_of::<GLuint>() as *libc::c_void);
    }
  }

  pub fn transformation<'r>(&'r mut self) -> &'r mut Transform3d
  { &mut self.transform }

  pub fn geometry<'r>(&'r self) -> &'r Option<Geometry>
  { &'r self.geometry }

  pub fn geometry_mut<'r>(&'r mut self) -> &'r mut Option<Geometry>
  { &'r mut self.geometry }

  pub fn set_color(@mut self, r: f32, g: f32, b: f32) -> @mut Object
  {
    self.color.at[0] = r;
    self.color.at[1] = g;
    self.color.at[2] = b;

    self
  }
}
<|endoftext|>


<commit_before><commit_msg>Add proper error handling in parser<commit_after><|endoftext|>


<commit_before><commit_msg>Only updated history once<commit_after><|endoftext|>


<commit_before><commit_msg>siiiiiiiiiiimple<commit_after><|endoftext|>


<commit_before><commit_msg>Add shutdown mechanism.<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::utils::{Reflectable, Reflector};
use dom::bindings::utils::{DOMString, null_str_as_empty};
use dom::bindings::codegen::FormDataBinding;
use dom::blob::Blob;
use script_task::{page_from_context};

use js::jsapi::{JSObject, JSContext};

use std::hashmap::HashMap;

enum FormDatum {
    StringData(DOMString),
    BlobData { blob: @mut Blob, name: DOMString }
}

pub struct FormData {
    data: HashMap<~str, FormDatum>,
    reflector_: Reflector
}

impl FormData {
    pub fn new() -> @mut FormData {
        @mut FormData {
            data: HashMap::new(),
            reflector_: Reflector::new()
        }
    }

    pub fn init_wrapper(@mut self, cx: *JSContext, scope: *JSObject) {
        self.wrap_object_shared(cx, scope);
    }

    pub fn Append(&mut self, name: &DOMString, value: @mut Blob, filename: Option<DOMString>) {
        let blob = BlobData {
            blob: value,
            name: filename.unwrap_or_default(Some(~"default"))
        };
        self.data.insert(null_str_as_empty(name), blob);
    }

    pub fn Append_(&mut self, name: &DOMString, value: &DOMString) {
        self.data.insert(null_str_as_empty(name), StringData((*value).clone()));
    }
}

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

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        FormDataBinding::Wrap(cx, scope, self)
    }

    fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> {
        let page = page_from_context(cx);
        unsafe {
            Some((*page).frame.get_ref().window as @mut Reflectable)
        }
    }
}
<commit_msg>Create FormData reflectors eagerly.<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::utils::{Reflectable, Reflector};
use dom::bindings::utils::{DOMString, null_str_as_empty};
use dom::bindings::codegen::FormDataBinding;
use dom::blob::Blob;
use dom::window::Window;

use js::jsapi::{JSObject, JSContext};

use std::hashmap::HashMap;

enum FormDatum {
    StringData(DOMString),
    BlobData { blob: @mut Blob, name: DOMString }
}

pub struct FormData {
    data: HashMap<~str, FormDatum>,
    reflector_: Reflector,
    window: @mut Window,
}

impl FormData {
    pub fn new_inherited(window: @mut Window) -> FormData {
        FormData {
            data: HashMap::new(),
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: @mut Window) -> @mut FormData {
        let formdata = @mut FormData::new_inherited(window);
        let cx = window.get_cx();
        let scope = window.reflector().get_jsobject();
        if FormDataBinding::Wrap(cx, scope, formdata).is_null() {
            fail!("FormDataBinding::Wrap failed");
        }
        assert!(formdata.reflector().get_jsobject().is_not_null());
        formdata
    }

    pub fn Append(&mut self, name: &DOMString, value: @mut Blob, filename: Option<DOMString>) {
        let blob = BlobData {
            blob: value,
            name: filename.unwrap_or_default(Some(~"default"))
        };
        self.data.insert(null_str_as_empty(name), blob);
    }

    pub fn Append_(&mut self, name: &DOMString, value: &DOMString) {
        self.data.insert(null_str_as_empty(name), StringData((*value).clone()));
    }
}

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

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }

    fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
        unreachable!();
    }

    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {
        Some(self.window as @mut Reflectable)
    }
}
<|endoftext|>


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

use dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use errors::Diagnostic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
                      SpecializedDecoder};
use session::Session;
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::mem;
use syntax::codemap::{CodeMap, StableFilemapId};
use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP};

pub struct OnDiskCache<'sess> {
    prev_diagnostics: FxHashMap<SerializedDepNodeIndex, Vec<Diagnostic>>,

    _prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
    codemap: &'sess CodeMap,

    current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
}

#[derive(RustcEncodable, RustcDecodable)]
struct Header {
    prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
}

#[derive(RustcEncodable, RustcDecodable)]
struct Body {
    diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)>,
}

impl<'sess> OnDiskCache<'sess> {
    pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> {
        OnDiskCache {
            prev_diagnostics: FxHashMap(),
            _prev_filemap_starts: BTreeMap::new(),
            codemap,
            current_diagnostics: RefCell::new(FxHashMap()),
        }
    }

    pub fn new(sess: &'sess Session, data: &[u8]) -> OnDiskCache<'sess> {
        debug_assert!(sess.opts.incremental.is_some());

        let mut decoder = opaque::Decoder::new(&data[..], 0);
        let header = Header::decode(&mut decoder).unwrap();

        let prev_diagnostics: FxHashMap<_, _> = {
            let mut decoder = CacheDecoder {
                opaque: decoder,
                codemap: sess.codemap(),
                prev_filemap_starts: &header.prev_filemap_starts,
            };
            let body = Body::decode(&mut decoder).unwrap();
            body.diagnostics.into_iter().collect()
        };

        OnDiskCache {
            prev_diagnostics,
            _prev_filemap_starts: header.prev_filemap_starts,
            codemap: sess.codemap(),
            current_diagnostics: RefCell::new(FxHashMap()),
        }
    }

    pub fn serialize<'a, 'tcx, E>(&self,
                                  encoder: &mut E)
                                  -> Result<(), E::Error>
        where E: Encoder
    {
        let prev_filemap_starts: BTreeMap<_, _> = self
            .codemap
            .files()
            .iter()
            .map(|fm| (fm.start_pos, StableFilemapId::new(fm)))
            .collect();

        Header { prev_filemap_starts }.encode(encoder)?;

        let diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)> =
            self.current_diagnostics
                .borrow()
                .iter()
                .map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
                .collect();

        Body { diagnostics }.encode(encoder)?;

        Ok(())
    }

    pub fn load_diagnostics(&self,
                            dep_node_index: SerializedDepNodeIndex)
                            -> Vec<Diagnostic> {
        self.prev_diagnostics.get(&dep_node_index).cloned().unwrap_or(vec![])
    }

    pub fn store_diagnostics(&self,
                             dep_node_index: DepNodeIndex,
                             diagnostics: Vec<Diagnostic>) {
        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
        let prev = current_diagnostics.insert(dep_node_index, diagnostics);
        debug_assert!(prev.is_none());
    }

    pub fn store_diagnostics_for_anon_node(&self,
                                           dep_node_index: DepNodeIndex,
                                           mut diagnostics: Vec<Diagnostic>) {
        let mut current_diagnostics = self.current_diagnostics.borrow_mut();

        let x = current_diagnostics.entry(dep_node_index).or_insert_with(|| {
            mem::replace(&mut diagnostics, Vec::new())
        });

        x.extend(diagnostics.into_iter());
    }
}

impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
        let lo = BytePos::decode(self)?;
        let hi = BytePos::decode(self)?;

        if let Some((prev_filemap_start, filemap_id)) = self.find_filemap_prev_bytepos(lo) {
            if let Some(current_filemap) = self.codemap.filemap_by_stable_id(filemap_id) {
                let lo = (lo + current_filemap.start_pos) - prev_filemap_start;
                let hi = (hi + current_filemap.start_pos) - prev_filemap_start;
                return Ok(Span::new(lo, hi, NO_EXPANSION));
            }
        }

        Ok(DUMMY_SP)
    }
}

struct CacheDecoder<'a> {
    opaque: opaque::Decoder<'a>,
    codemap: &'a CodeMap,
    prev_filemap_starts: &'a BTreeMap<BytePos, StableFilemapId>,
}

impl<'a> CacheDecoder<'a> {
    fn find_filemap_prev_bytepos(&self,
                                 prev_bytepos: BytePos)
                                 -> Option<(BytePos, StableFilemapId)> {
        for (start, id) in self.prev_filemap_starts.range(BytePos(0) ... prev_bytepos).rev() {
            return Some((*start, *id))
        }

        None
    }
}

macro_rules! decoder_methods {
    ($($name:ident -> $ty:ty;)*) => {
        $(fn $name(&mut self) -> Result<$ty, Self::Error> {
            self.opaque.$name()
        })*
    }
}

impl<'sess> Decoder for CacheDecoder<'sess> {
    type Error = String;

    decoder_methods! {
        read_nil -> ();

        read_u128 -> u128;
        read_u64 -> u64;
        read_u32 -> u32;
        read_u16 -> u16;
        read_u8 -> u8;
        read_usize -> usize;

        read_i128 -> i128;
        read_i64 -> i64;
        read_i32 -> i32;
        read_i16 -> i16;
        read_i8 -> i8;
        read_isize -> isize;

        read_bool -> bool;
        read_f64 -> f64;
        read_f32 -> f32;
        read_char -> char;
        read_str -> Cow<str>;
    }

    fn error(&mut self, err: &str) -> Self::Error {
        self.opaque.error(err)
    }
}
<commit_msg>incr.comp.: Add documentation for OnDiskCache.<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 dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use errors::Diagnostic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
                      SpecializedDecoder};
use session::Session;
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::mem;
use syntax::codemap::{CodeMap, StableFilemapId};
use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP};

/// `OnDiskCache` provides an interface to incr. comp. data cached from the
/// previous compilation session. This data will eventually include the results
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
/// any diagnostics that have been emitted during a query.
pub struct OnDiskCache<'sess> {
    // The diagnostics emitted during the previous compilation session.
    prev_diagnostics: FxHashMap<SerializedDepNodeIndex, Vec<Diagnostic>>,

    // This field collects all Diagnostics emitted during the current
    // compilation session.
    current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,

    // This will eventually be needed for creating Decoders that can rebase
    // spans.
    _prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
    codemap: &'sess CodeMap,
}

// This type is used only for (de-)serialization.
#[derive(RustcEncodable, RustcDecodable)]
struct Header {
    prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
}

// This type is used only for (de-)serialization.
#[derive(RustcEncodable, RustcDecodable)]
struct Body {
    diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)>,
}

impl<'sess> OnDiskCache<'sess> {
    /// Create a new OnDiskCache instance from the serialized data in `data`.
    /// Note that the current implementation (which only deals with diagnostics
    /// so far) will eagerly deserialize the complete cache. Once we are
    /// dealing with larger amounts of data (i.e. cached query results),
    /// deserialization will need to happen lazily.
    pub fn new(sess: &'sess Session, data: &[u8]) -> OnDiskCache<'sess> {
        debug_assert!(sess.opts.incremental.is_some());

        let mut decoder = opaque::Decoder::new(&data[..], 0);
        let header = Header::decode(&mut decoder).unwrap();

        let prev_diagnostics: FxHashMap<_, _> = {
            let mut decoder = CacheDecoder {
                opaque: decoder,
                codemap: sess.codemap(),
                prev_filemap_starts: &header.prev_filemap_starts,
            };
            let body = Body::decode(&mut decoder).unwrap();
            body.diagnostics.into_iter().collect()
        };

        OnDiskCache {
            prev_diagnostics,
            _prev_filemap_starts: header.prev_filemap_starts,
            codemap: sess.codemap(),
            current_diagnostics: RefCell::new(FxHashMap()),
        }
    }

    pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> {
        OnDiskCache {
            prev_diagnostics: FxHashMap(),
            _prev_filemap_starts: BTreeMap::new(),
            codemap,
            current_diagnostics: RefCell::new(FxHashMap()),
        }
    }

    pub fn serialize<'a, 'tcx, E>(&self,
                                  encoder: &mut E)
                                  -> Result<(), E::Error>
        where E: Encoder
    {
        let prev_filemap_starts: BTreeMap<_, _> = self
            .codemap
            .files()
            .iter()
            .map(|fm| (fm.start_pos, StableFilemapId::new(fm)))
            .collect();

        Header { prev_filemap_starts }.encode(encoder)?;

        let diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)> =
            self.current_diagnostics
                .borrow()
                .iter()
                .map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
                .collect();

        Body { diagnostics }.encode(encoder)?;

        Ok(())
    }

    /// Load a diagnostic emitted during the previous compilation session.
    pub fn load_diagnostics(&self,
                            dep_node_index: SerializedDepNodeIndex)
                            -> Vec<Diagnostic> {
        self.prev_diagnostics.get(&dep_node_index).cloned().unwrap_or(vec![])
    }

    /// Store a diagnostic emitted during the current compilation session.
    /// Anything stored like this will be available via `load_diagnostics` in
    /// the next compilation session.
    pub fn store_diagnostics(&self,
                             dep_node_index: DepNodeIndex,
                             diagnostics: Vec<Diagnostic>) {
        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
        let prev = current_diagnostics.insert(dep_node_index, diagnostics);
        debug_assert!(prev.is_none());
    }

    /// Store a diagnostic emitted during computation of an anonymous query.
    /// Since many anonymous queries can share the same `DepNode`, we aggregate
    /// them -- as opposed to regular queries where we assume that there is a
    /// 1:1 relationship between query-key and `DepNode`.
    pub fn store_diagnostics_for_anon_node(&self,
                                           dep_node_index: DepNodeIndex,
                                           mut diagnostics: Vec<Diagnostic>) {
        let mut current_diagnostics = self.current_diagnostics.borrow_mut();

        let x = current_diagnostics.entry(dep_node_index).or_insert_with(|| {
            mem::replace(&mut diagnostics, Vec::new())
        });

        x.extend(diagnostics.into_iter());
    }
}

/// A decoder that can read the incr. comp. cache. It is similar to the one
/// we use for crate metadata decoding in that it can rebase spans and
/// eventually will also handle things that contain `Ty` instances.
struct CacheDecoder<'a> {
    opaque: opaque::Decoder<'a>,
    codemap: &'a CodeMap,
    prev_filemap_starts: &'a BTreeMap<BytePos, StableFilemapId>,
}

impl<'a> CacheDecoder<'a> {
    fn find_filemap_prev_bytepos(&self,
                                 prev_bytepos: BytePos)
                                 -> Option<(BytePos, StableFilemapId)> {
        for (start, id) in self.prev_filemap_starts.range(BytePos(0) ... prev_bytepos).rev() {
            return Some((*start, *id))
        }

        None
    }
}

macro_rules! decoder_methods {
    ($($name:ident -> $ty:ty;)*) => {
        $(fn $name(&mut self) -> Result<$ty, Self::Error> {
            self.opaque.$name()
        })*
    }
}

impl<'sess> Decoder for CacheDecoder<'sess> {
    type Error = String;

    decoder_methods! {
        read_nil -> ();

        read_u128 -> u128;
        read_u64 -> u64;
        read_u32 -> u32;
        read_u16 -> u16;
        read_u8 -> u8;
        read_usize -> usize;

        read_i128 -> i128;
        read_i64 -> i64;
        read_i32 -> i32;
        read_i16 -> i16;
        read_i8 -> i8;
        read_isize -> isize;

        read_bool -> bool;
        read_f64 -> f64;
        read_f32 -> f32;
        read_char -> char;
        read_str -> Cow<str>;
    }

    fn error(&mut self, err: &str) -> Self::Error {
        self.opaque.error(err)
    }
}

impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
        let lo = BytePos::decode(self)?;
        let hi = BytePos::decode(self)?;

        if let Some((prev_filemap_start, filemap_id)) = self.find_filemap_prev_bytepos(lo) {
            if let Some(current_filemap) = self.codemap.filemap_by_stable_id(filemap_id) {
                let lo = (lo + current_filemap.start_pos) - prev_filemap_start;
                let hi = (hi + current_filemap.start_pos) - prev_filemap_start;
                return Ok(Span::new(lo, hi, NO_EXPANSION));
            }
        }

        Ok(DUMMY_SP)
    }
}
<|endoftext|>


<commit_before><commit_msg>game_of_stones<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for bowling case<commit_after>type Frame = (u32, u32, u32);

const MAX_FRAME: usize = 10;
const FRAME_WINDOW: usize = 3;
const FRAME_SIZE: usize = MAX_FRAME + FRAME_WINDOW - 1;
const INVALID_SCORE: u32 = std::u32::MAX;

#[derive(Default)]
pub struct BowlingGame {
    record: [Frame; FRAME_SIZE],
    count: usize,
}

impl BowlingGame {
    pub fn new() -> BowlingGame {
        BowlingGame {
            record: [(INVALID_SCORE, INVALID_SCORE, INVALID_SCORE); FRAME_SIZE],
            count: 0,
        }
    }

    pub fn roll(&mut self, pins: u32) -> Result<u32, String> {
        if pins > 10 {
            return Err("Invalid pins".to_string());
        }

        match self.count {
            0...8 => roll_in_normal_frame(self, pins),
            9 => roll_in_final_frame(self, pins),
            _ => Err("No more pins".to_string()),
        }
    }

    pub fn score(&self) -> Result<u32, String> {
        if self.count != MAX_FRAME {
            return Err("Unfinished games".to_string());
        }

        let r = &self.record;
        let v = r.windows(FRAME_WINDOW).map(|v| count(v)).sum();

        Ok(v)
    }
}

fn roll_in_normal_frame(v: &mut BowlingGame, pins: u32) -> Result<u32, String> {
    let f = &mut v.record[v.count];

    match *f {
        (INVALID_SCORE, _, _) if pins == 10 => {
            f.0 = pins;
            v.count += 1;
            Ok(0)
        }
        (INVALID_SCORE, _, _) if pins < 10 => {
            f.0 = pins;
            Ok(0)
        }
        (a, INVALID_SCORE, _) if pins > 10 - a => Err("Invalid second pins".to_string()),
        (a, INVALID_SCORE, _) if pins <= 10 - a => {
            f.1 = pins;
            v.count += 1;
            Ok(1)
        }
        _ => panic!("Should not reach here"),
    }
}

fn roll_in_final_frame(v: &mut BowlingGame, pins: u32) -> Result<u32, String> {
    let f = &mut v.record[v.count];

    match *f {
        (INVALID_SCORE, _, _) => {
            f.0 = pins;
            Ok(0)
        }
        (10, INVALID_SCORE, _) => {
            f.1 = pins;
            Ok(1)
        }
        (a, INVALID_SCORE, _) if pins > 10 - a => Err("Invalid second pins".to_string()),
        (a, INVALID_SCORE, _) if pins < 10 - a => {
            f.1 = pins;
            v.count += 1;
            Ok(1)
        }
        (a, INVALID_SCORE, _) if pins == 10 - a => {
            f.1 = pins;
            Ok(1)
        }
        (10, 10, INVALID_SCORE) => {
            f.2 = pins;
            v.count += 1;
            Ok(2)
        }
        (10, b, INVALID_SCORE) if b != 10 && pins > 10 - b => Err("Invalid third pins".to_string()),
        (a, b, INVALID_SCORE) if a + b < 10 => Err("Invalid third pins".to_string()),
        (a, b, INVALID_SCORE) if a + b >= 10 => {
            f.2 = pins;
            v.count += 1;
            Ok(2)
        }
        _ => panic!("Should not reach here"),
    }
}

fn count(frames: &[Frame]) -> u32 {
    let f = &frames[1];
    if f.0 == INVALID_SCORE {
        return count_final_frame(frames);
    }

    count_normal_frame(frames)
}

fn count_normal_frame(frames: &[Frame]) -> u32 {
    let f = &frames[0];
    let s = &frames[1];
    let t = &frames[2];

    match *f {
        (10, _, _) if s.0 == 10 && t.0 != INVALID_SCORE => 10 + s.0 + t.0,
        (10, _, _) if s.0 == 10 && t.0 == INVALID_SCORE => 10 + s.0 + s.1,
        (10, _, _) if s.0 != 10 => 10 + s.0 + s.1,
        (a, b, _) if a + b == 10 => 10 + s.0,
        (a, b, _) if a + b < 10 => a + b,
        _ => panic!("Should not reach here"),
    }
}

fn count_final_frame(frames: &[Frame]) -> u32 {
    let f = &frames[0];

    match *f {
        (10, b, c) => 10 + b + c,
        (a, b, c) if a + b == 10 => a + b + c,
        (a, b, INVALID_SCORE) => a + b,
        _ => panic!("Should not reach here"),
    }
}
<|endoftext|>


<commit_before><commit_msg>Create unique StdRng instances for arguments of run_inc<commit_after><|endoftext|>


<commit_before><commit_msg>Derive `Clone` for `Datum`<commit_after><|endoftext|>


<commit_before><commit_msg>Use a collection of descriptor sets per swapchain image<commit_after><|endoftext|>


<commit_before><commit_msg>Replace the explicit subpass dependency with a stricter semaphore on the queue submission<commit_after><|endoftext|>


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

/*!

typeck.rs, an introduction

The type checker is responsible for:

1. Determining the type of each expression
2. Resolving methods and traits
3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
   Well, dear reader, read on)

The main entry point is `check_crate()`.  Type checking operates in
several major phases:

1. The collect phase first passes over all items and determines their
   type, without examining their "innards".

2. Variance inference then runs to compute the variance of each parameter

3. Coherence checks for overlapping or orphaned impls

4. Finally, the check phase then checks function bodies and so forth.
   Within the check phase, we check each function body one at a time
   (bodies of function expressions are checked as part of the
   containing function).  Inference is used to supply types wherever
   they are unknown. The actual checking of a function itself has
   several phases (check, regionck, writeback), as discussed in the
   documentation for the `check` module.

The type checker is defined into various submodules which are documented
independently:

- astconv: converts the AST representation of types
  into the `ty` representation

- collect: computes the types of each top-level item and enters them into
  the `cx.tcache` table for later use

- coherence: enforces coherence rules, builds some tables

- variance: variance inference

- check: walks over function bodies and type checks them, inferring types for
  local variables, type parameters, etc as necessary.

- infer: finds the types to use for each type variable such that
  all subtyping and assignment constraints are met.  In essence, the check
  module specifies the constraints, and the infer module solves them.

# Note

This API is completely unstable and subject to change.

*/

#![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]

#![allow(non_camel_case_types)]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(iter_arith)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;

extern crate arena;
extern crate fmt_macros;
#[macro_use] extern crate rustc;
extern crate rustc_platform_intrinsics as intrinsics;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_const_eval;

pub use rustc::dep_graph;
pub use rustc::hir;
pub use rustc::lint;
pub use rustc::middle;
pub use rustc::session;
pub use rustc::util;

use dep_graph::DepNode;
use hir::map as hir_map;
use hir::def::Def;
use rustc::infer::TypeOrigin;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::traits::ProjectionMode;
use session::{config, CompileResult};
use util::common::time;

use syntax::codemap::Span;
use syntax::ast;
use syntax::abi::Abi;

use std::cell::RefCell;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod check;
pub mod check_unused;
mod rscope;
mod astconv;
pub mod collect;
mod constrained_type_params;
pub mod coherence;
pub mod variance;

pub struct TypeAndSubsts<'tcx> {
    pub substs: Substs<'tcx>,
    pub ty: Ty<'tcx>,
}

pub struct CrateCtxt<'a, 'tcx: 'a> {
    // A mapping from method call sites to traits that have that method.
    pub trait_map: hir::TraitMap,

    /// A vector of every trait accessible in the whole crate
    /// (i.e. including those from subcrates). This is used only for
    /// error reporting, and so is lazily initialised and generally
    /// shouldn't taint the common path (hence the RefCell).
    pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,

    /// This stack is used to identify cycles in the user's source.
    /// Note that these cycles can cross multiple items.
    pub stack: RefCell<Vec<collect::AstConvRequest>>,

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

// Functions that write types into the node type table
fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
    debug!("write_ty_to_tcx({}, {:?})", node_id,  ty);
    assert!(!ty.needs_infer());
    ccx.tcx.node_type_insert(node_id, ty);
}

fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 node_id: ast::NodeId,
                                 item_substs: ty::ItemSubsts<'tcx>) {
    if !item_substs.is_noop() {
        debug!("write_substs_to_tcx({}, {:?})",
               node_id,
               item_substs);

        assert!(!item_substs.substs.types.needs_infer());

        ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
    }
}

fn lookup_full_def(tcx: TyCtxt, sp: Span, id: ast::NodeId) -> Def {
    match tcx.def_map.borrow().get(&id) {
        Some(x) => x.full_def(),
        None => {
            span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
        }
    }
}

fn require_c_abi_if_variadic(tcx: TyCtxt,
                             decl: &hir::FnDecl,
                             abi: Abi,
                             span: Span) {
    if decl.variadic && abi != Abi::C {
        span_err!(tcx.sess, span, E0045,
                  "variadic function must have C calling convention");
    }
}

pub fn emit_type_err<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                     span: Span,
                                     found_ty: Ty<'tcx>,
                                     expected_ty: Ty<'tcx>,
                                     terr: &ty::error::TypeError<'tcx>,
                                     msg: &str) {
    let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
    err = err.span_label(span, &terr);
    err = err.note_expected_found(&"type", &expected_ty, &found_ty);
    tcx.note_and_explain_type_err(&mut err, terr, span);
    err.emit();
}

fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                span: Span,
                                t1: Ty<'tcx>,
                                t2: Ty<'tcx>,
                                msg: &str)
                                -> bool {
    ccx.tcx.infer_ctxt(None, None, ProjectionMode::AnyFinal).enter(|infcx| {
        if let Err(err) = infcx.eq_types(false, TypeOrigin::Misc(span), t1, t2) {
            emit_type_err(infcx.tcx, span, t1, t2, &err, msg);
            false
        } else {
            true
        }
    })
}

fn check_main_fn_ty(ccx: &CrateCtxt,
                    main_id: ast::NodeId,
                    main_span: Span) {
    let tcx = ccx.tcx;
    let main_t = tcx.node_id_to_type(main_id);
    match main_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(main_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_, _, _, _, ref ps, _)
                        if ps.is_parameterized() => {
                            span_err!(ccx.tcx.sess, main_span, E0131,
                                      "main function is not allowed to have type parameters");
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }
            let main_def_id = tcx.map.local_def_id(main_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(main_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: Vec::new(),
                    output: ty::FnConverging(tcx.mk_nil()),
                    variadic: false
                })
            }));

            require_same_types(ccx, main_span, main_t, se_ty,
                               "main function has wrong type");
        }
        _ => {
            span_bug!(main_span,
                      "main has a non-function type: found `{}`",
                      main_t);
        }
    }
}

fn check_start_fn_ty(ccx: &CrateCtxt,
                     start_id: ast::NodeId,
                     start_span: Span) {
    let tcx = ccx.tcx;
    let start_t = tcx.node_id_to_type(start_id);
    match start_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(start_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_,_,_,_,ref ps,_)
                        if ps.is_parameterized() => {
                            span_err!(tcx.sess, start_span, E0132,
                                      "start function is not allowed to have type parameters");
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }

            let start_def_id = ccx.tcx.map.local_def_id(start_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(start_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: vec!(
                        tcx.types.isize,
                        tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
                    ),
                    output: ty::FnConverging(tcx.types.isize),
                    variadic: false,
                }),
            }));

            require_same_types(ccx, start_span, start_t, se_ty,
                               "start function has wrong type");
        }
        _ => {
            span_bug!(start_span,
                      "start has a non-function type: found `{}`",
                      start_t);
        }
    }
}

fn check_for_entry_fn(ccx: &CrateCtxt) {
    let tcx = ccx.tcx;
    let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
    match *tcx.sess.entry_fn.borrow() {
        Some((id, sp)) => match tcx.sess.entry_type.get() {
            Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
            Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
            Some(config::EntryNone) => {}
            None => bug!("entry function without a type")
        },
        None => {}
    }
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             trait_map: hir::TraitMap)
                             -> CompileResult {
    let time_passes = tcx.sess.time_passes();
    let ccx = CrateCtxt {
        trait_map: trait_map,
        all_traits: RefCell::new(None),
        stack: RefCell::new(Vec::new()),
        tcx: tcx
    };

    // this ensures that later parts of type checking can assume that items
    // have valid types and not error
    tcx.sess.track_errors(|| {
        time(time_passes, "type collecting", ||
             collect::collect_item_types(&ccx));

    })?;

    time(time_passes, "variance inference", ||
         variance::infer_variance(tcx));

    tcx.sess.track_errors(|| {
      time(time_passes, "coherence checking", ||
          coherence::check_coherence(&ccx));
    })?;

    time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;

    time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;

    time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;

    time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;

    check_unused::check_crate(tcx);
    check_for_entry_fn(&ccx);

    let err_count = tcx.sess.err_count();
    if err_count == 0 {
        Ok(())
    } else {
        Err(err_count)
    }
}

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

/*!

typeck.rs, an introduction

The type checker is responsible for:

1. Determining the type of each expression
2. Resolving methods and traits
3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
   Well, dear reader, read on)

The main entry point is `check_crate()`.  Type checking operates in
several major phases:

1. The collect phase first passes over all items and determines their
   type, without examining their "innards".

2. Variance inference then runs to compute the variance of each parameter

3. Coherence checks for overlapping or orphaned impls

4. Finally, the check phase then checks function bodies and so forth.
   Within the check phase, we check each function body one at a time
   (bodies of function expressions are checked as part of the
   containing function).  Inference is used to supply types wherever
   they are unknown. The actual checking of a function itself has
   several phases (check, regionck, writeback), as discussed in the
   documentation for the `check` module.

The type checker is defined into various submodules which are documented
independently:

- astconv: converts the AST representation of types
  into the `ty` representation

- collect: computes the types of each top-level item and enters them into
  the `cx.tcache` table for later use

- coherence: enforces coherence rules, builds some tables

- variance: variance inference

- check: walks over function bodies and type checks them, inferring types for
  local variables, type parameters, etc as necessary.

- infer: finds the types to use for each type variable such that
  all subtyping and assignment constraints are met.  In essence, the check
  module specifies the constraints, and the infer module solves them.

# Note

This API is completely unstable and subject to change.

*/

#![crate_name = "rustc_typeck"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]

#![allow(non_camel_case_types)]

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(iter_arith)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;

extern crate arena;
extern crate fmt_macros;
#[macro_use] extern crate rustc;
extern crate rustc_platform_intrinsics as intrinsics;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_const_eval;

pub use rustc::dep_graph;
pub use rustc::hir;
pub use rustc::lint;
pub use rustc::middle;
pub use rustc::session;
pub use rustc::util;

use dep_graph::DepNode;
use hir::map as hir_map;
use hir::def::Def;
use rustc::infer::TypeOrigin;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::traits::ProjectionMode;
use session::{config, CompileResult};
use util::common::time;

use syntax::codemap::Span;
use syntax::ast;
use syntax::abi::Abi;

use std::cell::RefCell;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod check;
pub mod check_unused;
mod rscope;
mod astconv;
pub mod collect;
mod constrained_type_params;
pub mod coherence;
pub mod variance;

pub struct TypeAndSubsts<'tcx> {
    pub substs: Substs<'tcx>,
    pub ty: Ty<'tcx>,
}

pub struct CrateCtxt<'a, 'tcx: 'a> {
    // A mapping from method call sites to traits that have that method.
    pub trait_map: hir::TraitMap,

    /// A vector of every trait accessible in the whole crate
    /// (i.e. including those from subcrates). This is used only for
    /// error reporting, and so is lazily initialised and generally
    /// shouldn't taint the common path (hence the RefCell).
    pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,

    /// This stack is used to identify cycles in the user's source.
    /// Note that these cycles can cross multiple items.
    pub stack: RefCell<Vec<collect::AstConvRequest>>,

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

// Functions that write types into the node type table
fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
    debug!("write_ty_to_tcx({}, {:?})", node_id,  ty);
    assert!(!ty.needs_infer());
    ccx.tcx.node_type_insert(node_id, ty);
}

fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 node_id: ast::NodeId,
                                 item_substs: ty::ItemSubsts<'tcx>) {
    if !item_substs.is_noop() {
        debug!("write_substs_to_tcx({}, {:?})",
               node_id,
               item_substs);

        assert!(!item_substs.substs.types.needs_infer());

        ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
    }
}

fn lookup_full_def(tcx: TyCtxt, sp: Span, id: ast::NodeId) -> Def {
    match tcx.def_map.borrow().get(&id) {
        Some(x) => x.full_def(),
        None => {
            span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
        }
    }
}

fn require_c_abi_if_variadic(tcx: TyCtxt,
                             decl: &hir::FnDecl,
                             abi: Abi,
                             span: Span) {
    if decl.variadic && abi != Abi::C {
        span_err!(tcx.sess, span, E0045,
                  "variadic function must have C calling convention");
    }
}

pub fn emit_type_err<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                     span: Span,
                                     found_ty: Ty<'tcx>,
                                     expected_ty: Ty<'tcx>,
                                     terr: &ty::error::TypeError<'tcx>,
                                     msg: &str) {
    let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
    err.span_label(span, &terr);
    err.note_expected_found(&"type", &expected_ty, &found_ty);
    tcx.note_and_explain_type_err(&mut err, terr, span);
    err.emit();
}

fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                span: Span,
                                t1: Ty<'tcx>,
                                t2: Ty<'tcx>,
                                msg: &str)
                                -> bool {
    ccx.tcx.infer_ctxt(None, None, ProjectionMode::AnyFinal).enter(|infcx| {
        if let Err(err) = infcx.eq_types(false, TypeOrigin::Misc(span), t1, t2) {
            emit_type_err(infcx.tcx, span, t1, t2, &err, msg);
            false
        } else {
            true
        }
    })
}

fn check_main_fn_ty(ccx: &CrateCtxt,
                    main_id: ast::NodeId,
                    main_span: Span) {
    let tcx = ccx.tcx;
    let main_t = tcx.node_id_to_type(main_id);
    match main_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(main_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_, _, _, _, ref ps, _)
                        if ps.is_parameterized() => {
                            span_err!(ccx.tcx.sess, main_span, E0131,
                                      "main function is not allowed to have type parameters");
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }
            let main_def_id = tcx.map.local_def_id(main_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(main_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: Vec::new(),
                    output: ty::FnConverging(tcx.mk_nil()),
                    variadic: false
                })
            }));

            require_same_types(ccx, main_span, main_t, se_ty,
                               "main function has wrong type");
        }
        _ => {
            span_bug!(main_span,
                      "main has a non-function type: found `{}`",
                      main_t);
        }
    }
}

fn check_start_fn_ty(ccx: &CrateCtxt,
                     start_id: ast::NodeId,
                     start_span: Span) {
    let tcx = ccx.tcx;
    let start_t = tcx.node_id_to_type(start_id);
    match start_t.sty {
        ty::TyFnDef(..) => {
            match tcx.map.find(start_id) {
                Some(hir_map::NodeItem(it)) => {
                    match it.node {
                        hir::ItemFn(_,_,_,_,ref ps,_)
                        if ps.is_parameterized() => {
                            span_err!(tcx.sess, start_span, E0132,
                                      "start function is not allowed to have type parameters");
                            return;
                        }
                        _ => ()
                    }
                }
                _ => ()
            }

            let start_def_id = ccx.tcx.map.local_def_id(start_id);
            let substs = tcx.mk_substs(Substs::empty());
            let se_ty = tcx.mk_fn_def(start_def_id, substs,
                                      tcx.mk_bare_fn(ty::BareFnTy {
                unsafety: hir::Unsafety::Normal,
                abi: Abi::Rust,
                sig: ty::Binder(ty::FnSig {
                    inputs: vec!(
                        tcx.types.isize,
                        tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
                    ),
                    output: ty::FnConverging(tcx.types.isize),
                    variadic: false,
                }),
            }));

            require_same_types(ccx, start_span, start_t, se_ty,
                               "start function has wrong type");
        }
        _ => {
            span_bug!(start_span,
                      "start has a non-function type: found `{}`",
                      start_t);
        }
    }
}

fn check_for_entry_fn(ccx: &CrateCtxt) {
    let tcx = ccx.tcx;
    let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
    match *tcx.sess.entry_fn.borrow() {
        Some((id, sp)) => match tcx.sess.entry_type.get() {
            Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
            Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
            Some(config::EntryNone) => {}
            None => bug!("entry function without a type")
        },
        None => {}
    }
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             trait_map: hir::TraitMap)
                             -> CompileResult {
    let time_passes = tcx.sess.time_passes();
    let ccx = CrateCtxt {
        trait_map: trait_map,
        all_traits: RefCell::new(None),
        stack: RefCell::new(Vec::new()),
        tcx: tcx
    };

    // this ensures that later parts of type checking can assume that items
    // have valid types and not error
    tcx.sess.track_errors(|| {
        time(time_passes, "type collecting", ||
             collect::collect_item_types(&ccx));

    })?;

    time(time_passes, "variance inference", ||
         variance::infer_variance(tcx));

    tcx.sess.track_errors(|| {
      time(time_passes, "coherence checking", ||
          coherence::check_coherence(&ccx));
    })?;

    time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;

    time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;

    time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;

    time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;

    check_unused::check_crate(tcx);
    check_for_entry_fn(&ccx);

    let err_count = tcx.sess.err_count();
    if err_count == 0 {
        Ok(())
    } else {
        Err(err_count)
    }
}

__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
<|endoftext|>


<commit_before><commit_msg>test: Test yielding in crust functions<commit_after>native mod rustrt {
    fn rust_dbg_call(cb: *u8,
                     data: ctypes::uintptr_t) -> ctypes::uintptr_t;
}

crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
    if data == 1u {
        data
    } else {
        count(data - 1u) + count(data - 1u)
    }
}

fn count(n: uint) -> uint {
    task::yield();
    rustrt::rust_dbg_call(cb, n)
}

fn main() {
    iter::repeat(10u) {||
        task::spawn {||
            let result = count(5u);
            #debug("result = %?", result);
            assert result == 16u;
        };
    }
}
<|endoftext|>


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

pub struct Chan;
pub struct ChanSelect<'c, T> {
    chans: Vec<(&'c Chan, T)>,
}
impl<'c, T> ChanSelect<'c, T> {
    pub fn add_recv_ret(&mut self, chan: &'c Chan, ret: T)
    {
        self.chans.push((chan, ret));
    }
}
fn main() {}
<|endoftext|>