Skip to content

Commit cfe8e37

Browse files
committed
Auto merge of #18080 - Veykril:dedup, r=Veykril
Remove crate graph deduplication logic Fixes #17748
2 parents 14a18b4 + c2258d8 commit cfe8e37

File tree

21 files changed

+133
-19760
lines changed

21 files changed

+133
-19760
lines changed

crates/base-db/src/change.rs

+13-1
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

crates/base-db/src/input.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -491,43 +491,29 @@ impl CrateGraph {
491491
.for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id));
492492
}
493493

494-
/// Extends this crate graph by adding a complete disjoint second crate
494+
/// Extends this crate graph by adding a complete second crate
495495
/// graph and adjust the ids in the [`ProcMacroPaths`] accordingly.
496496
///
497-
/// This will deduplicate the crates of the graph where possible.
498-
/// Note that for deduplication to fully work, `self`'s crate dependencies must be sorted by crate id.
499-
/// If the crate dependencies were sorted, the resulting graph from this `extend` call will also
500-
/// have the crate dependencies sorted.
501-
///
502-
/// Returns a mapping from `other`'s crate ids to the new crate ids in `self`.
497+
/// Returns a map mapping `other`'s IDs to the new IDs in `self`.
503498
pub fn extend(
504499
&mut self,
505500
mut other: CrateGraph,
506501
proc_macros: &mut ProcMacroPaths,
507-
merge: impl Fn((CrateId, &mut CrateData), (CrateId, &CrateData)) -> bool,
508502
) -> FxHashMap<CrateId, CrateId> {
509-
let m = self.len();
510503
let topo = other.crates_in_topological_order();
511504
let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default();
512505
for topo in topo {
513506
let crate_data = &mut other.arena[topo];
514507

515508
crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
516509
crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
517-
let res = self
518-
.arena
519-
.iter_mut()
520-
.take(m)
521-
.find_map(|(id, data)| merge((id, data), (topo, crate_data)).then_some(id));
522-
523-
let new_id =
524-
if let Some(res) = res { res } else { self.arena.alloc(crate_data.clone()) };
510+
511+
let new_id = self.arena.alloc(crate_data.clone());
525512
id_map.insert(topo, new_id);
526513
}
527514

528515
*proc_macros =
529516
mem::take(proc_macros).into_iter().map(|(id, macros)| (id_map[&id], macros)).collect();
530-
531517
id_map
532518
}
533519

crates/base-db/src/lib.rs

+19-7
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> {

crates/hir-def/src/attr.rs

+2-2
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))

crates/hir-def/src/body.rs

+1-1
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

crates/hir-def/src/macro_expansion_tests/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
320320
_: Span,
321321
_: Span,
322322
_: Span,
323+
_: Option<String>,
323324
) -> Result<Subtree, ProcMacroExpansionError> {
324325
let (parse, _) = syntax_bridge::token_tree_to_syntax_node(
325326
subtree,

crates/hir-expand/src/change.rs

+10-33
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
}

crates/hir-expand/src/proc_macro.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe {
2929
def_site: Span,
3030
call_site: Span,
3131
mixed_site: Span,
32+
current_dir: Option<String>,
3233
) -> Result<tt::Subtree, ProcMacroExpansionError>;
3334
}
3435

@@ -234,8 +235,18 @@ impl CustomProcMacroExpander {
234235
let krate_graph = db.crate_graph();
235236
// Proc macros have access to the environment variables of the invoking crate.
236237
let env = &krate_graph[calling_crate].env;
237-
match proc_macro.expander.expand(tt, attr_arg, env, def_site, call_site, mixed_site)
238-
{
238+
match proc_macro.expander.expand(
239+
tt,
240+
attr_arg,
241+
env,
242+
def_site,
243+
call_site,
244+
mixed_site,
245+
db.crate_workspace_data()[&calling_crate]
246+
.proc_macro_cwd
247+
.as_ref()
248+
.map(ToString::to_string),
249+
) {
239250
Ok(t) => ExpandResult::ok(t),
240251
Err(err) => match err {
241252
// Don't discard the item in case something unexpected happened while expanding attributes

crates/hir-ty/src/layout/target.rs

+3-3
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
}

crates/ide/src/lib.rs

+13-5
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
}

crates/load-cargo/src/lib.rs

+20-7
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
@@ -489,8 +493,17 @@ impl ProcMacroExpander for Expander {
489493
def_site: Span,
490494
call_site: Span,
491495
mixed_site: Span,
496+
current_dir: Option<String>,
492497
) -> Result<tt::Subtree<Span>, ProcMacroExpansionError> {
493-
match self.0.expand(subtree, attrs, env.clone(), def_site, call_site, mixed_site) {
498+
match self.0.expand(
499+
subtree,
500+
attrs,
501+
env.clone(),
502+
def_site,
503+
call_site,
504+
mixed_site,
505+
current_dir,
506+
) {
494507
Ok(Ok(subtree)) => Ok(subtree),
495508
Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err.0)),
496509
Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),

0 commit comments

Comments
 (0)