diff options
| author | bors <bors@rust-lang.org> | 2020-08-23 23:10:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-08-23 23:10:33 +0000 |
| commit | 8fdce9bbb9eb25defd9429cc5122fe6eb59f5ffd (patch) | |
| tree | 4967006a0c165333603255797dca21e6a63e6428 /src/test/rustdoc-ui | |
| parent | 5180f3da5fd72627a8d38558ad1297df38793acd (diff) | |
| parent | d77eff21b97886a0829b784100846daf59df2f39 (diff) | |
| download | rust-8fdce9bbb9eb25defd9429cc5122fe6eb59f5ffd.tar.gz rust-8fdce9bbb9eb25defd9429cc5122fe6eb59f5ffd.zip | |
Auto merge of #74489 - jyn514:assoc-items, r=manishearth,petrochenkov
Fix intra-doc links for associated items
@Manishearth and I found that links of the following sort are broken:
```rust
$ cat str_from.rs
/// [`String::from`]
pub fn foo() {}
$ rustdoc str_from.rs
warning: `[String::from]` cannot be resolved, ignoring it.
--> str_from.rs:4:6
|
4 | /// [`String::from`]
| ^^^^^^^^^^^^^^ cannot be resolved, ignoring
```
It turns out this is because the current implementation only looks at inherent impls (`impl Bar {}`) and traits _for the item being documented_. Note that this is not the same as the item being _linked_ to. So this code would work:
```rust
pub trait T1 {
fn method();
}
pub struct S;
impl T1 for S {
/// [S::method] on method
fn method() {}
}
```
but putting the documentation on `trait T1` would not.
~~I realized that writing it up that my fix is only partially correct: It removes the inherent impls code when it should instead remove the `trait_item` code.~~ Fixed.
Additionally, I discovered while writing this there is some ambiguity: you could have multiple methods with the same name, but for different traits:
```rust
pub trait T1 {
fn method();
}
pub trait T2 {
fn method();
}
/// See [S::method]
pub struct S;
```
Rustdoc should give an ambiguity error here, but since there is currently no way to disambiguate the traits (https://github.com/rust-lang/rust/issues/74563) it does not (https://github.com/rust-lang/rust/pull/74489#issuecomment-673878404).
There is a _third_ ambiguity that pops up: What if the trait is generic and is implemented multiple times with different generic parameters? In this case, my fix does not do very well: it thinks there is only one trait instantiated and links to that trait:
```
/// [`String::from`] -- this resolves to https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.from
pub fn foo() {}
```
However, every `From` implementation has a method called `from`! So the browser picks a random one. This is not the desired behavior, but it's not clear how to avoid it.
To be consistent with the rest of intra-doc links, this only resolves associated items from traits that are in scope. This required changes to rustc_resolve to work cross-crate; the relevant commits are prefixed with `resolve: `. As a bonus, considering only traits in scope is slightly faster. To avoid re-calculating the traits over and over, rustdoc uses a cache to store the traits in scope for a given module.
Diffstat (limited to 'src/test/rustdoc-ui')
| -rw-r--r-- | src/test/rustdoc-ui/assoc-item-not-in-scope.rs | 22 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/assoc-item-not-in-scope.stderr | 15 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/test/rustdoc-ui/assoc-item-not-in-scope.rs b/src/test/rustdoc-ui/assoc-item-not-in-scope.rs new file mode 100644 index 00000000000..c5bb4305db7 --- /dev/null +++ b/src/test/rustdoc-ui/assoc-item-not-in-scope.rs @@ -0,0 +1,22 @@ +#![deny(broken_intra_doc_links)] + +#[derive(Debug)] +/// Link to [`S::fmt`] +//~^ ERROR unresolved link +pub struct S; + +pub mod inner { + use std::fmt::Debug; + use super::S; + + /// Link to [`S::fmt`] + pub fn f() {} +} + +pub mod ambiguous { + use std::fmt::{Display, Debug}; + use super::S; + + /// Link to [`S::fmt`] + pub fn f() {} +} diff --git a/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr new file mode 100644 index 00000000000..8827c9351a6 --- /dev/null +++ b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr @@ -0,0 +1,15 @@ +error: unresolved link to `S::fmt` + --> $DIR/assoc-item-not-in-scope.rs:4:14 + | +LL | /// Link to [`S::fmt`] + | ^^^^^^^^ unresolved link + | +note: the lint level is defined here + --> $DIR/assoc-item-not-in-scope.rs:1:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to previous error + |
