@@ -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 ! [
@@ -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
22452266 let env = TestEnvironment :: new_with_runtime ( ) ?;
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}
0 commit comments