Skip to content

Commit 3bb8d3a

Browse files
committed
Auto merge of rust-lang#16247 - Veykril:opqueues, r=Veykril
fix: Fix build scripts not being rebuilt in some occasions Also makes proc-macro changed flag setting async, we don't wanna block `process_changes` on the database as that is on the main thread!
2 parents 004190b + 1e6cef9 commit 3bb8d3a

File tree

16 files changed

+121
-77
lines changed

16 files changed

+121
-77
lines changed

crates/hir-def/src/nameres/collector.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
101101
if it.disabled {
102102
CustomProcMacroExpander::disabled()
103103
} else {
104-
CustomProcMacroExpander::new(hir_expand::proc_macro::ProcMacroId(
105-
idx as u32,
106-
))
104+
CustomProcMacroExpander::new(
105+
hir_expand::proc_macro::ProcMacroId::new(idx as u32),
106+
)
107107
},
108108
)
109109
})
@@ -2354,7 +2354,7 @@ impl ModCollector<'_, '_> {
23542354
resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
23552355
},
23562356
) {
2357-
// FIXME: if there were errors, this mightve been in the eager expansion from an
2357+
// FIXME: if there were errors, this might've been in the eager expansion from an
23582358
// unresolved macro, so we need to push this into late macro resolution. see fixme above
23592359
if res.err.is_none() {
23602360
// Legacy macros need to be expanded immediately, so that any macros they produce

crates/hir-expand/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ pub enum MacroCallKind {
227227
},
228228
Attr {
229229
ast_id: AstId<ast::Item>,
230-
// FIXME: This is being interned, subtrees can vary quickly differ just slightly causing
231-
// leakage problems here
230+
// FIXME: This shouldn't be here, we can derive this from `invoc_attr_index`
231+
// but we need to fix the `cfg_attr` handling first.
232232
attr_args: Option<Arc<tt::Subtree>>,
233233
/// Syntactical index of the invoking `#[attribute]`.
234234
///

crates/hir-expand/src/proc_macro.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ use syntax::SmolStr;
1212
use crate::{db::ExpandDatabase, tt, ExpandError, ExpandResult};
1313

1414
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
15-
pub struct ProcMacroId(pub u32);
15+
pub struct ProcMacroId(u32);
16+
17+
impl ProcMacroId {
18+
pub fn new(u32: u32) -> Self {
19+
ProcMacroId(u32)
20+
}
21+
}
1622

1723
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
1824
pub enum ProcMacroKind {

crates/ide/src/parent_module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
5454
}
5555
}
5656

57-
/// Returns `Vec` for the same reason as `parent_module`
57+
/// This returns `Vec` because a module may be included from several places.
5858
pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
5959
db.relevant_crates(file_id)
6060
.iter()

crates/project-model/src/build_scripts.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use toolchain::Tool;
2424

2525
use crate::{
2626
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
27-
InvocationStrategy, Package, Sysroot,
27+
InvocationStrategy, Package, Sysroot, TargetKind,
2828
};
2929

3030
#[derive(Debug, Default, Clone, PartialEq, Eq)]
@@ -467,7 +467,11 @@ impl WorkspaceBuildScripts {
467467
.collect();
468468
for p in rustc.packages() {
469469
let package = &rustc[p];
470-
if package.targets.iter().any(|&it| rustc[it].is_proc_macro) {
470+
if package
471+
.targets
472+
.iter()
473+
.any(|&it| matches!(rustc[it].kind, TargetKind::Lib { is_proc_macro: true }))
474+
{
471475
if let Some((_, path)) = proc_macro_dylibs
472476
.iter()
473477
.find(|(name, _)| *name.trim_start_matches("lib") == package.name)

crates/project-model/src/cargo_workspace.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,6 @@ pub struct TargetData {
189189
pub root: AbsPathBuf,
190190
/// Kind of target
191191
pub kind: TargetKind,
192-
/// Is this target a proc-macro
193-
pub is_proc_macro: bool,
194192
/// Required features of the target without which it won't build
195193
pub required_features: Vec<String>,
196194
}
@@ -199,7 +197,10 @@ pub struct TargetData {
199197
pub enum TargetKind {
200198
Bin,
201199
/// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
202-
Lib,
200+
Lib {
201+
/// Is this target a proc-macro
202+
is_proc_macro: bool,
203+
},
203204
Example,
204205
Test,
205206
Bench,
@@ -216,8 +217,8 @@ impl TargetKind {
216217
"bench" => TargetKind::Bench,
217218
"example" => TargetKind::Example,
218219
"custom-build" => TargetKind::BuildScript,
219-
"proc-macro" => TargetKind::Lib,
220-
_ if kind.contains("lib") => TargetKind::Lib,
220+
"proc-macro" => TargetKind::Lib { is_proc_macro: true },
221+
_ if kind.contains("lib") => TargetKind::Lib { is_proc_macro: false },
221222
_ => continue,
222223
};
223224
}
@@ -371,7 +372,6 @@ impl CargoWorkspace {
371372
name,
372373
root: AbsPathBuf::assert(src_path.into()),
373374
kind: TargetKind::new(&kind),
374-
is_proc_macro: *kind == ["proc-macro"],
375375
required_features,
376376
});
377377
pkg_data.targets.push(tgt);

crates/project-model/src/workspace.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ impl ProjectWorkspace {
625625
let extra_targets = cargo[pkg]
626626
.targets
627627
.iter()
628-
.filter(|&&tgt| cargo[tgt].kind == TargetKind::Lib)
628+
.filter(|&&tgt| matches!(cargo[tgt].kind, TargetKind::Lib { .. }))
629629
.filter_map(|&tgt| cargo[tgt].root.parent())
630630
.map(|tgt| tgt.normalize().to_path_buf())
631631
.filter(|path| !path.starts_with(&pkg_root));
@@ -991,15 +991,15 @@ fn cargo_to_crate_graph(
991991

992992
let mut lib_tgt = None;
993993
for &tgt in cargo[pkg].targets.iter() {
994-
if cargo[tgt].kind != TargetKind::Lib && !cargo[pkg].is_member {
994+
if !matches!(cargo[tgt].kind, TargetKind::Lib { .. }) && !cargo[pkg].is_member {
995995
// For non-workspace-members, Cargo does not resolve dev-dependencies, so we don't
996996
// add any targets except the library target, since those will not work correctly if
997997
// they use dev-dependencies.
998998
// In fact, they can break quite badly if multiple client workspaces get merged:
999999
// https://github.com/rust-lang/rust-analyzer/issues/11300
10001000
continue;
10011001
}
1002-
let &TargetData { ref name, kind, is_proc_macro, ref root, .. } = &cargo[tgt];
1002+
let &TargetData { ref name, kind, ref root, .. } = &cargo[tgt];
10031003

10041004
let Some(file_id) = load(root) else { continue };
10051005

@@ -1011,19 +1011,24 @@ fn cargo_to_crate_graph(
10111011
cfg_options.clone(),
10121012
file_id,
10131013
name,
1014-
is_proc_macro,
1014+
kind,
10151015
target_layout.clone(),
10161016
false,
10171017
toolchain.cloned(),
10181018
);
1019-
if kind == TargetKind::Lib {
1019+
if let TargetKind::Lib { .. } = kind {
10201020
lib_tgt = Some((crate_id, name.clone()));
10211021
pkg_to_lib_crate.insert(pkg, crate_id);
10221022
}
10231023
// Even crates that don't set proc-macro = true are allowed to depend on proc_macro
10241024
// (just none of the APIs work when called outside of a proc macro).
10251025
if let Some(proc_macro) = libproc_macro {
1026-
add_proc_macro_dep(crate_graph, crate_id, proc_macro, is_proc_macro);
1026+
add_proc_macro_dep(
1027+
crate_graph,
1028+
crate_id,
1029+
proc_macro,
1030+
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
1031+
);
10271032
}
10281033

10291034
pkg_crates.entry(pkg).or_insert_with(Vec::new).push((crate_id, kind));
@@ -1221,9 +1226,9 @@ fn handle_rustc_crates(
12211226
};
12221227

12231228
for &tgt in rustc_workspace[pkg].targets.iter() {
1224-
if rustc_workspace[tgt].kind != TargetKind::Lib {
1229+
let kind @ TargetKind::Lib { is_proc_macro } = rustc_workspace[tgt].kind else {
12251230
continue;
1226-
}
1231+
};
12271232
if let Some(file_id) = load(&rustc_workspace[tgt].root) {
12281233
let crate_id = add_target_crate_root(
12291234
crate_graph,
@@ -1233,7 +1238,7 @@ fn handle_rustc_crates(
12331238
cfg_options.clone(),
12341239
file_id,
12351240
&rustc_workspace[tgt].name,
1236-
rustc_workspace[tgt].is_proc_macro,
1241+
kind,
12371242
target_layout.clone(),
12381243
true,
12391244
toolchain.cloned(),
@@ -1242,12 +1247,7 @@ fn handle_rustc_crates(
12421247
// Add dependencies on core / std / alloc for this crate
12431248
public_deps.add_to_crate_graph(crate_graph, crate_id);
12441249
if let Some(proc_macro) = libproc_macro {
1245-
add_proc_macro_dep(
1246-
crate_graph,
1247-
crate_id,
1248-
proc_macro,
1249-
rustc_workspace[tgt].is_proc_macro,
1250-
);
1250+
add_proc_macro_dep(crate_graph, crate_id, proc_macro, is_proc_macro);
12511251
}
12521252
rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
12531253
}
@@ -1309,7 +1309,7 @@ fn add_target_crate_root(
13091309
cfg_options: CfgOptions,
13101310
file_id: FileId,
13111311
cargo_name: &str,
1312-
is_proc_macro: bool,
1312+
kind: TargetKind,
13131313
target_layout: TargetLayoutLoadResult,
13141314
rustc_crate: bool,
13151315
toolchain: Option<Version>,
@@ -1359,7 +1359,7 @@ fn add_target_crate_root(
13591359
cfg_options,
13601360
potential_cfg_options,
13611361
env,
1362-
is_proc_macro,
1362+
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
13631363
if rustc_crate {
13641364
CrateOrigin::Rustc { name: pkg.name.clone() }
13651365
} else if pkg.is_member {
@@ -1370,7 +1370,7 @@ fn add_target_crate_root(
13701370
target_layout,
13711371
toolchain,
13721372
);
1373-
if is_proc_macro {
1373+
if let TargetKind::Lib { is_proc_macro: true } = kind {
13741374
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
13751375
Some(it) => it.cloned().map(|path| Ok((Some(cargo_name.to_owned()), path))),
13761376
None => Some(Err("crate has not yet been built".to_owned())),

crates/rust-analyzer/src/cargo_target_spec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl CargoTargetSpec {
174174
buf.push("--example".to_owned());
175175
buf.push(self.target);
176176
}
177-
TargetKind::Lib => {
177+
TargetKind::Lib { is_proc_macro: _ } => {
178178
buf.push("--lib".to_owned());
179179
}
180180
TargetKind::Other | TargetKind::BuildScript => (),

crates/rust-analyzer/src/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ config_data! {
112112
cargo_buildScripts_overrideCommand: Option<Vec<String>> = "null",
113113
/// Rerun proc-macros building/build-scripts running when proc-macro
114114
/// or build-script sources change and are saved.
115-
cargo_buildScripts_rebuildOnSave: bool = "false",
115+
cargo_buildScripts_rebuildOnSave: bool = "true",
116116
/// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
117117
/// avoid checking unnecessary things.
118118
cargo_buildScripts_useRustcWrapper: bool = "true",

crates/rust-analyzer/src/global_state.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crossbeam_channel::{unbounded, Receiver, Sender};
99
use flycheck::FlycheckHandle;
1010
use hir::Change;
1111
use ide::{Analysis, AnalysisHost, Cancellable, FileId};
12-
use ide_db::base_db::{CrateId, FileLoader, ProcMacroPaths, SourceDatabase};
12+
use ide_db::base_db::{CrateId, ProcMacroPaths};
1313
use load_cargo::SourceRootConfig;
1414
use lsp_types::{SemanticTokens, Url};
1515
use nohash_hasher::IntMap;
@@ -74,8 +74,8 @@ pub(crate) struct GlobalState {
7474
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
7575

7676
// proc macros
77-
pub(crate) proc_macro_changed: bool,
7877
pub(crate) proc_macro_clients: Arc<[anyhow::Result<ProcMacroServer>]>,
78+
pub(crate) build_deps_changed: bool,
7979

8080
// Flycheck
8181
pub(crate) flycheck: Arc<[FlycheckHandle]>,
@@ -203,9 +203,10 @@ impl GlobalState {
203203
source_root_config: SourceRootConfig::default(),
204204
config_errors: Default::default(),
205205

206-
proc_macro_changed: false,
207206
proc_macro_clients: Arc::from_iter([]),
208207

208+
build_deps_changed: false,
209+
209210
flycheck: Arc::from_iter([]),
210211
flycheck_sender,
211212
flycheck_receiver,
@@ -300,12 +301,19 @@ impl GlobalState {
300301
if let Some(path) = vfs_path.as_path() {
301302
let path = path.to_path_buf();
302303
if reload::should_refresh_for_change(&path, file.kind()) {
303-
workspace_structure_change = Some((path.clone(), false));
304+
workspace_structure_change = Some((
305+
path.clone(),
306+
false,
307+
AsRef::<std::path::Path>::as_ref(&path).ends_with("build.rs"),
308+
));
304309
}
305310
if file.is_created_or_deleted() {
306311
has_structure_changes = true;
307-
workspace_structure_change =
308-
Some((path, self.crate_graph_file_dependencies.contains(vfs_path)));
312+
workspace_structure_change = Some((
313+
path,
314+
self.crate_graph_file_dependencies.contains(vfs_path),
315+
false,
316+
));
309317
} else if path.extension() == Some("rs".as_ref()) {
310318
modified_rust_files.push(file.file_id);
311319
}
@@ -346,23 +354,28 @@ impl GlobalState {
346354
};
347355

348356
self.analysis_host.apply_change(change);
357+
349358
{
350-
let raw_database = self.analysis_host.raw_database();
359+
if !matches!(&workspace_structure_change, Some((.., true))) {
360+
_ = self
361+
.deferred_task_queue
362+
.sender
363+
.send(crate::main_loop::QueuedTask::CheckProcMacroSources(modified_rust_files));
364+
}
351365
// FIXME: ideally we should only trigger a workspace fetch for non-library changes
352366
// but something's going wrong with the source root business when we add a new local
353367
// crate see https://github.com/rust-lang/rust-analyzer/issues/13029
354-
if let Some((path, force_crate_graph_reload)) = workspace_structure_change {
368+
if let Some((path, force_crate_graph_reload, build_scripts_touched)) =
369+
workspace_structure_change
370+
{
355371
self.fetch_workspaces_queue.request_op(
356372
format!("workspace vfs file change: {path}"),
357373
force_crate_graph_reload,
358374
);
375+
if build_scripts_touched {
376+
self.fetch_build_data_queue.request_op(format!("build.rs changed: {path}"), ());
377+
}
359378
}
360-
self.proc_macro_changed = modified_rust_files.into_iter().any(|file_id| {
361-
let crates = raw_database.relevant_crates(file_id);
362-
let crate_graph = raw_database.crate_graph();
363-
364-
crates.iter().any(|&krate| crate_graph[krate].is_proc_macro)
365-
});
366379
}
367380

368381
true

crates/rust-analyzer/src/handlers/notification.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ pub(crate) fn handle_did_save_text_document(
145145
state: &mut GlobalState,
146146
params: DidSaveTextDocumentParams,
147147
) -> anyhow::Result<()> {
148-
if state.config.script_rebuild_on_save() && state.proc_macro_changed {
149-
// reset the flag
150-
state.proc_macro_changed = false;
151-
// rebuild the proc macros
152-
state.fetch_build_data_queue.request_op("ScriptRebuildOnSave".to_owned(), ());
148+
if state.config.script_rebuild_on_save() && state.build_deps_changed {
149+
state.build_deps_changed = false;
150+
state
151+
.fetch_build_data_queue
152+
.request_op("build_deps_changed - save notification".to_owned(), ());
153153
}
154154

155155
if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
@@ -158,7 +158,7 @@ pub(crate) fn handle_did_save_text_document(
158158
if reload::should_refresh_for_change(abs_path, ChangeKind::Modify) {
159159
state
160160
.fetch_workspaces_queue
161-
.request_op(format!("DidSaveTextDocument {abs_path}"), false);
161+
.request_op(format!("workspace vfs file change saved {abs_path}"), false);
162162
}
163163
}
164164

crates/rust-analyzer/src/handlers/request.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ use crate::{
5252

5353
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
5454
state.proc_macro_clients = Arc::from_iter([]);
55-
state.proc_macro_changed = false;
55+
state.build_deps_changed = false;
5656

5757
state.fetch_workspaces_queue.request_op("reload workspace request".to_owned(), false);
5858
Ok(())
5959
}
6060

6161
pub(crate) fn handle_proc_macros_rebuild(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
6262
state.proc_macro_clients = Arc::from_iter([]);
63-
state.proc_macro_changed = false;
63+
state.build_deps_changed = false;
6464

6565
state.fetch_build_data_queue.request_op("rebuild proc macros request".to_owned(), ());
6666
Ok(())

0 commit comments

Comments
 (0)