@@ -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}
0 commit comments