Make command-line arguments owned
authorAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 9 Mar 2018 10:18:32 +0000 (13:18 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 9 Mar 2018 10:18:32 +0000 (13:18 +0300)
src/bin/cli/mod.rs
src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_doc.rs
src/cargo/ops/cargo_generate_lockfile.rs
src/cargo/ops/cargo_install.rs
src/cargo/ops/cargo_package.rs
src/cargo/ops/cargo_run.rs

index 743a925be87a56e66904f270cabe85045b576b0b..411c289a03b97caebd909b715c4e9ad3d2b8abe0 100644 (file)
@@ -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<String> = args.values_of(name).unwrap_or_default()
+fn values(args: &ArgMatches, name: &str) -> Vec<String> {
+    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<CompileOptions<'a>> {
     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<CompileOptions<'a>> {
     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)
 }
 
index 647aa1d3657eb93feb94f47f842d11036c03ba87..287b1533aa104af4ac4d4acf569eae84e20b1751 100644 (file)
@@ -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<String>,
     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)?;
index 7477f6a0c4639832aa6f1f3bed4572876380639c..08be6ea75eeec01bdb2e01060ae8e27f4ac30af0 100644 (file)
@@ -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<String>,
     /// 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<Vec<String>>,
     /// 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<Vec<String>>,
 }
 
 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<String>),
+    Packages(Vec<String>),
 }
 
-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<String>, package: Vec<String>)
         -> CargoResult<Self>
     {
         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<Vec<PackageIdSpec>> {
-        let specs = match self {
+    pub fn into_package_id_specs(&self, ws: &Workspace) -> CargoResult<Vec<PackageIdSpec>> {
+        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::<CargoResult<Vec<_>>>()?
             }
             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<String>),
 }
 
 #[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<Executor>)
                       -> CargoResult<ops::Compilation<'a>> {
-    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<String>, 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<Vec<String>> {
         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<String>, all_bins: bool,
+               tsts: Vec<String>, all_tsts: bool,
+               exms: Vec<String>, all_exms: bool,
+               bens: Vec<String>, 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<Vec<BuildProposal<'a>>> {
-    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
             };
index d747b42d0985c6e02b4a451725f89b65969b32c4..777cb99568bdaf92da221f2fce3de8506e14b889 100644 (file)
@@ -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)?;
index d08c11b1662e37221d053d5b4805a6bd768fbded..e968460f999a28e49b150f408b2eb1f1dc90887c 100644 (file)
@@ -12,7 +12,7 @@ use util::CargoResult;
 
 pub struct UpdateOptions<'a> {
     pub config: &'a Config,
-    pub to_update: &'a [String],
+    pub to_update: Vec<String>,
     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,
index 40037e74e4e3bbe26c386452d9480a295c704177..126dfae0902e150fdeac66462716db2390a87f4f 100644 (file)
@@ -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<String> = bins.try_collect().unwrap_or_else(|| {
                 pkg.targets().iter().filter(|t| t.is_bin())
                                     .map(|t| t.name().to_string())
index b1fe6e767596e9ea6d8a8fdfc83c5a59848c619b..4ed1c902b3d4988173b0e68475763435f6b606f8 100644 (file)
@@ -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,
index 81ac7790844c5c15124a0ef11e403c35a6b05605..cfd26e7524ba3610ce21b4e64ae6f9f55c87eda5 100644 (file)
@@ -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])