From bb643ccab845aec930948424d4082620b3c451ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 9 Mar 2018 13:18:32 +0300 Subject: [PATCH] Make command-line arguments owned --- src/bin/cli/mod.rs | 42 ++++----- src/cargo/ops/cargo_clean.rs | 4 +- src/cargo/ops/cargo_compile.rs | 104 +++++++++++------------ src/cargo/ops/cargo_doc.rs | 2 +- src/cargo/ops/cargo_generate_lockfile.rs | 4 +- src/cargo/ops/cargo_install.rs | 2 +- src/cargo/ops/cargo_package.rs | 4 +- src/cargo/ops/cargo_run.rs | 2 +- 8 files changed, 78 insertions(+), 86 deletions(-) diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs index 743a925be..411c289a0 100644 --- a/src/bin/cli/mod.rs +++ b/src/bin/cli/mod.rs @@ -134,7 +134,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { let ws = workspace_from_args(config, args)?; let opts = ops::CleanOptions { config, - spec: &values(args, "package"), + spec: values(args, "package"), target: args.value_of("target"), release: args.is_present("release"), }; @@ -285,7 +285,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { }; let options = OutputMetadataOptions { - features: values(args, "features").to_vec(), + features: values(args, "features"), all_features: args.is_present("all-features"), no_default_features: args.is_present("no-default-features"), no_deps: args.is_present("no-deps"), @@ -413,7 +413,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { let mut compile_opts = compile_options_from_args_for_single_package( config, args, mode, )?; - compile_opts.target_rustc_args = Some(&values(args, "args")); + compile_opts.target_rustc_args = Some(values(args, "args")); ops::compile(&ws, &compile_opts)?; Ok(()) } @@ -422,7 +422,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { let mut compile_opts = compile_options_from_args_for_single_package( config, args, CompileMode::Doc { deps: false }, )?; - compile_opts.target_rustdoc_args = Some(&values(args, "args")); + compile_opts.target_rustdoc_args = Some(values(args, "args")); let doc_opts = ops::DocOptions { open_result: args.is_present("open"), compile_opts, @@ -449,10 +449,10 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { if doc { compile_opts.mode = ops::CompileMode::Doctest; compile_opts.filter = ops::CompileFilter::new(true, - &[], false, - &[], false, - &[], false, - &[], false, + Vec::new(), false, + Vec::new(), false, + Vec::new(), false, + Vec::new(), false, false); } @@ -483,7 +483,7 @@ fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult { ("uninstall", Some(args)) => { let root = args.value_of("root"); let specs = args.values_of("spec").unwrap_or_default().collect(); - ops::uninstall(root, specs, values(args, "bin"), config)?; + ops::uninstall(root, specs, &values(args, "bin"), config)?; Ok(()) } ("update", Some(args)) => { @@ -897,20 +897,13 @@ a global configuration.") } } - -fn values<'a>(args: &ArgMatches, name: &str) -> &'a [String] { - let owned: Vec = args.values_of(name).unwrap_or_default() +fn values(args: &ArgMatches, name: &str) -> Vec { + args.values_of(name).unwrap_or_default() .map(|s| s.to_string()) - .collect(); - let owned = owned.into_boxed_slice(); - let ptr = owned.as_ptr(); - let len = owned.len(); - ::std::mem::forget(owned); - unsafe { - slice::from_raw_parts(ptr, len) - } + .collect() } + fn config_from_args(config: &mut Config, args: &ArgMatches) -> CargoResult<()> { let color = args.value_of("color").map(|s| s.to_string()); config.configure( @@ -952,8 +945,8 @@ fn compile_options_from_args<'a>( ) -> CargoResult> { let spec = Packages::from_flags( args.is_present("all"), - &values(args, "exclude"), - &values(args, "package"), + values(args, "exclude"), + values(args, "package"), )?; let message_format = match args.value_of("message-format") { @@ -973,7 +966,7 @@ fn compile_options_from_args<'a>( config, jobs: jobs_from_args(args)?, target: args.value_of("target"), - features: &values(args, "features"), + features: values(args, "features"), all_features: args.is_present("all-features"), no_default_features: args.is_present("no-default-features"), spec, @@ -998,8 +991,7 @@ fn compile_options_from_args_for_single_package<'a>( mode: CompileMode, ) -> CargoResult> { let mut compile_opts = compile_options_from_args(config, args, mode)?; - let packages = values(args, "package"); - compile_opts.spec = Packages::Packages(&packages); + compile_opts.spec = Packages::Packages(values(args, "package")); Ok(compile_opts) } diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 647aa1d36..287b1533a 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -9,7 +9,7 @@ use util::paths; use ops::{self, Context, BuildConfig, Kind, Unit}; pub struct CleanOptions<'a> { - pub spec: &'a [String], + pub spec: Vec, pub target: Option<&'a str>, pub config: &'a Config, pub release: bool, @@ -45,7 +45,7 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> { profiles)?; let mut units = Vec::new(); - for spec in opts.spec { + for spec in opts.spec.iter() { // Translate the spec to a Package let pkgid = resolve.query(spec)?; let pkg = packages.get(pkgid)?; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 7477f6a0c..08be6ea75 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -43,16 +43,16 @@ pub struct CompileOptions<'a> { /// The target platform to compile for (example: `i686-unknown-linux-gnu`). pub target: Option<&'a str>, /// Extra features to build for the root package - pub features: &'a [String], + pub features: Vec, /// Flag whether all available features should be built for the root package pub all_features: bool, /// Flag if the default feature should be built for the root package pub no_default_features: bool, /// A set of packages to build. - pub spec: Packages<'a>, + pub spec: Packages, /// Filter to apply to the root package to select which targets will be /// built. - pub filter: CompileFilter<'a>, + pub filter: CompileFilter, /// Whether this is a release build or not pub release: bool, /// Mode for this compile. @@ -60,10 +60,10 @@ pub struct CompileOptions<'a> { /// `--error_format` flag for the compiler. pub message_format: MessageFormat, /// Extra arguments to be passed to rustdoc (for main crate and dependencies) - pub target_rustdoc_args: Option<&'a [String]>, + pub target_rustdoc_args: Option>, /// The specified target will be compiled with all the available arguments, /// note that this only accounts for the *final* invocation of rustc - pub target_rustc_args: Option<&'a [String]>, + pub target_rustc_args: Option>, } impl<'a> CompileOptions<'a> { @@ -73,10 +73,10 @@ impl<'a> CompileOptions<'a> { config, jobs: None, target: None, - features: &[], + features: Vec::new(), all_features: false, no_default_features: false, - spec: ops::Packages::Packages(&[]), + spec: ops::Packages::Packages(Vec::new()), mode, release: false, filter: CompileFilter::Default { required_features_filterable: false }, @@ -103,16 +103,16 @@ pub enum MessageFormat { Json } -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum Packages<'a> { +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Packages { Default, All, - OptOut(&'a [String]), - Packages(&'a [String]), + OptOut(Vec), + Packages(Vec), } -impl<'a> Packages<'a> { - pub fn from_flags(all: bool, exclude: &'a [String], package: &'a [String]) +impl Packages { + pub fn from_flags(all: bool, exclude: Vec, package: Vec) -> CargoResult { Ok(match (all, exclude.len(), package.len()) { @@ -124,28 +124,28 @@ impl<'a> Packages<'a> { }) } - pub fn into_package_id_specs(self, ws: &Workspace) -> CargoResult> { - let specs = match self { + pub fn into_package_id_specs(&self, ws: &Workspace) -> CargoResult> { + let specs = match *self { Packages::All => { ws.members() .map(Package::package_id) .map(PackageIdSpec::from_package_id) .collect() } - Packages::OptOut(opt_out) => { + Packages::OptOut(ref opt_out) => { ws.members() .map(Package::package_id) .map(PackageIdSpec::from_package_id) .filter(|p| opt_out.iter().position(|x| *x == p.name()).is_none()) .collect() } - Packages::Packages(packages) if packages.is_empty() => { + Packages::Packages(ref packages) if packages.is_empty() => { ws.current_opt() .map(Package::package_id) .map(PackageIdSpec::from_package_id) .into_iter().collect() } - Packages::Packages(packages) => { + Packages::Packages(ref packages) => { packages.iter().map(|p| PackageIdSpec::parse(p)).collect::>>()? } Packages::Default => { @@ -166,14 +166,14 @@ impl<'a> Packages<'a> { } } -#[derive(Clone, Copy, Debug)] -pub enum FilterRule<'a> { +#[derive(Debug)] +pub enum FilterRule { All, - Just (&'a [String]), + Just(Vec), } #[derive(Debug)] -pub enum CompileFilter<'a> { +pub enum CompileFilter { Default { /// Flag whether targets can be safely skipped when required-features are not satisfied. required_features_filterable: bool, @@ -181,10 +181,10 @@ pub enum CompileFilter<'a> { Only { all_targets: bool, lib: bool, - bins: FilterRule<'a>, - examples: FilterRule<'a>, - tests: FilterRule<'a>, - benches: FilterRule<'a>, + bins: FilterRule, + examples: FilterRule, + tests: FilterRule, + benches: FilterRule, } } @@ -217,7 +217,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>, exec: Arc) -> CargoResult> { - let CompileOptions { config, jobs, target, spec, features, + let CompileOptions { config, jobs, target, ref spec, ref features, all_features, no_default_features, release, mode, message_format, ref filter, @@ -257,12 +257,12 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, let mut general_targets = Vec::new(); let mut package_targets = Vec::new(); - match (*target_rustc_args, *target_rustdoc_args) { - (Some(..), _) | - (_, Some(..)) if to_builds.len() != 1 => { + match (target_rustc_args, target_rustdoc_args) { + (&Some(..), _) | + (_, &Some(..)) if to_builds.len() != 1 => { panic!("`rustc` and `rustdoc` should not accept multiple `-p` flags") } - (Some(args), _) => { + (&Some(ref args), _) => { let all_features = resolve_all_features(&resolve_with_overrides, to_builds[0].package_id()); let targets = generate_targets(to_builds[0], profiles, @@ -278,7 +278,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, e.g. `--lib` or `--bin NAME` to specify a single target") } } - (None, Some(args)) => { + (&None, &Some(ref args)) => { let all_features = resolve_all_features(&resolve_with_overrides, to_builds[0].package_id()); let targets = generate_targets(to_builds[0], profiles, @@ -294,7 +294,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, `--lib` or `--bin NAME` to specify a single target") } } - (None, None) => { + (&None, &None) => { for &to_build in to_builds.iter() { let all_features = resolve_all_features(&resolve_with_overrides, to_build.package_id()); @@ -353,8 +353,8 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, } } -impl<'a> FilterRule<'a> { - pub fn new(targets: &'a [String], all: bool) -> FilterRule<'a> { +impl FilterRule { + pub fn new(targets: Vec, all: bool) -> FilterRule { if all { FilterRule::All } else { @@ -365,7 +365,7 @@ impl<'a> FilterRule<'a> { fn matches(&self, target: &Target) -> bool { match *self { FilterRule::All => true, - FilterRule::Just(targets) => { + FilterRule::Just(ref targets) => { targets.iter().any(|x| *x == target.name()) }, } @@ -374,25 +374,25 @@ impl<'a> FilterRule<'a> { fn is_specific(&self) -> bool { match *self { FilterRule::All => true, - FilterRule::Just(targets) => !targets.is_empty(), + FilterRule::Just(ref targets) => !targets.is_empty(), } } pub fn try_collect(&self) -> Option> { match *self { FilterRule::All => None, - FilterRule::Just(targets) => Some(targets.to_vec()), + FilterRule::Just(ref targets) => Some(targets.clone()), } } } -impl<'a> CompileFilter<'a> { +impl CompileFilter { pub fn new(lib_only: bool, - bins: &'a [String], all_bins: bool, - tsts: &'a [String], all_tsts: bool, - exms: &'a [String], all_exms: bool, - bens: &'a [String], all_bens: bool, - all_targets: bool) -> CompileFilter<'a> { + bins: Vec, all_bins: bool, + tsts: Vec, all_tsts: bool, + exms: Vec, all_exms: bool, + bens: Vec, all_bens: bool, + all_targets: bool) -> CompileFilter { let rule_bins = FilterRule::new(bins, all_bins); let rule_tsts = FilterRule::new(tsts, all_tsts); let rule_exms = FilterRule::new(exms, all_exms); @@ -423,7 +423,7 @@ impl<'a> CompileFilter<'a> { pub fn need_dev_deps(&self) -> bool { match *self { CompileFilter::Default { .. } => true, - CompileFilter::Only { examples, tests, benches, .. } => + CompileFilter::Only { ref examples, ref tests, ref benches, .. } => examples.is_specific() || tests.is_specific() || benches.is_specific() } } @@ -431,7 +431,7 @@ impl<'a> CompileFilter<'a> { pub fn matches(&self, target: &Target) -> bool { match *self { CompileFilter::Default { .. } => true, - CompileFilter::Only { lib, bins, examples, tests, benches, .. } => { + CompileFilter::Only { lib, ref bins, ref examples, ref tests, ref benches, .. } => { let rule = match *target.kind() { TargetKind::Bin => bins, TargetKind::Test => tests, @@ -538,11 +538,11 @@ fn generate_auto_targets<'a>(mode: CompileMode, targets: &'a [Target], /// Given a filter rule and some context, propose a list of targets fn propose_indicated_targets<'a>(pkg: &'a Package, - rule: FilterRule, + rule: &FilterRule, desc: &'static str, is_expected_kind: fn(&Target) -> bool, profile: &'a Profile) -> CargoResult>> { - match rule { + match *rule { FilterRule::All => { let result = pkg.targets().iter().filter(|t| is_expected_kind(t)).map(|t| { BuildProposal { @@ -553,7 +553,7 @@ fn propose_indicated_targets<'a>(pkg: &'a Package, }); Ok(result.collect()) } - FilterRule::Just(names) => { + FilterRule::Just(ref names) => { let mut targets = Vec::new(); for name in names { let target = pkg.targets().iter().find(|t| { @@ -658,7 +658,7 @@ fn generate_targets<'a>(pkg: &'a Package, }; generate_auto_targets(mode, pkg.targets(), profile, deps, required_features_filterable) } - CompileFilter::Only { all_targets, lib, bins, examples, tests, benches } => { + CompileFilter::Only { all_targets, lib, ref bins, ref examples, ref tests, ref benches } => { let mut targets = Vec::new(); if lib { @@ -678,7 +678,7 @@ fn generate_targets<'a>(pkg: &'a Package, pkg, examples, "example", Target::is_example, profile)?); // If --tests was specified, add all targets that would be // generated by `cargo test`. - let test_filter = match tests { + let test_filter = match *tests { FilterRule::All => Target::tested, FilterRule::Just(_) => Target::is_test }; @@ -686,7 +686,7 @@ fn generate_targets<'a>(pkg: &'a Package, pkg, tests, "test", test_filter, test_profile)?); // If --benches was specified, add all targets that would be // generated by `cargo bench`. - let bench_filter = match benches { + let bench_filter = match *benches { FilterRule::All => Target::benched, FilterRule::Just(_) => Target::is_bench }; diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index d747b42d0..777cb9956 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -16,7 +16,7 @@ pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> { let specs = options.compile_opts.spec.into_package_id_specs(ws)?; let resolve = ops::resolve_ws_precisely(ws, None, - options.compile_opts.features, + &options.compile_opts.features, options.compile_opts.all_features, options.compile_opts.no_default_features, &specs)?; diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index d08c11b16..e968460f9 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -12,7 +12,7 @@ use util::CargoResult; pub struct UpdateOptions<'a> { pub config: &'a Config, - pub to_update: &'a [String], + pub to_update: Vec, pub precise: Option<&'a str>, pub aggressive: bool, } @@ -57,7 +57,7 @@ pub fn update_lockfile(ws: &Workspace, opts: &UpdateOptions) to_avoid.extend(previous_resolve.iter()); } else { let mut sources = Vec::new(); - for name in opts.to_update { + for name in opts.to_update.iter() { let dep = previous_resolve.query(name)?; if opts.aggressive { fill_with_deps(&previous_resolve, dep, &mut to_avoid, diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 40037e74e..126dfae09 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -504,7 +504,7 @@ fn find_duplicates(dst: &Path, .filter_map(|t| check(t.name().to_string())) .collect() } - CompileFilter::Only { bins, examples, .. } => { + CompileFilter::Only { ref bins, ref examples, .. } => { let all_bins: Vec = bins.try_collect().unwrap_or_else(|| { pkg.targets().iter().filter(|t| t.is_bin()) .map(|t| t.name().to_string()) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index b1fe6e767..4ed1c902b 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -321,10 +321,10 @@ fn run_verify(ws: &Workspace, tar: &FileLock, opts: &PackageOpts) -> CargoResult config, jobs: opts.jobs, target: opts.target, - features: &[], + features: Vec::new(), no_default_features: false, all_features: false, - spec: ops::Packages::Packages(&[]), + spec: ops::Packages::Packages(Vec::new()), filter: ops::CompileFilter::Default { required_features_filterable: true }, release: false, message_format: ops::MessageFormat::Human, diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 81ac77908..cfd26e752 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -13,7 +13,7 @@ pub fn run(ws: &Workspace, Packages::All | Packages::Default | Packages::OptOut(_) => unreachable!("cargo run supports single package only"), - Packages::Packages(xs) => match xs.len() { + Packages::Packages(ref xs) => match xs.len() { 0 => ws.current()?, 1 => ws.members() .find(|pkg| pkg.name() == xs[0]) -- 2.30.2