From 7bfa62e99f1ccdb7f15c579fc4c7de7e472ebd28 Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Mon, 22 Dec 2025 22:20:33 +0900 Subject: [PATCH] update based on comment --- crates/ide/src/runnables.rs | 64 +++++++++++-------------- crates/rust-analyzer/src/target_spec.rs | 7 +-- 2 files changed, 30 insertions(+), 41 deletions(-) diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 136ce6ac1e..6798504378 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -57,7 +57,7 @@ pub enum RunnableKind { TestMod { path: String }, Test { test_id: TestId, attr: TestAttr }, Bench { test_id: TestId }, - DocTest { test_id: TestId, has_compile_fail: bool }, + DocTest { test_id: TestId }, Bin, } @@ -404,7 +404,9 @@ pub(crate) fn runnable_impl( let display_target = def.module(sema.db).krate(sema.db).to_display_target(sema.db); let edition = display_target.edition; let attrs = def.attrs(sema.db); - let doc_test_info = runnable_doc_test_info(sema.db, &attrs)?; + if !has_runnable_doc_test(sema.db, &attrs) { + return None; + } let cfg = attrs.cfgs(sema.db).cloned(); let nav = def.try_to_nav(sema)?.call_site(); let ty = def.self_ty(sema.db); @@ -427,7 +429,7 @@ pub(crate) fn runnable_impl( Some(Runnable { use_name_in_title: false, nav, - kind: RunnableKind::DocTest { test_id, has_compile_fail: doc_test_info.has_compile_fail }, + kind: RunnableKind::DocTest { test_id }, cfg, update_test, }) @@ -506,7 +508,9 @@ fn module_def_doctest(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Op let display_target = krate .unwrap_or_else(|| (*db.all_crates().last().expect("no crate graph present")).into()) .to_display_target(db); - let doc_test_info = runnable_doc_test_info(db, &attrs)?; + if !has_runnable_doc_test(db, &attrs) { + return None; + } let def_name = def.name(db)?; let path = (|| { let mut path = String::new(); @@ -547,7 +551,7 @@ fn module_def_doctest(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Op let res = Runnable { use_name_in_title: false, nav, - kind: RunnableKind::DocTest { test_id, has_compile_fail: doc_test_info.has_compile_fail }, + kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfgs(db).cloned(), update_test: UpdateTest::default(), }; @@ -565,23 +569,18 @@ impl TestAttr { } } -#[derive(Default, Clone, Copy)] -struct RunnableDocTestInfo { - has_compile_fail: bool, -} - -fn runnable_doc_test_info( - db: &RootDatabase, - attrs: &hir::AttrsWithOwner, -) -> Option { +fn has_runnable_doc_test(db: &RootDatabase, attrs: &hir::AttrsWithOwner) -> bool { const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"]; const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] = &["", "rust", "should_panic", "edition2015", "edition2018", "edition2021", "edition2024"]; - let doc = attrs.hir_docs(db)?; - let mut info = RunnableDocTestInfo::default(); + let doc = match attrs.hir_docs(db) { + Some(doc) => doc, + None => return false, + }; let mut in_code_block = false; let mut runnable_found = false; + let mut has_compile_fail = false; for line in doc.docs().lines() { let trimmed_line = line.trim_start(); @@ -606,7 +605,7 @@ fn runnable_doc_test_info( if attr.eq_ignore_ascii_case("compile_fail") { block_has_compile_fail = true; block_runnable = false; - continue; + break; } if !RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE @@ -617,12 +616,12 @@ fn runnable_doc_test_info( } } - info.has_compile_fail |= block_has_compile_fail; + has_compile_fail |= block_has_compile_fail; runnable_found |= block_runnable; } } - runnable_found.then_some(info) + runnable_found && !has_compile_fail } // We could create runnables for modules with number_of_test_submodules > 0, @@ -780,7 +779,6 @@ impl UpdateTest { mod tests { use expect_test::{Expect, expect}; - use super::RunnableKind; use crate::fixture; fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { @@ -970,11 +968,13 @@ impl Test for StructWithRunnable {} } #[test] - fn doc_test_runnable_tracks_compile_fail_blocks() { - let (analysis, position) = fixture::position( + fn doc_test_with_compile_fail_blocks_is_skipped() { + check( r#" //- /lib.rs $0 +fn main() {} + /// ```compile_fail /// let x = 5; /// x += 1; @@ -984,22 +984,14 @@ $0 /// let x = 5; /// x + 1; /// ``` -fn add(left: u64, right: u64) -> u64 { - left + right -} +fn add() {} "#, + expect![[r#" + [ + "(Bin, NavigationTarget { file_id: FileId(0), full_range: 1..13, focus_range: 4..8, name: \"main\", kind: Function })", + ] + "#]], ); - - let runnables = analysis.runnables(position.file_id).unwrap(); - let doc_test = runnables - .into_iter() - .find(|runnable| matches!(runnable.kind, RunnableKind::DocTest { .. })) - .expect("expected doctest runnable"); - - match doc_test.kind { - RunnableKind::DocTest { has_compile_fail, .. } => assert!(has_compile_fail), - _ => panic!("expected doctest runnable"), - } } #[test] diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs index f47df6e5c9..e532d15553 100644 --- a/crates/rust-analyzer/src/target_spec.rs +++ b/crates/rust-analyzer/src/target_spec.rs @@ -116,7 +116,7 @@ impl CargoTargetSpec { cfg: &Option, ) -> (Vec, Vec) { let config = snap.config.runnables(None); - let mut extra_test_binary_args = config.extra_test_binary_args; + let extra_test_binary_args = config.extra_test_binary_args; let mut cargo_args = Vec::new(); let mut executable_args = Vec::new(); @@ -146,13 +146,10 @@ impl CargoTargetSpec { } executable_args.extend(extra_test_binary_args); } - RunnableKind::DocTest { test_id, has_compile_fail } => { + RunnableKind::DocTest { test_id } => { cargo_args.push("test".to_owned()); cargo_args.push("--doc".to_owned()); executable_args.push(test_id.to_string()); - if *has_compile_fail { - extra_test_binary_args.retain(|arg| arg != "--nocapture"); - } executable_args.extend(extra_test_binary_args); } RunnableKind::Bin => {