From 2607f6d30fd492fe0657cbd23b278cff7d8aadd3 Mon Sep 17 00:00:00 2001 From: Tor Hovland <55164+torhovland@users.noreply.github.com> Date: Tue, 7 May 2024 10:58:55 +0200 Subject: [PATCH 1/5] Old syntax suggestion. --- src/cargo/core/compiler/custom_build.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 0e1ca88ea6d..318602d8ffb 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -725,13 +725,26 @@ impl BuildOutput { fn check_minimum_supported_rust_version_for_new_syntax( pkg_descr: &str, msrv: &Option, + key: &str, ) -> CargoResult<()> { if let Some(msrv) = msrv { let new_syntax_added_in = RustVersion::from_str("1.77.0")?; if !new_syntax_added_in.is_compatible_with(msrv.as_partial()) { + let prefix = format!("{key}="); + + let old_syntax_suggestion = RESERVED_PREFIXES + .contains(&&*prefix) + .then(|| { + format!( + "Consider using the old `cargo:` syntax in front of `{prefix}`.\n" + ) + }) + .unwrap_or_default(); + bail!( "the `cargo::` syntax for build script output instructions was added in \ Rust 1.77.0, but the minimum supported Rust version of `{pkg_descr}` is {msrv}.\n\ + {old_syntax_suggestion}\ {DOCS_LINK_SUGGESTION}" ); } @@ -793,9 +806,10 @@ impl BuildOutput { }; let mut old_syntax = false; let (key, value) = if let Some(data) = line.strip_prefix("cargo::") { - check_minimum_supported_rust_version_for_new_syntax(pkg_descr, msrv)?; // For instance, `cargo::rustc-flags=foo` or `cargo::metadata=foo=bar`. - parse_directive(whence.as_str(), line, data, old_syntax)? + let (key, value) = parse_directive(whence.as_str(), line, data, old_syntax)?; + check_minimum_supported_rust_version_for_new_syntax(pkg_descr, msrv, key)?; + (key, value) } else if let Some(data) = line.strip_prefix("cargo:") { old_syntax = true; // For instance, `cargo:rustc-flags=foo`. From 4aac847678e762b5d07e91730a2c480b298e06e1 Mon Sep 17 00:00:00 2001 From: Tor Hovland <55164+torhovland@users.noreply.github.com> Date: Tue, 7 May 2024 10:59:07 +0200 Subject: [PATCH 2/5] Added test. --- tests/testsuite/build_script.rs | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 18ba76c44dd..f0f70364e6c 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -5508,6 +5508,47 @@ for more information about build script outputs. .run(); } +#[cargo_test] +fn test_new_syntax_with_old_msrv_and_reserved_prefix() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + edition = "2015" + authors = [] + build = "build.rs" + rust-version = "1.60.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "build.rs", + r#" + fn main() { + println!("cargo::rustc-check-cfg=cfg(foo)"); + } + "#, + ) + .build(); + + p.cargo("build") + .with_status(101) + .with_stderr_contains( + "\ +[COMPILING] foo [..] +error: the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ +but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. +Consider using the old `cargo:` syntax in front of `rustc-check-cfg=`. +See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ +for more information about build script outputs. +", + ) + .run(); +} + #[cargo_test] fn test_new_syntax_with_compatible_partial_msrv() { let p = project() From 4b498267c864103f8472261c50bb5ee40fe854b2 Mon Sep 17 00:00:00 2001 From: Tor Hovland <55164+torhovland@users.noreply.github.com> Date: Tue, 7 May 2024 12:16:35 +0200 Subject: [PATCH 3/5] Added a similar suggestion when using cargo::metadata=. --- src/cargo/core/compiler/custom_build.rs | 36 ++++++++++++------------- tests/testsuite/build_script.rs | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 318602d8ffb..874b08102f7 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -722,24 +722,28 @@ impl BuildOutput { const DOCS_LINK_SUGGESTION: &str = "See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs."; + fn has_reserved_prefix(flag: &str) -> bool { + RESERVED_PREFIXES + .iter() + .any(|reserved_prefix| flag.starts_with(reserved_prefix)) + } + fn check_minimum_supported_rust_version_for_new_syntax( pkg_descr: &str, msrv: &Option, - key: &str, + flag: &str, ) -> CargoResult<()> { if let Some(msrv) = msrv { let new_syntax_added_in = RustVersion::from_str("1.77.0")?; if !new_syntax_added_in.is_compatible_with(msrv.as_partial()) { - let prefix = format!("{key}="); - - let old_syntax_suggestion = RESERVED_PREFIXES - .contains(&&*prefix) - .then(|| { - format!( - "Consider using the old `cargo:` syntax in front of `{prefix}`.\n" - ) - }) - .unwrap_or_default(); + let old_syntax_suggestion = if has_reserved_prefix(flag) { + format!("Consider using the old `cargo:` syntax in front of `{flag}`.\n") + } else if flag.starts_with("metadata=") { + let old_format_flag = flag.strip_prefix("metadata=").unwrap(); + format!("Consider using the old `cargo:{old_format_flag}` syntax instead of `cargo::{flag}` (note the single colon).\n") + } else { + String::new() + }; bail!( "the `cargo::` syntax for build script output instructions was added in \ @@ -806,17 +810,13 @@ impl BuildOutput { }; let mut old_syntax = false; let (key, value) = if let Some(data) = line.strip_prefix("cargo::") { + check_minimum_supported_rust_version_for_new_syntax(pkg_descr, msrv, data)?; // For instance, `cargo::rustc-flags=foo` or `cargo::metadata=foo=bar`. - let (key, value) = parse_directive(whence.as_str(), line, data, old_syntax)?; - check_minimum_supported_rust_version_for_new_syntax(pkg_descr, msrv, key)?; - (key, value) + parse_directive(whence.as_str(), line, data, old_syntax)? } else if let Some(data) = line.strip_prefix("cargo:") { old_syntax = true; // For instance, `cargo:rustc-flags=foo`. - if RESERVED_PREFIXES - .iter() - .any(|prefix| data.starts_with(prefix)) - { + if has_reserved_prefix(data) { parse_directive(whence.as_str(), line, data, old_syntax)? } else { // For instance, `cargo:foo=bar`. diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index f0f70364e6c..64026f2c7e6 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -5541,7 +5541,7 @@ fn test_new_syntax_with_old_msrv_and_reserved_prefix() { [COMPILING] foo [..] error: the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. -Consider using the old `cargo:` syntax in front of `rustc-check-cfg=`. +Consider using the old `cargo:` syntax in front of `rustc-check-cfg=cfg(foo)`. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. ", From ff0453b21f0304573fd7906f70a32cea0237bc45 Mon Sep 17 00:00:00 2001 From: Tor Hovland <55164+torhovland@users.noreply.github.com> Date: Tue, 7 May 2024 12:40:40 +0200 Subject: [PATCH 4/5] Added another test. --- tests/testsuite/build_script.rs | 61 +++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 64026f2c7e6..367ae346522 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -625,7 +625,7 @@ fn custom_build_invalid_host_config_feature_flag() { .with_status(101) .with_stderr_contains( "\ -error: the -Zhost-config flag requires the -Ztarget-applies-to-host flag to be set +[ERROR] the -Zhost-config flag requires the -Ztarget-applies-to-host flag to be set ", ) .run(); @@ -1038,7 +1038,7 @@ fn links_duplicates() { p.cargo("build").with_status(101) .with_stderr("\ -error: failed to select a version for `a-sys`. +[ERROR] failed to select a version for `a-sys`. ... required by package `foo v0.5.0 ([..])` versions that meet the requirements `*` are: 0.5.0 @@ -1163,7 +1163,7 @@ fn links_duplicates_deep_dependency() { p.cargo("build").with_status(101) .with_stderr("\ -error: failed to select a version for `a-sys`. +[ERROR] failed to select a version for `a-sys`. ... required by package `a v0.5.0 ([..])` ... which satisfies path dependency `a` of package `foo v0.5.0 ([..])` versions that meet the requirements `*` are: 0.5.0 @@ -4508,7 +4508,7 @@ fn links_duplicates_with_cycle() { p.cargo("build").with_status(101) .with_stderr("\ -error: failed to select a version for `a`. +[ERROR] failed to select a version for `a`. ... required by package `foo v0.5.0 ([..])` versions that meet the requirements `*` are: 0.5.0 @@ -5315,7 +5315,7 @@ fn wrong_output() { .with_stderr( "\ [COMPILING] foo [..] -error: invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::example` +[ERROR] invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::example` Expected a line with `cargo::KEY=VALUE` with an `=` character, but none was found. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. @@ -5405,7 +5405,7 @@ fn test_invalid_old_syntax() { .with_stderr( "\ [COMPILING] foo [..] -error: invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo:foo` +[ERROR] invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo:foo` Expected a line with `cargo:KEY=VALUE` with an `=` character, but none was found. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. @@ -5434,7 +5434,7 @@ fn test_invalid_new_syntax() { .with_stderr( "\ [COMPILING] foo [..] -error: invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::metadata=foo` +[ERROR] invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::metadata=foo` Expected a line with `cargo::metadata=KEY=VALUE` with an `=` character, but none was found. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. @@ -5459,7 +5459,7 @@ for more information about build script outputs. .with_stderr( "\ [COMPILING] foo [..] -error: invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::foo=bar` +[ERROR] invalid output in build script of `foo v0.0.1 ([ROOT]/foo)`: `cargo::foo=bar` Unknown key: `foo`. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. @@ -5499,8 +5499,9 @@ fn test_new_syntax_with_old_msrv() { .with_stderr_contains( "\ [COMPILING] foo [..] -error: the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ +[ERROR] the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. +Consider using the old `cargo:foo=bar` syntax instead of `cargo::metadata=foo=bar` (note the single colon). See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. ", @@ -5539,7 +5540,7 @@ fn test_new_syntax_with_old_msrv_and_reserved_prefix() { .with_stderr_contains( "\ [COMPILING] foo [..] -error: the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ +[ERROR] the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. Consider using the old `cargo:` syntax in front of `rustc-check-cfg=cfg(foo)`. See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ @@ -5549,6 +5550,46 @@ for more information about build script outputs. .run(); } +#[cargo_test] +fn test_new_syntax_with_old_msrv_and_unknown_prefix() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + edition = "2015" + authors = [] + build = "build.rs" + rust-version = "1.60.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "build.rs", + r#" + fn main() { + println!("cargo::foo=bar"); + } + "#, + ) + .build(); + + p.cargo("build") + .with_status(101) + .with_stderr_contains( + "\ +[COMPILING] foo [..] +[ERROR] the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ +but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. +See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ +for more information about build script outputs. +", + ) + .run(); +} + #[cargo_test] fn test_new_syntax_with_compatible_partial_msrv() { let p = project() From 3ea3638c1b2718d01dab8fd6d115b58d40134032 Mon Sep 17 00:00:00 2001 From: Tor Hovland <55164+torhovland@users.noreply.github.com> Date: Wed, 8 May 2024 22:35:47 +0200 Subject: [PATCH 5/5] Adjusted the suggestion text. --- src/cargo/core/compiler/custom_build.rs | 6 ++++-- tests/testsuite/build_script.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 874b08102f7..cdde79501ed 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -737,10 +737,12 @@ impl BuildOutput { let new_syntax_added_in = RustVersion::from_str("1.77.0")?; if !new_syntax_added_in.is_compatible_with(msrv.as_partial()) { let old_syntax_suggestion = if has_reserved_prefix(flag) { - format!("Consider using the old `cargo:` syntax in front of `{flag}`.\n") + format!( + "Switch to the old `cargo:{flag}` syntax (note the single colon).\n" + ) } else if flag.starts_with("metadata=") { let old_format_flag = flag.strip_prefix("metadata=").unwrap(); - format!("Consider using the old `cargo:{old_format_flag}` syntax instead of `cargo::{flag}` (note the single colon).\n") + format!("Switch to the old `cargo:{old_format_flag}` syntax instead of `cargo::{flag}` (note the single colon).\n") } else { String::new() }; diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 367ae346522..ef76309233b 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -5501,7 +5501,7 @@ fn test_new_syntax_with_old_msrv() { [COMPILING] foo [..] [ERROR] the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. -Consider using the old `cargo:foo=bar` syntax instead of `cargo::metadata=foo=bar` (note the single colon). +Switch to the old `cargo:foo=bar` syntax instead of `cargo::metadata=foo=bar` (note the single colon). See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. ", @@ -5542,7 +5542,7 @@ fn test_new_syntax_with_old_msrv_and_reserved_prefix() { [COMPILING] foo [..] [ERROR] the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, \ but the minimum supported Rust version of `foo v0.5.0 ([ROOT]/foo)` is 1.60.0. -Consider using the old `cargo:` syntax in front of `rustc-check-cfg=cfg(foo)`. +Switch to the old `cargo:rustc-check-cfg=cfg(foo)` syntax (note the single colon). See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \ for more information about build script outputs. ",