@@ -18,7 +18,7 @@ use std::{iter, mem};
1818use hir:: { ChangeWithProcMacros , ProcMacrosBuilder , db:: DefDatabase } ;
1919use ide_db:: {
2020 FxHashMap ,
21- base_db:: { CrateGraphBuilder , ProcMacroPaths , RootQueryDb , salsa:: Durability } ,
21+ base_db:: { CrateGraphBuilder , ProcMacroPaths , salsa:: Durability } ,
2222} ;
2323use itertools:: Itertools ;
2424use load_cargo:: { ProjectFolders , load_proc_macro} ;
@@ -408,11 +408,11 @@ impl GlobalState {
408408 } ;
409409
410410 let mut builder = ProcMacrosBuilder :: default ( ) ;
411- let chain = proc_macro_clients
411+ let proc_macro_clients = proc_macro_clients
412412 . iter ( )
413413 . map ( |res| res. as_ref ( ) . map_err ( |e| e. to_string ( ) ) )
414414 . chain ( iter:: repeat_with ( || Err ( "proc-macro-srv is not running" . into ( ) ) ) ) ;
415- for ( client, paths) in chain . zip ( paths) {
415+ for ( client, paths) in proc_macro_clients . zip ( paths) {
416416 paths
417417 . into_iter ( )
418418 . map ( move |( crate_id, res) | {
@@ -458,11 +458,12 @@ impl GlobalState {
458458 else {
459459 return ;
460460 } ;
461+ let switching_from_empty_workspace = self . workspaces . is_empty ( ) ;
461462
462- info ! ( %cause, ?force_crate_graph_reload) ;
463- if self . fetch_workspace_error ( ) . is_err ( ) && !self . workspaces . is_empty ( ) {
463+ info ! ( %cause, ?force_crate_graph_reload, %switching_from_empty_workspace ) ;
464+ if self . fetch_workspace_error ( ) . is_err ( ) && !switching_from_empty_workspace {
464465 if * force_crate_graph_reload {
465- self . recreate_crate_graph ( cause) ;
466+ self . recreate_crate_graph ( cause, false ) ;
466467 }
467468 // It only makes sense to switch to a partially broken workspace
468469 // if we don't have any workspace at all yet.
@@ -479,36 +480,44 @@ impl GlobalState {
479480 . all ( |( l, r) | l. eq_ignore_build_data ( r) ) ;
480481
481482 if same_workspaces {
482- let ( workspaces, build_scripts) = match self . fetch_build_data_queue . last_op_result ( ) {
483- Some ( FetchBuildDataResponse { workspaces, build_scripts } ) => {
484- ( workspaces. clone ( ) , build_scripts. as_slice ( ) )
485- }
486- None => ( Default :: default ( ) , Default :: default ( ) ) ,
487- } ;
483+ if switching_from_empty_workspace {
484+ // Switching from empty to empty is a no-op
485+ return ;
486+ }
487+ if let Some ( FetchBuildDataResponse { workspaces, build_scripts } ) =
488+ self . fetch_build_data_queue . last_op_result ( )
489+ {
490+ if Arc :: ptr_eq ( workspaces, & self . workspaces ) {
491+ info ! ( "set build scripts to workspaces" ) ;
488492
489- if Arc :: ptr_eq ( & workspaces, & self . workspaces ) {
490- info ! ( "set build scripts to workspaces" ) ;
493+ let workspaces = workspaces
494+ . iter ( )
495+ . cloned ( )
496+ . zip ( build_scripts)
497+ . map ( |( mut ws, bs) | {
498+ ws. set_build_scripts ( bs. as_ref ( ) . ok ( ) . cloned ( ) . unwrap_or_default ( ) ) ;
499+ ws
500+ } )
501+ . collect :: < Vec < _ > > ( ) ;
502+ // Workspaces are the same, but we've updated build data.
503+ info ! ( "same workspace, but new build data" ) ;
504+ self . workspaces = Arc :: new ( workspaces) ;
505+ } else {
506+ info ! ( "build scripts do not match the version of the active workspace" ) ;
507+ if * force_crate_graph_reload {
508+ self . recreate_crate_graph ( cause, switching_from_empty_workspace) ;
509+ }
491510
492- let workspaces = workspaces
493- . iter ( )
494- . cloned ( )
495- . zip ( build_scripts)
496- . map ( |( mut ws, bs) | {
497- ws. set_build_scripts ( bs. as_ref ( ) . ok ( ) . cloned ( ) . unwrap_or_default ( ) ) ;
498- ws
499- } )
500- . collect :: < Vec < _ > > ( ) ;
501- // Workspaces are the same, but we've updated build data.
502- info ! ( "same workspace, but new build data" ) ;
503- self . workspaces = Arc :: new ( workspaces) ;
511+ // Current build scripts do not match the version of the active
512+ // workspace, so there's nothing for us to update.
513+ return ;
514+ }
504515 } else {
505- info ! ( "build scripts do not match the version of the active workspace" ) ;
506516 if * force_crate_graph_reload {
507- self . recreate_crate_graph ( cause) ;
517+ self . recreate_crate_graph ( cause, switching_from_empty_workspace ) ;
508518 }
509519
510- // Current build scripts do not match the version of the active
511- // workspace, so there's nothing for us to update.
520+ // No build scripts but unchanged workspaces, nothing to do here
512521 return ;
513522 }
514523 } else {
@@ -528,8 +537,7 @@ impl GlobalState {
528537 self . build_deps_changed = false ;
529538 self . fetch_build_data_queue . request_op ( "workspace updated" . to_owned ( ) , ( ) ) ;
530539
531- let initial_build = self . analysis_host . raw_database ( ) . all_crates ( ) . is_empty ( ) ;
532- if !initial_build {
540+ if !switching_from_empty_workspace {
533541 // `switch_workspaces()` will be called again when build scripts already run, which should
534542 // take a short time. If we update the workspace now we will invalidate proc macros and cfgs,
535543 // and then when build scripts complete we will invalidate them again.
@@ -691,12 +699,12 @@ impl GlobalState {
691699 self . local_roots_parent_map = Arc :: new ( self . source_root_config . source_root_parent_map ( ) ) ;
692700
693701 info ! ( ?cause, "recreating the crate graph" ) ;
694- self . recreate_crate_graph ( cause) ;
702+ self . recreate_crate_graph ( cause, switching_from_empty_workspace ) ;
695703
696704 info ! ( "did switch workspaces" ) ;
697705 }
698706
699- fn recreate_crate_graph ( & mut self , cause : String ) {
707+ fn recreate_crate_graph ( & mut self , cause : String , initial_build : bool ) {
700708 info ! ( ?cause, "Building Crate Graph" ) ;
701709 self . report_progress (
702710 "Building CrateGraph" ,
@@ -732,7 +740,6 @@ impl GlobalState {
732740 ws_to_crate_graph ( & self . workspaces , self . config . extra_env ( None ) , load)
733741 } ;
734742 let mut change = ChangeWithProcMacros :: new ( ) ;
735- let initial_build = self . analysis_host . raw_database ( ) . all_crates ( ) . is_empty ( ) ;
736743 if initial_build || !self . config . expand_proc_macros ( ) {
737744 if self . config . expand_proc_macros ( ) {
738745 change. set_proc_macros (
0 commit comments