mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Auto merge of #16617 - Veykril:rustc-tests-timeout, r=Veykril
internal: Attempt to add a timeout to rustc-tests Looks like some new test is stuck, this might help with figuring that out, though it unfortunately won't if its a chalk hang (which is the most likely)
This commit is contained in:
commit
4760d856bc
@ -4,7 +4,7 @@ use ide_db::{
|
|||||||
source_change::SourceChange,
|
source_change::SourceChange,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use syntax::{ast, AstNode, SyntaxNode};
|
use syntax::{ast, AstNode, SyntaxNode, SyntaxNodePtr};
|
||||||
use text_edit::TextEdit;
|
use text_edit::TextEdit;
|
||||||
|
|
||||||
use crate::{fix, Diagnostic, DiagnosticCode};
|
use crate::{fix, Diagnostic, DiagnosticCode};
|
||||||
@ -43,7 +43,7 @@ pub(crate) fn useless_braces(
|
|||||||
"Unnecessary braces in use statement".to_owned(),
|
"Unnecessary braces in use statement".to_owned(),
|
||||||
FileRange { file_id, range: use_range },
|
FileRange { file_id, range: use_range },
|
||||||
)
|
)
|
||||||
.with_main_node(InFile::new(file_id.into(), node.clone()))
|
.with_main_node(InFile::new(file_id.into(), SyntaxNodePtr::new(node)))
|
||||||
.with_fixes(Some(vec![fix(
|
.with_fixes(Some(vec![fix(
|
||||||
"remove_braces",
|
"remove_braces",
|
||||||
"Remove unnecessary braces",
|
"Remove unnecessary braces",
|
||||||
|
@ -142,7 +142,7 @@ pub struct Diagnostic {
|
|||||||
pub experimental: bool,
|
pub experimental: bool,
|
||||||
pub fixes: Option<Vec<Assist>>,
|
pub fixes: Option<Vec<Assist>>,
|
||||||
// The node that will be affected by `#[allow]` and similar attributes.
|
// The node that will be affected by `#[allow]` and similar attributes.
|
||||||
pub main_node: Option<InFile<SyntaxNode>>,
|
pub main_node: Option<InFile<SyntaxNodePtr>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Diagnostic {
|
impl Diagnostic {
|
||||||
@ -174,9 +174,8 @@ impl Diagnostic {
|
|||||||
message: impl Into<String>,
|
message: impl Into<String>,
|
||||||
node: InFile<SyntaxNodePtr>,
|
node: InFile<SyntaxNodePtr>,
|
||||||
) -> Diagnostic {
|
) -> Diagnostic {
|
||||||
let file_id = node.file_id;
|
|
||||||
Diagnostic::new(code, message, ctx.sema.diagnostics_display_range(node))
|
Diagnostic::new(code, message, ctx.sema.diagnostics_display_range(node))
|
||||||
.with_main_node(node.map(|x| x.to_node(&ctx.sema.parse_or_expand(file_id))))
|
.with_main_node(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn experimental(mut self) -> Diagnostic {
|
fn experimental(mut self) -> Diagnostic {
|
||||||
@ -184,7 +183,7 @@ impl Diagnostic {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_main_node(mut self, main_node: InFile<SyntaxNode>) -> Diagnostic {
|
fn with_main_node(mut self, main_node: InFile<SyntaxNodePtr>) -> Diagnostic {
|
||||||
self.main_node = Some(main_node);
|
self.main_node = Some(main_node);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -394,8 +393,17 @@ pub fn diagnostics(
|
|||||||
res.push(d)
|
res.push(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostics_of_range =
|
let mut diagnostics_of_range = res
|
||||||
res.iter_mut().filter_map(|x| Some((x.main_node.clone()?, x))).collect::<FxHashMap<_, _>>();
|
.iter_mut()
|
||||||
|
.filter_map(|it| {
|
||||||
|
Some((
|
||||||
|
it.main_node
|
||||||
|
.map(|ptr| ptr.map(|node| node.to_node(&ctx.sema.parse_or_expand(ptr.file_id))))
|
||||||
|
.clone()?,
|
||||||
|
it,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect::<FxHashMap<_, _>>();
|
||||||
|
|
||||||
let mut rustc_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
|
let mut rustc_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
|
||||||
let mut clippy_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
|
let mut clippy_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
//! Run all tests in a project, similar to `cargo test`, but using the mir interpreter.
|
//! Run all tests in a project, similar to `cargo test`, but using the mir interpreter.
|
||||||
|
|
||||||
|
use std::convert::identity;
|
||||||
|
use std::thread::Builder;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::PathBuf};
|
use std::{cell::RefCell, fs::read_to_string, panic::AssertUnwindSafe, path::PathBuf};
|
||||||
|
|
||||||
use hir::{Change, Crate};
|
use hir::{Change, Crate};
|
||||||
use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig};
|
use ide::{AnalysisHost, DiagnosticCode, DiagnosticsConfig};
|
||||||
|
use itertools::Either;
|
||||||
use profile::StopWatch;
|
use profile::StopWatch;
|
||||||
use project_model::target_data_layout::RustcDataLayoutConfig;
|
use project_model::target_data_layout::RustcDataLayoutConfig;
|
||||||
use project_model::{target_data_layout, CargoConfig, ProjectWorkspace, RustLibSource, Sysroot};
|
use project_model::{target_data_layout, CargoConfig, ProjectWorkspace, RustLibSource, Sysroot};
|
||||||
@ -100,6 +104,7 @@ impl Tester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test(&mut self, p: PathBuf) {
|
fn test(&mut self, p: PathBuf) {
|
||||||
|
println!("{}", p.display());
|
||||||
if p.parent().unwrap().file_name().unwrap() == "auxiliary" {
|
if p.parent().unwrap().file_name().unwrap() == "auxiliary" {
|
||||||
// These are not tests
|
// These are not tests
|
||||||
return;
|
return;
|
||||||
@ -132,15 +137,44 @@ impl Tester {
|
|||||||
self.host.apply_change(change);
|
self.host.apply_change(change);
|
||||||
let diagnostic_config = DiagnosticsConfig::test_sample();
|
let diagnostic_config = DiagnosticsConfig::test_sample();
|
||||||
|
|
||||||
|
let res = std::thread::scope(|s| {
|
||||||
|
let worker = Builder::new()
|
||||||
|
.stack_size(40 * 1024 * 1024)
|
||||||
|
.spawn_scoped(s, {
|
||||||
|
let diagnostic_config = &diagnostic_config;
|
||||||
|
let main = std::thread::current();
|
||||||
|
let analysis = self.host.analysis();
|
||||||
|
let root_file = self.root_file;
|
||||||
|
move || {
|
||||||
|
let res = std::panic::catch_unwind(move || {
|
||||||
|
analysis.diagnostics(
|
||||||
|
diagnostic_config,
|
||||||
|
ide::AssistResolveStrategy::None,
|
||||||
|
root_file,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
main.unpark();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let timeout = Duration::from_secs(5);
|
||||||
|
let now = Instant::now();
|
||||||
|
while now.elapsed() <= timeout && !worker.is_finished() {
|
||||||
|
std::thread::park_timeout(timeout - now.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !worker.is_finished() {
|
||||||
|
// attempt to cancel the worker, won't work for chalk hangs unfortunately
|
||||||
|
self.host.request_cancellation();
|
||||||
|
}
|
||||||
|
worker.join().and_then(identity)
|
||||||
|
});
|
||||||
let mut actual = FxHashMap::default();
|
let mut actual = FxHashMap::default();
|
||||||
let panicked = match std::panic::catch_unwind(|| {
|
let panicked = match res {
|
||||||
self.host
|
Err(e) => Some(Either::Left(e)),
|
||||||
.analysis()
|
Ok(Ok(diags)) => {
|
||||||
.diagnostics(&diagnostic_config, ide::AssistResolveStrategy::None, self.root_file)
|
|
||||||
.unwrap()
|
|
||||||
}) {
|
|
||||||
Err(e) => Some(e),
|
|
||||||
Ok(diags) => {
|
|
||||||
for diag in diags {
|
for diag in diags {
|
||||||
if !matches!(diag.code, DiagnosticCode::RustcHardError(_)) {
|
if !matches!(diag.code, DiagnosticCode::RustcHardError(_)) {
|
||||||
continue;
|
continue;
|
||||||
@ -152,6 +186,7 @@ impl Tester {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Ok(Err(e)) => Some(Either::Right(e)),
|
||||||
};
|
};
|
||||||
// Ignore tests with diagnostics that we don't emit.
|
// Ignore tests with diagnostics that we don't emit.
|
||||||
ignore_test |= expected.keys().any(|k| !SUPPORTED_DIAGNOSTICS.contains(k));
|
ignore_test |= expected.keys().any(|k| !SUPPORTED_DIAGNOSTICS.contains(k));
|
||||||
@ -159,14 +194,19 @@ impl Tester {
|
|||||||
println!("{p:?} IGNORE");
|
println!("{p:?} IGNORE");
|
||||||
self.ignore_count += 1;
|
self.ignore_count += 1;
|
||||||
} else if let Some(panic) = panicked {
|
} else if let Some(panic) = panicked {
|
||||||
if let Some(msg) = panic
|
match panic {
|
||||||
.downcast_ref::<String>()
|
Either::Left(panic) => {
|
||||||
.map(String::as_str)
|
if let Some(msg) = panic
|
||||||
.or_else(|| panic.downcast_ref::<&str>().copied())
|
.downcast_ref::<String>()
|
||||||
{
|
.map(String::as_str)
|
||||||
println!("{msg:?} ")
|
.or_else(|| panic.downcast_ref::<&str>().copied())
|
||||||
|
{
|
||||||
|
println!("{msg:?} ")
|
||||||
|
}
|
||||||
|
println!("{p:?} PANIC");
|
||||||
|
}
|
||||||
|
Either::Right(_) => println!("{p:?} CANCELLED"),
|
||||||
}
|
}
|
||||||
println!("PANIC");
|
|
||||||
self.fail_count += 1;
|
self.fail_count += 1;
|
||||||
} else if actual == expected {
|
} else if actual == expected {
|
||||||
println!("{p:?} PASS");
|
println!("{p:?} PASS");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user