<commit_before>use cargo::core::features;
use cargo::{self, drop_print, drop_println, CliResult, Config};
use clap::{AppSettings, Arg, ArgMatches};

use super::commands;
use super::list_commands;
use crate::command_prelude::*;

pub fn main(config: &mut Config) -> CliResult {
    // CAUTION: Be careful with using `config` until it is configured below.
    // In general, try to avoid loading config values unless necessary (like
    // the [alias] table).
    let args = match cli().get_matches_safe() {
        Ok(args) => args,
        Err(e) => {
            if e.kind == clap::ErrorKind::UnrecognizedSubcommand {
                // An unrecognized subcommand might be an external subcommand.
                let cmd = &e.info.as_ref().unwrap()[0].to_owned();
                return super::execute_external_subcommand(config, cmd, &[cmd, "--help"])
                    .map_err(|_| e.into());
            } else {
                return Err(e.into());
            }
        }
    };

    if args.value_of("unstable-features") == Some("help") {
        drop_println!(
            config,
            "
Available unstable (nightly-only) flags:

    -Z avoid-dev-deps   -- Avoid installing dev-dependencies if possible
    -Z minimal-versions -- Install minimal dependency versions instead of maximum
    -Z no-index-update  -- Do not update the registry, avoids a network request for benchmarking
    -Z unstable-options -- Allow the usage of unstable options
    -Z timings          -- Display concurrency information
    -Z doctest-xcompile -- Compile and run doctests for non-host target using runner config
    -Z crate-versions   -- Add crate versions to generated docs

Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
        );
        if !features::nightly_features_allowed() {
            drop_println!(
                config,
                "\nUnstable flags are only available on the nightly channel \
                 of Cargo, but this is the `{}` channel.\n\
                 {}",
                features::channel(),
                features::SEE_CHANNELS
            );
        }
        drop_println!(
            config,
            "\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \
             for more information about these flags."
        );
        return Ok(());
    }

    let is_verbose = args.occurrences_of("verbose") > 0;
    if args.is_present("version") {
        let version = get_version_string(is_verbose);
        drop_print!(config, "{}", version);
        return Ok(());
    }

    if let Some(code) = args.value_of("explain") {
        let mut procss = config.load_global_rustc(None)?.process();
        procss.arg("--explain").arg(code).exec()?;
        return Ok(());
    }

    if args.is_present("list") {
        drop_println!(config, "Installed Commands:");
        for command in list_commands(config) {
            match command {
                CommandInfo::BuiltIn { name, about } => {
                    let summary = about.unwrap_or_default();
                    let summary = summary.lines().next().unwrap_or(&summary); // display only the first line
                    drop_println!(config, "    {:<20} {}", name, summary);
                }
                CommandInfo::External { name, path } => {
                    if is_verbose {
                        drop_println!(config, "    {:<20} {}", name, path.display());
                    } else {
                        drop_println!(config, "    {}", name);
                    }
                }
            }
        }
        return Ok(());
    }

    // Global args need to be extracted before expanding aliases because the
    // clap code for extracting a subcommand discards global options
    // (appearing before the subcommand).
    let (expanded_args, global_args) = expand_aliases(config, args)?;
    let (cmd, subcommand_args) = match expanded_args.subcommand() {
        (cmd, Some(args)) => (cmd, args),
        _ => {
            // No subcommand provided.
            cli().print_help()?;
            return Ok(());
        }
    };
    config_configure(config, &expanded_args, subcommand_args, global_args)?;
    super::init_git_transports(config);

    execute_subcommand(config, cmd, subcommand_args)
}

pub fn get_version_string(is_verbose: bool) -> String {
    let version = cargo::version();
    let mut version_string = version.to_string();
    version_string.push_str("\n");
    if is_verbose {
        version_string.push_str(&format!(
            "release: {}.{}.{}\n",
            version.major, version.minor, version.patch
        ));
        if let Some(ref cfg) = version.cfg_info {
            if let Some(ref ci) = cfg.commit_info {
                version_string.push_str(&format!("commit-hash: {}\n", ci.commit_hash));
                version_string.push_str(&format!("commit-date: {}\n", ci.commit_date));
            }
        }
    }
    version_string
}

fn expand_aliases(
    config: &mut Config,
    args: ArgMatches<'static>,
) -> Result<(ArgMatches<'static>, GlobalArgs), CliError> {
    if let (cmd, Some(args)) = args.subcommand() {
        match (
            commands::builtin_exec(cmd),
            super::aliased_command(config, cmd)?,
        ) {
            (Some(_), Some(_)) => {
                // User alias conflicts with a built-in subcommand
                config.shell().warn(format!(
                    "user-defined alias `{}` is ignored, because it is shadowed by a built-in command",
                    cmd,
                ))?;
            }
            (_, Some(mut alias)) => {
                alias.extend(
                    args.values_of("")
                        .unwrap_or_default()
                        .map(|s| s.to_string()),
                );
                // new_args strips out everything before the subcommand, so
                // capture those global options now.
                // Note that an alias to an external command will not receive
                // these arguments. That may be confusing, but such is life.
                let global_args = GlobalArgs::new(args);
                let new_args = cli()
                    .setting(AppSettings::NoBinaryName)
                    .get_matches_from_safe(alias)?;
                let (expanded_args, _) = expand_aliases(config, new_args)?;
                return Ok((expanded_args, global_args));
            }
            (_, None) => {}
        }
    };

    Ok((args, GlobalArgs::default()))
}

fn config_configure(
    config: &mut Config,
    args: &ArgMatches<'_>,
    subcommand_args: &ArgMatches<'_>,
    global_args: GlobalArgs,
) -> CliResult {
    let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
    let verbose = global_args.verbose + args.occurrences_of("verbose") as u32;
    // quiet is unusual because it is redefined in some subcommands in order
    // to provide custom help text.
    let quiet =
        args.is_present("quiet") || subcommand_args.is_present("quiet") || global_args.quiet;
    let global_color = global_args.color; // Extract so it can take reference.
    let color = args.value_of("color").or_else(|| global_color.as_deref());
    let frozen = args.is_present("frozen") || global_args.frozen;
    let locked = args.is_present("locked") || global_args.locked;
    let offline = args.is_present("offline") || global_args.offline;
    let mut unstable_flags = global_args.unstable_flags;
    if let Some(values) = args.values_of("unstable-features") {
        unstable_flags.extend(values.map(|s| s.to_string()));
    }
    let mut config_args = global_args.config_args;
    if let Some(values) = args.values_of("config") {
        config_args.extend(values.map(|s| s.to_string()));
    }
    config.configure(
        verbose,
        quiet,
        color,
        frozen,
        locked,
        offline,
        arg_target_dir,
        &unstable_flags,
        &config_args,
    )?;
    Ok(())
}

fn execute_subcommand(
    config: &mut Config,
    cmd: &str,
    subcommand_args: &ArgMatches<'_>,
) -> CliResult {
    if let Some(exec) = commands::builtin_exec(cmd) {
        return exec(config, subcommand_args);
    }

    let mut ext_args: Vec<&str> = vec![cmd];
    ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
    super::execute_external_subcommand(config, cmd, &ext_args)
}

#[derive(Default)]
struct GlobalArgs {
    verbose: u32,
    quiet: bool,
    color: Option<String>,
    frozen: bool,
    locked: bool,
    offline: bool,
    unstable_flags: Vec<String>,
    config_args: Vec<String>,
}

impl GlobalArgs {
    fn new(args: &ArgMatches<'_>) -> GlobalArgs {
        GlobalArgs {
            verbose: args.occurrences_of("verbose") as u32,
            quiet: args.is_present("quiet"),
            color: args.value_of("color").map(|s| s.to_string()),
            frozen: args.is_present("frozen"),
            locked: args.is_present("locked"),
            offline: args.is_present("offline"),
            unstable_flags: args
                .values_of_lossy("unstable-features")
                .unwrap_or_default(),
            config_args: args
                .values_of("config")
                .unwrap_or_default()
                .map(|s| s.to_string())
                .collect(),
        }
    }
}

fn cli() -> App {
    App::new("cargo")
        .settings(&[
            AppSettings::UnifiedHelpMessage,
            AppSettings::DeriveDisplayOrder,
            AppSettings::VersionlessSubcommands,
            AppSettings::AllowExternalSubcommands,
        ])
        .template(
            "\
Rust's package manager

USAGE:
    {usage}

OPTIONS:
{unified}

Some common cargo commands are (see all commands with --list):
    build       Compile the current package
    check       Analyze the current package and report errors, but don't build object files
    clean       Remove the target directory
    doc         Build this package's and its dependencies' documentation
    new         Create a new cargo package
    init        Create a new cargo package in an existing directory
    run         Run a binary or example of the local package
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock
    search      Search registry for crates
    publish     Package and upload this package to the registry
    install     Install a Rust binary. Default location is $HOME/.cargo/bin
    uninstall   Uninstall a Rust binary

See 'cargo help <command>' for more information on a specific command.\n",
        )
        .arg(opt("version", "Print version info and exit").short("V"))
        .arg(opt("list", "List installed commands"))
        .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
        .arg(
            opt(
                "verbose",
                "Use verbose output (-vv very verbose/build.rs output)",
            )
            .short("v")
            .multiple(true)
            .global(true),
        )
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(
            opt("color", "Coloring: auto, always, never")
                .value_name("WHEN")
                .global(true),
        )
        .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
        .arg(opt("locked", "Require Cargo.lock is up to date").global(true))
        .arg(opt("offline", "Run without accessing the network").global(true))
        .arg(
            multi_opt("config", "KEY=VALUE", "Override a configuration value")
                .global(true)
                .hidden(true),
        )
        .arg(
            Arg::with_name("unstable-features")
                .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
                .short("Z")
                .value_name("FLAG")
                .multiple(true)
                .number_of_values(1)
                .global(true),
        )
        .subcommands(commands::builtin())
}
<commit_msg>Show alias in help message<commit_after>use cargo::core::features;
use cargo::{self, drop_print, drop_println, CliResult, Config};
use clap::{AppSettings, Arg, ArgMatches};

