@@ -21,7 +21,10 @@ use span::Edition;
2121use triomphe:: Arc ;
2222use vfs:: { AbsPathBuf , AnchoredPath , FileId , VfsPath , file_set:: FileSet } ;
2323
24- use crate :: { CrateWorkspaceData , EditionedFileId , FxIndexSet , RootQueryDb } ;
24+ use crate :: {
25+ CrateWorkspaceData , EditionedFileId , FxIndexSet , SourceDatabase , all_crates,
26+ set_all_crates_with_durability,
27+ } ;
2528
2629pub type ProcMacroPaths =
2730 FxHashMap < CrateBuilderId , Result < ( String , AbsPathBuf ) , ProcMacroLoadingError > > ;
@@ -490,13 +493,13 @@ impl Crate {
490493 /// including the crate itself.
491494 ///
492495 /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
493- pub fn transitive_rev_deps ( self , db : & dyn RootQueryDb ) -> Box < [ Crate ] > {
496+ pub fn transitive_rev_deps ( self , db : & dyn SourceDatabase ) -> Box < [ Crate ] > {
494497 let mut worklist = vec ! [ self ] ;
495498 let mut rev_deps = FxHashSet :: default ( ) ;
496499 rev_deps. insert ( self ) ;
497500
498501 let mut inverted_graph = FxHashMap :: < _ , Vec < _ > > :: default ( ) ;
499- db . all_crates ( ) . iter ( ) . for_each ( |& krate| {
502+ all_crates ( db ) . iter ( ) . for_each ( |& krate| {
500503 krate
501504 . data ( db)
502505 . dependencies
@@ -586,15 +589,15 @@ impl CrateGraphBuilder {
586589 Ok ( ( ) )
587590 }
588591
589- pub fn set_in_db ( self , db : & mut dyn RootQueryDb ) -> CratesIdMap {
592+ pub fn set_in_db ( self , db : & mut dyn SourceDatabase ) -> CratesIdMap {
593+ let old_all_crates = all_crates ( db) ;
594+
590595 // For some reason in some repositories we have duplicate crates, so we use a set and not `Vec`.
591596 // We use an `IndexSet` because the list needs to be topologically sorted.
592597 let mut all_crates = FxIndexSet :: with_capacity_and_hasher ( self . arena . len ( ) , FxBuildHasher ) ;
593598 let mut visited = FxHashMap :: default ( ) ;
594599 let mut visited_root_files = FxHashSet :: default ( ) ;
595600
596- let old_all_crates = db. all_crates ( ) ;
597-
598601 let crates_map = db. crates_map ( ) ;
599602 // salsa doesn't compare new input to old input to see if they are the same, so here we are doing all the work ourselves.
600603 for krate in self . iter ( ) {
@@ -612,17 +615,14 @@ impl CrateGraphBuilder {
612615 if old_all_crates. len ( ) != all_crates. len ( )
613616 || old_all_crates. iter ( ) . any ( |& krate| !all_crates. contains ( & krate) )
614617 {
615- db. set_all_crates_with_durability (
616- Arc :: new ( Vec :: from_iter ( all_crates) . into_boxed_slice ( ) ) ,
617- Durability :: MEDIUM ,
618- ) ;
618+ set_all_crates_with_durability ( db, all_crates, Durability :: MEDIUM ) ;
619619 }
620620
621621 return visited;
622622
623623 fn go (
624624 graph : & CrateGraphBuilder ,
625- db : & mut dyn RootQueryDb ,
625+ db : & mut dyn SourceDatabase ,
626626 crates_map : & CratesMap ,
627627 visited : & mut FxHashMap < CrateBuilderId , Crate > ,
628628 visited_root_files : & mut FxHashSet < FileId > ,
@@ -929,6 +929,27 @@ impl<'a> IntoIterator for &'a Env {
929929 }
930930}
931931
932+ /// The crate graph had a cycle. This is typically a bug, and
933+ /// rust-analyzer logs a warning when it encounters a cycle. Generally
934+ /// rust-analyzer will continue working OK in the presence of cycle,
935+ /// but it's better to have an accurate crate graph.
936+ ///
937+ /// ## dev-dependencies
938+ ///
939+ /// Note that it's actually legal for a cargo package (i.e. a thing
940+ /// with a Cargo.toml) to depend on itself in dev-dependencies. This
941+ /// can enable additional features, and is typically used when a
942+ /// project wants features to be enabled in tests. Dev-dependencies
943+ /// are not propagated, so they aren't visible to package that depend
944+ /// on this one.
945+ ///
946+ /// <https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies>
947+ ///
948+ /// However, rust-analyzer constructs its crate graph from Cargo
949+ /// metadata, so it can end up producing a cyclic crate graph from a
950+ /// well-formed package graph.
951+ ///
952+ /// <https://github.com/rust-lang/rust-analyzer/issues/14167>
932953#[ derive( Debug ) ]
933954pub struct CyclicDependenciesError {
934955 path : Vec < ( CrateBuilderId , Option < CrateDisplayName > ) > ,
0 commit comments