From f675b5ead8e45fc71f5c490e8ad7690e71c225a8 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jan 2024 11:05:50 +0100 Subject: [PATCH] Don't early exit on panics in rustc_tests command --- crates/rust-analyzer/src/cli/rustc_tests.rs | 49 ++++++++++++++------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs index 87bb3cbd34..baa85d3295 100644 --- a/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -55,7 +55,9 @@ fn detect_errors_from_rustc_stderr_file(p: PathBuf) -> HashMap Result { - let tmp_file = AbsPathBuf::assert("/tmp/ra-rustc-test.rs".into()); + let mut path = std::env::temp_dir(); + path.push("ra-rustc-test.rs"); + let tmp_file = AbsPathBuf::try_from(path).unwrap(); std::fs::write(&tmp_file, "")?; let mut cargo_config = CargoConfig::default(); cargo_config.sysroot = Some(RustLibSource::Discover); @@ -122,26 +124,43 @@ impl Tester { change.change_file(self.root_file, Some(Arc::from(text))); self.host.apply_change(change); let diagnostic_config = DiagnosticsConfig::test_sample(); - let diags = self - .host - .analysis() - .diagnostics(&diagnostic_config, ide::AssistResolveStrategy::None, self.root_file) - .unwrap(); + let mut actual = HashMap::new(); - for diag in diags { - if !matches!(diag.code, DiagnosticCode::RustcHardError(_)) { - continue; + let panicked = match std::panic::catch_unwind(|| { + self.host + .analysis() + .diagnostics(&diagnostic_config, ide::AssistResolveStrategy::None, self.root_file) + .unwrap() + }) { + Err(e) => Some(e), + Ok(diags) => { + for diag in diags { + if !matches!(diag.code, DiagnosticCode::RustcHardError(_)) { + continue; + } + if !should_have_no_error && !SUPPORTED_DIAGNOSTICS.contains(&diag.code) { + continue; + } + *actual.entry(diag.code).or_insert(0) += 1; + } + None } - if !should_have_no_error && !SUPPORTED_DIAGNOSTICS.contains(&diag.code) { - continue; - } - *actual.entry(diag.code).or_insert(0) += 1; - } + }; // Ignore tests with diagnostics that we don't emit. ignore_test |= expected.keys().any(|k| !SUPPORTED_DIAGNOSTICS.contains(k)); if ignore_test { println!("{p:?} IGNORE"); self.ignore_count += 1; + } else if let Some(panic) = panicked { + if let Some(msg) = panic + .downcast_ref::() + .map(String::as_str) + .or_else(|| panic.downcast_ref::<&str>().copied()) + { + println!("{msg:?} ") + } + println!("PANIC"); + self.fail_count += 1; } else if actual == expected { println!("{p:?} PASS"); self.pass_count += 1; @@ -225,11 +244,11 @@ impl flags::RustcTests { let tester = AssertUnwindSafe(&mut tester); let p = p.clone(); move || { + let _guard = stdx::panic_context::enter(p.display().to_string()); let tester = tester; tester.0.test(p); } }) { - println!("panic detected at test {:?}", p); std::panic::resume_unwind(e); } }