use super::commands;
use super::list_commands;
use crate::command_prelude::*;

pub fn main(config: &mut Config) -> CliResult {
    // CAUTION: Be careful with using `config` until it is configured below.
    // In general, try to avoid loading config values unless necessary (like
    // the [alias] table).
    let args = match cli().get_matches_safe() {
        Ok(args) => args,
        Err(e) => {
            if e.kind == clap::ErrorKind::UnrecognizedSubcommand {
                // An unrecognized subcommand might be an external subcommand.
                let cmd = &e.info.as_ref().unwrap()[0].to_owned();
                return super::execute_external_subcommand(config, cmd, &[cmd, "--help"])
                    .map_err(|_| e.into());
            } else {
                return Err(e.into());
            }
        }
    };

    if args.value_of("unstable-features") == Some("help") {
        drop_println!(
            config,
            "
Available unstable (nightly-only) flags:

    -Z avoid-dev-deps   -- Avoid installing dev-dependencies if possible
    -Z minimal-versions -- Install minimal dependency versions instead of maximum
    -Z no-index-update  -- Do not update the registry, avoids a network request for benchmarking
    -Z unstable-options -- Allow the usage of unstable options
    -Z timings          -- Display concurrency information
    -Z doctest-xcompile -- Compile and run doctests for non-host target using runner config
    -Z crate-versions   -- Add crate versions to generated docs

Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
        );
        if !features::nightly_features_allowed() {
            drop_println!(
                config,
                "\nUnstable flags are only available on the nightly channel \
                 of Cargo, but this is the `{}` channel.\n\
                 {}",
                features::channel(),
                features::SEE_CHANNELS
            );
        }
        drop_println!(
            config,
            "\nSee https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \
             for more information about these flags."
        );
        return Ok(());
    }

    let is_verbose = args.occurrences_of("verbose") > 0;
    if args.is_present("version") {
        let version = get_version_string(is_verbose);
        drop_print!(config, "{}", version);
        return Ok(());
    }

    if let Some(code) = args.value_of("explain") {
        let mut procss = config.load_global_rustc(None)?.process();
        procss.arg("--explain").arg(code).exec()?;
        return Ok(());
    }

    if args.is_present("list") {
        drop_println!(config, "Installed Commands:");
        for command in list_commands(config) {
            match command {
                CommandInfo::BuiltIn { name, about } => {
                    let summary = about.unwrap_or_default();
                    let summary = summary.lines().next().unwrap_or(&summary); // display only the first line
                    drop_println!(config, "    {:<20} {}", name, summary);
                }
                CommandInfo::External { name, path } => {
                    if is_verbose {
                        drop_println!(config, "    {:<20} {}", name, path.display());
                    } else {
                        drop_println!(config, "    {}", name);
                    }
                }
            }
        }
        return Ok(());
    }

    // Global args need to be extracted before expanding aliases because the
    // clap code for extracting a subcommand discards global options
    // (appearing before the subcommand).
    let (expanded_args, global_args) = expand_aliases(config, args)?;
    let (cmd, subcommand_args) = match expanded_args.subcommand() {
        (cmd, Some(args)) => (cmd, args),
        _ => {
            // No subcommand provided.
            cli().print_help()?;
            return Ok(());
        }
    };
    config_configure(config, &expanded_args, subcommand_args, global_args)?;
    super::init_git_transports(config);

    execute_subcommand(config, cmd, subcommand_args)
}

pub fn get_version_string(is_verbose: bool) -> String {
    let version = cargo::version();
    let mut version_string = version.to_string();
    version_string.push_str("\n");
    if is_verbose {
        version_string.push_str(&format!(
            "release: {}.{}.{}\n",
            version.major, version.minor, version.patch
        ));
        if let Some(ref cfg) = version.cfg_info {
            if let Some(ref ci) = cfg.commit_info {
                version_string.push_str(&format!("commit-hash: {}\n", ci.commit_hash));
                version_string.push_str(&format!("commit-date: {}\n", ci.commit_date));
            }
        }
    }
    version_string
}

fn expand_aliases(
    config: &mut Config,
    args: ArgMatches<'static>,
) -> Result<(ArgMatches<'static>, GlobalArgs), CliError> {
    if let (cmd, Some(args)) = args.subcommand() {
        match (
            commands::builtin_exec(cmd),
            super::aliased_command(config, cmd)?,
        ) {
            (Some(_), Some(_)) => {
                // User alias conflicts with a built-in subcommand
                config.shell().warn(format!(
                    "user-defined alias `{}` is ignored, because it is shadowed by a built-in command",
                    cmd,
                ))?;
            }
            (_, Some(mut alias)) => {
                alias.extend(
                    args.values_of("")
                        .unwrap_or_default()
                        .map(|s| s.to_string()),
                );
                // new_args strips out everything before the subcommand, so
                // capture those global options now.
                // Note that an alias to an external command will not receive
                // these arguments. That may be confusing, but such is life.
                let global_args = GlobalArgs::new(args);
                let new_args = cli()
                    .setting(AppSettings::NoBinaryName)
                    .get_matches_from_safe(alias)?;
                let (expanded_args, _) = expand_aliases(config, new_args)?;
                return Ok((expanded_args, global_args));
            }
            (_, None) => {}
        }
    };

    Ok((args, GlobalArgs::default()))
}

fn config_configure(
    config: &mut Config,
    args: &ArgMatches<'_>,
    subcommand_args: &ArgMatches<'_>,
    global_args: GlobalArgs,
) -> CliResult {
    let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
    let verbose = global_args.verbose + args.occurrences_of("verbose") as u32;
    // quiet is unusual because it is redefined in some subcommands in order
    // to provide custom help text.
    let quiet =
        args.is_present("quiet") || subcommand_args.is_present("quiet") || global_args.quiet;
    let global_color = global_args.color; // Extract so it can take reference.
    let color = args.value_of("color").or_else(|| global_color.as_deref());
    let frozen = args.is_present("frozen") || global_args.frozen;
    let locked = args.is_present("locked") || global_args.locked;
    let offline = args.is_present("offline") || global_args.offline;
    let mut unstable_flags = global_args.unstable_flags;
    if let Some(values) = args.values_of("unstable-features") {
        unstable_flags.extend(values.map(|s| s.to_string()));
    }
    let mut config_args = global_args.config_args;
    if let Some(values) = args.values_of("config") {
        config_args.extend(values.map(|s| s.to_string()));
    }
    config.configure(
        verbose,
        quiet,
        color,
        frozen,
        locked,
        offline,
        arg_target_dir,
        &unstable_flags,
        &config_args,
    )?;
    Ok(())
}

fn execute_subcommand(
    config: &mut Config,
    cmd: &str,
    subcommand_args: &ArgMatches<'_>,
) -> CliResult {
    if let Some(exec) = commands::builtin_exec(cmd) {
        return exec(config, subcommand_args);
    }

    let mut ext_args: Vec<&str> = vec![cmd];
    ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
    super::execute_external_subcommand(config, cmd, &ext_args)
}

#[derive(Default)]
struct GlobalArgs {
    verbose: u32,
    quiet: bool,
    color: Option<String>,
    frozen: bool,
    locked: bool,
    offline: bool,
    unstable_flags: Vec<String>,
    config_args: Vec<String>,
}

impl GlobalArgs {
    fn new(args: &ArgMatches<'_>) -> GlobalArgs {
        GlobalArgs {
            verbose: args.occurrences_of("verbose") as u32,
            quiet: args.is_present("quiet"),
            color: args.value_of("color").map(|s| s.to_string()),
            frozen: args.is_present("frozen"),
            locked: args.is_present("locked"),
            offline: args.is_present("offline"),
            unstable_flags: args
                .values_of_lossy("unstable-features")
                .unwrap_or_default(),
            config_args: args
                .values_of("config")
                .unwrap_or_default()
                .map(|s| s.to_string())
                .collect(),
        }
    }
}

fn cli() -> App {
    App::new("cargo")
        .settings(&[
            AppSettings::UnifiedHelpMessage,
            AppSettings::DeriveDisplayOrder,
            AppSettings::VersionlessSubcommands,
            AppSettings::AllowExternalSubcommands,
        ])
        .template(
            "\
Rust's package manager

USAGE:
    {usage}

OPTIONS:
{unified}

Some common cargo commands are (see all commands with --list):
    build, b    Compile the current package
    check, c    Analyze the current package and report errors, but don't build object files
    clean       Remove the target directory
    doc         Build this package's and its dependencies' documentation
    new         Create a new cargo package
    init        Create a new cargo package in an existing directory
    run, r      Run a binary or example of the local package
    test, t     Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock
    search      Search registry for crates
    publish     Package and upload this package to the registry
    install     Install a Rust binary. Default location is $HOME/.cargo/bin
    uninstall   Uninstall a Rust binary

See 'cargo help <command>' for more information on a specific command.\n",
        )
        .arg(opt("version", "Print version info and exit").short("V"))
        .arg(opt("list", "List installed commands"))
        .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
        .arg(
            opt(
                "verbose",
                "Use verbose output (-vv very verbose/build.rs output)",
            )
            .short("v")
            .multiple(true)
            .global(true),
        )
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(
            opt("color", "Coloring: auto, always, never")
                .value_name("WHEN")
                .global(true),
        )
        .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
        .arg(opt("locked", "Require Cargo.lock is up to date").global(true))
        .arg(opt("offline", "Run without accessing the network").global(true))
        .arg(
            multi_opt("config", "KEY=VALUE", "Override a configuration value")
                .global(true)
                .hidden(true),
        )
        .arg(
            Arg::with_name("unstable-features")
                .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
                .short("Z")
                .value_name("FLAG")
                .multiple(true)
                .number_of_values(1)
                .global(true),
        )
        .subcommands(commands::builtin())
}
<|endoftext|>


