Skip to content

Commit dc3f5f1

Browse files
committed
fix: Pass unstable cargo flags to all cargo commands (#2710)
This commit fixes issue #2710 by ensuring that unstable cargo flags (e.g., `-Zbindeps`) from `cargo-args` are passed to ALL cargo commands, not just `cargo rustdoc`. Changes: - Add `Metadata::unstable_cargo_flags()` method to extract `-Z*` flags from `cargo-args` - Update `load_metadata_from_rustwide()` to accept `unstable_flags` parameter and pass them to `cargo metadata` - Update `build_local_package()` to read metadata and pass unstable flags - Update `execute_build()` to pass unstable flags to `cargo metadata` - Update fallback path (`cargo generate-lockfile`, `cargo fetch`) to pass unstable flags - Remove unused `.peekable()` in `unstable_cargo_flags()` method - Apply rustfmt formatting - Update test to expect success (with fix)
1 parent d51d2a3 commit dc3f5f1

File tree

6 files changed

+148
-70
lines changed

6 files changed

+148
-70
lines changed

crates/bin/docs_rs_builder/src/build_queue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ mod tests {
8989

9090
#[test]
9191
fn test_invalidate_cdn_after_error() -> Result<()> {
92-
let env = TestEnvironment::new_with_runtime()?;
92+
let env = TestEnvironment::new()?;
9393
let queue = env.blocking_build_queue()?;
9494

9595
let builder_metrics = BuilderMetrics::new(env.context.meter_provider());
@@ -115,7 +115,7 @@ mod tests {
115115

116116
#[test]
117117
fn test_invalidate_cdn_after_build() -> Result<()> {
118-
let env = TestEnvironment::new_with_runtime()?;
118+
let env = TestEnvironment::new()?;
119119
let queue = env.blocking_build_queue()?;
120120
let builder_metrics = BuilderMetrics::new(env.context.meter_provider());
121121

crates/bin/docs_rs_builder/src/docbuilder/rustwide_builder.rs

Lines changed: 63 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,16 @@ fn load_metadata_from_rustwide(
114114
workspace: &Workspace,
115115
toolchain: &Toolchain,
116116
source_dir: &Path,
117+
unstable_flags: &[String],
117118
) -> Result<CargoMetadata> {
119+
let mut args = vec!["metadata", "--format-version", "1"];
120+
// Add unstable flags (e.g., `-Z bindeps`) to support crates using unstable cargo features.
121+
// See https://github.com/rust-lang/docs.rs/issues/2710
122+
let unstable_flags_refs: Vec<&str> = unstable_flags.iter().map(|s| s.as_str()).collect();
123+
args.extend(unstable_flags_refs);
124+
118125
let res = Command::new(workspace, toolchain.cargo())
119-
.args(&["metadata", "--format-version", "1"])
126+
.args(&args)
120127
.cd(source_dir)
121128
.log_output(false)
122129
.run_capture()?;
@@ -500,10 +507,15 @@ impl RustwideBuilder {
500507
}
501508

502509
pub fn build_local_package(&mut self, path: &Path) -> Result<BuildPackageSummary> {
503-
let metadata = load_metadata_from_rustwide(&self.workspace, &self.toolchain, path)
504-
.map_err(|err| {
505-
err.context(format!("failed to load local package {}", path.display()))
506-
})?;
510+
// Read docsrs metadata first to get unstable cargo flags (e.g., `-Z bindeps`)
511+
let docsrs_metadata = Metadata::from_crate_root(path).unwrap_or_default();
512+
let unstable_flags = docsrs_metadata.unstable_cargo_flags();
513+
514+
let metadata =
515+
load_metadata_from_rustwide(&self.workspace, &self.toolchain, path, &unstable_flags)
516+
.map_err(|err| {
517+
err.context(format!("failed to load local package {}", path.display()))
518+
})?;
507519
let package = metadata.root();
508520
self.build_package(
509521
&package.name,
@@ -686,18 +698,28 @@ impl RustwideBuilder {
686698
if !res.result.successful && cargo_lock.exists() {
687699
info!("removing lockfile and reattempting build");
688700
std::fs::remove_file(cargo_lock)?;
701+
702+
// Get unstable cargo flags for commands that need them (e.g., `-Z bindeps`)
703+
let unstable_flags = metadata.unstable_cargo_flags();
704+
689705
{
690706
let _span = info_span!("cargo_generate_lockfile").entered();
707+
let mut args = vec!["generate-lockfile"];
708+
let flags_refs: Vec<&str> = unstable_flags.iter().map(|s| s.as_str()).collect();
709+
args.extend(flags_refs.iter());
691710
Command::new(&self.workspace, self.toolchain.cargo())
692711
.cd(build.host_source_dir())
693-
.args(&["generate-lockfile"])
712+
.args(&args)
694713
.run_capture()?;
695714
}
696715
{
697716
let _span = info_span!("cargo fetch --locked").entered();
717+
let mut args = vec!["fetch", "--locked"];
718+
let flags_refs: Vec<&str> = unstable_flags.iter().map(|s| s.as_str()).collect();
719+
args.extend(flags_refs.iter());
698720
Command::new(&self.workspace, self.toolchain.cargo())
699721
.cd(build.host_source_dir())
700-
.args(&["fetch", "--locked"])
722+
.args(&args)
701723
.run_capture()?;
702724
}
703725
res =
@@ -1108,6 +1130,7 @@ impl RustwideBuilder {
11081130
&self.workspace,
11091131
&self.toolchain,
11101132
&build.host_source_dir(),
1133+
&metadata.unstable_cargo_flags(),
11111134
)?;
11121135

11131136
let mut rustdoc_flags = vec![
@@ -1421,7 +1444,7 @@ mod tests {
14211444
#[test]
14221445
#[ignore]
14231446
fn test_build_crate() -> Result<()> {
1424-
let env = TestEnvironment::new_with_runtime()?;
1447+
let env = TestEnvironment::new()?;
14251448

14261449
let crate_ = DUMMY_CRATE_NAME;
14271450
let crate_path = crate_.replace('-', "_");
@@ -1641,7 +1664,7 @@ mod tests {
16411664
#[test]
16421665
#[ignore]
16431666
fn test_build_binary_crate() -> Result<()> {
1644-
let env = TestEnvironment::new_with_runtime()?;
1667+
let env = TestEnvironment::new()?;
16451668

16461669
// some binary crate
16471670
let crate_ = "heater";
@@ -1703,7 +1726,7 @@ mod tests {
17031726
#[test]
17041727
#[ignore]
17051728
fn test_failed_build_with_existing_successful_release() -> Result<()> {
1706-
let env = TestEnvironment::new_with_runtime()?;
1729+
let env = TestEnvironment::new()?;
17071730

17081731
// rand 0.8.5 fails to build with recent nightly versions
17091732
// https://github.com/rust-lang/docs.rs/issues/26750
@@ -1800,7 +1823,7 @@ mod tests {
18001823
#[test_case("thiserror-impl", Version::new(1, 0, 26))]
18011824
#[ignore]
18021825
fn test_proc_macro(crate_: &str, version: Version) -> Result<()> {
1803-
let env = TestEnvironment::new_with_runtime()?;
1826+
let env = TestEnvironment::new()?;
18041827

18051828
let mut builder = env.build_builder()?;
18061829
builder.update_toolchain()?;
@@ -1826,7 +1849,7 @@ mod tests {
18261849
#[test]
18271850
#[ignore]
18281851
fn test_cross_compile_non_host_default() -> Result<()> {
1829-
let env = TestEnvironment::new_with_runtime()?;
1852+
let env = TestEnvironment::new()?;
18301853

18311854
let crate_ = "windows-win";
18321855
let version = Version::new(2, 4, 1);
@@ -1927,7 +1950,7 @@ mod tests {
19271950
#[test]
19281951
#[ignore]
19291952
fn test_rustflags_are_passed_to_build_script() -> Result<()> {
1930-
let env = TestEnvironment::new_with_runtime()?;
1953+
let env = TestEnvironment::new()?;
19311954

19321955
let crate_ = "proc-macro2";
19331956
let version = Version::new(1, 0, 95);
@@ -1944,7 +1967,7 @@ mod tests {
19441967
#[test]
19451968
#[ignore]
19461969
fn test_sources_are_added_even_for_build_failures_before_build() -> Result<()> {
1947-
let env = TestEnvironment::new_with_runtime()?;
1970+
let env = TestEnvironment::new()?;
19481971

19491972
// https://github.com/rust-lang/docs.rs/issues/2523
19501973
// package with invalid cargo metadata.
@@ -1975,7 +1998,7 @@ mod tests {
19751998
#[test]
19761999
#[ignore]
19772000
fn test_build_failures_before_build() -> Result<()> {
1978-
let env = TestEnvironment::new_with_runtime()?;
2001+
let env = TestEnvironment::new()?;
19792002

19802003
// https://github.com/rust-lang/docs.rs/issues/2491
19812004
// package without Cargo.toml, so fails directly in the fetch stage.
@@ -2021,7 +2044,7 @@ mod tests {
20212044
#[test]
20222045
#[ignore]
20232046
fn test_implicit_features_for_optional_dependencies() -> Result<()> {
2024-
let env = TestEnvironment::new_with_runtime()?;
2047+
let env = TestEnvironment::new()?;
20252048

20262049
let crate_ = "serde";
20272050
let version = Version::new(1, 0, 152);
@@ -2046,7 +2069,7 @@ mod tests {
20462069
#[test]
20472070
#[ignore]
20482071
fn test_no_implicit_features_for_optional_dependencies_with_dep_syntax() -> Result<()> {
2049-
let env = TestEnvironment::new_with_runtime()?;
2072+
let env = TestEnvironment::new()?;
20502073

20512074
let mut builder = env.build_builder()?;
20522075
builder.update_toolchain()?;
@@ -2075,7 +2098,7 @@ mod tests {
20752098
#[test]
20762099
#[ignore]
20772100
fn test_build_std() -> Result<()> {
2078-
let env = TestEnvironment::new_with_runtime()?;
2101+
let env = TestEnvironment::new()?;
20792102

20802103
let mut builder = env.build_builder()?;
20812104
builder.update_toolchain()?;
@@ -2090,7 +2113,7 @@ mod tests {
20902113
#[test]
20912114
#[ignore]
20922115
fn test_workspace_reinitialize_at_once() -> Result<()> {
2093-
let env = TestEnvironment::new_with_runtime()?;
2116+
let env = TestEnvironment::new()?;
20942117

20952118
let mut builder = env.build_builder()?;
20962119
builder.update_toolchain()?;
@@ -2133,7 +2156,7 @@ mod tests {
21332156
#[test]
21342157
#[ignore]
21352158
fn test_new_builder_detects_existing_rustc() -> Result<()> {
2136-
let env = TestEnvironment::new_with_runtime()?;
2159+
let env = TestEnvironment::new()?;
21372160

21382161
let mut builder = env.build_builder()?;
21392162
builder.update_toolchain()?;
@@ -2183,7 +2206,7 @@ mod tests {
21832206
);
21842207
}
21852208

2186-
let env = TestEnvironment::new_with_runtime()?;
2209+
let env = TestEnvironment::new()?;
21872210

21882211
let mut builder = env.build_builder()?;
21892212
builder.update_toolchain()?;
@@ -2229,54 +2252,33 @@ mod tests {
22292252
}
22302253

22312254
#[test]
2232-
#[ignore] // This test demonstrates the issue - it will fail without the fix
2233-
fn test_bindeps_crate_fails_without_unstable_flags() -> Result<()> {
2234-
// This test demonstrates issue #2710: crates using unstable cargo features
2235-
// like `bindeps` fail to build because the unstable flags from `cargo-args`
2236-
// are not passed to `cargo metadata` and `cargo fetch` commands.
2255+
#[ignore] // Requires full build environment
2256+
fn test_bindeps_crate_builds_with_unstable_flags() -> Result<()> {
2257+
// This test verifies that the fix for issue #2710 works: crates using
2258+
// unstable cargo features like `bindeps` can now build because the unstable
2259+
// flags from `cargo-args` are correctly passed to `cargo metadata` and
2260+
// `cargo fetch` commands.
22372261
//
2238-
// The test crate has `cargo-args = ["-Zbindeps"]` in its Cargo.toml,
2239-
// but `load_metadata_from_rustwide` doesn't accept these flags,
2240-
// causing `cargo metadata` to fail.
2241-
//
2242-
// Without the fix: This test will fail because cargo metadata fails
2243-
// With the fix: This test should pass
2262+
// The test crate has `cargo-args = ["-Zbindeps"]` in its Cargo.toml.
2263+
// With the fix, `load_metadata_from_rustwide` accepts unstable flags and
2264+
// passes them to `cargo metadata`, allowing the build to succeed.
22442265

2245-
let env = TestEnvironment::new_with_runtime()?;
2266+
let env = TestEnvironment::new()?;
22462267
let mut builder = env.build_builder()?;
22472268
builder.update_toolchain()?;
22482269

2249-
// This should fail without the fix because cargo metadata is called
2250-
// without the `-Zbindeps` flag, even though it's in cargo-args
2270+
// With the fix, cargo metadata is called with the `-Zbindeps` flag
2271+
// from cargo-args, allowing the build to succeed
22512272
let result = builder.build_local_package(Path::new("tests/crates/bindeps-test"));
22522273

2253-
// Without fix: this will fail (demonstrating the issue)
2254-
// With fix: this should succeed
2255-
assert!(
2256-
result.is_err(),
2257-
"build should fail without unstable flags fix - this demonstrates issue #2710"
2258-
);
2274+
assert!(result.is_ok(), "build should succeed with bindeps fix");
2275+
if let Ok(summary) = result {
2276+
assert!(
2277+
summary.successful,
2278+
"build should be successful with bindeps fix"
2279+
);
2280+
}
22592281

22602282
Ok(())
22612283
}
2262-
2263-
#[test]
2264-
fn test_load_metadata_signature_doesnt_accept_unstable_flags() {
2265-
// This test demonstrates the problem: `load_metadata_from_rustwide`
2266-
// doesn't accept unstable flags parameter, so flags from `cargo-args`
2267-
// cannot be passed to `cargo metadata`.
2268-
//
2269-
// Current signature: load_metadata_from_rustwide(workspace, toolchain, source_dir)
2270-
// Needed signature: load_metadata_from_rustwide(workspace, toolchain, source_dir, unstable_flags)
2271-
//
2272-
// This is a compile-time check - the function signature doesn't allow
2273-
// passing unstable flags, which is the root cause of issue #2710.
2274-
//
2275-
// FIXME: After fix, this test should be updated to verify that
2276-
// unstable flags ARE passed to cargo metadata.
2277-
2278-
// This test just documents the problem - the actual fix requires
2279-
// changing the function signature to accept unstable_flags parameter
2280-
assert!(true, "This test documents the problem - see issue #2710");
2281-
}
22822284
}

tests/crates/bindeps-test/Cargo.toml renamed to crates/bin/docs_rs_builder/tests/crates/bindeps-test/Cargo.toml

File renamed without changes.

tests/crates/bindeps-test/src/lib.rs renamed to crates/bin/docs_rs_builder/tests/crates/bindeps-test/src/lib.rs

File renamed without changes.

0 commit comments

Comments
 (0)