Skip to content

Commit 5edbdd1

Browse files
committed
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 rust-lang/rust#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.
2 parents 2b472f6 + d40ab66 commit 5edbdd1

File tree

1 file changed

+71
-6
lines changed

1 file changed

+71
-6
lines changed

crates/ide/src/runnables.rs

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,13 @@ pub(crate) fn runnable_impl(
373373
let adt_name = ty.as_adt()?.name(sema.db);
374374
let mut ty_args = ty.type_arguments().peekable();
375375
let params = if ty_args.peek().is_some() {
376-
format!("<{}>", ty_args.format_with(", ", |ty, cb| cb(&ty.display(sema.db))))
376+
format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty.display(sema.db))))
377377
} else {
378378
String::new()
379379
};
380-
let test_id = TestId::Path(format!("{}{}", adt_name, params));
380+
let mut test_id = format!("{}{}", adt_name, params);
381+
test_id.retain(|c| c != ' ');
382+
let test_id = TestId::Path(test_id);
381383

382384
Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg })
383385
}
@@ -441,10 +443,11 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
441443
format_to!(
442444
path,
443445
"<{}>",
444-
ty_args.format_with(", ", |ty, cb| cb(&ty.display(db)))
446+
ty_args.format_with(",", |ty, cb| cb(&ty.display(db)))
445447
);
446448
}
447449
format_to!(path, "::{}", def_name);
450+
path.retain(|c| c != ' ');
448451
return Some(path);
449452
}
450453
}
@@ -2067,13 +2070,23 @@ mod tests {
20672070
$0
20682071
struct Foo<T, U>;
20692072
2073+
/// ```
2074+
/// ```
20702075
impl<T, U> Foo<T, U> {
20712076
/// ```rust
20722077
/// ````
20732078
fn t() {}
20742079
}
2080+
2081+
/// ```
2082+
/// ```
2083+
impl Foo<Foo<(), ()>, ()> {
2084+
/// ```
2085+
/// ```
2086+
fn t() {}
2087+
}
20752088
"#,
2076-
&[DocTest],
2089+
&[DocTest, DocTest, DocTest, DocTest],
20772090
expect![[r#"
20782091
[
20792092
Runnable {
@@ -2082,12 +2095,64 @@ impl<T, U> Foo<T, U> {
20822095
file_id: FileId(
20832096
0,
20842097
),
2085-
full_range: 47..85,
2098+
full_range: 20..103,
2099+
focus_range: 47..56,
2100+
name: "impl",
2101+
kind: Impl,
2102+
},
2103+
kind: DocTest {
2104+
test_id: Path(
2105+
"Foo<T,U>",
2106+
),
2107+
},
2108+
cfg: None,
2109+
},
2110+
Runnable {
2111+
use_name_in_title: false,
2112+
nav: NavigationTarget {
2113+
file_id: FileId(
2114+
0,
2115+
),
2116+
full_range: 63..101,
2117+
name: "t",
2118+
},
2119+
kind: DocTest {
2120+
test_id: Path(
2121+
"Foo<T,U>::t",
2122+
),
2123+
},
2124+
cfg: None,
2125+
},
2126+
Runnable {
2127+
use_name_in_title: false,
2128+
nav: NavigationTarget {
2129+
file_id: FileId(
2130+
0,
2131+
),
2132+
full_range: 105..188,
2133+
focus_range: 126..146,
2134+
name: "impl",
2135+
kind: Impl,
2136+
},
2137+
kind: DocTest {
2138+
test_id: Path(
2139+
"Foo<Foo<(),()>,()>",
2140+
),
2141+
},
2142+
cfg: None,
2143+
},
2144+
Runnable {
2145+
use_name_in_title: false,
2146+
nav: NavigationTarget {
2147+
file_id: FileId(
2148+
0,
2149+
),
2150+
full_range: 153..186,
20862151
name: "t",
20872152
},
20882153
kind: DocTest {
20892154
test_id: Path(
2090-
"Foo<T, U>::t",
2155+
"Foo<Foo<(),()>,()>::t",
20912156
),
20922157
},
20932158
cfg: None,

0 commit comments

Comments
 (0)