<commit_before>use std::ops::{Index, IndexMut, Mul, Add};

#[macro_use]
extern crate quick_error;

extern crate nalgebra;
use nalgebra::{DMat};

extern crate image;
use image::{ImageBuffer, Luma, DynamicImage};

extern crate rand;
use rand::{StdRng, Rng, SeedableRng, Closed01};

type FloatType = f64;
type Mat = DMat<FloatType>;

fn horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for col in cols {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for row in rows {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn mat_to_image(mat: &Mat) -> DynamicImage {
    let mut image_buffer
        = ImageBuffer::new(mat.ncols() as u32, mat.nrows() as u32);
    for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
        let value = mat.index((y as usize, x as usize));
        let byte = (*value * 255.).round() as u8;
        *pixel = Luma([byte]);
    }
    DynamicImage::ImageLuma8(image_buffer)
}

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        Io(err: std::io::Error) {}
        Image(err: image::ImageError) {}
    }
}

fn save_as_png(mat: &Mat, filename: &str) -> Result<(), ImageSaveError> {
    let image = mat_to_image(&mat);
    let path = std::path::Path::new(filename);
    let mut file = try!(std::fs::File::create(&path)
                        .map_err(ImageSaveError::Io));
    image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
}

fn linear_combination(factors: &[Mat], coefficients: &[FloatType]) -> Mat {
    assert!(0 < factors.len());
    assert_eq!(factors.len(), coefficients.len());
    let nrows = factors[0].nrows();
    let ncols = factors[0].ncols();
    let mut result = DMat::new_zeros(nrows, ncols);
    for (factor, coefficient) in factors.iter().zip(coefficients.iter()) {
        assert_eq!(factor.nrows(), nrows);
        assert_eq!(factor.ncols(), ncols);
        result = result.add(factor.clone().mul(coefficient.clone()));
    }
    // result.div(factors.len() as FloatType)
    result
}

fn random_linear_combination<R: Rng>(factors: &[Mat], rng: &mut R) -> Mat {
    let mut coefficients: Vec<f64> = Vec::new();
    for _ in 0..factors.len() {
        let Closed01(random) = rng.gen::<Closed01<f64>>();
        coefficients.push(random / 2.);
    }
    linear_combination(factors, &coefficients[..])
}

