From e205af259d7518e9042adcc1852ddff4457ce3ed Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 13 Apr 2023 16:43:36 +0200 Subject: [PATCH] Prefer test duped crates for ide features --- Cargo.lock | 2 + crates/base-db/Cargo.toml | 1 + crates/base-db/src/lib.rs | 25 ++++- crates/hir-def/src/test_db.rs | 12 +- crates/hir-ty/Cargo.toml | 1 + crates/hir-ty/src/test_db.rs | 12 +- crates/hir/src/semantics/source_to_def.rs | 4 +- crates/ide-db/src/lib.rs | 8 +- crates/project-model/src/workspace.rs | 13 ++- .../cargo_dev_dependencies-crate-graph.txt | 106 +----------------- 10 files changed, 65 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8759782bb2..0e384a2e42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,7 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "indexmap", "la-arena", "profile", "rustc-hash", @@ -579,6 +580,7 @@ dependencies = [ "hir-def", "hir-expand", "hkalbasi-rustc-ap-rustc_index", + "indexmap", "intern", "itertools", "la-arena", diff --git a/crates/base-db/Cargo.toml b/crates/base-db/Cargo.toml index c2d021c223..3c0aedce14 100644 --- a/crates/base-db/Cargo.toml +++ b/crates/base-db/Cargo.toml @@ -14,6 +14,7 @@ doctest = false [dependencies] salsa = "0.17.0-pre.2" rustc-hash = "1.1.0" +indexmap = "1.6.0" la-arena = { version = "0.3.0", path = "../../lib/la-arena" } diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs index b65cf7341f..7593135c5c 100644 --- a/crates/base-db/src/lib.rs +++ b/crates/base-db/src/lib.rs @@ -6,9 +6,10 @@ mod input; mod change; pub mod fixture; -use std::{panic, sync::Arc}; +use std::{hash::BuildHasherDefault, panic, sync::Arc}; -use rustc_hash::FxHashSet; +use indexmap::IndexSet; +use rustc_hash::FxHasher; use syntax::{ast, Parse, SourceFile, TextRange, TextSize}; pub use crate::{ @@ -59,7 +60,10 @@ pub trait FileLoader { /// Text of the file. fn file_text(&self, file_id: FileId) -> Arc; fn resolve_path(&self, path: AnchoredPath<'_>) -> Option; - fn relevant_crates(&self, file_id: FileId) -> Arc>; + fn relevant_crates( + &self, + file_id: FileId, + ) -> Arc>>; } /// Database which stores all significant input facts: source code and project @@ -99,10 +103,16 @@ pub trait SourceDatabaseExt: SourceDatabase { #[salsa::input] fn source_root(&self, id: SourceRootId) -> Arc; - fn source_root_crates(&self, id: SourceRootId) -> Arc>; + fn source_root_crates( + &self, + id: SourceRootId, + ) -> Arc>>; } -fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc> { +fn source_root_crates( + db: &dyn SourceDatabaseExt, + id: SourceRootId, +) -> Arc>> { let graph = db.crate_graph(); let res = graph .iter() @@ -128,7 +138,10 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { source_root.resolve_path(path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates( + &self, + file_id: FileId, + ) -> Arc>> { let _p = profile::span("relevant_crates"); let source_root = self.0.file_source_root(file_id); self.0.source_root_crates(source_root) diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index 6bfcd90970..5a186466bc 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -1,7 +1,9 @@ //! Database used for testing `hir_def`. use std::{ - fmt, panic, + fmt, + hash::BuildHasherDefault, + panic, sync::{Arc, Mutex}, }; @@ -11,7 +13,8 @@ use base_db::{ Upcast, }; use hir_expand::{db::ExpandDatabase, InFile}; -use rustc_hash::FxHashSet; +use indexmap::IndexSet; +use rustc_hash::FxHasher; use syntax::{algo, ast, AstNode}; use crate::{ @@ -77,7 +80,10 @@ impl FileLoader for TestDB { fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { FileLoaderDelegate(self).resolve_path(path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates( + &self, + file_id: FileId, + ) -> Arc>> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml index 3ab7460e8c..7c153e28d0 100644 --- a/crates/hir-ty/Cargo.toml +++ b/crates/hir-ty/Cargo.toml @@ -30,6 +30,7 @@ la-arena = { version = "0.3.0", path = "../../lib/la-arena" } once_cell = "1.17.0" typed-arena = "2.0.1" rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false } +indexmap = "1.6.0" # local deps stdx.workspace = true diff --git a/crates/hir-ty/src/test_db.rs b/crates/hir-ty/src/test_db.rs index ca96a8d172..7525106fd0 100644 --- a/crates/hir-ty/src/test_db.rs +++ b/crates/hir-ty/src/test_db.rs @@ -1,7 +1,9 @@ //! Database used for testing `hir`. use std::{ - fmt, panic, + fmt, + hash::BuildHasherDefault, + panic, sync::{Arc, Mutex}, }; @@ -11,7 +13,8 @@ use base_db::{ }; use hir_def::{db::DefDatabase, ModuleId}; use hir_expand::db::ExpandDatabase; -use rustc_hash::FxHashSet; +use indexmap::IndexSet; +use rustc_hash::FxHasher; use stdx::hash::NoHashHashMap; use syntax::TextRange; use test_utils::extract_annotations; @@ -82,7 +85,10 @@ impl FileLoader for TestDB { fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { FileLoaderDelegate(self).resolve_path(path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates( + &self, + file_id: FileId, + ) -> Arc>> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index c50ffa4f8b..12257247c8 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -119,7 +119,9 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn file_to_def(&self, file: FileId) -> SmallVec<[ModuleId; 1]> { let _p = profile::span("SourceBinder::to_module_def"); let mut mods = SmallVec::new(); - for &crate_id in self.db.relevant_crates(file).iter() { + // HACK: We iterate in reverse so that dev-dependency duplicated crates appear first in this + // Most code only deals with one module and we want to prefer the test enabled code where possible + for &crate_id in self.db.relevant_crates(file).iter().rev() { // FIXME: inner items let crate_def_map = self.db.crate_def_map(crate_id); mods.extend( diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index b0c5820fb0..879dbb7450 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -43,7 +43,7 @@ pub mod syntax_helpers { pub use parser::LexedStr; } -use std::{fmt, mem::ManuallyDrop, sync::Arc}; +use std::{fmt, hash::BuildHasherDefault, mem::ManuallyDrop, sync::Arc}; use base_db::{ salsa::{self, Durability}, @@ -53,6 +53,7 @@ use hir::{ db::{DefDatabase, ExpandDatabase, HirDatabase}, symbols::FileSymbolKind, }; +use indexmap::IndexSet; use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; @@ -119,7 +120,10 @@ impl FileLoader for RootDatabase { fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { FileLoaderDelegate(self).resolve_path(path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates( + &self, + file_id: FileId, + ) -> Arc>> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index a0b185a3a5..065b25d746 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -938,7 +938,7 @@ fn cargo_to_crate_graph( // Get all dependencies of the workspace members that are used as dev-dependencies for pkg in cargo.packages() { for dep in &cargo[pkg].dependencies { - if dep.kind == DepKind::Dev { + if dep.kind == DepKind::Dev && cargo[dep.pkg].is_member { work.push(dep.pkg); } } @@ -955,6 +955,10 @@ fn cargo_to_crate_graph( } v.insert({ let duped = crate_graph.duplicate(to); + tracing::info!( + "duplicating workspace crate {:?} as it is being used as a dev-dependency: {to:?} -> {duped:?}", + crate_graph[to].display_name + ); if let Some(proc_macro) = proc_macros.get(&to).cloned() { proc_macros.insert(duped, proc_macro); } @@ -1008,7 +1012,12 @@ fn cargo_to_crate_graph( for (&pkg, targets) in &pkg_crates { for &(krate, _) in targets { - if test_dupes.get(&krate).is_some() { + if let Some(&dupe) = test_dupes.get(&krate) { + tracing::info!( + "{krate:?} {:?} {dupe:?} {:?}", + crate_graph[krate].cfg_options, + crate_graph[dupe].cfg_options + ); // if the crate got duped as a dev-dep the dupe already has test set continue; } diff --git a/crates/project-model/test_data/cargo_dev_dependencies-crate-graph.txt b/crates/project-model/test_data/cargo_dev_dependencies-crate-graph.txt index 2dba4efa92..1070940251 100644 --- a/crates/project-model/test_data/cargo_dev_dependencies-crate-graph.txt +++ b/crates/project-model/test_data/cargo_dev_dependencies-crate-graph.txt @@ -244,14 +244,14 @@ prelude: true, }, Dependency { - crate_id: Idx::(8), + crate_id: Idx::(7), name: CrateName( "ra_playground", ), prelude: true, }, Dependency { - crate_id: Idx::(7), + crate_id: Idx::(5), name: CrateName( "regex", ), @@ -328,14 +328,14 @@ prelude: true, }, Dependency { - crate_id: Idx::(8), + crate_id: Idx::(7), name: CrateName( "ra_playground", ), prelude: true, }, Dependency { - crate_id: Idx::(7), + crate_id: Idx::(5), name: CrateName( "regex", ), @@ -552,104 +552,6 @@ channel: None, }, 7: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2018, - version: Some( - "1.7.3", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "regex", - ), - canonical_name: "regex", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "feature=aho-corasick", - "feature=default", - "feature=memchr", - "feature=perf", - "feature=perf-cache", - "feature=perf-dfa", - "feature=perf-inline", - "feature=perf-literal", - "feature=std", - "feature=unicode", - "feature=unicode-age", - "feature=unicode-bool", - "feature=unicode-case", - "feature=unicode-gencat", - "feature=unicode-perl", - "feature=unicode-script", - "feature=unicode-segment", - "test", - ], - ), - potential_cfg_options: Some( - CfgOptions( - [ - "debug_assertions", - "feature=aho-corasick", - "feature=default", - "feature=memchr", - "feature=pattern", - "feature=perf", - "feature=perf-cache", - "feature=perf-dfa", - "feature=perf-inline", - "feature=perf-literal", - "feature=std", - "feature=unicode", - "feature=unicode-age", - "feature=unicode-bool", - "feature=unicode-case", - "feature=unicode-gencat", - "feature=unicode-perl", - "feature=unicode-script", - "feature=unicode-segment", - "feature=unstable", - "feature=use_std", - ], - ), - ), - env: Env { - entries: { - "CARGO_PKG_LICENSE": "", - "CARGO_PKG_VERSION_MAJOR": "1", - "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.7.3", - "CARGO_PKG_VERSION": "1.7.3", - "CARGO_PKG_AUTHORS": "", - "CARGO_CRATE_NAME": "regex", - "CARGO_PKG_LICENSE_FILE": "", - "CARGO_PKG_HOMEPAGE": "", - "CARGO_PKG_DESCRIPTION": "", - "CARGO_PKG_NAME": "regex", - "CARGO_PKG_VERSION_PATCH": "3", - "CARGO": "cargo", - "CARGO_PKG_REPOSITORY": "", - "CARGO_PKG_VERSION_MINOR": "7", - "CARGO_PKG_VERSION_PRE": "", - }, - }, - dependencies: [], - origin: Library { - repo: Some( - "https://github.com/rust-lang/regex", - ), - name: "regex", - }, - is_proc_macro: false, - target_layout: Err( - "target_data_layout not loaded", - ), - channel: None, - }, - 8: CrateData { root_file_id: FileId( 4, ),