@@ -69,6 +69,7 @@ pub struct ProjectWorkspace {
6969}
7070
7171#[ derive( Clone ) ]
72+ #[ allow( clippy:: large_enum_variant) ]
7273pub enum ProjectWorkspaceKind {
7374 /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
7475 Cargo {
@@ -400,20 +401,17 @@ impl ProjectWorkspace {
400401 }
401402
402403 pub fn load_inline (
403- project_json : ProjectJson ,
404+ mut project_json : ProjectJson ,
404405 config : & CargoConfig ,
405406 progress : & dyn Fn ( String ) ,
406407 ) -> ProjectWorkspace {
407408 progress ( "Discovering sysroot" . to_owned ( ) ) ;
408409 let mut sysroot =
409410 Sysroot :: new ( project_json. sysroot . clone ( ) , project_json. sysroot_src . clone ( ) ) ;
410- let loaded_sysroot = sysroot. load_workspace ( & RustSourceWorkspaceConfig :: Stitched ) ;
411- if let Some ( loaded_sysroot) = loaded_sysroot {
412- sysroot. set_workspace ( loaded_sysroot) ;
413- }
414411
415412 tracing:: info!( workspace = %project_json. manifest_or_root( ) , src_root = ?sysroot. rust_lib_src_root( ) , root = ?sysroot. root( ) , "Using sysroot" ) ;
416413 progress ( "Querying project metadata" . to_owned ( ) ) ;
414+ let sysroot_project = project_json. sysroot_project . take ( ) ;
417415 let query_config = QueryConfig :: Rustc ( & sysroot, project_json. path ( ) . as_ref ( ) ) ;
418416 let targets = target_tuple:: get ( query_config, config. target . as_deref ( ) , & config. extra_env )
419417 . unwrap_or_default ( ) ;
@@ -435,14 +433,31 @@ impl ProjectWorkspace {
435433 & config. extra_env ,
436434 )
437435 } ) ;
438- thread:: Result :: Ok ( ( toolchain. join ( ) ?, rustc_cfg. join ( ) ?, data_layout. join ( ) ?) )
436+ let loaded_sysroot = s. spawn ( || {
437+ if let Some ( sysroot_project) = sysroot_project {
438+ sysroot. load_workspace ( & RustSourceWorkspaceConfig :: Json ( * sysroot_project) )
439+ } else {
440+ sysroot. load_workspace ( & RustSourceWorkspaceConfig :: Stitched )
441+ }
442+ } ) ;
443+
444+ thread:: Result :: Ok ( (
445+ toolchain. join ( ) ?,
446+ rustc_cfg. join ( ) ?,
447+ data_layout. join ( ) ?,
448+ loaded_sysroot. join ( ) ?,
449+ ) )
439450 } ) ;
440451
441- let ( toolchain, rustc_cfg, target_layout) = match join {
452+ let ( toolchain, rustc_cfg, target_layout, loaded_sysroot ) = match join {
442453 Ok ( it) => it,
443454 Err ( e) => std:: panic:: resume_unwind ( e) ,
444455 } ;
445456
457+ if let Some ( loaded_sysroot) = loaded_sysroot {
458+ sysroot. set_workspace ( loaded_sysroot) ;
459+ }
460+
446461 ProjectWorkspace {
447462 kind : ProjectWorkspaceKind :: Json ( project_json) ,
448463 sysroot,
@@ -667,6 +682,14 @@ impl ProjectWorkspace {
667682 Some ( PackageRoot { is_local : false , include, exclude } )
668683 } )
669684 . collect ( ) ,
685+ RustLibSrcWorkspace :: Json ( project_json) => project_json
686+ . crates ( )
687+ . map ( |( _, krate) | PackageRoot {
688+ is_local : false ,
689+ include : krate. include . clone ( ) ,
690+ exclude : krate. exclude . clone ( ) ,
691+ } )
692+ . collect ( ) ,
670693 RustLibSrcWorkspace :: Stitched ( _) | RustLibSrcWorkspace :: Empty => vec ! [ ] ,
671694 } ;
672695
@@ -1490,6 +1513,65 @@ impl SysrootPublicDeps {
14901513 }
14911514}
14921515
1516+ fn extend_crate_graph_with_sysroot (
1517+ crate_graph : & mut CrateGraph ,
1518+ mut sysroot_crate_graph : CrateGraph ,
1519+ mut sysroot_proc_macros : ProcMacroPaths ,
1520+ ) -> ( SysrootPublicDeps , Option < CrateId > ) {
1521+ let mut pub_deps = vec ! [ ] ;
1522+ let mut libproc_macro = None ;
1523+ let diff = CfgDiff :: new ( vec ! [ ] , vec ! [ CfgAtom :: Flag ( sym:: test. clone( ) ) ] ) . unwrap ( ) ;
1524+ for ( cid, c) in sysroot_crate_graph. iter_mut ( ) {
1525+ // uninject `test` flag so `core` keeps working.
1526+ Arc :: make_mut ( & mut c. cfg_options ) . apply_diff ( diff. clone ( ) ) ;
1527+ // patch the origin
1528+ if c. origin . is_local ( ) {
1529+ let lang_crate = LangCrateOrigin :: from (
1530+ c. display_name . as_ref ( ) . map_or ( "" , |it| it. canonical_name ( ) . as_str ( ) ) ,
1531+ ) ;
1532+ c. origin = CrateOrigin :: Lang ( lang_crate) ;
1533+ match lang_crate {
1534+ LangCrateOrigin :: Test
1535+ | LangCrateOrigin :: Alloc
1536+ | LangCrateOrigin :: Core
1537+ | LangCrateOrigin :: Std => pub_deps. push ( (
1538+ CrateName :: normalize_dashes ( & lang_crate. to_string ( ) ) ,
1539+ cid,
1540+ !matches ! ( lang_crate, LangCrateOrigin :: Test | LangCrateOrigin :: Alloc ) ,
1541+ ) ) ,
1542+ LangCrateOrigin :: ProcMacro => libproc_macro = Some ( cid) ,
1543+ LangCrateOrigin :: Other => ( ) ,
1544+ }
1545+ }
1546+ }
1547+
1548+ let mut marker_set = vec ! [ ] ;
1549+ for & ( _, cid, _) in pub_deps. iter ( ) {
1550+ marker_set. extend ( sysroot_crate_graph. transitive_deps ( cid) ) ;
1551+ }
1552+ if let Some ( cid) = libproc_macro {
1553+ marker_set. extend ( sysroot_crate_graph. transitive_deps ( cid) ) ;
1554+ }
1555+
1556+ marker_set. sort ( ) ;
1557+ marker_set. dedup ( ) ;
1558+
1559+ // Remove all crates except the ones we are interested in to keep the sysroot graph small.
1560+ let removed_mapping = sysroot_crate_graph. remove_crates_except ( & marker_set) ;
1561+ let mapping = crate_graph. extend ( sysroot_crate_graph, & mut sysroot_proc_macros) ;
1562+
1563+ // Map the id through the removal mapping first, then through the crate graph extension mapping.
1564+ pub_deps. iter_mut ( ) . for_each ( |( _, cid, _) | {
1565+ * cid = mapping[ & removed_mapping[ cid. into_raw ( ) . into_u32 ( ) as usize ] . unwrap ( ) ]
1566+ } ) ;
1567+ if let Some ( libproc_macro) = & mut libproc_macro {
1568+ * libproc_macro =
1569+ mapping[ & removed_mapping[ libproc_macro. into_raw ( ) . into_u32 ( ) as usize ] . unwrap ( ) ] ;
1570+ }
1571+
1572+ ( SysrootPublicDeps { deps : pub_deps } , libproc_macro)
1573+ }
1574+
14931575fn sysroot_to_crate_graph (
14941576 crate_graph : & mut CrateGraph ,
14951577 sysroot : & Sysroot ,
@@ -1499,7 +1581,7 @@ fn sysroot_to_crate_graph(
14991581 let _p = tracing:: info_span!( "sysroot_to_crate_graph" ) . entered ( ) ;
15001582 match sysroot. workspace ( ) {
15011583 RustLibSrcWorkspace :: Workspace ( cargo) => {
1502- let ( mut cg, mut pm) = cargo_to_crate_graph (
1584+ let ( cg, pm) = cargo_to_crate_graph (
15031585 load,
15041586 None ,
15051587 cargo,
@@ -1520,58 +1602,30 @@ fn sysroot_to_crate_graph(
15201602 false ,
15211603 ) ;
15221604
1523- let mut pub_deps = vec ! [ ] ;
1524- let mut libproc_macro = None ;
1525- let diff = CfgDiff :: new ( vec ! [ ] , vec ! [ CfgAtom :: Flag ( sym:: test. clone( ) ) ] ) . unwrap ( ) ;
1526- for ( cid, c) in cg. iter_mut ( ) {
1527- // uninject `test` flag so `core` keeps working.
1528- Arc :: make_mut ( & mut c. cfg_options ) . apply_diff ( diff. clone ( ) ) ;
1529- // patch the origin
1530- if c. origin . is_local ( ) {
1531- let lang_crate = LangCrateOrigin :: from (
1532- c. display_name . as_ref ( ) . map_or ( "" , |it| it. canonical_name ( ) . as_str ( ) ) ,
1533- ) ;
1534- c. origin = CrateOrigin :: Lang ( lang_crate) ;
1535- match lang_crate {
1536- LangCrateOrigin :: Test
1537- | LangCrateOrigin :: Alloc
1538- | LangCrateOrigin :: Core
1539- | LangCrateOrigin :: Std => pub_deps. push ( (
1540- CrateName :: normalize_dashes ( & lang_crate. to_string ( ) ) ,
1541- cid,
1542- !matches ! ( lang_crate, LangCrateOrigin :: Test | LangCrateOrigin :: Alloc ) ,
1543- ) ) ,
1544- LangCrateOrigin :: ProcMacro => libproc_macro = Some ( cid) ,
1545- LangCrateOrigin :: Other => ( ) ,
1546- }
1547- }
1548- }
1549-
1550- let mut marker_set = vec ! [ ] ;
1551- for & ( _, cid, _) in pub_deps. iter ( ) {
1552- marker_set. extend ( cg. transitive_deps ( cid) ) ;
1553- }
1554- if let Some ( cid) = libproc_macro {
1555- marker_set. extend ( cg. transitive_deps ( cid) ) ;
1556- }
1557-
1558- marker_set. sort ( ) ;
1559- marker_set. dedup ( ) ;
1560-
1561- // Remove all crates except the ones we are interested in to keep the sysroot graph small.
1562- let removed_mapping = cg. remove_crates_except ( & marker_set) ;
1563- let mapping = crate_graph. extend ( cg, & mut pm) ;
1564-
1565- // Map the id through the removal mapping first, then through the crate graph extension mapping.
1566- pub_deps. iter_mut ( ) . for_each ( |( _, cid, _) | {
1567- * cid = mapping[ & removed_mapping[ cid. into_raw ( ) . into_u32 ( ) as usize ] . unwrap ( ) ]
1568- } ) ;
1569- if let Some ( libproc_macro) = & mut libproc_macro {
1570- * libproc_macro = mapping
1571- [ & removed_mapping[ libproc_macro. into_raw ( ) . into_u32 ( ) as usize ] . unwrap ( ) ] ;
1572- }
1605+ extend_crate_graph_with_sysroot ( crate_graph, cg, pm)
1606+ }
1607+ RustLibSrcWorkspace :: Json ( project_json) => {
1608+ let ( cg, pm) = project_json_to_crate_graph (
1609+ rustc_cfg,
1610+ load,
1611+ project_json,
1612+ & Sysroot :: empty ( ) ,
1613+ & FxHashMap :: default ( ) ,
1614+ & CfgOverrides {
1615+ global : CfgDiff :: new (
1616+ vec ! [
1617+ CfgAtom :: Flag ( sym:: debug_assertions. clone( ) ) ,
1618+ CfgAtom :: Flag ( sym:: miri. clone( ) ) ,
1619+ ] ,
1620+ vec ! [ ] ,
1621+ )
1622+ . unwrap ( ) ,
1623+ ..Default :: default ( )
1624+ } ,
1625+ false ,
1626+ ) ;
15731627
1574- ( SysrootPublicDeps { deps : pub_deps } , libproc_macro )
1628+ extend_crate_graph_with_sysroot ( crate_graph , cg , pm )
15751629 }
15761630 RustLibSrcWorkspace :: Stitched ( stitched) => {
15771631 let cfg_options = Arc :: new ( {
0 commit comments