fn main() {
    let mut factors: Vec<Mat> = Vec::new();

    factors.push(horizontal_line(9, 0..5));
    for row in (0..9).rev() {
        factors.push(horizontal_line(row, 0..10));
    }

    factors.push(vertical_line(5..10, 0));
    for col in 1..10 {
        factors.push(vertical_line(0..10, col));
    }

    println!("factors:\n");
    for (i, factor) in factors.iter().enumerate() {
        save_as_png(&factor, &format!("factor-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut horizontal_evolving: Vec<Mat> = Vec::new();
    for start_col in 0..6 {
        horizontal_evolving.push(horizontal_line(9, start_col..(start_col + 5)));
    }

    println!("short horizontal bar that moves from left to right:\n");
    for (i, factor) in horizontal_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("horizontal-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut vertical_evolving: Vec<Mat> = Vec::new();
    for start_row in (0..6).rev() {
        vertical_evolving.push(vertical_line(start_row..(start_row + 5), 0));
    }

    println!("short vertical bar that moves from bottom to top:\n");
    for (i, factor) in vertical_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("vertical-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    for i in 0..10 {
        let combination = random_linear_combination(&factors[..], &mut rng);
        save_as_png(&combination, &format!("combination-{}.png", i)[..]).unwrap();
    }
}
<commit_msg>testdata generation complete<commit_after>use std::ops::{Index, IndexMut, Mul, Add, Div};

#[macro_use]
extern crate quick_error;

extern crate nalgebra;
use nalgebra::{DMat, DVec};

extern crate image;
use image::{ImageBuffer, Luma, DynamicImage};

extern crate rand;
use rand::{StdRng, Rng, SeedableRng, Closed01};

type FloatType = f64;
type Mat = DMat<FloatType>;

fn horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for col in cols {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for row in rows {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn mat_to_image(mat: &Mat) -> DynamicImage {
    let mut image_buffer
        = ImageBuffer::new(mat.ncols() as u32, mat.nrows() as u32);
    for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
        let value = mat.index((y as usize, x as usize));
        let byte = (*value * 255.).round() as u8;
        *pixel = Luma([byte]);
    }
    DynamicImage::ImageLuma8(image_buffer)
}

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        Io(err: std::io::Error) {}
        Image(err: image::ImageError) {}
    }
}

fn save_as_png(mat: &Mat, filename: &str) -> Result<(), ImageSaveError> {
    let image = mat_to_image(&mat);
    let path = std::path::Path::new(filename);
    let mut file = try!(std::fs::File::create(&path)
                        .map_err(ImageSaveError::Io));
    image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
}

fn linear_combination(factors: &[Mat], coefficients: &[FloatType]) -> Mat {
    assert!(0 < factors.len());
    assert_eq!(factors.len(), coefficients.len());
    let nrows = factors[0].nrows();
    let ncols = factors[0].ncols();
    let mut result = DMat::new_zeros(nrows, ncols);
    for (factor, coefficient) in factors.iter().zip(coefficients.iter()) {
        assert_eq!(factor.nrows(), nrows);
        assert_eq!(factor.ncols(), ncols);
        result = result.add(factor.clone().mul(coefficient.clone()));
    }
    // result.div(factors.len() as FloatType)
    result
}

fn random_coefficient<R: Rng>(rng: &mut R) -> FloatType {
    let Closed01(random) = rng.gen::<Closed01<FloatType>>();
    random
}

fn random_coefficients<R: Rng>(rng: &mut R, count: usize) -> DVec<FloatType> {
    let mut coefficients: DVec<FloatType> = DVec::new_zeros(count);
    for i in 0..count {
        coefficients[i] = random_coefficient(rng);
    }
    coefficients
}

fn main() {
    let mut factors: Vec<Mat> = Vec::new();

    factors.push(horizontal_line(9, 0..5));
    for row in (0..9).rev() {
        factors.push(horizontal_line(row, 0..10));
    }

    factors.push(vertical_line(5..10, 0));
    for col in 1..10 {
        factors.push(vertical_line(0..10, col));
    }

    println!("factors:\n");
    for (i, factor) in factors.iter().enumerate() {
        save_as_png(&factor, &format!("factor-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut horizontal_evolving: Vec<Mat> = Vec::new();
    for start_col in 0..6 {
        horizontal_evolving.push(horizontal_line(9, start_col..(start_col + 5)));
    }

    println!("short horizontal bar that moves from left to right:\n");
    for (i, factor) in horizontal_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("horizontal-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut vertical_evolving: Vec<Mat> = Vec::new();
    for start_row in (0..6).rev() {
        vertical_evolving.push(vertical_line(start_row..(start_row + 5), 0));
    }

    println!("short vertical bar that moves from bottom to top:\n");
    for (i, factor) in vertical_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("vertical-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    // for i in 0..10 {
    //     let combination = random_linear_combination(&factors[..], &mut rng);
    //     save_as_png(&combination, &format!("combination-{}.png", i)[..]).unwrap();
    // }

    let mut iter = horizontal_evolving.iter()
        .zip(vertical_evolving.iter()).enumerate();
    for (step, (horizontal, vertical)) in iter {
        for i in 0..10 {
            // static factors
            let random_coefficients = random_coefficients(&mut rng, factors.len()).div(4.);
            let result = linear_combination(&factors[..], random_coefficients.as_slice());

            // evolving factors
            let horizontal_coefficient = random_coefficient(&mut rng) / 4.;
            let result = result.add(
                horizontal.clone().mul(horizontal_coefficient));

            let vertical_coefficient = random_coefficient(&mut rng) / 4.;
            let result = result.add(
                vertical.clone().mul(vertical_coefficient));

            save_as_png(&result, &format!("test-{}-{}.png", step, i)[..]).unwrap();
        }
    }
}
<|endoftext|>


<commit_before>#![feature(process, path, env)]
use std::process::Command;
use std::env::current_dir;

fn main() {

  assert!(
    Command::new("mkdir")
      .args(&["-p", "target/test-ir"])
      .status()
      .unwrap()
      .success()
  );

  assert!(
  	Command::new("clang++")
  		.args(&["test-ir/test-ir.cc", "-S", "-emit-llvm", "-O2", "-o", "target/test-ir/test-ir-cpp.ll"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("rustc")
  		.args(&["test-ir/test-ir.rs", "--crate-type", "lib", "--emit", "llvm-ir", "-O", "-o", "target/test-ir/test-ir-rs.ll"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("llvm-as")
  		.args(&["target/test-ir/test-ir-cpp.ll", "-o=target/test-ir/test-ir-cpp.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("llvm-as")
  		.args(&["target/test-ir/test-ir-rs.ll", "-o=target/test-ir/test-ir-rs.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("llvm-link")
  		.args(&["target/test-ir/test-ir-cpp.bc", "target/test-ir/test-ir-rs.bc", "-o=target/test-ir/test-module.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);

}<commit_msg>Disable ir code in rust.<commit_after>#![feature(process, path, env)]
use std::process::Command;
use std::env::current_dir;

fn main() {

  assert!(
    Command::new("mkdir")
      .args(&["-p", "target/test-ir"])
      .status()
      .unwrap()
      .success()
  );

  assert!(
  	Command::new("clang++")
  		.args(&["test-ir/test-ir.cc", "-S", "-emit-llvm", "-O2", "-o", "target/test-ir/test-ir-cpp.ll"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("llvm-as")
  		.args(&["target/test-ir/test-ir-cpp.ll", "-o=target/test-ir/test-ir-cpp.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);

  /*
  assert!(
  	Command::new("rustc")
  		.args(&["test-ir/test-ir.rs", "--crate-type", "lib", "--emit", "llvm-ir", "-O", "-o", "target/test-ir/test-ir-rs.ll"])
    	.status()
    	.unwrap()
    	.success()
 	);

  assert!(
  	Command::new("llvm-as")
  		.args(&["target/test-ir/test-ir-rs.ll", "-o=target/test-ir/test-ir-rs.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);*/

  assert!(
  	Command::new("llvm-link")
  		.args(&["target/test-ir/test-ir-cpp.bc", "-o=target/test-ir/test-module.bc"])
    	.status()
    	.unwrap()
    	.success()
 	);

}<|endoftext|>


<commit_before>use error::*;
use super::Command;

extern crate chrono;

use lib::fs::*;
use lib::io::*;
use lib::setting::*;
use self::chrono::Local;
use std::fs;
use std::io::Error as IoError;
use std::path::PathBuf;

pub struct Sweep;

impl Command for Sweep {
    fn validation(&self) -> bool { true }

    fn usage(&self) -> Usage {
        return Usage::new(UsageKind::Sweep);
    }

    fn main(&self) -> Result<(), CliError> {
        println!("Sweep ...\n");

        let now  = Local::now();
        let date = now.format("%Y-%m-%d").to_string();

        let path_to_dust_box = path_buf![storage_dir(), date, "dusts"];
        try!(create_essential_dir_all(&path_to_dust_box));

        let ignore = try!(read_ignore_file());

        let target_files = walk_dir(".")
            .difference(&ignore)
            .cloned()
            .collect::<Vec<String>>();
        try!(move_files_to_dust_box(target_files, &path_to_dust_box));

        try!(move_empty_dir_to_dust_box(&path_to_dust_box));

        Ok(())
    }
}

fn move_files_to_dust_box(target_files: Vec<String>, path_to_dust_box: &PathBuf) -> Result<(), CliError> {
    for target in &target_files {
        print_with_tag(0, Tag::Execution, "Analyze the path to file");

        let target_path = path_buf![&target];
        let target_name = try!(extract_file_name(&target_path).ok_or(CannotHappenError));
        let target_base = try!(target_path.parent().ok_or(CannotHappenError));
        let to = path_buf![&path_to_dust_box, target_base];

        print_with_okay(1);

        try!(create_essential_dir_all(&to));

        print_with_tag(0, Tag::Execution, format!("Move \"{}\" to dust box", target_name));

        // forcedly overwrite if the file exists with same name.
        try!(fs::rename(target, path_buf![to, target_name]));
        print_with_okay(1);
    }

    Ok(())
}

fn move_empty_dir_to_dust_box(path_to_dust_box: &PathBuf) -> Result<(), IoError> {
    let all_dirs = dirs_ordered_by_descending_depth(".");
    for dir in all_dirs.iter().filter(|d| *d != ".") {
        print_with_tag(0, Tag::Execution, format!("Remove \"{}\" directory", dir));

        match fs::remove_dir(dir) {
            Ok(_) => {
                print_with_okay(1);
                try!(create_essential_dir_all(&path_buf![&path_to_dust_box, dir]));
            },
            Err(why) => match why.raw_os_error() {
                Some(39) => print_with_tag(1, Tag::Notice, "The directory is not empty. Cancelled to remove it"),
                _        => return Err(why),
            },
        };
    }

    Ok(())
}
<commit_msg>[Remedy] Do not use extract_file_name() if useless<commit_after>use error::*;
use super::Command;

extern crate chrono;

use lib::fs::*;
use lib::io::*;
use lib::setting::*;
use self::chrono::Local;
use std::fs;
use std::io::Error as IoError;
use std::path::PathBuf;

pub struct Sweep;

impl Command for Sweep {
    fn validation(&self) -> bool { true }

    fn usage(&self) -> Usage {
        return Usage::new(UsageKind::Sweep);
    }

    fn main(&self) -> Result<(), CliError> {
        println!("Sweep ...\n");

        let now  = Local::now();
        let date = now.format("%Y-%m-%d").to_string();

        let path_to_dust_box = path_buf![storage_dir(), date, "dusts"];
        try!(create_essential_dir_all(&path_to_dust_box));

        let ignore = try!(read_ignore_file());

        let target_files = walk_dir(".")
            .difference(&ignore)
            .cloned()
            .collect::<Vec<String>>();
        try!(move_files_to_dust_box(target_files, &path_to_dust_box));

        try!(move_empty_dir_to_dust_box(&path_to_dust_box));

        Ok(())
    }
}

fn move_files_to_dust_box(target_files: Vec<String>, path_to_dust_box: &PathBuf) -> Result<(), CliError> {
    for target in &target_files {
        print_with_tag(0, Tag::Execution, "Analyze the path to file");

        let target_path = path_buf![&target];
        let target_file = try!(target_path.file_name().ok_or(CannotHappenError));
        let target_base = try!(target_path.parent().ok_or(CannotHappenError));
        let to = path_buf![&path_to_dust_box, target_base];

        print_with_okay(1);

        try!(create_essential_dir_all(&to));

        let target_name = extract_file_name(&target_path).unwrap_or("<Unknown File Name>");
        print_with_tag(0, Tag::Execution, format!("Move \"{}\" to dust box", target_name));

        // forcedly overwrite if the file exists with same name.
        try!(fs::rename(target, path_buf![to, target_file]));
        print_with_okay(1);
    }

    Ok(())
}

fn move_empty_dir_to_dust_box(path_to_dust_box: &PathBuf) -> Result<(), IoError> {
    let all_dirs = dirs_ordered_by_descending_depth(".");
    for dir in all_dirs.iter().filter(|d| *d != ".") {
        print_with_tag(0, Tag::Execution, format!("Remove \"{}\" directory", dir));

        match fs::remove_dir(dir) {
            Ok(_) => {
                print_with_okay(1);
                try!(create_essential_dir_all(&path_buf![&path_to_dust_box, dir]));
            },
            Err(why) => match why.raw_os_error() {
                Some(39) => print_with_tag(1, Tag::Notice, "The directory is not empty. Cancelled to remove it"),
                _        => return Err(why),
            },
        };
    }

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

#![allow(clippy::trivially_copy_pass_by_ref)]
pub mod ser {
    use chrono::Duration;
    use serde::Serializer;

    pub fn bool_to_string<S>(v: &bool, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        Ok(serializer.serialize_str(if *v { "true" } else { "false" })?)
    }

    pub fn duration_option_to_int<S>(v: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_i64(v.unwrap_or(Duration::seconds(0)).num_seconds())
    }

    pub fn duration_to_int<S>(v: &Duration, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_i64(v.num_seconds())
    }
}

pub mod de {
    use chrono::Duration;
    use serde::{de, Deserialize, Deserializer};

    pub fn duration_from_str<'de, D>(deserializer: D) -> Result<Duration, D::Error>
    where
        D: Deserializer<'de>,
    {
        use parse_duration::parse;

        let s = String::deserialize(deserializer)?;
        Ok(Duration::from_std(parse(&s).map_err(de::Error::custom)?).map_err(de::Error::custom)?)
    }

    pub fn octal_from_str<'de, D>(deserializer: D) -> Result<u32, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(u32::from_str_radix(&s, 8).map_err(de::Error::custom)?)
    }

    pub fn duration_from_int<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let i = i64::deserialize(deserializer)?;
        Ok(if i > 0 {
            Some(Duration::seconds(i))
        } else {
            None
        })
    }

    pub fn bool_from_str<'de, D>(deserializer: D) -> Result<bool, D::Error>
    where
        D: Deserializer<'de>,
    {
        use std::str::FromStr;

        let s = String::deserialize(deserializer)?;
        bool::from_str(&s).map_err(de::Error::custom)
    }

    pub fn vec_from_str<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(String::deserialize(deserializer)?
            .split(',')
            .map(std::string::ToString::to_string)
            .collect())
    }

    pub fn supported_hardware_any<'de, D>(deserializer: D) -> Result<(), D::Error>
    where
        D: Deserializer<'de>,
    {
        if String::deserialize(deserializer)? == "any" {
            Ok(())
        } else {
            Err(de::Error::custom("expected \"any\""))
        }
    }
}
<commit_msg>serde_helpers: Simplify serializer code<commit_after>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

#![allow(clippy::trivially_copy_pass_by_ref)]
pub mod ser {
    use chrono::Duration;
    use serde::Serializer;

    pub fn bool_to_string<S>(v: &bool, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(if *v { "true" } else { "false" })
    }

    pub fn duration_option_to_int<S>(v: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_i64(v.unwrap_or(Duration::seconds(0)).num_seconds())
    }

    pub fn duration_to_int<S>(v: &Duration, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_i64(v.num_seconds())
    }
}

pub mod de {
    use chrono::Duration;
    use serde::{de, Deserialize, Deserializer};

    pub fn duration_from_str<'de, D>(deserializer: D) -> Result<Duration, D::Error>
    where
        D: Deserializer<'de>,
    {
        use parse_duration::parse;

        let s = String::deserialize(deserializer)?;
        Ok(Duration::from_std(parse(&s).map_err(de::Error::custom)?).map_err(de::Error::custom)?)
    }

    pub fn octal_from_str<'de, D>(deserializer: D) -> Result<u32, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(u32::from_str_radix(&s, 8).map_err(de::Error::custom)?)
    }

    pub fn duration_from_int<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let i = i64::deserialize(deserializer)?;
        Ok(if i > 0 {
            Some(Duration::seconds(i))
        } else {
            None
        })
    }

    pub fn bool_from_str<'de, D>(deserializer: D) -> Result<bool, D::Error>
    where
        D: Deserializer<'de>,
    {
        use std::str::FromStr;

        let s = String::deserialize(deserializer)?;
        bool::from_str(&s).map_err(de::Error::custom)
    }

    pub fn vec_from_str<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(String::deserialize(deserializer)?
            .split(',')
            .map(std::string::ToString::to_string)
            .collect())
    }

    pub fn supported_hardware_any<'de, D>(deserializer: D) -> Result<(), D::Error>
    where
        D: Deserializer<'de>,
    {
        if String::deserialize(deserializer)? == "any" {
            Ok(())
        } else {
            Err(de::Error::custom("expected \"any\""))
        }
    }
}
<|endoftext|>


<commit_before>// compile-flags: -Z panic-in-drop=abort -O

// Ensure that unwinding code paths are eliminated from the output after
// optimization.

#![crate_type = "lib"]
use std::any::Any;
use std::mem::forget;

pub struct ExternDrop;
impl Drop for ExternDrop {
    #[inline(always)]
    fn drop(&mut self) {
        // This call may potentially unwind.
        extern "Rust" {
            fn extern_drop();
        }
        unsafe {
            extern_drop();
        }
    }
}

struct AssertNeverDrop;
impl Drop for AssertNeverDrop {
    #[inline(always)]
    fn drop(&mut self) {
        // This call should be optimized away as unreachable.
        extern "C" {
            fn should_not_appear_in_output();
        }
        unsafe {
            should_not_appear_in_output();
        }
    }
}

// CHECK-LABEL: normal_drop
// CHECK-NOT: should_not_appear_in_output
#[no_mangle]
pub fn normal_drop(x: ExternDrop) {
    let guard = AssertNeverDrop;
    drop(x);
    forget(guard);
}

// CHECK-LABEL: indirect_drop
// CHECK-NOT: should_not_appear_in_output
#[no_mangle]
pub fn indirect_drop(x: Box<dyn Any>) {
    let guard = AssertNeverDrop;
    drop(x);
    forget(guard);
}
<commit_msg>Make expectation in panic-in-drop-abort.rs test more precise<commit_after>// compile-flags: -Z panic-in-drop=abort -O

// Ensure that unwinding code paths are eliminated from the output after
// optimization.

// CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output

#![crate_type = "lib"]
use std::any::Any;
use std::mem::forget;

pub struct ExternDrop;
impl Drop for ExternDrop {
    #[inline(always)]
    fn drop(&mut self) {
        // This call may potentially unwind.
        extern "Rust" {
            fn extern_drop();
        }
        unsafe {
            extern_drop();
        }
    }
}

struct AssertNeverDrop;
impl Drop for AssertNeverDrop {
    #[inline(always)]
    fn drop(&mut self) {
        // This call should be optimized away as unreachable.
        extern "C" {
            fn should_not_appear_in_output();
        }
        unsafe {
            should_not_appear_in_output();
        }
    }
}

#[no_mangle]
pub fn normal_drop(x: ExternDrop) {
    let guard = AssertNeverDrop;
    drop(x);
    forget(guard);
}

#[no_mangle]
pub fn indirect_drop(x: Box<dyn Any>) {
    let guard = AssertNeverDrop;
    drop(x);
    forget(guard);
}
<|endoftext|>


<commit_before>// only-cdb
// ignore-tidy-linelength
// compile-flags:-g

// cdb-command: g

// Note: The natvis used to visualize niche-layout enums don't work correctly in cdb
//       so the best we can do is to make sure we are generating the right debuginfo.
//       Therefore, we use the `!` [format specifier](https://docs.microsoft.com/en-us/visualstudio/debugger/format-specifiers-in-cpp?view=vs-2019#BKMK_Visual_Studio_2012_format_specifiers)
//       to disable the natvis for a given expression. We also provide the `-r2` flag
//       to expand the expression 2 levels.

// cdb-command: dx -r2 a,!
// cdb-check:a,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
// cdb-check:        [+0x000] __0              : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : 0x2 [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]

// cdb-command: dx -r2 b,!
// cdb-check:b,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
// cdb-check:        [+0x000] __0              : 0x11 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : None (0x11) [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]

// cdb-command: dx -r2 c,!
// cdb-check:c,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : 0x11 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : Tag1 (0x11) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 d,!
// cdb-check:d,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : 0x10 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 e,!
// cdb-check:e,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : 0x13 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : Tag2 (0x13) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 f,!
// cdb-check:f,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              : 0x[...] : 0x1 [Type: unsigned int *]
// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 g,!
// cdb-check:g,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              : 0x0 [Type: unsigned int *]
// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 h,!
// cdb-check:h,!              : Some [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [+0x000] variant0         [Type: enum$<core::option::Option<u32> >::None]
// cdb-check:    [+0x000] variant1         [Type: enum$<core::option::Option<u32> >::Some]
// cdb-check:        [+0x004] __0              : 0xc [Type: unsigned int]
// cdb-check:    [+0x000] discriminant     : Some (0x1) [Type: core::option::Option]

// cdb-command: dx h
// cdb-check:h                : Some [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [variant]        : Some
// cdb-check:    [+0x004] __0              : 0xc [Type: unsigned int]

// cdb-command: dx -r2 i,!
// cdb-check:i,!              : None [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [+0x000] variant0         [Type: enum$<core::option::Option<u32> >::None]
// cdb-check:    [+0x000] variant1         [Type: enum$<core::option::Option<u32> >::Some]
// cdb-check:        [+0x004] __0              : 0x5c0065 [Type: unsigned int]
// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: core::option::Option]

// cdb-command: dx i
// cdb-check:i                : None [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [variant]        : None

// cdb-command: dx j
// cdb-check:j                : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]

// cdb-command: dx -r2 k,!
// cdb-check:k,!              [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              [Type: alloc::string::String]
// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 l,!
// cdb-check:l,!              : $T2 [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>]
// cdb-check:    [+0x000] Ok               [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
// cdb-check:        [+0x000] __0              : 0x2a [Type: unsigned int]

pub enum CStyleEnum {
    Low = 2,
    High = 16,
}

pub enum NicheLayoutEnum {
    Tag1,
    Data { my_data: CStyleEnum },
    Tag2,
}

pub enum Empty { }

fn main() {
    let a = Some(CStyleEnum::Low);
    let b = Option::<CStyleEnum>::None;
    let c = NicheLayoutEnum::Tag1;
    let d = NicheLayoutEnum::Data { my_data: CStyleEnum::High };
    let e = NicheLayoutEnum::Tag2;
    let f = Some(&1u32);
    let g = Option::<&'static u32>::None;
    let h = Some(12u32);
    let i = Option::<u32>::None;
    let j = CStyleEnum::High;
    let k = Some("IAMA optional string!".to_string());
    let l = Result::<u32, Empty>::Ok(42);

    zzz(); // #break
}

fn zzz() { () }
<commit_msg>Fix failing test on i686-pc-windows-msvc<commit_after>// only-cdb
// ignore-tidy-linelength
// compile-flags:-g

// cdb-command: g

// Note: The natvis used to visualize niche-layout enums don't work correctly in cdb
//       so the best we can do is to make sure we are generating the right debuginfo.
//       Therefore, we use the `!` [format specifier](https://docs.microsoft.com/en-us/visualstudio/debugger/format-specifiers-in-cpp?view=vs-2019#BKMK_Visual_Studio_2012_format_specifiers)
//       to disable the natvis for a given expression. We also provide the `-r2` flag
//       to expand the expression 2 levels.

// cdb-command: dx -r2 a,!
// cdb-check:a,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
// cdb-check:        [+0x000] __0              : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : 0x2 [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]

// cdb-command: dx -r2 b,!
// cdb-check:b,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
// cdb-check:        [+0x000] __0              : 0x11 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : None (0x11) [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]

// cdb-command: dx -r2 c,!
// cdb-check:c,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : 0x11 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : Tag1 (0x11) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 d,!
// cdb-check:d,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : 0x10 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 e,!
// cdb-check:e,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Data]
// cdb-check:        [+0x000] my_data          : 0x13 [Type: msvc_pretty_enums::CStyleEnum]
// cdb-check:    [+0x000] discriminant     : Tag2 (0x13) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]

// cdb-command: dx -r2 f,!
// cdb-check:f,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              : 0x[...] : 0x1 [Type: unsigned int *]
// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 g,!
// cdb-check:g,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              : 0x0 [Type: unsigned int *]
// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 h,!
// cdb-check:h,!              : Some [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [+0x000] variant0         [Type: enum$<core::option::Option<u32> >::None]
// cdb-check:    [+0x000] variant1         [Type: enum$<core::option::Option<u32> >::Some]
// cdb-check:        [+0x004] __0              : 0xc [Type: unsigned int]
// cdb-check:    [+0x000] discriminant     : Some (0x1) [Type: core::option::Option]

// cdb-command: dx h
// cdb-check:h                : Some [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [variant]        : Some
// cdb-check:    [+0x004] __0              : 0xc [Type: unsigned int]

// cdb-command: dx -r2 i,!
// cdb-check:i,!              : None [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [+0x000] variant0         [Type: enum$<core::option::Option<u32> >::None]
// cdb-check:    [+0x000] variant1         [Type: enum$<core::option::Option<u32> >::Some]
// cdb-check:        [+0x004] __0              : 0x[...] [Type: unsigned int]
// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: core::option::Option]

// cdb-command: dx i
// cdb-check:i                : None [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [<Raw View>]     [Type: enum$<core::option::Option<u32> >]
// cdb-check:    [variant]        : None

// cdb-command: dx j
// cdb-check:j                : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]

// cdb-command: dx -r2 k,!
// cdb-check:k,!              [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Some]
// cdb-check:        [+0x000] __0              [Type: alloc::string::String]
// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Discriminant$]

// cdb-command: dx -r2 l,!
// cdb-check:l,!              : $T2 [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>]
// cdb-check:    [+0x000] Ok               [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
// cdb-check:        [+0x000] __0              : 0x2a [Type: unsigned int]

pub enum CStyleEnum {
    Low = 2,
    High = 16,
}

pub enum NicheLayoutEnum {
    Tag1,
    Data { my_data: CStyleEnum },
    Tag2,
}

pub enum Empty { }

fn main() {
    let a = Some(CStyleEnum::Low);
    let b = Option::<CStyleEnum>::None;
    let c = NicheLayoutEnum::Tag1;
    let d = NicheLayoutEnum::Data { my_data: CStyleEnum::High };
    let e = NicheLayoutEnum::Tag2;
    let f = Some(&1u32);
    let g = Option::<&'static u32>::None;
    let h = Some(12u32);
    let i = Option::<u32>::None;
    let j = CStyleEnum::High;
    let k = Some("IAMA optional string!".to_string());
    let l = Result::<u32, Empty>::Ok(42);

    zzz(); // #break
}

fn zzz() { () }
<|endoftext|>


<commit_before>// check-pass

// Bastion of the Turbofish
// ------------------------
// Beware travellers, lest you venture into waters callous and unforgiving,
// where hope must be abandoned, ere it is cruelly torn from you. For here
// stands the bastion of the Turbofish: an impenetrable fortress holding
// unshaking against those who would dare suggest the supererogation of the
// Turbofish.
//
// Once I was young and foolish and had the impudence to imagine that I could
// shake free from the coils by which that creature had us tightly bound. I
// dared to suggest that there was a better way: a brighter future, in which
// Rustaceans both new and old could be rid of that vile beast. But alas! In
// my foolhardiness my ignorance was unveiled and my dreams were dashed
// unforgivingly against the rock of syntactic ambiguity.
//
// This humble program, small and insignificant though it might seem,
// demonstrates that to which we had previously cast a blind eye: an ambiguity
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.

// See https://github.com/rust-lang/rust/pull/53562
// and https://github.com/rust-lang/rfcs/pull/2527
// for context.

fn main() {
    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
    let _: (bool, bool) = (oh<woe, is>(me));
}
<commit_msg>memorialize Anna Harren in the bastion of the turbofish<commit_after>// check-pass

// Bastion of the Turbofish
// ------------------------
// Beware travellers, lest you venture into waters callous and unforgiving,
// where hope must be abandoned, ere it is cruelly torn from you. For here
// stands the bastion of the Turbofish: an impenetrable fortress holding
// unshaking against those who would dare suggest the supererogation of the
// Turbofish.
//
// Once I was young and foolish and had the impudence to imagine that I could
// shake free from the coils by which that creature had us tightly bound. I
// dared to suggest that there was a better way: a brighter future, in which
// Rustaceans both new and old could be rid of that vile beast. But alas! In
// my foolhardiness my ignorance was unveiled and my dreams were dashed
// unforgivingly against the rock of syntactic ambiguity.
//
// This humble program, small and insignificant though it might seem,
// demonstrates that to which we had previously cast a blind eye: an ambiguity
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.
//
// RIP Anna Harren, Guardian Angel of the Hallowed Turbofish. <3

// See https://github.com/rust-lang/rust/pull/53562
// and https://github.com/rust-lang/rfcs/pull/2527
// and https://twitter.com/garblefart/status/1393236602856611843
// for context.

fn main() {
    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
    let _: (bool, bool) = (oh<woe, is>(me));
}
<|endoftext|>


<commit_before>//! Checks that all error codes have at least one test to prevent having error
//! codes that are silently not thrown by the compiler anymore.

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::path::Path;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
    "E0183", "E0227", "E0279", "E0280", "E0311", "E0313", "E0314", "E0315", "E0377", "E0461",
    "E0462", "E0464", "E0465", "E0472", "E0473", "E0474", "E0475", "E0476", "E0479", "E0480",
    "E0481", "E0482", "E0483", "E0484", "E0485", "E0486", "E0487", "E0488", "E0489", "E0514",
    "E0519", "E0523", "E0553", "E0554", "E0570", "E0629", "E0630", "E0640", "E0717", "E0727",
    "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] =
    &["E0570", "E0601", "E0602", "E0639", "E0729", "E0749", "E0750"];

fn check_error_code_explanation(
    f: &str,
    error_codes: &mut HashMap<String, bool>,
    err_code: String,
) -> bool {
    let mut invalid_compile_fail_format = false;
    let mut found_error_code = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains('E') {
                if !found_error_code {
                    error_codes.insert(err_code.clone(), true);
                    found_error_code = true;
                }
            } else if s.contains("compile-fail") {
                invalid_compile_fail_format = true;
            }
        } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            if !found_error_code {
                error_codes.get_mut(&err_code).map(|x| *x = true);
                found_error_code = true;
            }
        }
    }
    invalid_compile_fail_format
}

fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &String) -> bool {
    let mut can_be_ignored = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            return true;
        }
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains(err_code) {
                return true;
            } else if s.contains("(") {
                // It's very likely that we can't actually make it fail compilation...
                can_be_ignored = true;
            }
        }
    }
    can_be_ignored
}

macro_rules! some_or_continue {
    ($e:expr) => {
        match $e {
            Some(e) => e,
            None => continue,
        }
    };
}

fn extract_error_codes(
    f: &str,
    error_codes: &mut HashMap<String, bool>,
    path: &Path,
    errors: &mut Vec<String>,
) {
    let mut reached_no_explanation = false;

    for line in f.lines() {
        let s = line.trim();
        if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
            if let Some(err_code) = s.splitn(2, ':').next() {
                let err_code = err_code.to_owned();
                if !error_codes.contains_key(&err_code) {
                    error_codes.insert(err_code.clone(), false);
                }
                // Now we extract the tests from the markdown file!
                let md = some_or_continue!(s.splitn(2, "include_str!(\"").nth(1));
                let md_file_name = some_or_continue!(md.splitn(2, "\")").next());
                let path = some_or_continue!(path.parent())
                    .join(md_file_name)
                    .canonicalize()
                    .expect("failed to canonicalize error explanation file path");
                match read_to_string(&path) {
                    Ok(content) => {
                        if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str())
                            && !check_if_error_code_is_test_in_explanation(&content, &err_code)
                        {
                            errors.push(format!(
                                "`{}` doesn't use its own error code in compile_fail example",
                                path.display(),
                            ));
                        }
                        if check_error_code_explanation(&content, error_codes, err_code) {
                            errors.push(format!(
                                "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
                                path.display(),
                            ));
                        }
                    }
                    Err(e) => {
                        eprintln!("Couldn't read `{}`: {}", path.display(), e);
                    }
                }
            }
        } else if reached_no_explanation && s.starts_with('E') {
            if let Some(err_code) = s.splitn(2, ',').next() {
                let err_code = err_code.to_owned();
                if !error_codes.contains_key(&err_code) {
                    // this check should *never* fail!
                    error_codes.insert(err_code, false);
                }
            }
        } else if s == ";" {
            reached_no_explanation = true;
        }
    }
}

fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, bool>) {
    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("error[E") || s.starts_with("warning[E") {
            if let Some(err_code) = s.splitn(2, ']').next() {
                if let Some(err_code) = err_code.splitn(2, '[').nth(1) {
                    let nb = error_codes.entry(err_code.to_owned()).or_insert(false);
                    *nb = true;
                }
            }
        }
    }
}

pub fn check(path: &Path, bad: &mut bool) {
    let mut errors = Vec::new();
    println!("Checking which error codes lack tests...");
    let mut error_codes: HashMap<String, bool> = HashMap::new();
    super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
        let file_name = entry.file_name();
        if file_name == "error_codes.rs" {
            extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
        } else if entry.path().extension() == Some(OsStr::new("stderr")) {
            extract_error_codes_from_tests(contents, &mut error_codes);
        }
    });
    if errors.is_empty() {
        println!("Found {} error codes", error_codes.len());

        for (err_code, nb) in &error_codes {
            if !*nb && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!("Error code {} needs to have at least one UI test!", err_code));
            }
        }
    }
    errors.sort();
    for err in &errors {
        eprintln!("{}", err);
    }
    println!("Found {} error codes with no tests", errors.len());
    if !errors.is_empty() {
        *bad = true;
    }
    println!("Done!");
}
<commit_msg>Remove E0750 from unchecked error codes<commit_after>//! Checks that all error codes have at least one test to prevent having error
//! codes that are silently not thrown by the compiler anymore.

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::read_to_string;
use std::path::Path;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
    "E0183", "E0227", "E0279", "E0280", "E0311", "E0313", "E0314", "E0315", "E0377", "E0461",
    "E0462", "E0464", "E0465", "E0472", "E0473", "E0474", "E0475", "E0476", "E0479", "E0480",
    "E0481", "E0482", "E0483", "E0484", "E0485", "E0486", "E0487", "E0488", "E0489", "E0514",
    "E0519", "E0523", "E0553", "E0554", "E0570", "E0629", "E0630", "E0640", "E0717", "E0727",
    "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729", "E0749"];

fn check_error_code_explanation(
    f: &str,
    error_codes: &mut HashMap<String, bool>,
    err_code: String,
) -> bool {
    let mut invalid_compile_fail_format = false;
    let mut found_error_code = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains('E') {
                if !found_error_code {
                    error_codes.insert(err_code.clone(), true);
                    found_error_code = true;
                }
            } else if s.contains("compile-fail") {
                invalid_compile_fail_format = true;
            }
        } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            if !found_error_code {
                error_codes.get_mut(&err_code).map(|x| *x = true);
                found_error_code = true;
            }
        }
    }
    invalid_compile_fail_format
}

fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &String) -> bool {
    let mut can_be_ignored = false;

    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
            return true;
        }
        if s.starts_with("```") {
            if s.contains("compile_fail") && s.contains(err_code) {
                return true;
            } else if s.contains("(") {
                // It's very likely that we can't actually make it fail compilation...
                can_be_ignored = true;
            }
        }
    }
    can_be_ignored
}

macro_rules! some_or_continue {
    ($e:expr) => {
        match $e {
            Some(e) => e,
            None => continue,
        }
    };
}

fn extract_error_codes(
    f: &str,
    error_codes: &mut HashMap<String, bool>,
    path: &Path,
    errors: &mut Vec<String>,
) {
    let mut reached_no_explanation = false;

    for line in f.lines() {
        let s = line.trim();
        if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
            if let Some(err_code) = s.splitn(2, ':').next() {
                let err_code = err_code.to_owned();
                if !error_codes.contains_key(&err_code) {
                    error_codes.insert(err_code.clone(), false);
                }
                // Now we extract the tests from the markdown file!
                let md = some_or_continue!(s.splitn(2, "include_str!(\"").nth(1));
                let md_file_name = some_or_continue!(md.splitn(2, "\")").next());
                let path = some_or_continue!(path.parent())
                    .join(md_file_name)
                    .canonicalize()
                    .expect("failed to canonicalize error explanation file path");
                match read_to_string(&path) {
                    Ok(content) => {
                        if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str())
                            && !check_if_error_code_is_test_in_explanation(&content, &err_code)
                        {
                            errors.push(format!(
                                "`{}` doesn't use its own error code in compile_fail example",
                                path.display(),
                            ));
                        }
                        if check_error_code_explanation(&content, error_codes, err_code) {
                            errors.push(format!(
                                "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
                                path.display(),
                            ));
                        }
                    }
                    Err(e) => {
                        eprintln!("Couldn't read `{}`: {}", path.display(), e);
                    }
                }
            }
        } else if reached_no_explanation && s.starts_with('E') {
            if let Some(err_code) = s.splitn(2, ',').next() {
                let err_code = err_code.to_owned();
                if !error_codes.contains_key(&err_code) {
                    // this check should *never* fail!
                    error_codes.insert(err_code, false);
                }
            }
        } else if s == ";" {
            reached_no_explanation = true;
        }
    }
}

fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, bool>) {
    for line in f.lines() {
        let s = line.trim();
        if s.starts_with("error[E") || s.starts_with("warning[E") {
            if let Some(err_code) = s.splitn(2, ']').next() {
                if let Some(err_code) = err_code.splitn(2, '[').nth(1) {
                    let nb = error_codes.entry(err_code.to_owned()).or_insert(false);
                    *nb = true;
                }
            }
        }
    }
}

pub fn check(path: &Path, bad: &mut bool) {
    let mut errors = Vec::new();
    println!("Checking which error codes lack tests...");
    let mut error_codes: HashMap<String, bool> = HashMap::new();
    super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
        let file_name = entry.file_name();
        if file_name == "error_codes.rs" {
            extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
        } else if entry.path().extension() == Some(OsStr::new("stderr")) {
            extract_error_codes_from_tests(contents, &mut error_codes);
        }
    });
    if errors.is_empty() {
        println!("Found {} error codes", error_codes.len());

        for (err_code, nb) in &error_codes {
            if !*nb && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
                errors.push(format!("Error code {} needs to have at least one UI test!", err_code));
            }
        }
    }
    errors.sort();
    for err in &errors {
        eprintln!("{}", err);
    }
    println!("Found {} error codes with no tests", errors.len());
    if !errors.is_empty() {
        *bad = true;
    }
    println!("Done!");
}
<|endoftext|>


