diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 3a901cbbf866..f601fd627660 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1634,6 +1634,16 @@ impl HasVisibility for AssocItem { } } +impl From for ModuleDef { + fn from(assoc: AssocItem) -> Self { + match assoc { + AssocItem::Function(it) => ModuleDef::Function(it), + AssocItem::Const(it) => ModuleDef::Const(it), + AssocItem::TypeAlias(it) => ModuleDef::TypeAlias(it), + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum GenericDef { Function(Function), diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index 3821e1d2460d..6d4ba98d087d 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs @@ -57,24 +57,22 @@ pub(crate) fn annotations( continue; } - let action = runnable.action(); let range = runnable.nav.focus_or_full_range(); + // dbg_runnable should go after the run annotation, to prevent a clone we do it this way + let dbg_runnable = (runnable.debugee() && config.debug).then(|| Annotation { + range, + kind: AnnotationKind::Runnable { debug: true, runnable: runnable.clone() }, + }); + if config.run { annotations.push(Annotation { range, - - // FIXME: This one allocates without reason if run is enabled, but debug is disabled - kind: AnnotationKind::Runnable { debug: false, runnable: runnable.clone() }, + kind: AnnotationKind::Runnable { debug: false, runnable }, }); } - if action.debugee && config.debug { - annotations.push(Annotation { - range, - kind: AnnotationKind::Runnable { debug: true, runnable }, - }); - } + annotations.extend(dbg_runnable); } } @@ -228,6 +226,7 @@ fn main() { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -247,6 +246,7 @@ fn main() { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -332,6 +332,7 @@ fn main() { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -351,6 +352,7 @@ fn main() { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -440,6 +442,7 @@ fn main() { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -459,6 +462,7 @@ fn main() { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -601,6 +605,7 @@ fn main() {} kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -620,6 +625,7 @@ fn main() {} kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -674,6 +680,7 @@ fn main() { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -693,6 +700,7 @@ fn main() { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -816,6 +824,7 @@ mod tests { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -835,6 +844,7 @@ mod tests { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -854,6 +864,7 @@ mod tests { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -876,6 +887,7 @@ mod tests { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -898,6 +910,7 @@ mod tests { kind: Runnable { debug: false, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -924,6 +937,7 @@ mod tests { kind: Runnable { debug: true, runnable: Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index db1596b45a03..94ad090ac3ab 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -2462,6 +2462,7 @@ fn foo_$0test() {} ), Runnable( Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -2500,6 +2501,7 @@ mod tests$0 { [ Runnable( Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index d1ea3491e838..c0374d424251 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -12,7 +12,7 @@ use ide_db::{ RootDatabase, SymbolKind, }; use itertools::Itertools; -use rustc_hash::FxHashSet; +use rustc_hash::{FxHashMap, FxHashSet}; use stdx::always; use syntax::ast::{self, AstNode, AttrsOwner}; @@ -20,6 +20,7 @@ use crate::{display::TryToNav, references, FileId, NavigationTarget}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Runnable { + pub use_name_in_title: bool, pub nav: NavigationTarget, pub kind: RunnableKind, pub cfg: Option, @@ -49,20 +50,16 @@ pub enum RunnableKind { Bin, } -#[derive(Debug, Eq, PartialEq)] -pub struct RunnableAction { - pub run_title: &'static str, - pub debugee: bool, +#[cfg(test)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +enum RunnableTestKind { + Test, + TestMod, + DocTest, + Bench, + Bin, } -const TEST: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Test", debugee: true }; -const TEST_MOD: RunnableAction = - RunnableAction { run_title: "▶\u{fe0e} Run Tests", debugee: true }; -const DOCTEST: RunnableAction = - RunnableAction { run_title: "▶\u{fe0e} Run Doctest", debugee: false }; -const BENCH: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Bench", debugee: true }; -const BIN: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run", debugee: true }; - impl Runnable { // test package::module::testname pub fn label(&self, target: Option) -> String { @@ -77,13 +74,44 @@ impl Runnable { } } - pub fn action(&self) -> &'static RunnableAction { + pub fn debugee(&self) -> bool { match &self.kind { - RunnableKind::TestMod { .. } => &TEST_MOD, - RunnableKind::Test { .. } => &TEST, - RunnableKind::DocTest { .. } => &DOCTEST, - RunnableKind::Bench { .. } => &BENCH, - RunnableKind::Bin => &BIN, + RunnableKind::TestMod { .. } => true, + RunnableKind::Test { .. } => true, + RunnableKind::DocTest { .. } => false, + RunnableKind::Bench { .. } => true, + RunnableKind::Bin => true, + } + } + + pub fn title(&self) -> String { + use std::fmt::Write as _; + let mut s = String::from("▶\u{fe0e} Run "); + if self.use_name_in_title { + let _ = write!(s, "{}", self.nav.name); + if !matches!(self.kind, RunnableKind::Bin) { + s.push(' '); + } + } + let suffix = match &self.kind { + RunnableKind::TestMod { .. } => "Tests", + RunnableKind::Test { .. } => "Test", + RunnableKind::DocTest { .. } => "Doctest", + RunnableKind::Bench { .. } => "Bench", + RunnableKind::Bin => return s, + }; + s.push_str(suffix); + s + } + + #[cfg(test)] + fn test_kind(&self) -> RunnableTestKind { + match &self.kind { + RunnableKind::TestMod { .. } => RunnableTestKind::TestMod, + RunnableKind::Test { .. } => RunnableTestKind::Test, + RunnableKind::DocTest { .. } => RunnableTestKind::DocTest, + RunnableKind::Bench { .. } => RunnableTestKind::Bench, + RunnableKind::Bin => RunnableTestKind::Bin, } } } @@ -104,13 +132,27 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec { let sema = Semantics::new(db); let mut res = Vec::new(); - let mut add_opt = |runnable: Option| { + // Record all runnables that come from macro expansions here instead. + // In case an expansion creates multiple runnables we want to name them to avoid emitting a bunch of equally named runnables. + let mut in_macro_expansion = FxHashMap::>::default(); + let mut add_opt = |runnable: Option, def| { if let Some(runnable) = runnable.filter(|r| { always!( r.nav.file_id == file_id, "tried adding a runnable pointing to a different file" ) }) { + if let Some(def) = def { + let file_id = match def { + hir::ModuleDef::Module(it) => it.declaration_source(db).map(|src| src.file_id), + hir::ModuleDef::Function(it) => it.source(db).map(|src| src.file_id), + _ => None, + }; + if let Some(file_id) = file_id.filter(|file| file.call_node(db).is_some()) { + in_macro_expansion.entry(file_id).or_default().push(runnable); + return; + } + } res.push(runnable); } }; @@ -121,23 +163,35 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec { hir::ModuleDef::Function(it) => runnable_fn(&sema, it), _ => None, }; - add_opt(runnable.or_else(|| module_def_doctest(&sema, def))); + add_opt(runnable.or_else(|| module_def_doctest(&sema, def)), Some(def)); } Either::Right(impl_) => { - add_opt(runnable_impl(&sema, &impl_)); + add_opt(runnable_impl(&sema, &impl_), None); impl_ .items(db) .into_iter() - .map(|assoc| match assoc { - hir::AssocItem::Function(it) => { - runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into())) - } - hir::AssocItem::Const(it) => module_def_doctest(&sema, it.into()), - hir::AssocItem::TypeAlias(it) => module_def_doctest(&sema, it.into()), + .map(|assoc| { + ( + match assoc { + hir::AssocItem::Function(it) => runnable_fn(&sema, it) + .or_else(|| module_def_doctest(&sema, it.into())), + hir::AssocItem::Const(it) => module_def_doctest(&sema, it.into()), + hir::AssocItem::TypeAlias(it) => module_def_doctest(&sema, it.into()), + }, + assoc, + ) }) - .for_each(|r| add_opt(r)); + .for_each(|(r, assoc)| add_opt(r, Some(assoc.into()))); } }); + + res.extend(in_macro_expansion.into_iter().flat_map(|(_, runnables)| { + let use_name_in_title = runnables.len() != 1; + runnables.into_iter().map(move |mut r| { + r.use_name_in_title = use_name_in_title; + r + }) + })); res } @@ -270,7 +324,7 @@ pub(crate) fn runnable_fn(sema: &Semantics, def: hir::Function) -> SymbolKind::Function, ); let cfg = def.attrs(sema.db).cfg(); - Some(Runnable { nav, kind, cfg }) + Some(Runnable { use_name_in_title: false, nav, kind, cfg }) } pub(crate) fn runnable_mod(sema: &Semantics, def: hir::Module) -> Option { @@ -283,7 +337,7 @@ pub(crate) fn runnable_mod(sema: &Semantics, def: hir::Module) -> let attrs = def.attrs(sema.db); let cfg = attrs.cfg(); let nav = NavigationTarget::from_module_to_decl(sema.db, def); - Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) + Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::TestMod { path }, cfg }) } pub(crate) fn runnable_impl(sema: &Semantics, def: &hir::Impl) -> Option { @@ -303,7 +357,7 @@ pub(crate) fn runnable_impl(sema: &Semantics, def: &hir::Impl) -> }; let test_id = TestId::Path(format!("{}{}", adt_name, params)); - Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg }) + Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg }) } fn module_def_doctest(sema: &Semantics, def: hir::ModuleDef) -> Option { @@ -363,7 +417,12 @@ fn module_def_doctest(sema: &Semantics, def: hir::ModuleDef) -> Op nav.description = None; nav.docs = None; nav.kind = None; - let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() }; + let res = Runnable { + use_name_in_title: false, + nav, + kind: RunnableKind::DocTest { test_id }, + cfg: attrs.cfg(), + }; Some(res) } @@ -443,12 +502,12 @@ mod tests { use crate::fixture; - use super::*; + use super::{RunnableTestKind::*, *}; fn check( ra_fixture: &str, // FIXME: fold this into `expect` as well - actions: &[&RunnableAction], + actions: &[RunnableTestKind], expect: Expect, ) { let (analysis, position) = fixture::position(ra_fixture); @@ -456,7 +515,7 @@ mod tests { expect.assert_debug_eq(&runnables); assert_eq!( actions, - runnables.into_iter().map(|it| it.action()).collect::>().as_slice() + runnables.into_iter().map(|it| it.test_kind()).collect::>().as_slice() ); } @@ -488,10 +547,11 @@ mod not_a_root { fn main() {} } "#, - &[&BIN, &TEST, &TEST, &BENCH], + &[Bin, Test, Test, Bench], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -505,6 +565,7 @@ mod not_a_root { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -525,6 +586,7 @@ mod not_a_root { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -545,6 +607,7 @@ mod not_a_root { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -662,10 +725,11 @@ trait Test { /// ``` impl Test for StructWithRunnable {} "#, - &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST], + &[Bin, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -679,6 +743,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -694,6 +759,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -709,6 +775,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -724,6 +791,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -739,6 +807,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -754,6 +823,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -769,6 +839,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -786,6 +857,7 @@ impl Test for StructWithRunnable {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -823,10 +895,11 @@ impl Data { fn foo() {} } "#, - &[&BIN, &DOCTEST], + &[Bin, DocTest], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -840,6 +913,7 @@ impl Data { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -870,10 +944,11 @@ mod test_mod { fn test_foo1() {} } "#, - &[&TEST_MOD, &TEST], + &[TestMod, Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -890,6 +965,7 @@ mod test_mod { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -941,10 +1017,11 @@ mod root_tests { mod nested_tests_4 {} } "#, - &[&TEST_MOD, &TEST_MOD, &TEST_MOD, &TEST, &TEST, &TEST], + &[TestMod, TestMod, TestMod, Test, Test, Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -961,6 +1038,7 @@ mod root_tests { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -977,6 +1055,7 @@ mod root_tests { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -993,6 +1072,7 @@ mod root_tests { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1013,6 +1093,7 @@ mod root_tests { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1033,6 +1114,7 @@ mod root_tests { cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1067,10 +1149,11 @@ $0 #[cfg(feature = "foo")] fn test_foo1() {} "#, - &[&TEST], + &[Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1112,10 +1195,11 @@ $0 #[cfg(all(feature = "foo", feature = "bar"))] fn test_foo1() {} "#, - &[&TEST], + &[Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1189,10 +1273,11 @@ impl Foo { fn foo() {} } "#, - &[&DOCTEST], + &[DocTest], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 1, @@ -1226,9 +1311,9 @@ macro_rules! gen { } macro_rules! gen2 { () => { - mod m_tests { + mod tests2 { #[test] - fn foo_test() {} + fn foo_test2() {} } } } @@ -1237,10 +1322,11 @@ mod tests { } gen2!(); "#, - &[&TEST_MOD, &TEST_MOD, &TEST, &TEST], + &[TestMod, TestMod, Test, Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1257,22 +1343,45 @@ gen2!(); cfg: None, }, Runnable { + use_name_in_title: true, nav: NavigationTarget { file_id: FileId( 0, ), full_range: 228..236, focus_range: 228..236, - name: "m_tests", + name: "tests2", kind: Module, - description: "mod m_tests", + description: "mod tests2", }, kind: TestMod { - path: "m_tests", + path: "tests2", }, cfg: None, }, Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 228..236, + focus_range: 228..236, + name: "foo_test2", + kind: Function, + }, + kind: Test { + test_id: Path( + "tests2::foo_test2", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, + }, + Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1292,19 +1401,107 @@ gen2!(); }, cfg: None, }, + ] + "#]], + ); + } + + #[test] + fn big_mac() { + check( + r#" +//- /lib.rs +$0 +macro_rules! foo { + () => { + mod foo_tests { + #[test] + fn foo0() {} + #[test] + fn foo1() {} + #[test] + fn foo2() {} + } + }; +} +foo!(); +"#, + &[TestMod, Test, Test, Test], + expect![[r#" + [ + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 210..217, + focus_range: 210..217, + name: "foo_tests", + kind: Module, + description: "mod foo_tests", + }, + kind: TestMod { + path: "foo_tests", + }, + cfg: None, + }, Runnable { + use_name_in_title: true, nav: NavigationTarget { file_id: FileId( 0, ), - full_range: 228..236, - focus_range: 228..236, - name: "foo_test", + full_range: 210..217, + focus_range: 210..217, + name: "foo0", kind: Function, }, kind: Test { test_id: Path( - "m_tests::foo_test", + "foo_tests::foo0", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, + }, + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 210..217, + focus_range: 210..217, + name: "foo1", + kind: Function, + }, + kind: Test { + test_id: Path( + "foo_tests::foo1", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, + }, + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 210..217, + focus_range: 210..217, + name: "foo2", + kind: Function, + }, + kind: Test { + test_id: Path( + "foo_tests::foo2", ), attr: TestAttr { ignore: false, @@ -1350,10 +1547,11 @@ fn t0() {} #[test] fn t1() {} "#, - &[&TEST_MOD], + &[TestMod], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1387,10 +1585,11 @@ fn t0() {} #[test] fn t1() {} "#, - &[&TEST, &TEST], + &[Test, Test], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 1, @@ -1411,6 +1610,7 @@ fn t1() {} cfg: None, }, Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 1, @@ -1465,6 +1665,7 @@ mod tests { expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1507,28 +1708,29 @@ mod tests { } "#, expect![[r#" - [ - Runnable { - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 71..122, - focus_range: 86..94, - name: "foo_test", - kind: Function, - }, - kind: Test { - test_id: Path( - "tests::foo_test", - ), - attr: TestAttr { - ignore: false, + [ + Runnable { + use_name_in_title: false, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 71..122, + focus_range: 86..94, + name: "foo_test", + kind: Function, + }, + kind: Test { + test_id: Path( + "tests::foo_test", + ), + attr: TestAttr { + ignore: false, + }, }, + cfg: None, }, - cfg: None, - }, - ] + ] "#]], ); } @@ -1560,6 +1762,7 @@ mod tests { expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, @@ -1609,48 +1812,50 @@ mod tests { } "#, expect![[r#" - [ - Runnable { - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 52..115, - focus_range: 67..75, - name: "foo_test", - kind: Function, - }, - kind: Test { - test_id: Path( - "tests::foo_test", - ), - attr: TestAttr { - ignore: false, + [ + Runnable { + use_name_in_title: false, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 52..115, + focus_range: 67..75, + name: "foo_test", + kind: Function, }, + kind: Test { + test_id: Path( + "tests::foo_test", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, }, - cfg: None, - }, - Runnable { - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 121..185, - focus_range: 136..145, - name: "foo2_test", - kind: Function, - }, - kind: Test { - test_id: Path( - "tests::foo2_test", - ), - attr: TestAttr { - ignore: false, + Runnable { + use_name_in_title: false, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 121..185, + focus_range: 136..145, + name: "foo2_test", + kind: Function, + }, + kind: Test { + test_id: Path( + "tests::foo2_test", + ), + attr: TestAttr { + ignore: false, + }, }, + cfg: None, }, - cfg: None, - }, - ] + ] "#]], ); } @@ -1669,10 +1874,11 @@ impl Foo { fn t() {} } "#, - &[&DOCTEST], + &[DocTest], expect![[r#" [ Runnable { + use_name_in_title: false, nav: NavigationTarget { file_id: FileId( 0, diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 406039b73684..d98f320ed74d 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -1547,12 +1547,12 @@ fn runnable_action_links( return None; } - let action: &'static _ = runnable.action(); + let title = runnable.title(); to_proto::runnable(snap, runnable).ok().map(|r| { let mut group = lsp_ext::CommandLinkGroup::default(); if hover_actions_config.run { - let run_command = to_proto::command::run_single(&r, action.run_title); + let run_command = to_proto::command::run_single(&r, &title); group.commands.push(to_command_link(run_command, r.label.clone())); } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 5e440f0d996d..723d6182b720 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -958,15 +958,11 @@ pub(crate) fn code_lens( let line_index = snap.file_line_index(run.nav.file_id)?; let annotation_range = range(&line_index, annotation.range); - let action = run.action(); + let title = run.title(); let r = runnable(snap, run)?; - let command = if debug { - command::debug_single(&r) - } else { - let title = action.run_title.to_string(); - command::run_single(&r, &title) - }; + let command = + if debug { command::debug_single(&r) } else { command::run_single(&r, &title) }; Ok(lsp_types::CodeLens { range: annotation_range, command: Some(command), data: None }) }