@@ -69,6 +69,7 @@ pub struct ProjectWorkspace {
69
69
}
70
70
71
71
#[ derive( Clone ) ]
72
+ #[ allow( clippy:: large_enum_variant) ]
72
73
pub enum ProjectWorkspaceKind {
73
74
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
74
75
Cargo {
@@ -400,20 +401,17 @@ impl ProjectWorkspace {
400
401
}
401
402
402
403
pub fn load_inline (
403
- project_json : ProjectJson ,
404
+ mut project_json : ProjectJson ,
404
405
config : & CargoConfig ,
405
406
progress : & dyn Fn ( String ) ,
406
407
) -> ProjectWorkspace {
407
408
progress ( "Discovering sysroot" . to_owned ( ) ) ;
408
409
let mut sysroot =
409
410
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
- }
414
411
415
412
tracing:: info!( workspace = %project_json. manifest_or_root( ) , src_root = ?sysroot. rust_lib_src_root( ) , root = ?sysroot. root( ) , "Using sysroot" ) ;
416
413
progress ( "Querying project metadata" . to_owned ( ) ) ;
414
+ let sysroot_project = project_json. sysroot_project . take ( ) ;
417
415
let query_config = QueryConfig :: Rustc ( & sysroot, project_json. path ( ) . as_ref ( ) ) ;
418
416
let targets = target_tuple:: get ( query_config, config. target . as_deref ( ) , & config. extra_env )
419
417
. unwrap_or_default ( ) ;
@@ -435,14 +433,31 @@ impl ProjectWorkspace {
435
433
& config. extra_env ,
436
434
)
437
435
} ) ;
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
+ ) )
439
450
} ) ;
440
451
441
- let ( toolchain, rustc_cfg, target_layout) = match join {
452
+ let ( toolchain, rustc_cfg, target_layout, loaded_sysroot ) = match join {
442
453
Ok ( it) => it,
443
454
Err ( e) => std:: panic:: resume_unwind ( e) ,
444
455
} ;
445
456
457
+ if let Some ( loaded_sysroot) = loaded_sysroot {
458
+ sysroot. set_workspace ( loaded_sysroot) ;
459
+ }
460
+
446
461
ProjectWorkspace {
447
462
kind : ProjectWorkspaceKind :: Json ( project_json) ,
448
463
sysroot,
@@ -667,6 +682,14 @@ impl ProjectWorkspace {
667
682
Some ( PackageRoot { is_local : false , include, exclude } )
668
683
} )
669
684
. 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 ( ) ,
670
693
RustLibSrcWorkspace :: Stitched ( _) | RustLibSrcWorkspace :: Empty => vec ! [ ] ,
671
694
} ;
672
695
@@ -1490,6 +1513,65 @@ impl SysrootPublicDeps {
1490
1513
}
1491
1514
}
1492
1515
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
+
1493
1575
fn sysroot_to_crate_graph (
1494
1576
crate_graph : & mut CrateGraph ,
1495
1577
sysroot : & Sysroot ,
@@ -1499,7 +1581,7 @@ fn sysroot_to_crate_graph(
1499
1581
let _p = tracing:: info_span!( "sysroot_to_crate_graph" ) . entered ( ) ;
1500
1582
match sysroot. workspace ( ) {
1501
1583
RustLibSrcWorkspace :: Workspace ( cargo) => {
1502
- let ( mut cg, mut pm) = cargo_to_crate_graph (
1584
+ let ( cg, pm) = cargo_to_crate_graph (
1503
1585
load,
1504
1586
None ,
1505
1587
cargo,
@@ -1520,58 +1602,30 @@ fn sysroot_to_crate_graph(
1520
1602
false ,
1521
1603
) ;
1522
1604
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
+ ) ;
1573
1627
1574
- ( SysrootPublicDeps { deps : pub_deps } , libproc_macro )
1628
+ extend_crate_graph_with_sysroot ( crate_graph , cg , pm )
1575
1629
}
1576
1630
RustLibSrcWorkspace :: Stitched ( stitched) => {
1577
1631
let cfg_options = Arc :: new ( {
0 commit comments