Skip to content

Commit

Permalink
Auto merge of rust-lang#13874 - torhovland:old-syntax-suggestion, r=w…
Browse files Browse the repository at this point in the history
…eihanglo

Old syntax suggestion

Fixes rust-lang#13868.

The build error in the issue will now include a suggestion:

```
   Compiling zerocopy v0.8.0-alpha.9
error: the `cargo::` syntax for build script output instructions was added in Rust 1.77.0, but the minimum supported Rust version of `zerocopy v0.8.0-alpha.9` is 1.56.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.
```

The suggestion is only included for reserved prefixes.

A test has been added.
  • Loading branch information
bors committed May 8, 2024
2 parents 91a6b8f + 3ea3638 commit 1fec089
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 14 deletions.
26 changes: 21 additions & 5 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,16 +722,35 @@ 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<RustVersion>,
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 old_syntax_suggestion = if has_reserved_prefix(flag) {
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!("Switch to 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 \
Rust 1.77.0, but the minimum supported Rust version of `{pkg_descr}` is {msrv}.\n\
{old_syntax_suggestion}\
{DOCS_LINK_SUGGESTION}"
);
}
Expand Down Expand Up @@ -793,16 +812,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)?;
check_minimum_supported_rust_version_for_new_syntax(pkg_descr, msrv, data)?;
// For instance, `cargo::rustc-flags=foo` or `cargo::metadata=foo=bar`.
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`.
Expand Down
100 changes: 91 additions & 9 deletions tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -5499,7 +5499,89 @@ 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.
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.
",
)
.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.
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.
",
)
.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.
Expand Down

0 comments on commit 1fec089

Please sign in to comment.