Skip to content

Commit b5e0452

Browse files
committed
Lazy progress reporting
1 parent 64a8887 commit b5e0452

File tree

2 files changed

+75
-70
lines changed

2 files changed

+75
-70
lines changed

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use profile::{Bytes, StopWatch};
2929
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource};
3030
use rayon::prelude::*;
3131
use rustc_hash::FxHashSet;
32-
use stdx::format_to;
3332
use syntax::{AstNode, SyntaxNode};
3433
use vfs::{AbsPathBuf, Vfs, VfsPath};
3534

@@ -241,8 +240,10 @@ impl flags::AnalysisStats {
241240
continue;
242241
}
243242
all += 1;
244-
let Err(e) = db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into()) else {
245-
continue;
243+
let Err(e)
244+
= db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into())
245+
else {
246+
continue
246247
};
247248
if verbosity.is_spammy() {
248249
let full_name = a
@@ -363,7 +364,7 @@ impl flags::AnalysisStats {
363364
for &body_id in bodies {
364365
let name = body_id.name(db).unwrap_or_else(Name::missing);
365366
let module = body_id.module(db);
366-
let full_name = || {
367+
let full_name = move || {
367368
module
368369
.krate()
369370
.display_name(db)
@@ -375,7 +376,7 @@ impl flags::AnalysisStats {
375376
.into_iter()
376377
.filter_map(|it| it.name(db))
377378
.rev()
378-
.chain(Some(name.clone()))
379+
.chain(Some(body_id.name(db).unwrap_or_else(Name::missing)))
379380
.map(|it| it.display(db).to_string()),
380381
)
381382
.join("::")
@@ -385,26 +386,31 @@ impl flags::AnalysisStats {
385386
continue;
386387
}
387388
}
388-
let mut msg = format!("processing: {}", full_name());
389-
if verbosity.is_verbose() {
390-
let source = match body_id {
391-
DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
392-
DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
393-
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
394-
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
395-
DefWithBody::InTypeConst(_) => unimplemented!(),
396-
};
397-
if let Some(src) = source {
398-
let original_file = src.file_id.original_file(db);
399-
let path = vfs.file_path(original_file);
400-
let syntax_range = src.value.text_range();
401-
format_to!(msg, " ({} {:?})", path, syntax_range);
389+
let msg = move || {
390+
if verbosity.is_verbose() {
391+
let source = match body_id {
392+
DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
393+
DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
394+
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
395+
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
396+
DefWithBody::InTypeConst(_) => unimplemented!(),
397+
};
398+
if let Some(src) = source {
399+
let original_file = src.file_id.original_file(db);
400+
let path = vfs.file_path(original_file);
401+
let syntax_range = src.value.text_range();
402+
format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
403+
} else {
404+
format!("processing: {}", full_name())
405+
}
406+
} else {
407+
format!("processing: {}", full_name())
402408
}
403-
}
409+
};
404410
if verbosity.is_spammy() {
405-
bar.println(msg.to_string());
411+
bar.println(msg());
406412
}
407-
bar.set_message(&msg);
413+
bar.set_message(msg);
408414
let (body, sm) = db.body_with_source_map(body_id.into());
409415
let inference_result = db.infer(body_id.into());
410416

@@ -641,16 +647,15 @@ impl flags::AnalysisStats {
641647
) {
642648
let mut bar = match verbosity {
643649
Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
644-
_ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
650+
_ if self.output.is_some() => ProgressReport::hidden(),
645651
_ => ProgressReport::new(bodies.len() as u64),
646652
};
647653

648654
let mut sw = self.stop_watch();
649655
bar.tick();
650656
for &body_id in bodies {
651-
let name = body_id.name(db).unwrap_or_else(Name::missing);
652657
let module = body_id.module(db);
653-
let full_name = || {
658+
let full_name = move || {
654659
module
655660
.krate()
656661
.display_name(db)
@@ -662,38 +667,45 @@ impl flags::AnalysisStats {
662667
.into_iter()
663668
.filter_map(|it| it.name(db))
664669
.rev()
665-
.chain(Some(name.clone()))
670+
.chain(Some(body_id.name(db).unwrap_or_else(Name::missing)))
666671
.map(|it| it.display(db).to_string()),
667672
)
668673
.join("::")
669674
};
670675
if let Some(only_name) = self.only.as_deref() {
671-
if name.display(db).to_string() != only_name && full_name() != only_name {
676+
if body_id.name(db).unwrap_or_else(Name::missing).display(db).to_string()
677+
!= only_name
678+
&& full_name() != only_name
679+
{
672680
continue;
673681
}
674682
}
675-
let mut msg = format!("processing: {}", full_name());
676-
if verbosity.is_verbose() {
677-
let source = match body_id {
678-
DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
679-
DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
680-
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
681-
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
682-
DefWithBody::InTypeConst(_) => unimplemented!(),
683-
};
684-
if let Some(src) = source {
685-
let original_file = src.file_id.original_file(db);
686-
let path = vfs.file_path(original_file);
687-
let syntax_range = src.value.text_range();
688-
format_to!(msg, " ({} {:?})", path, syntax_range);
683+
let msg = move || {
684+
if verbosity.is_verbose() {
685+
let source = match body_id {
686+
DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
687+
DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
688+
DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
689+
DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
690+
DefWithBody::InTypeConst(_) => unimplemented!(),
691+
};
692+
if let Some(src) = source {
693+
let original_file = src.file_id.original_file(db);
694+
let path = vfs.file_path(original_file);
695+
let syntax_range = src.value.text_range();
696+
format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
697+
} else {
698+
format!("processing: {}", full_name())
699+
}
700+
} else {
701+
format!("processing: {}", full_name())
689702
}
690-
}
703+
};
691704
if verbosity.is_spammy() {
692-
bar.println(msg.to_string());
705+
bar.println(msg());
693706
}
694-
bar.set_message(&msg);
695-
let (body, sm) = db.body_with_source_map(body_id.into());
696-
// endregion:patterns
707+
bar.set_message(msg);
708+
db.body_with_source_map(body_id.into());
697709
bar.inc(1);
698710
}
699711

crates/rust-analyzer/src/cli/progress_report.rs

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,29 @@
44
use std::io::{self, Write};
55

66
/// A Simple ASCII Progress Bar
7-
pub(crate) struct ProgressReport {
7+
pub(crate) struct ProgressReport<'a> {
88
curr: f32,
99
text: String,
1010
hidden: bool,
1111

1212
len: u64,
1313
pos: u64,
14-
msg: String,
14+
msg: Option<Box<dyn Fn() -> String + 'a>>,
1515
}
1616

17-
impl ProgressReport {
18-
pub(crate) fn new(len: u64) -> ProgressReport {
19-
ProgressReport {
20-
curr: 0.0,
21-
text: String::new(),
22-
hidden: false,
23-
len,
24-
pos: 0,
25-
msg: String::new(),
26-
}
17+
impl<'a> ProgressReport<'a> {
18+
pub(crate) fn new(len: u64) -> ProgressReport<'a> {
19+
ProgressReport { curr: 0.0, text: String::new(), hidden: false, len, pos: 0, msg: None }
2720
}
2821

29-
pub(crate) fn hidden() -> ProgressReport {
30-
ProgressReport {
31-
curr: 0.0,
32-
text: String::new(),
33-
hidden: true,
34-
len: 0,
35-
pos: 0,
36-
msg: String::new(),
37-
}
22+
pub(crate) fn hidden() -> ProgressReport<'a> {
23+
ProgressReport { curr: 0.0, text: String::new(), hidden: true, len: 0, pos: 0, msg: None }
3824
}
3925

40-
pub(crate) fn set_message(&mut self, msg: &str) {
41-
self.msg = msg.to_string();
26+
pub(crate) fn set_message(&mut self, msg: impl Fn() -> String + 'a) {
27+
if !self.hidden {
28+
self.msg = Some(Box::new(msg));
29+
}
4230
self.tick();
4331
}
4432

@@ -67,7 +55,12 @@ impl ProgressReport {
6755
return;
6856
}
6957
let percent = (self.curr * 100.0) as u32;
70-
let text = format!("{}/{} {percent:3>}% {}", self.pos, self.len, self.msg);
58+
let text = format!(
59+
"{}/{} {percent:3>}% {}",
60+
self.pos,
61+
self.len,
62+
self.msg.as_ref().map_or_else(|| String::new(), |it| it())
63+
);
7164
self.update_text(&text);
7265
}
7366

0 commit comments

Comments
 (0)