Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/runnables.rs')
-rw-r--r--crates/ide/src/runnables.rs290
1 files changed, 277 insertions, 13 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 5b35262aab..8a8a9151c4 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2,7 +2,7 @@ use std::fmt;
use ast::HasName;
use cfg::CfgExpr;
-use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics};
+use hir::{AsAssocItem, HasAttrs, HasSource, Semantics};
use ide_assists::utils::test_related_attribute;
use ide_db::{
base_db::{FilePosition, FileRange},
@@ -195,14 +195,13 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
//
// Provides a sneak peek of all tests where the current item is used.
//
-// The simplest way to use this feature is via the context menu:
-// - Right-click on the selected item. The context menu opens.
-// - Select **Peek related tests**
+// The simplest way to use this feature is via the context menu. Right-click on
+// the selected item. The context menu opens. Select **Peek Related Tests**.
//
// |===
// | Editor | Action Name
//
-// | VS Code | **rust-analyzer: Peek related tests**
+// | VS Code | **rust-analyzer: Peek Related Tests**
// |===
pub(crate) fn related_tests(
db: &RootDatabase,
@@ -371,9 +370,9 @@ pub(crate) fn runnable_impl(
let nav = def.try_to_nav(sema.db)?;
let ty = def.self_ty(sema.db);
let adt_name = ty.as_adt()?.name(sema.db);
- let mut ty_args = ty.type_arguments().peekable();
+ let mut ty_args = ty.generic_parameters(sema.db).peekable();
let params = if ty_args.peek().is_some() {
- format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty.display(sema.db))))
+ format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)))
} else {
String::new()
};
@@ -417,6 +416,7 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
Definition::Const(it) => it.attrs(db),
Definition::Static(it) => it.attrs(db),
Definition::Trait(it) => it.attrs(db),
+ Definition::TraitAlias(it) => it.attrs(db),
Definition::TypeAlias(it) => it.attrs(db),
Definition::Macro(it) => it.attrs(db),
Definition::SelfType(it) => it.attrs(db),
@@ -437,14 +437,10 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
let ty = imp.self_ty(db);
if let Some(adt) = ty.as_adt() {
let name = adt.name(db);
- let mut ty_args = ty.type_arguments().peekable();
+ let mut ty_args = ty.generic_parameters(db).peekable();
format_to!(path, "{}", name);
if ty_args.peek().is_some() {
- format_to!(
- path,
- "<{}>",
- ty_args.format_with(",", |ty, cb| cb(&ty.display(db)))
- );
+ format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty)));
}
format_to!(path, "::{}", def_name);
path.retain(|c| c != ' ');
@@ -1001,6 +997,221 @@ impl Data {
}
#[test]
+ fn test_runnables_doc_test_in_impl_with_lifetime() {
+ check(
+ r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<'a>;
+impl Data<'a> {
+ /// ```
+ /// let x = 5;
+ /// ```
+ fn foo() {}
+}
+"#,
+ &[Bin, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..13,
+ focus_range: 4..8,
+ name: "main",
+ kind: Function,
+ },
+ kind: Bin,
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 52..106,
+ name: "foo",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Data<'a>::foo",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
+ fn test_runnables_doc_test_in_impl_with_lifetime_and_types() {
+ check(
+ r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<'a, T, U>;
+impl<T, U> Data<'a, T, U> {
+ /// ```
+ /// let x = 5;
+ /// ```
+ fn foo() {}
+}
+"#,
+ &[Bin, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..13,
+ focus_range: 4..8,
+ name: "main",
+ kind: Function,
+ },
+ kind: Bin,
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 70..124,
+ name: "foo",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Data<'a,T,U>::foo",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
+ fn test_runnables_doc_test_in_impl_with_const() {
+ check(
+ r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<const N: usize>;
+impl<const N: usize> Data<N> {
+ /// ```
+ /// let x = 5;
+ /// ```
+ fn foo() {}
+}
+"#,
+ &[Bin, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..13,
+ focus_range: 4..8,
+ name: "main",
+ kind: Function,
+ },
+ kind: Bin,
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 79..133,
+ name: "foo",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Data<N>::foo",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
+ fn test_runnables_doc_test_in_impl_with_lifetime_types_and_const() {
+ check(
+ r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<'a, T, const N: usize>;
+impl<'a, T, const N: usize> Data<'a, T, N> {
+ /// ```
+ /// let x = 5;
+ /// ```
+ fn foo() {}
+}
+"#,
+ &[Bin, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..13,
+ focus_range: 4..8,
+ name: "main",
+ kind: Function,
+ },
+ kind: Bin,
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 100..154,
+ name: "foo",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Data<'a,T,N>::foo",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ );
+ }
+ #[test]
fn test_runnables_module() {
check(
r#"
@@ -2063,6 +2274,59 @@ mod tests {
}
#[test]
+ fn test_runnables_doc_test_in_impl_with_lifetime_type_const_value() {
+ check(
+ r#"
+//- /lib.rs
+$0
+fn main() {}
+
+struct Data<'a, A, const B: usize, C, const D: u32>;
+impl<A, C, const D: u32> Data<'a, A, 12, C, D> {
+ /// ```
+ /// ```
+ fn foo() {}
+}
+"#,
+ &[Bin, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..13,
+ focus_range: 4..8,
+ name: "main",
+ kind: Function,
+ },
+ kind: Bin,
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 121..156,
+ name: "foo",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Data<'a,A,12,C,D>::foo",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
fn doc_test_type_params() {
check(
r#"