diff --git a/src/bin/cargo/commands/add.rs b/src/bin/cargo/commands/add.rs index 39f0e189e3d..90c4f4dd5df 100644 --- a/src/bin/cargo/commands/add.rs +++ b/src/bin/cargo/commands/add.rs @@ -72,6 +72,10 @@ The package will be removed from your features.") Example uses: - Depending on multiple versions of a crate - Depend on crates with the same name from different registries"), + flag( + "ignore-rust-version", + "Ignore `rust-version` specification in packages (unstable)" + ), ]) .arg_manifest_path() .arg_package("Package to modify") @@ -188,12 +192,24 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let dependencies = parse_dependencies(config, args)?; + let ignore_rust_version = args.flag("ignore-rust-version"); + if ignore_rust_version && !config.cli_unstable().msrv_policy { + return Err(CliError::new( + anyhow::format_err!( + "`--ignore-rust-version` is unstable; pass `-Zmsrv-policy` to enable support for it" + ), + 101, + )); + } + let honor_rust_version = !ignore_rust_version; + let options = AddOptions { config, spec, dependencies, section, dry_run, + honor_rust_version, }; add(&ws, &options)?; diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index 5c519ac09f0..11ca282ee42 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -51,6 +51,8 @@ pub struct AddOptions<'a> { pub section: DepTable, /// Act as if dependencies will be added pub dry_run: bool, + /// Whether the minimum supported Rust version should be considered during resolution + pub honor_rust_version: bool, } /// Add dependencies to a manifest @@ -86,7 +88,9 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<( &manifest, raw, workspace, + &options.spec, &options.section, + options.honor_rust_version, options.config, &mut registry, ) @@ -256,7 +260,9 @@ fn resolve_dependency( manifest: &LocalManifest, arg: &DepOp, ws: &Workspace<'_>, + spec: &Package, section: &DepTable, + honor_rust_version: bool, config: &Config, registry: &mut PackageRegistry<'_>, ) -> CargoResult { @@ -368,7 +374,14 @@ fn resolve_dependency( } dependency = dependency.set_source(src); } else { - let latest = get_latest_dependency(&dependency, false, config, registry)?; + let latest = get_latest_dependency( + spec, + &dependency, + false, + honor_rust_version, + config, + registry, + )?; if dependency.name != latest.name { config.shell().warn(format!( @@ -518,8 +531,10 @@ fn get_existing_dependency( } fn get_latest_dependency( + spec: &Package, dependency: &Dependency, _flag_allow_prerelease: bool, + honor_rust_version: bool, config: &Config, registry: &mut PackageRegistry<'_>, ) -> CargoResult { @@ -529,7 +544,7 @@ fn get_latest_dependency( unreachable!("registry dependencies required, found a workspace dependency"); } MaybeWorkspace::Other(query) => { - let possibilities = loop { + let mut possibilities = loop { match registry.query_vec(&query, QueryKind::Fuzzy) { std::task::Poll::Ready(res) => { break res?; @@ -537,19 +552,79 @@ fn get_latest_dependency( std::task::Poll::Pending => registry.block_until_ready()?, } }; - let latest = possibilities - .iter() - .max_by_key(|s| { - // Fallback to a pre-release if no official release is available by sorting them as - // less. - let stable = s.version().pre.is_empty(); - (stable, s.version()) - }) - .ok_or_else(|| { - anyhow::format_err!( - "the crate `{dependency}` could not be found in registry index." - ) - })?; + + possibilities.sort_by_key(|s| { + // Fallback to a pre-release if no official release is available by sorting them as + // less. + let stable = s.version().pre.is_empty(); + (stable, s.version().clone()) + }); + + let mut latest = possibilities.last().ok_or_else(|| { + anyhow::format_err!( + "the crate `{dependency}` could not be found in registry index." + ) + })?; + + if config.cli_unstable().msrv_policy && honor_rust_version { + fn parse_msrv(rust_version: impl AsRef) -> (u64, u64, u64) { + // HACK: `rust-version` is a subset of the `VersionReq` syntax that only ever + // has one comparator with a required minor and optional patch, and uses no + // other features. If in the future this syntax is expanded, this code will need + // to be updated. + let version_req = semver::VersionReq::parse(rust_version.as_ref()).unwrap(); + assert!(version_req.comparators.len() == 1); + let comp = &version_req.comparators[0]; + assert_eq!(comp.op, semver::Op::Caret); + assert_eq!(comp.pre, semver::Prerelease::EMPTY); + (comp.major, comp.minor.unwrap_or(0), comp.patch.unwrap_or(0)) + } + + if let Some(req_msrv) = spec.rust_version().map(parse_msrv) { + let msrvs = possibilities + .iter() + .map(|s| (s, s.rust_version().map(parse_msrv))) + .collect::>(); + + // Find the latest version of the dep which has a compatible rust-version. To + // determine whether or not one rust-version is compatible with another, we + // compare the lowest possible versions they could represent, and treat + // candidates without a rust-version as compatible by default. + let (latest_msrv, _) = msrvs + .iter() + .filter(|(_, v)| v.map(|msrv| req_msrv >= msrv).unwrap_or(true)) + .last() + .ok_or_else(|| { + // Failing that, try to find the highest version with the lowest + // rust-version to report to the user. + let lowest_candidate = msrvs + .iter() + .min_set_by_key(|(_, v)| v) + .iter() + .map(|(s, _)| s) + .max_by_key(|s| s.version()); + rust_version_incompat_error( + &dependency.name, + spec.rust_version().unwrap(), + lowest_candidate.copied(), + ) + })?; + + if latest_msrv.version() < latest.version() { + config.shell().warn(format_args!( + "ignoring `{dependency}@{latest_version}` (which has a rust-version of \ + {latest_rust_version}) to satisfy this package's rust-version of \ + {rust_version} (use `--ignore-rust-version` to override)", + latest_version = latest.version(), + latest_rust_version = latest.rust_version().unwrap(), + rust_version = spec.rust_version().unwrap(), + ))?; + + latest = latest_msrv; + } + } + } + let mut dep = Dependency::from(latest); if let Some(reg_name) = dependency.registry.as_deref() { dep = dep.set_registry(reg_name); @@ -559,6 +634,31 @@ fn get_latest_dependency( } } +fn rust_version_incompat_error( + dep: &str, + rust_version: &str, + lowest_rust_version: Option<&Summary>, +) -> anyhow::Error { + let mut error_msg = format!( + "could not find version of crate `{dep}` that satisfies this package's rust-version of \ + {rust_version}\n\ + help: use `--ignore-rust-version` to override this behavior" + ); + + if let Some(lowest) = lowest_rust_version { + // rust-version must be present for this candidate since it would have been selected as + // compatible previously if it weren't. + let version = lowest.version(); + let rust_version = lowest.rust_version().unwrap(); + error_msg.push_str(&format!( + "\nnote: the lowest rust-version available for `{dep}` is {rust_version}, used in \ + version {version}" + )); + } + + anyhow::format_err!(error_msg) +} + fn select_package( dependency: &Dependency, config: &Config, diff --git a/src/doc/man/cargo-add.md b/src/doc/man/cargo-add.md index c441a82b2ff..3c15fc9d5db 100644 --- a/src/doc/man/cargo-add.md +++ b/src/doc/man/cargo-add.md @@ -123,6 +123,15 @@ crates, the features for a specific crate may be enabled with which enables all specified features. {{/option}} +{{#option "`--ignore-rust-version`" }} +Ignore `rust-version` specification in packages. + +This option is unstable and available only on the +[nightly channel](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html) +and requires the `-Z unstable-options` flag to enable. +See for more information. +{{/option}} + {{/options}} diff --git a/src/doc/man/generated_txt/cargo-add.txt b/src/doc/man/generated_txt/cargo-add.txt index ac332a44e72..6447499dc04 100644 --- a/src/doc/man/generated_txt/cargo-add.txt +++ b/src/doc/man/generated_txt/cargo-add.txt @@ -111,6 +111,15 @@ OPTIONS be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. + --ignore-rust-version + Ignore rust-version specification in packages. + + This option is unstable and available only on the nightly channel + and + requires the -Z unstable-options flag to enable. See + for more + information. + Display Options -v, --verbose Use verbose output. May be specified twice for “very verbose” diff --git a/src/doc/src/commands/cargo-add.md b/src/doc/src/commands/cargo-add.md index 89c1cc6f1ea..132c093264d 100644 --- a/src/doc/src/commands/cargo-add.md +++ b/src/doc/src/commands/cargo-add.md @@ -129,6 +129,14 @@ crates, the features for a specific crate may be enabled with which enables all specified features. +
--ignore-rust-version
+
Ignore rust-version specification in packages.

+

This option is unstable and available only on the +nightly channel +and requires the -Z unstable-options flag to enable. +See https://github.com/rust-lang/cargo/issues/5579 for more information.

+ + diff --git a/src/etc/man/cargo-add.1 b/src/etc/man/cargo-add.1 index 086a561fd65..f69e6d0db2f 100644 --- a/src/etc/man/cargo-add.1 +++ b/src/etc/man/cargo-add.1 @@ -140,6 +140,16 @@ crates, the features for a specific crate may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may be specified multiple times, which enables all specified features. .RE +.sp +\fB\-\-ignore\-rust\-version\fR +.RS 4 +Ignore \fBrust\-version\fR specification in packages. +.sp +This option is unstable and available only on the +\fInightly channel\fR +and requires the \fB\-Z unstable\-options\fR flag to enable. +See for more information. +.RE .SS "Display Options" .sp \fB\-v\fR, diff --git a/tests/testsuite/cargo_add/mod.rs b/tests/testsuite/cargo_add/mod.rs index 26a11dd8a49..cd7e94e0995 100644 --- a/tests/testsuite/cargo_add/mod.rs +++ b/tests/testsuite/cargo_add/mod.rs @@ -102,6 +102,10 @@ mod quiet; mod registry; mod rename; mod require_weak; +mod rust_version_ignore; +mod rust_version_incompatible; +mod rust_version_latest; +mod rust_version_older; mod sorted_table_with_dotted_item; mod target; mod target_cfg; diff --git a/tests/testsuite/cargo_add/rust_version_ignore/in/Cargo.toml b/tests/testsuite/cargo_add/rust_version_ignore/in/Cargo.toml new file mode 100644 index 00000000000..b24cd9deb20 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_ignore/in/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.68" diff --git a/tests/testsuite/cargo_add/rust_version_ignore/in/src/lib.rs b/tests/testsuite/cargo_add/rust_version_ignore/in/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_ignore/mod.rs b/tests/testsuite/cargo_add/rust_version_ignore/mod.rs new file mode 100644 index 00000000000..9aa11eaac95 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_ignore/mod.rs @@ -0,0 +1,36 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use crate::cargo_add::init_registry; +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + init_registry(); + + cargo_test_support::registry::Package::new("rust-version-user", "0.1.0") + .rust_version("1.66") + .publish(); + cargo_test_support::registry::Package::new("rust-version-user", "0.2.1") + .rust_version("1.72") + .publish(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("-Zmsrv-policy") + .arg("add") + .arg("--ignore-rust-version") + .arg_line("rust-version-user") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["msrv-policy"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/tests/testsuite/cargo_add/rust_version_ignore/out/Cargo.toml b/tests/testsuite/cargo_add/rust_version_ignore/out/Cargo.toml new file mode 100644 index 00000000000..62164a3445a --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_ignore/out/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.68" + +[dependencies] +rust-version-user = "0.2.1" diff --git a/tests/testsuite/cargo_add/rust_version_ignore/out/src/lib.rs b/tests/testsuite/cargo_add/rust_version_ignore/out/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_ignore/stderr.log b/tests/testsuite/cargo_add/rust_version_ignore/stderr.log new file mode 100644 index 00000000000..430abe31b47 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_ignore/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding rust-version-user v0.2.1 to dependencies. diff --git a/tests/testsuite/cargo_add/rust_version_ignore/stdout.log b/tests/testsuite/cargo_add/rust_version_ignore/stdout.log new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/in/Cargo.toml b/tests/testsuite/cargo_add/rust_version_incompatible/in/Cargo.toml new file mode 100644 index 00000000000..ef6fce441ff --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_incompatible/in/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.56" diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/in/src/lib.rs b/tests/testsuite/cargo_add/rust_version_incompatible/in/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/mod.rs b/tests/testsuite/cargo_add/rust_version_incompatible/mod.rs new file mode 100644 index 00000000000..6baad0e05b1 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_incompatible/mod.rs @@ -0,0 +1,38 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use crate::cargo_add::init_registry; +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + init_registry(); + + cargo_test_support::registry::Package::new("rust-version-user", "0.1.0") + .rust_version("1.66") + .publish(); + cargo_test_support::registry::Package::new("rust-version-user", "0.1.1") + .rust_version("1.66") + .publish(); + cargo_test_support::registry::Package::new("rust-version-user", "0.2.1") + .rust_version("1.72") + .publish(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("-Zmsrv-policy") + .arg("add") + .arg_line("rust-version-user") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["msrv-policy"]) + .assert() + .failure() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/out/Cargo.toml b/tests/testsuite/cargo_add/rust_version_incompatible/out/Cargo.toml new file mode 100644 index 00000000000..ef6fce441ff --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_incompatible/out/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.56" diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/out/src/lib.rs b/tests/testsuite/cargo_add/rust_version_incompatible/out/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/stderr.log b/tests/testsuite/cargo_add/rust_version_incompatible/stderr.log new file mode 100644 index 00000000000..babed5b23ca --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_incompatible/stderr.log @@ -0,0 +1,4 @@ + Updating `dummy-registry` index +error: could not find version of crate `rust-version-user` that satisfies this package's rust-version of 1.56 +help: use `--ignore-rust-version` to override this behavior +note: the lowest rust-version available for `rust-version-user` is 1.66, used in version 0.1.1 diff --git a/tests/testsuite/cargo_add/rust_version_incompatible/stdout.log b/tests/testsuite/cargo_add/rust_version_incompatible/stdout.log new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_latest/in/Cargo.toml b/tests/testsuite/cargo_add/rust_version_latest/in/Cargo.toml new file mode 100644 index 00000000000..d9358a5de5e --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_latest/in/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.72" diff --git a/tests/testsuite/cargo_add/rust_version_latest/in/src/lib.rs b/tests/testsuite/cargo_add/rust_version_latest/in/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_latest/mod.rs b/tests/testsuite/cargo_add/rust_version_latest/mod.rs new file mode 100644 index 00000000000..60e38960fa4 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_latest/mod.rs @@ -0,0 +1,35 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use crate::cargo_add::init_registry; +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + init_registry(); + + cargo_test_support::registry::Package::new("rust-version-user", "0.1.0") + .rust_version("1.66") + .publish(); + cargo_test_support::registry::Package::new("rust-version-user", "0.2.1") + .rust_version("1.72") + .publish(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("-Zmsrv-policy") + .arg("add") + .arg_line("rust-version-user") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["msrv-policy"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/tests/testsuite/cargo_add/rust_version_latest/out/Cargo.toml b/tests/testsuite/cargo_add/rust_version_latest/out/Cargo.toml new file mode 100644 index 00000000000..f824b41c3d0 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_latest/out/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.72" + +[dependencies] +rust-version-user = "0.2.1" diff --git a/tests/testsuite/cargo_add/rust_version_latest/out/src/lib.rs b/tests/testsuite/cargo_add/rust_version_latest/out/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_latest/stderr.log b/tests/testsuite/cargo_add/rust_version_latest/stderr.log new file mode 100644 index 00000000000..430abe31b47 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_latest/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding rust-version-user v0.2.1 to dependencies. diff --git a/tests/testsuite/cargo_add/rust_version_latest/stdout.log b/tests/testsuite/cargo_add/rust_version_latest/stdout.log new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_older/in/Cargo.toml b/tests/testsuite/cargo_add/rust_version_older/in/Cargo.toml new file mode 100644 index 00000000000..6fd6f12324f --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_older/in/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.70" diff --git a/tests/testsuite/cargo_add/rust_version_older/in/src/lib.rs b/tests/testsuite/cargo_add/rust_version_older/in/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_older/mod.rs b/tests/testsuite/cargo_add/rust_version_older/mod.rs new file mode 100644 index 00000000000..60e38960fa4 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_older/mod.rs @@ -0,0 +1,35 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use crate::cargo_add::init_registry; +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + init_registry(); + + cargo_test_support::registry::Package::new("rust-version-user", "0.1.0") + .rust_version("1.66") + .publish(); + cargo_test_support::registry::Package::new("rust-version-user", "0.2.1") + .rust_version("1.72") + .publish(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("-Zmsrv-policy") + .arg("add") + .arg_line("rust-version-user") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["msrv-policy"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/tests/testsuite/cargo_add/rust_version_older/out/Cargo.toml b/tests/testsuite/cargo_add/rust_version_older/out/Cargo.toml new file mode 100644 index 00000000000..14737e3288d --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_older/out/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" +rust-version = "1.70" + +[dependencies] +rust-version-user = "0.1.0" diff --git a/tests/testsuite/cargo_add/rust_version_older/out/src/lib.rs b/tests/testsuite/cargo_add/rust_version_older/out/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/testsuite/cargo_add/rust_version_older/stderr.log b/tests/testsuite/cargo_add/rust_version_older/stderr.log new file mode 100644 index 00000000000..4c5988d0bb0 --- /dev/null +++ b/tests/testsuite/cargo_add/rust_version_older/stderr.log @@ -0,0 +1,3 @@ + Updating `dummy-registry` index +warning: ignoring `rust-version-user@0.2.1` (which has a rust-version of 1.72) to satisfy this package's rust-version of 1.70 (use `--ignore-rust-version` to override) + Adding rust-version-user v0.1.0 to dependencies. diff --git a/tests/testsuite/cargo_add/rust_version_older/stdout.log b/tests/testsuite/cargo_add/rust_version_older/stdout.log new file mode 100644 index 00000000000..e69de29bb2d