Skip to content

Commit aa883b4

Browse files
committed
Lift out workspace related data into a separate query to preserve crategraph deduplication
1 parent 69ab8c2 commit aa883b4

File tree

10 files changed

+98
-97
lines changed

10 files changed

+98
-97
lines changed

src/tools/rust-analyzer/crates/base-db/src/change.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@
33
44
use std::fmt;
55

6+
use rustc_hash::FxHashMap;
67
use salsa::Durability;
78
use triomphe::Arc;
89
use vfs::FileId;
910

10-
use crate::{CrateGraph, SourceDatabaseFileInputExt, SourceRoot, SourceRootDatabase, SourceRootId};
11+
use crate::{
12+
CrateGraph, CrateId, CrateWorkspaceData, SourceDatabaseFileInputExt, SourceRoot,
13+
SourceRootDatabase, SourceRootId,
14+
};
1115

1216
/// Encapsulate a bunch of raw `.set` calls on the database.
1317
#[derive(Default)]
1418
pub struct FileChange {
1519
pub roots: Option<Vec<SourceRoot>>,
1620
pub files_changed: Vec<(FileId, Option<String>)>,
1721
pub crate_graph: Option<CrateGraph>,
22+
pub ws_data: Option<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>,
1823
}
1924

2025
impl fmt::Debug for FileChange {
@@ -50,6 +55,10 @@ impl FileChange {
5055
self.crate_graph = Some(graph);
5156
}
5257

58+
pub fn set_ws_data(&mut self, data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>) {
59+
self.ws_data = Some(data);
60+
}
61+
5362
pub fn apply(self, db: &mut dyn SourceRootDatabase) {
5463
let _p = tracing::info_span!("FileChange::apply").entered();
5564
if let Some(roots) = self.roots {
@@ -74,6 +83,9 @@ impl FileChange {
7483
if let Some(crate_graph) = self.crate_graph {
7584
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH);
7685
}
86+
if let Some(data) = self.ws_data {
87+
db.set_crate_workspace_data_with_durability(Arc::new(data), Durability::HIGH);
88+
}
7789
}
7890
}
7991

src/tools/rust-analyzer/crates/base-db/src/lib.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ mod input;
55

66
use std::panic;
77

8+
use rustc_hash::FxHashMap;
89
use salsa::Durability;
910
use span::EditionedFileId;
1011
use syntax::{ast, Parse, SourceFile, SyntaxError};
1112
use triomphe::Arc;
12-
use vfs::FileId;
13+
use vfs::{AbsPathBuf, FileId};
1314

1415
pub use crate::{
1516
change::FileChange,
@@ -74,19 +75,30 @@ pub trait SourceDatabase: FileLoader + std::fmt::Debug {
7475
#[salsa::input]
7576
fn crate_graph(&self) -> Arc<CrateGraph>;
7677

77-
// FIXME: Consider removing this, making HirDatabase::target_data_layout an input query
78-
#[salsa::input]
79-
fn data_layout(&self, krate: CrateId) -> TargetLayoutLoadResult;
80-
8178
#[salsa::input]
82-
fn toolchain(&self, krate: CrateId) -> Option<Version>;
79+
fn crate_workspace_data(&self) -> Arc<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>;
8380

8481
#[salsa::transparent]
8582
fn toolchain_channel(&self, krate: CrateId) -> Option<ReleaseChannel>;
8683
}
8784

85+
/// Crate related data shared by the whole workspace.
86+
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
87+
pub struct CrateWorkspaceData {
88+
/// The working directory to run proc-macros in. This is usually the workspace root of cargo workspaces.
89+
pub proc_macro_cwd: Option<AbsPathBuf>,
90+
// FIXME: Consider removing this, making HirDatabase::target_data_layout an input query
91+
pub data_layout: TargetLayoutLoadResult,
92+
/// Toolchain version used to compile the crate.
93+
pub toolchain: Option<Version>,
94+
}
95+
8896
fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option<ReleaseChannel> {
89-
db.toolchain(krate).as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
97+
db.crate_workspace_data()
98+
.get(&krate)?
99+
.toolchain
100+
.as_ref()
101+
.and_then(|v| ReleaseChannel::from_str(&v.pre))
90102
}
91103

92104
fn parse(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Parse<ast::SourceFile> {

src/tools/rust-analyzer/crates/hir-def/src/attr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl Attrs {
117117
}
118118

119119
impl Attrs {
120-
pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'_> {
120+
pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'attrs> {
121121
AttrQuery { attrs: self, key }
122122
}
123123

@@ -594,7 +594,7 @@ impl<'attr> AttrQuery<'attr> {
594594
/// #[doc(html_root_url = "url")]
595595
/// ^^^^^^^^^^^^^ key
596596
/// ```
597-
pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&str> {
597+
pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&'attr str> {
598598
self.tt_values().find_map(|tt| {
599599
let name = tt.token_trees.iter()
600600
.skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == *key))

src/tools/rust-analyzer/crates/hir-def/src/body.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl Body {
204204
pub fn blocks<'a>(
205205
&'a self,
206206
db: &'a dyn DefDatabase,
207-
) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + '_ {
207+
) -> impl Iterator<Item = (BlockId, Arc<DefMap>)> + 'a {
208208
self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block)))
209209
}
210210

src/tools/rust-analyzer/crates/hir-expand/src/change.rs

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! Defines a unit of change that can applied to the database to get the next
22
//! state. Changes are transactional.
33
use base_db::{
4-
salsa::Durability, CrateGraph, CrateId, FileChange, SourceRoot, SourceRootDatabase,
5-
TargetLayoutLoadResult, Version,
4+
salsa::Durability, CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot,
5+
SourceRootDatabase,
66
};
7-
use la_arena::RawIdx;
7+
use rustc_hash::FxHashMap;
88
use span::FileId;
99
use triomphe::Arc;
1010

@@ -14,8 +14,6 @@ use crate::{db::ExpandDatabase, proc_macro::ProcMacros};
1414
pub struct ChangeWithProcMacros {
1515
pub source_change: FileChange,
1616
pub proc_macros: Option<ProcMacros>,
17-
pub toolchains: Option<Vec<Option<Version>>>,
18-
pub target_data_layouts: Option<Vec<TargetLayoutLoadResult>>,
1917
}
2018

2119
impl ChangeWithProcMacros {
@@ -28,46 +26,25 @@ impl ChangeWithProcMacros {
2826
if let Some(proc_macros) = self.proc_macros {
2927
db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH);
3028
}
31-
if let Some(target_data_layouts) = self.target_data_layouts {
32-
for (id, val) in target_data_layouts.into_iter().enumerate() {
33-
db.set_data_layout_with_durability(
34-
CrateId::from_raw(RawIdx::from(id as u32)),
35-
val,
36-
Durability::HIGH,
37-
);
38-
}
39-
}
40-
if let Some(toolchains) = self.toolchains {
41-
for (id, val) in toolchains.into_iter().enumerate() {
42-
db.set_toolchain_with_durability(
43-
CrateId::from_raw(RawIdx::from(id as u32)),
44-
val,
45-
Durability::HIGH,
46-
);
47-
}
48-
}
4929
}
5030

5131
pub fn change_file(&mut self, file_id: FileId, new_text: Option<String>) {
5232
self.source_change.change_file(file_id, new_text)
5333
}
5434

55-
pub fn set_crate_graph(&mut self, graph: CrateGraph) {
56-
self.source_change.set_crate_graph(graph)
35+
pub fn set_crate_graph(
36+
&mut self,
37+
graph: CrateGraph,
38+
ws_data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>,
39+
) {
40+
self.source_change.set_crate_graph(graph);
41+
self.source_change.set_ws_data(ws_data);
5742
}
5843

5944
pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
6045
self.proc_macros = Some(proc_macros);
6146
}
6247

63-
pub fn set_toolchains(&mut self, toolchains: Vec<Option<Version>>) {
64-
self.toolchains = Some(toolchains);
65-
}
66-
67-
pub fn set_target_data_layouts(&mut self, target_data_layouts: Vec<TargetLayoutLoadResult>) {
68-
self.target_data_layouts = Some(target_data_layouts);
69-
}
70-
7148
pub fn set_roots(&mut self, roots: Vec<SourceRoot>) {
7249
self.source_change.set_roots(roots)
7350
}

src/tools/rust-analyzer/crates/hir-ty/src/layout/target.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ pub fn target_data_layout_query(
1111
db: &dyn HirDatabase,
1212
krate: CrateId,
1313
) -> Result<Arc<TargetDataLayout>, Arc<str>> {
14-
match db.data_layout(krate) {
15-
Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(&it) {
14+
match &db.crate_workspace_data()[&krate].data_layout {
15+
Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) {
1616
Ok(it) => Ok(Arc::new(it)),
1717
Err(e) => {
1818
Err(match e {
@@ -42,6 +42,6 @@ pub fn target_data_layout_query(
4242
}.into())
4343
}
4444
},
45-
Err(e) => Err(e),
45+
Err(e) => Err(e.clone()),
4646
}
4747
}

src/tools/rust-analyzer/crates/ide/src/lib.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,16 @@ mod view_item_tree;
5757
mod view_memory_layout;
5858
mod view_mir;
5959

60-
use std::panic::UnwindSafe;
60+
use std::{iter, panic::UnwindSafe};
6161

6262
use cfg::CfgOptions;
6363
use fetch_crates::CrateInfo;
6464
use hir::{sym, ChangeWithProcMacros};
6565
use ide_db::{
6666
base_db::{
6767
salsa::{self, ParallelDatabase},
68-
CrateOrigin, Env, FileLoader, FileSet, SourceDatabase, SourceRootDatabase, VfsPath,
68+
CrateOrigin, CrateWorkspaceData, Env, FileLoader, FileSet, SourceDatabase,
69+
SourceRootDatabase, VfsPath,
6970
},
7071
prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase,
7172
};
@@ -256,9 +257,16 @@ impl Analysis {
256257
CrateOrigin::Local { repo: None, name: None },
257258
);
258259
change.change_file(file_id, Some(text));
259-
change.set_crate_graph(crate_graph);
260-
change.set_target_data_layouts(vec![Err("fixture has no layout".into())]);
261-
change.set_toolchains(vec![None]);
260+
let ws_data = crate_graph
261+
.iter()
262+
.zip(iter::repeat(Arc::new(CrateWorkspaceData {
263+
proc_macro_cwd: None,
264+
data_layout: Err("fixture has no layout".into()),
265+
toolchain: None,
266+
})))
267+
.collect();
268+
change.set_crate_graph(crate_graph, ws_data);
269+
262270
host.apply_change(change);
263271
(host.analysis(), file_id)
264272
}

src/tools/rust-analyzer/crates/load-cargo/src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir_expand::proc_macro::{
1010
ProcMacros,
1111
};
1212
use ide_db::{
13-
base_db::{CrateGraph, Env, SourceRoot, SourceRootId},
13+
base_db::{CrateGraph, CrateWorkspaceData, Env, SourceRoot, SourceRootId},
1414
prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase,
1515
};
1616
use itertools::Itertools;
@@ -447,12 +447,16 @@ fn load_crate_graph(
447447
let source_roots = source_root_config.partition(vfs);
448448
analysis_change.set_roots(source_roots);
449449

450-
let num_crates = crate_graph.len();
451-
analysis_change.set_crate_graph(crate_graph);
450+
let ws_data = crate_graph
451+
.iter()
452+
.zip(iter::repeat(From::from(CrateWorkspaceData {
453+
proc_macro_cwd: None,
454+
data_layout: target_layout.clone(),
455+
toolchain: toolchain.clone(),
456+
})))
457+
.collect();
458+
analysis_change.set_crate_graph(crate_graph, ws_data);
452459
analysis_change.set_proc_macros(proc_macros);
453-
analysis_change
454-
.set_target_data_layouts(iter::repeat(target_layout.clone()).take(num_crates).collect());
455-
analysis_change.set_toolchains(iter::repeat(toolchain.clone()).take(num_crates).collect());
456460

457461
db.apply_change(analysis_change);
458462
db

src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
use std::{iter, mem};
1717

1818
use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder};
19+
use ide::CrateId;
1920
use ide_db::{
20-
base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
21+
base_db::{salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths},
2122
FxHashMap,
2223
};
2324
use itertools::Itertools;
@@ -692,7 +693,7 @@ impl GlobalState {
692693
})
693694
.collect();
694695

695-
let (crate_graph, proc_macro_paths, layouts, toolchains) = {
696+
let (crate_graph, proc_macro_paths, ws_data) = {
696697
// Create crate graph from all the workspaces
697698
let vfs = &mut self.vfs.write().0;
698699

@@ -721,9 +722,7 @@ impl GlobalState {
721722
.collect(),
722723
);
723724
}
724-
change.set_crate_graph(crate_graph);
725-
change.set_target_data_layouts(layouts);
726-
change.set_toolchains(toolchains);
725+
change.set_crate_graph(crate_graph, ws_data);
727726
self.analysis_host.apply_change(change);
728727
self.report_progress(
729728
"Building CrateGraph",
@@ -863,42 +862,27 @@ pub fn ws_to_crate_graph(
863862
workspaces: &[ProjectWorkspace],
864863
extra_env: &FxHashMap<String, String>,
865864
mut load: impl FnMut(&AbsPath) -> Option<vfs::FileId>,
866-
) -> (CrateGraph, Vec<ProcMacroPaths>, Vec<Result<Arc<str>, Arc<str>>>, Vec<Option<Version>>) {
865+
) -> (CrateGraph, Vec<ProcMacroPaths>, FxHashMap<CrateId, Arc<CrateWorkspaceData>>) {
867866
let mut crate_graph = CrateGraph::default();
868867
let mut proc_macro_paths = Vec::default();
869-
let mut layouts = Vec::default();
870-
let mut toolchains = Vec::default();
871-
let e = Err(Arc::from("missing layout"));
868+
let mut ws_data = FxHashMap::default();
872869
for ws in workspaces {
873870
let (other, mut crate_proc_macros) = ws.to_crate_graph(&mut load, extra_env);
874-
let num_layouts = layouts.len();
875-
let num_toolchains = toolchains.len();
876871
let ProjectWorkspace { toolchain, target_layout, .. } = ws;
877872

878873
let mapping = crate_graph.extend(other, &mut crate_proc_macros);
879874
// Populate the side tables for the newly merged crates
880-
mapping.values().for_each(|val| {
881-
let idx = val.into_raw().into_u32() as usize;
882-
// we only need to consider crates that were not merged and remapped, as the
883-
// ones that were remapped already have the correct layout and toolchain
884-
if idx >= num_layouts {
885-
if layouts.len() <= idx {
886-
layouts.resize(idx + 1, e.clone());
887-
}
888-
layouts[idx].clone_from(target_layout);
889-
}
890-
if idx >= num_toolchains {
891-
if toolchains.len() <= idx {
892-
toolchains.resize(idx + 1, None);
893-
}
894-
toolchains[idx].clone_from(toolchain);
895-
}
896-
});
875+
ws_data.extend(mapping.values().copied().zip(iter::repeat(Arc::new(CrateWorkspaceData {
876+
toolchain: toolchain.clone(),
877+
data_layout: target_layout.clone(),
878+
proc_macro_cwd: Some(ws.workspace_root().to_owned()),
879+
}))));
897880
proc_macro_paths.push(crate_proc_macros);
898881
}
882+
899883
crate_graph.shrink_to_fit();
900884
proc_macro_paths.shrink_to_fit();
901-
(crate_graph, proc_macro_paths, layouts, toolchains)
885+
(crate_graph, proc_macro_paths, ws_data)
902886
}
903887

904888
pub(crate) fn should_refresh_for_change(

0 commit comments

Comments
 (0)