about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-01 10:12:59 +0000
committerbors <bors@rust-lang.org>2022-08-01 10:12:59 +0000
commit5edbdd127a59ed79bf9381a4005efb4e7bcb262b (patch)
tree7f3791792d821678780cd0bfa3c6a8abd1bb64ed
parent2b472f6684bb1958274995d12b2c50310d88cc52 (diff)
parentd40ab66186fa477177a10d01eb16960a5f20c7ac (diff)
downloadrust-5edbdd127a59ed79bf9381a4005efb4e7bcb262b.tar.gz
rust-5edbdd127a59ed79bf9381a4005efb4e7bcb262b.zip
Auto merge of #12918 - lowr:fix/doctest-names, r=Veykril
fix: remove whitespaces from doctest names

When rustdoc runs doctests, it removes whitespaces from the tests' path ([code](https://github.com/rust-lang/rust/blob/25bb1c13bd472b75ceebee3b8dcf4dcbc431a8be/src/librustdoc/doctest.rs#L951)). See https://github.com/rust-lang/rust/pull/89422 for details.

Interestingly enough, "Run doctest" has been working without much problem even though rust-analyzer hasn't followed the change. This is because cargo passes the test name to rustdoc via `--test-args` option, and then rustdoc [splits it by whitespace](https://github.com/rust-lang/rust/blob/25bb1c13bd472b75ceebee3b8dcf4dcbc431a8be/src/librustdoc/config.rs#L513-L514); the last element of the split test name **always** matches the test name that rustdoc generates.

However, it may run other tests unexpectedly (to be precise, this has long since been a thing because of the split). Consider the following example:

```rust
struct A<T, U>(T, U);
struct B<T, U>(T, U);
/// ```
/// doctest here
/// ```
impl<T, U> A<T, U> {}
/// ```
/// doctest here
/// ```
impl<T, U> B<T, U> {}
```

When you "Run doctest" either of the two, rustdoc considers "U>" one of the test specs and both doctests are run. This patch fixes it by following rustdoc and removing the whitespace from the doctests' name.
-rw-r--r--crates/ide/src/runnables.rs77
1 files changed, 71 insertions, 6 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index bec770ed99f..3155f97f258 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -373,11 +373,13 @@ pub(crate) fn runnable_impl(
     let adt_name = ty.as_adt()?.name(sema.db);
     let mut ty_args = ty.type_arguments().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.display(sema.db))))
     } else {
         String::new()
     };
-    let test_id = TestId::Path(format!("{}{}", adt_name, params));
+    let mut test_id = format!("{}{}", adt_name, params);
+    test_id.retain(|c| c != ' ');
+    let test_id = TestId::Path(test_id);
 
     Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg })
 }
@@ -441,10 +443,11 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
                         format_to!(
                             path,
                             "<{}>",
-                            ty_args.format_with(", ", |ty, cb| cb(&ty.display(db)))
+                            ty_args.format_with(",", |ty, cb| cb(&ty.display(db)))
                         );
                     }
                     format_to!(path, "::{}", def_name);
+                    path.retain(|c| c != ' ');
                     return Some(path);
                 }
             }
@@ -2067,13 +2070,23 @@ mod tests {
 $0
 struct Foo<T, U>;
 
+/// ```
+/// ```
 impl<T, U> Foo<T, U> {
     /// ```rust
     /// ````
     fn t() {}
 }
+
+/// ```
+/// ```
+impl Foo<Foo<(), ()>, ()> {
+    /// ```
+    /// ```
+    fn t() {}
+}
 "#,
-            &[DocTest],
+            &[DocTest, DocTest, DocTest, DocTest],
             expect![[r#"
                 [
                     Runnable {
@@ -2082,12 +2095,64 @@ impl<T, U> Foo<T, U> {
                             file_id: FileId(
                                 0,
                             ),
-                            full_range: 47..85,
+                            full_range: 20..103,
+                            focus_range: 47..56,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "Foo<T,U>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 63..101,
+                            name: "t",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "Foo<T,U>::t",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 105..188,
+                            focus_range: 126..146,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "Foo<Foo<(),()>,()>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 153..186,
                             name: "t",
                         },
                         kind: DocTest {
                             test_id: Path(
-                                "Foo<T, U>::t",
+                                "Foo<Foo<(),()>,()>::t",
                             ),
                         },
                         cfg: None,