@@ -190,8 +190,8 @@ impl ProjectWorkspace {
190190 } ) ?;
191191 let cargo = CargoWorkspace :: new ( meta) ;
192192
193- let sysroot = match & config. sysroot {
194- Some ( RustcSource :: Path ( path) ) => {
193+ let sysroot = match ( & config. sysroot , & config . sysroot_src ) {
194+ ( Some ( RustcSource :: Path ( path) ) , None ) => {
195195 match Sysroot :: with_sysroot_dir ( path. clone ( ) ) {
196196 Ok ( it) => Some ( it) ,
197197 Err ( e) => {
@@ -200,7 +200,7 @@ impl ProjectWorkspace {
200200 }
201201 }
202202 }
203- Some ( RustcSource :: Discover ) => {
203+ ( Some ( RustcSource :: Discover ) , None ) => {
204204 match Sysroot :: discover ( cargo_toml. parent ( ) , & config. extra_env ) {
205205 Ok ( it) => Some ( it) ,
206206 Err ( e) => {
@@ -213,8 +213,29 @@ impl ProjectWorkspace {
213213 }
214214 }
215215 }
216- None => None ,
216+ ( Some ( RustcSource :: Path ( sysroot) ) , Some ( sysroot_src) ) => {
217+ Some ( Sysroot :: load ( sysroot. clone ( ) , sysroot_src. clone ( ) ) )
218+ }
219+ ( Some ( RustcSource :: Discover ) , Some ( sysroot_src) ) => {
220+ match Sysroot :: discover_with_src_override (
221+ cargo_toml. parent ( ) ,
222+ & config. extra_env ,
223+ sysroot_src. clone ( ) ,
224+ ) {
225+ Ok ( it) => Some ( it) ,
226+ Err ( e) => {
227+ tracing:: error!(
228+ %e,
229+ "Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?" ,
230+ cargo_toml. display( )
231+ ) ;
232+ None
233+ }
234+ }
235+ }
236+ ( None , _) => None ,
217237 } ;
238+
218239 if let Some ( sysroot) = & sysroot {
219240 tracing:: info!( src_root = %sysroot. src_root( ) . display( ) , root = %sysroot. root( ) . display( ) , "Using sysroot" ) ;
220241 }
@@ -440,9 +461,11 @@ impl ProjectWorkspace {
440461 /// The return type contains the path and whether or not
441462 /// the root is a member of the current workspace
442463 pub fn to_roots ( & self ) -> Vec < PackageRoot > {
443- let mk_sysroot = |sysroot : Option < & Sysroot > | {
464+ let mk_sysroot = |sysroot : Option < & Sysroot > , project_root : Option < & AbsPath > | {
444465 sysroot. map ( |sysroot| PackageRoot {
445- is_local : false ,
466+ // mark the sysroot as mutable if it is located inside of the project
467+ is_local : project_root
468+ . map_or ( false , |project_root| sysroot. src_root ( ) . starts_with ( project_root) ) ,
446469 include : vec ! [ sysroot. src_root( ) . to_path_buf( ) ] ,
447470 exclude : Vec :: new ( ) ,
448471 } )
@@ -457,7 +480,7 @@ impl ProjectWorkspace {
457480 } )
458481 . collect :: < FxHashSet < _ > > ( )
459482 . into_iter ( )
460- . chain ( mk_sysroot ( sysroot. as_ref ( ) ) )
483+ . chain ( mk_sysroot ( sysroot. as_ref ( ) , Some ( project . path ( ) ) ) )
461484 . collect :: < Vec < _ > > ( ) ,
462485 ProjectWorkspace :: Cargo {
463486 cargo,
@@ -507,7 +530,7 @@ impl ProjectWorkspace {
507530 }
508531 PackageRoot { is_local, include, exclude }
509532 } )
510- . chain ( mk_sysroot ( sysroot. as_ref ( ) ) )
533+ . chain ( mk_sysroot ( sysroot. as_ref ( ) , Some ( cargo . workspace_root ( ) ) ) )
511534 . chain ( rustc. iter ( ) . flat_map ( |rustc| {
512535 rustc. packages ( ) . map ( move |krate| PackageRoot {
513536 is_local : false ,
@@ -524,7 +547,7 @@ impl ProjectWorkspace {
524547 include : vec ! [ detached_file. clone( ) ] ,
525548 exclude : Vec :: new ( ) ,
526549 } )
527- . chain ( mk_sysroot ( sysroot. as_ref ( ) ) )
550+ . chain ( mk_sysroot ( sysroot. as_ref ( ) , None ) )
528551 . collect ( ) ,
529552 }
530553 }
0 commit comments