<commit_before>#![allow(deprecated)]
use std::ops::Index;
use std::path::PathBuf;
use std::{io, fs, slice, cell};
use curl::easy::Easy;
use memmap::{Mmap, Protection};
use flate2::{Flush, Decompress};
use std::io::Write;
use utils::data::{Dataset, DatasetIntf};
use std::rc::Rc;
use tensor::{Tensor, TensorKind};
use torch;

type Sample = (TensorKind, i64);

static URLS: [&str; 4] = ["http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"];
static RAW_FOLDER: &str = "raw";
static PROCESSED_FOLDER: &str = "processed";
static TRAINING_FILE: &str = "training.pt";
static TEST_FILE: &str = "test.pt";

fn create_dir_f(arg: PathBuf) -> io::Result<()> {
    let result = fs::create_dir(arg);
    if let Some(err) = result.err() {
        match err.kind() {
            io::ErrorKind::AlreadyExists => Ok(()),
            _ => Err(err),
        }
    } else {
        Ok(())
    }
}

fn check_exists(arg: &PathBuf) -> io::Result<bool> {
    let train = fs::metadata(arg.join(TRAINING_FILE))?;
    let test = fs::metadata(arg.join(TEST_FILE))?;

    return Ok(train.is_file() && test.is_file());
}

fn download(root: &String) -> io::Result<()> {
    let raw_path = PathBuf::from(root).join(RAW_FOLDER);
    let processed_path = PathBuf::from(root).join(PROCESSED_FOLDER);
    create_dir_f(raw_path.clone())?;
    create_dir_f(processed_path.clone())?;

    for url in URLS.iter() {
        println!("downloading {}", url);
        let paths: Vec<_> = url.split("/").collect();
        let fname: Vec<_> = paths[5].split("/").collect();
        let file_path = raw_path.join(fname[0]);
        let mut file = fs::OpenOptions::new()
            .write(true)
            .create(true)
            .open(file_path)?;
        let mut data = Vec::new();
        let mut handle = Easy::new();
        handle.url(url).unwrap();
        {
            let mut transfer = handle.transfer();
            transfer
                .write_function(|new_data| {
                                    data.extend_from_slice(new_data);
                                    Ok(new_data.len())
                                })
                .unwrap();
            transfer.perform().unwrap();
        }
        let mut output = Vec::with_capacity(data.len());
        // do we have a header?
        Decompress::new(false)
            .decompress_vec(data.as_slice(), &mut output, Flush::Finish)?;
        file.write_all(output.as_slice())?;
    }
    println!("Proceeding");

    let training_set = vec![read_image_file(raw_path.join("train-images-idx3-ubyte"))?,
                            read_label_file(raw_path.join("train-labels-idx1-ubyte"))?];
    let test_set = vec![read_image_file(raw_path.join("t10k-images-idx3-ubyte"))?,
                        read_label_file(raw_path.join("t10k-labels-idx1-ubyte"))?];

    torch::save(processed_path.join(TRAINING_FILE), &training_set)?;
    torch::save(processed_path.join(TEST_FILE), &test_set)?;

    Ok(())
}

fn read_image_file(path: PathBuf) -> io::Result<TensorKind> {
    let fp = Mmap::open_path(path, Protection::Read)?;
    let (length, nrows, ncols);
    {
        let data = unsafe { slice::from_raw_parts(fp.ptr() as *const u32, fp.len()) };
        assert_eq!(data[0], 2051);
        length = data[1] as usize;
        nrows = data[2] as usize;
        ncols = data[3] as usize;
    }
    let data = unsafe { fp.as_slice() };
    let mut images: Vec<Vec<u8>> = Vec::with_capacity(length);
    let mut idx = 16;
    for _ in 0..length {
        let mut img = Vec::with_capacity(nrows * ncols);
        for _ in 0..nrows * ncols {
            img.push(data[idx]);
            idx += 1;
        }
        images.push(img)
    }
    Ok(torch::byte_tensor(images).view(&[-1, 28, 28]))
}

fn read_label_file(path: PathBuf) -> io::Result<TensorKind> {
    let fp = Mmap::open_path(path, Protection::Read)?;
    let length;
    {
        let data = unsafe { slice::from_raw_parts(fp.ptr() as *const u32, fp.len()) };
        assert_eq!(data[0], 20549);
        length = data[1] as usize;
    }
    let data = unsafe { fp.as_slice() };
    let mut labels: Vec<i64> = Vec::with_capacity(length);
    for i in 0..length {
        labels.push(data[8 + i] as i64)
    }
    Ok(torch::long_tensor(labels))
}

pub struct MNIST {
    pub root: String,
    pub train: bool,
    pub data: Tensor<u8>,
    pub labels: Tensor<i64>,
    pub transformed: cell::RefCell<Vec<(TensorKind, i64)>>,
    pub transform: Option<Xfrm>,
}

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct MNISTArgs {
    root: String,
    #[builder(default="true")]
    train: bool,
    #[builder(default="false")]
    download: bool,
}

