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.rs282
1 files changed, 273 insertions, 9 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index af53adee89..77aef710ad 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},
@@ -370,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()
};
@@ -436,14 +436,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 != ' ');
@@ -1000,6 +996,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#"
@@ -2062,6 +2273,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#"