Skip to content

Commit 87f3f81

Browse files
committed
Improve rustdoc error for failed intra-doc link resolution
The previous error was confusing since it made it sound like you can't link to items that are defined outside the current module. Also suggested importing the item.
1 parent 2ad6187 commit 87f3f81

8 files changed

+102
-58
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,17 +1575,17 @@ fn resolution_failure(
15751575
_ => None,
15761576
};
15771577
// See if this was a module: `[path]` or `[std::io::nope]`
1578-
if let Some(module) = last_found_module {
1579-
let module_name = collector.cx.tcx.item_name(module);
1578+
if let Some(_module) = last_found_module {
15801579
let note = format!(
1581-
"the module `{}` contains no item named `{}`",
1582-
module_name, unresolved
1580+
"there is no item named `{}` in scope",
1581+
unresolved
15831582
);
15841583
if let Some(span) = sp {
15851584
diag.span_label(span, &note);
15861585
} else {
15871586
diag.note(&note);
15881587
}
1588+
diag.help(&format!("did you mean to import `{}`?", unresolved));
15891589
// If the link has `::` in it, assume it was meant to be an intra-doc link.
15901590
// Otherwise, the `[]` might be unrelated.
15911591
// FIXME: don't show this for autolinks (`<>`), `()` style links, or reference links

src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ error: unresolved link to `v2`
22
--> $DIR/deny-intra-link-resolution-failure.rs:3:6
33
|
44
LL | /// [v2]
5-
| ^^ the module `deny_intra_link_resolution_failure` contains no item named `v2`
5+
| ^^ there is no item named `v2` in scope
66
|
77
note: the lint level is defined here
88
--> $DIR/deny-intra-link-resolution-failure.rs:1:9
99
|
1010
LL | #![deny(broken_intra_doc_links)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
= help: did you mean to import `v2`?
1213
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
1314

1415
error: aborting due to previous error

src/test/rustdoc-ui/intra-link-errors.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,28 @@
66
77
/// [path::to::nonexistent::module]
88
//~^ ERROR unresolved link
9-
//~| NOTE `intra_link_errors` contains no item named `path`
9+
//~| NOTE there is no item named `path` in scope
10+
//~| HELP did you mean to import `path`?
1011

1112
/// [path::to::nonexistent::macro!]
1213
//~^ ERROR unresolved link
13-
//~| NOTE `intra_link_errors` contains no item named `path`
14+
//~| NOTE there is no item named `path` in scope
15+
//~| HELP did you mean to import `path`?
1416

1517
/// [type@path::to::nonexistent::type]
1618
//~^ ERROR unresolved link
17-
//~| NOTE `intra_link_errors` contains no item named `path`
19+
//~| NOTE there is no item named `path` in scope
20+
//~| HELP did you mean to import `path`?
1821

1922
/// [std::io::not::here]
2023
//~^ ERROR unresolved link
21-
//~| NOTE `io` contains no item named `not`
24+
//~| NOTE there is no item named `not` in scope
25+
//~| HELP did you mean to import `not`?
2226

2327
/// [type@std::io::not::here]
2428
//~^ ERROR unresolved link
25-
//~| NOTE `io` contains no item named `not`
29+
//~| NOTE there is no item named `not` in scope
30+
//~| HELP did you mean to import `not`?
2631

2732
/// [std::io::Error::x]
2833
//~^ ERROR unresolved link

src/test/rustdoc-ui/intra-link-errors.stderr

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,94 +2,103 @@ error: unresolved link to `path::to::nonexistent::module`
22
--> $DIR/intra-link-errors.rs:7:6
33
|
44
LL | /// [path::to::nonexistent::module]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope
66
|
77
note: the lint level is defined here
88
--> $DIR/intra-link-errors.rs:1:9
99
|
1010
LL | #![deny(broken_intra_doc_links)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
= help: did you mean to import `path`?
1213

1314
error: unresolved link to `path::to::nonexistent::macro`
14-
--> $DIR/intra-link-errors.rs:11:6
15+
--> $DIR/intra-link-errors.rs:12:6
1516
|
1617
LL | /// [path::to::nonexistent::macro!]
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope
19+
|
20+
= help: did you mean to import `path`?
1821

1922
error: unresolved link to `path::to::nonexistent::type`
20-
--> $DIR/intra-link-errors.rs:15:6
23+
--> $DIR/intra-link-errors.rs:17:6
2124
|
2225
LL | /// [type@path::to::nonexistent::type]
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope
27+
|
28+
= help: did you mean to import `path`?
2429

2530
error: unresolved link to `std::io::not::here`
26-
--> $DIR/intra-link-errors.rs:19:6
31+
--> $DIR/intra-link-errors.rs:22:6
2732
|
2833
LL | /// [std::io::not::here]
29-
| ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not`
34+
| ^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope
35+
|
36+
= help: did you mean to import `not`?
3037

3138
error: unresolved link to `std::io::not::here`
32-
--> $DIR/intra-link-errors.rs:23:6
39+
--> $DIR/intra-link-errors.rs:27:6
3340
|
3441
LL | /// [type@std::io::not::here]
35-
| ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not`
42+
| ^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope
43+
|
44+
= help: did you mean to import `not`?
3645

3746
error: unresolved link to `std::io::Error::x`
38-
--> $DIR/intra-link-errors.rs:27:6
47+
--> $DIR/intra-link-errors.rs:32:6
3948
|
4049
LL | /// [std::io::Error::x]
4150
| ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x`
4251

4352
error: unresolved link to `std::io::ErrorKind::x`
44-
--> $DIR/intra-link-errors.rs:31:6
53+
--> $DIR/intra-link-errors.rs:36:6
4554
|
4655
LL | /// [std::io::ErrorKind::x]
4756
| ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x`
4857

4958
error: unresolved link to `f::A`
50-
--> $DIR/intra-link-errors.rs:35:6
59+
--> $DIR/intra-link-errors.rs:40:6
5160
|
5261
LL | /// [f::A]
5362
| ^^^^ `f` is a function, not a module or type, and cannot have associated items
5463

5564
error: unresolved link to `f::A`
56-
--> $DIR/intra-link-errors.rs:39:6
65+
--> $DIR/intra-link-errors.rs:44:6
5766
|
5867
LL | /// [f::A!]
5968
| ^^^^^ `f` is a function, not a module or type, and cannot have associated items
6069

6170
error: unresolved link to `S::A`
62-
--> $DIR/intra-link-errors.rs:43:6
71+
--> $DIR/intra-link-errors.rs:48:6
6372
|
6473
LL | /// [S::A]
6574
| ^^^^ the struct `S` has no field or associated item named `A`
6675

6776
error: unresolved link to `S::fmt`
68-
--> $DIR/intra-link-errors.rs:47:6
77+
--> $DIR/intra-link-errors.rs:52:6
6978
|
7079
LL | /// [S::fmt]
7180
| ^^^^^^ the struct `S` has no field or associated item named `fmt`
7281

7382
error: unresolved link to `E::D`
74-
--> $DIR/intra-link-errors.rs:51:6
83+
--> $DIR/intra-link-errors.rs:56:6
7584
|
7685
LL | /// [E::D]
7786
| ^^^^ the enum `E` has no variant or associated item named `D`
7887

7988
error: unresolved link to `u8::not_found`
80-
--> $DIR/intra-link-errors.rs:55:6
89+
--> $DIR/intra-link-errors.rs:60:6
8190
|
8291
LL | /// [u8::not_found]
8392
| ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
8493

8594
error: unresolved link to `std::primitive::u8::not_found`
86-
--> $DIR/intra-link-errors.rs:59:6
95+
--> $DIR/intra-link-errors.rs:64:6
8796
|
8897
LL | /// [std::primitive::u8::not_found]
8998
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
9099

91100
error: unresolved link to `Vec::into_iter`
92-
--> $DIR/intra-link-errors.rs:63:6
101+
--> $DIR/intra-link-errors.rs:68:6
93102
|
94103
LL | /// [type@Vec::into_iter]
95104
| ^^^^^^^^^^^^^^^^^^^
@@ -98,7 +107,7 @@ LL | /// [type@Vec::into_iter]
98107
| help: to link to the associated function, add parentheses: `Vec::into_iter()`
99108

100109
error: unresolved link to `S`
101-
--> $DIR/intra-link-errors.rs:68:6
110+
--> $DIR/intra-link-errors.rs:73:6
102111
|
103112
LL | /// [S!]
104113
| ^^
@@ -107,7 +116,7 @@ LL | /// [S!]
107116
| help: to link to the struct, prefix with `struct@`: `struct@S`
108117

109118
error: unresolved link to `T::g`
110-
--> $DIR/intra-link-errors.rs:86:6
119+
--> $DIR/intra-link-errors.rs:91:6
111120
|
112121
LL | /// [type@T::g]
113122
| ^^^^^^^^^
@@ -116,13 +125,13 @@ LL | /// [type@T::g]
116125
| help: to link to the associated function, add parentheses: `T::g()`
117126

118127
error: unresolved link to `T::h`
119-
--> $DIR/intra-link-errors.rs:91:6
128+
--> $DIR/intra-link-errors.rs:96:6
120129
|
121130
LL | /// [T::h!]
122131
| ^^^^^ the trait `T` has no macro named `h`
123132

124133
error: unresolved link to `S::h`
125-
--> $DIR/intra-link-errors.rs:78:6
134+
--> $DIR/intra-link-errors.rs:83:6
126135
|
127136
LL | /// [type@S::h]
128137
| ^^^^^^^^^
@@ -131,7 +140,7 @@ LL | /// [type@S::h]
131140
| help: to link to the associated function, add parentheses: `S::h()`
132141

133142
error: unresolved link to `m`
134-
--> $DIR/intra-link-errors.rs:98:6
143+
--> $DIR/intra-link-errors.rs:103:6
135144
|
136145
LL | /// [m()]
137146
| ^^^

src/test/rustdoc-ui/intra-link-span-ice-55723.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ error: unresolved link to `i`
22
--> $DIR/intra-link-span-ice-55723.rs:9:10
33
|
44
LL | /// (arr[i])
5-
| ^ the module `intra_link_span_ice_55723` contains no item named `i`
5+
| ^ there is no item named `i` in scope
66
|
77
note: the lint level is defined here
88
--> $DIR/intra-link-span-ice-55723.rs:1:9
99
|
1010
LL | #![deny(broken_intra_doc_links)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12+
= help: did you mean to import `i`?
1213
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
1314

1415
error: aborting due to previous error

src/test/rustdoc-ui/intra-links-warning-crlf.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,37 @@ warning: unresolved link to `error`
22
--> $DIR/intra-links-warning-crlf.rs:7:6
33
|
44
LL | /// [error]
5-
| ^^^^^ the module `intra_links_warning_crlf` contains no item named `error`
5+
| ^^^^^ there is no item named `error` in scope
66
|
77
= note: `#[warn(broken_intra_doc_links)]` on by default
8+
= help: did you mean to import `error`?
89
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
910

1011
warning: unresolved link to `error1`
1112
--> $DIR/intra-links-warning-crlf.rs:12:11
1213
|
1314
LL | /// docs [error1]
14-
| ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error1`
15+
| ^^^^^^ there is no item named `error1` in scope
1516
|
17+
= help: did you mean to import `error1`?
1618
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
1719

1820
warning: unresolved link to `error2`
1921
--> $DIR/intra-links-warning-crlf.rs:15:11
2022
|
2123
LL | /// docs [error2]
22-
| ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error2`
24+
| ^^^^^^ there is no item named `error2` in scope
2325
|
26+
= help: did you mean to import `error2`?
2427
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
2528

2629
warning: unresolved link to `error`
2730
--> $DIR/intra-links-warning-crlf.rs:23:20
2831
|
2932
LL | * It also has an [error].
30-
| ^^^^^ the module `intra_links_warning_crlf` contains no item named `error`
33+
| ^^^^^ there is no item named `error` in scope
3134
|
35+
= help: did you mean to import `error`?
3236
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
3337

3438
warning: 4 warnings emitted

0 commit comments

Comments
 (0)