type Xfrm = Box<fn(&TensorKind) -> TensorKind>;
impl MNISTArgsBuilder {
    pub fn done(self, xfrm: Option<Xfrm>) -> Dataset<Sample> {
        let args = self.build().unwrap();
        Dataset::new(Rc::new(MNIST::new(&args, xfrm)))
    }
}

impl MNIST {
    pub fn build(root: &str) -> MNISTArgsBuilder {
        MNISTArgsBuilder::default().root(root.into())
    }
    pub fn new(args: &MNISTArgs, xfrm: Option<Xfrm>) -> Self {
        if args.download {
            download(&args.root).expect("download failed");
        }
        let processed_path = PathBuf::from(&args.root).join(PROCESSED_FOLDER);
        if !check_exists(&processed_path).expect("Dataset not found, try downloading") {
            panic!("Dataset not found, use download=true to download it");
        }
        let mut v: Vec<TensorKind> = if args.train {
            torch::load(processed_path.join(TRAINING_FILE)).expect("torch load failed")
        } else {
            torch::load(processed_path.join(TEST_FILE)).expect("torch load failed")
        };
        let (data, labels) = (v.remove(0), v.remove(0));
        let count = data.size()[0];
        let mut mutable: Vec<(TensorKind, i64)> = Vec::with_capacity(count);
        for i in 0..count {
            mutable.push((data.s(i).copy().into(), i as i64))
        }

        MNIST {
            root: args.root.clone(),
            train: args.train,
            data: data.into(),
            labels: labels.into(),
            transformed: cell::RefCell::new(mutable),
            transform: xfrm,
        }
    }
}

impl Index<usize> for MNIST {
    type Output = Sample;
    fn index(&self, idx: usize) -> &Self::Output {
        let img = self.data.s(idx);
        let xfrmp = self.transformed.as_ptr();
        let mut xfrm = unsafe { &mut *xfrmp };

        xfrm[idx] = (img.copy().into(), self.labels[idx] as i64);
        &xfrm[idx]
    }
}

impl DatasetIntf<Sample> for MNIST {
    fn len(&self) -> usize {
        if self.train { 60000 } else { 10000 }
    }
    fn iter(&self) -> Box<Iterator<Item = Sample>> {
        unimplemented!();
    }
}
<commit_msg>call transform<commit_after>#![allow(deprecated)]
use std::ops::Index;
use std::path::PathBuf;
use std::{io, fs, slice, cell};
use curl::easy::Easy;
use memmap::{Mmap, Protection};
use flate2::{Flush, Decompress};
use std::io::Write;
use utils::data::{Dataset, DatasetIntf};
use std::rc::Rc;
use tensor::{Tensor, TensorKind};
use torch;

type Sample = (TensorKind, i64);

static URLS: [&str; 4] = ["http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"];
static RAW_FOLDER: &str = "raw";
static PROCESSED_FOLDER: &str = "processed";
static TRAINING_FILE: &str = "training.pt";
static TEST_FILE: &str = "test.pt";

fn create_dir_f(arg: PathBuf) -> io::Result<()> {
    let result = fs::create_dir(arg);
    if let Some(err) = result.err() {
        match err.kind() {
            io::ErrorKind::AlreadyExists => Ok(()),
            _ => Err(err),
        }
    } else {
        Ok(())
    }
}

fn check_exists(arg: &PathBuf) -> io::Result<bool> {
    let train = fs::metadata(arg.join(TRAINING_FILE))?;
    let test = fs::metadata(arg.join(TEST_FILE))?;

    return Ok(train.is_file() && test.is_file());
}

fn download(root: &String) -> io::Result<()> {
    let raw_path = PathBuf::from(root).join(RAW_FOLDER);
    let processed_path = PathBuf::from(root).join(PROCESSED_FOLDER);
    create_dir_f(raw_path.clone())?;
    create_dir_f(processed_path.clone())?;

    for url in URLS.iter() {
        println!("downloading {}", url);
        let paths: Vec<_> = url.split("/").collect();
        let fname: Vec<_> = paths[5].split("/").collect();
        let file_path = raw_path.join(fname[0]);
        let mut file = fs::OpenOptions::new()
            .write(true)
            .create(true)
            .open(file_path)?;
        let mut data = Vec::new();
        let mut handle = Easy::new();
        handle.url(url).unwrap();
        {
            let mut transfer = handle.transfer();
            transfer
                .write_function(|new_data| {
                                    data.extend_from_slice(new_data);
                                    Ok(new_data.len())
                                })
                .unwrap();
            transfer.perform().unwrap();
        }
        let mut output = Vec::with_capacity(data.len());
        // do we have a header?
        Decompress::new(false)
            .decompress_vec(data.as_slice(), &mut output, Flush::Finish)?;
        file.write_all(output.as_slice())?;
    }
    println!("Proceeding");

    let training_set = vec![read_image_file(raw_path.join("train-images-idx3-ubyte"))?,
                            read_label_file(raw_path.join("train-labels-idx1-ubyte"))?];
    let test_set = vec![read_image_file(raw_path.join("t10k-images-idx3-ubyte"))?,
                        read_label_file(raw_path.join("t10k-labels-idx1-ubyte"))?];

    torch::save(processed_path.join(TRAINING_FILE), &training_set)?;
    torch::save(processed_path.join(TEST_FILE), &test_set)?;

    Ok(())
}

fn read_image_file(path: PathBuf) -> io::Result<TensorKind> {
    let fp = Mmap::open_path(path, Protection::Read)?;
    let (length, nrows, ncols);
    {
        let data = unsafe { slice::from_raw_parts(fp.ptr() as *const u32, fp.len()) };
        assert_eq!(data[0], 2051);
        length = data[1] as usize;
        nrows = data[2] as usize;
        ncols = data[3] as usize;
    }
    let data = unsafe { fp.as_slice() };
    let mut images: Vec<Vec<u8>> = Vec::with_capacity(length);
    let mut idx = 16;
    for _ in 0..length {
        let mut img = Vec::with_capacity(nrows * ncols);
        for _ in 0..nrows * ncols {
            img.push(data[idx]);
            idx += 1;
        }
        images.push(img)
    }
    Ok(torch::byte_tensor(images).view(&[-1, 28, 28]))
}

fn read_label_file(path: PathBuf) -> io::Result<TensorKind> {
    let fp = Mmap::open_path(path, Protection::Read)?;
    let length;
    {
        let data = unsafe { slice::from_raw_parts(fp.ptr() as *const u32, fp.len()) };
        assert_eq!(data[0], 20549);
        length = data[1] as usize;
    }
    let data = unsafe { fp.as_slice() };
    let mut labels: Vec<i64> = Vec::with_capacity(length);
    for i in 0..length {
        labels.push(data[8 + i] as i64)
    }
    Ok(torch::long_tensor(labels))
}

pub struct MNIST {
    pub root: String,
    pub train: bool,
    pub data: Tensor<u8>,
    pub labels: Tensor<i64>,
    pub transformed: cell::RefCell<Vec<(TensorKind, i64)>>,
    pub transform: Option<Xfrm>,
}

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct MNISTArgs {
    root: String,
    #[builder(default="true")]
    train: bool,
    #[builder(default="false")]
    download: bool,
}

type Xfrm = Box<fn(&TensorKind) -> TensorKind>;
impl MNISTArgsBuilder {
    pub fn done(self, xfrm: Option<Xfrm>) -> Dataset<Sample> {
        let args = self.build().unwrap();
        Dataset::new(Rc::new(MNIST::new(&args, xfrm)))
    }
}

impl MNIST {
    pub fn build(root: &str) -> MNISTArgsBuilder {
        MNISTArgsBuilder::default().root(root.into())
    }
    pub fn new(args: &MNISTArgs, xfrm: Option<Xfrm>) -> Self {
        if args.download {
            download(&args.root).expect("download failed");
        }
        let processed_path = PathBuf::from(&args.root).join(PROCESSED_FOLDER);
        if !check_exists(&processed_path).expect("Dataset not found, try downloading") {
            panic!("Dataset not found, use download=true to download it");
        }
        let mut v: Vec<TensorKind> = if args.train {
            torch::load(processed_path.join(TRAINING_FILE)).expect("torch load failed")
        } else {
            torch::load(processed_path.join(TEST_FILE)).expect("torch load failed")
        };
        let (data, labels) = (v.remove(0), v.remove(0));
        let count = data.size()[0];
        let mut mutable: Vec<(TensorKind, i64)> = Vec::with_capacity(count);
        for i in 0..count {
            mutable.push((data.s(i).copy().into(), i as i64))
        }

        MNIST {
            root: args.root.clone(),
            train: args.train,
            data: data.into(),
            labels: labels.into(),
            transformed: cell::RefCell::new(mutable),
            transform: xfrm,
        }
    }
}

impl Index<usize> for MNIST {
    type Output = Sample;
    fn index(&self, idx: usize) -> &Self::Output {
        let img = self.data.s(idx);
        let xfrmp = self.transformed.as_ptr();
        let mut xfrm = unsafe { &mut *xfrmp };
        let img = if let Some(ref transform) = self.transform {
            transform(&img.into())
        } else {
            img.copy().into()
        };
        xfrm[idx] = (img, self.labels[idx] as i64);
        &xfrm[idx]
    }
}

impl DatasetIntf<Sample> for MNIST {
    fn len(&self) -> usize {
        if self.train { 60000 } else { 10000 }
    }
    fn iter(&self) -> Box<Iterator<Item = Sample>> {
        unimplemented!();
    }
}
<|endoftext|>