| Age | Commit message (Collapse) | Author | Lines |
|
r=oli-obk,ollie27
Doc alias name restriction
Fixes #76705.
|
|
|
|
separate lints
This is not ideal because it means `deny(broken_intra_doc_links)` will
no longer `deny(private_intra_doc_links)`. However, it can't be fixed
with a new lint group, because `broken` is already in the `rustdoc` lint
group; there would need to be a way to nest groups somehow.
This also removes the early `return` so that the link will be generated
even though it gives a warning.
|
|
Refactor and fix intra-doc link diagnostics, and fix links to primitives
Closes https://github.com/rust-lang/rust/issues/76925, closes https://github.com/rust-lang/rust/issues/76693, closes https://github.com/rust-lang/rust/issues/76692.
Originally I only meant to fix #76925. But the hack with `has_primitive` was so bad it was easier to fix the primitive issues than to try and work around it.
Note that this still has one bug: `std::primitive::i32::MAX` does not resolve. However, this fixes the ICE so I'm fine with fixing the link in a later PR.
This is part of a series of refactors to make #76467 possible.
This is best reviewed commit-by-commit; it has detailed commit messages.
r? `@euclio`
|
|
|
|
Now that `PrimTy::name()` exists, there's no need to carry around the
name of the primitive that failed to resolve. This removes the variants
special-casing primitives in favor of `NotResolved`.
- Remove `NoPrimitiveImpl` and `NoPrimitiveAssocItem`
- Remove hacky `has_primitive` check in `resolution_failure()`
- Fixup a couple tests that I forgot to `--bless` before
|
|
- Add `PrimTy::name` and `PrimTy::name_str`
- Use those new functions to distinguish between the name in scope and
the canonical name
- Fix diagnostics for primitive types
- Add tests for primitives
|
|
Previously, these were spread throughout the codebase. This had two
drawbacks:
1. It caused the fast path to be slower: even if a link resolved,
rustdoc would still perform various lookups for the error diagnostic.
2. It was inconsistent and didn't always give all diagnostics (https://github.com/rust-lang/rust/issues/76925)
Now, diagnostics only perform expensive lookups in the error case.
Additionally, the error handling is much more consistent, both in
wording and behavior.
- Remove `CannotHaveAssociatedItems`, `NotInScope`, `NoAssocItem`, and `NotAVariant`
in favor of the more general `NotResolved`
`resolution_failure` will now look up which of the four above
categories is relevant, instead of requiring the rest of the code to
be consistent and accurate in which it picked.
- Remove unnecessary lookups throughout the intra-doc link pass. These
are now done by `resolution_failure`.
+ Remove unnecessary `extra_fragment` argument to `variant_field()`;
it was only used to do lookups on failure.
+ Remove various lookups related to associated items
+ Remove distinction between 'not in scope' and 'no associated item'
- Don't perform unnecessary copies
- Remove unused variables and code
- Update tests
- Note why looking at other namespaces is still necessary
- 'has no inner item' -> 'contains no item'
bless tests
|
|
Do not lint ignored private doc tests
Fixes #76457.
r? @ehuss
|
|
This shows the span of the _whole_ link, including the brackets.
But rustdoc only wants to warn about the link text.
|
|
Thanks to marcusklaas' hard work in https://github.com/raphlinus/pulldown-cmark/pull/469, this fixes a lot of rustdoc bugs!
- Get rid of unnecessary `RefCell`
- Fix duplicate warnings for broken implicit reference link
- Remove unnecessary copy of links
|
|
|
|
Improve suggestions for broken intra-doc links
~~Depends on #74489 and should not be merged before that PR.~~ Merged 🎉
~~Depends on #75916 and should not be merged before.~~ Merged
Fixes https://github.com/rust-lang/rust/issues/75305.
This does a lot of different things 😆.
- Add `PerNS::into_iter()` so I didn't have to keep rewriting hacks around it. Also add `PerNS::iter()` for consistency. Let me know if this should be `impl IntoIterator` instead.
- Make `ResolutionFailure` an enum instead of a unit variant. This was most of the changes: everywhere that said `ErrorKind::ResolutionFailure` now has to say _why_ the link failed to resolve.
- Store the resolution in case of an anchor failure. Previously this was implemented as variants on `AnchorFailure` which was prone to typos and had inconsistent output compared to the rest of the diagnostics.
- Turn some `Err`ors into unwrap() or panic()s, because they're rustdoc bugs and not user error. These have comments as to why they're bugs (in particular this would have caught #76073 as a bug a while ago).
- If an item is not in scope at all, say the first segment in the path that failed to resolve
- If an item exists but not in the current namespaces, say that and suggests linking to that namespace.
- If there is a partial resolution for an item (part of the segments resolved, but not all of them), say the partial resolution and why the following segment didn't resolve.
- Add the `DefId` of associated items to `kind_side_channel` so it can be used for diagnostics (tl;dr of the hack: the rest of rustdoc expects the id of the item, but for diagnostics we need the associated item).
- No longer suggests escaping the brackets for every link that failed to resolve; this was pretty obnoxious. Now it only suggests `\[ \]` if no segment resolved and there is no `::` in the link.
- Add `Suggestion`, which says _what_ to prefix the link with, not just 'prefix with the item kind'.
Places where this is currently buggy:
<details><summary>All outdated</summary>
~~1. When the link has the wrong namespace:~~ Now fixed.
<details>
```rust
/// [type@S::h]
impl S {
pub fn h() {}
}
/// [type@T::g]
pub trait T {
fn g() {}
}
```
```
error: unresolved link to `T::g`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:53:6
|
53 | /// [type@T::g]
| ^^^^^^^^^
|
= note: this link partially resolves to the trait `T`,
= note: `T` has no field, variant, or associated item named `g`
error: unresolved link to `S::h`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:48:6
|
48 | /// [type@S::h]
| ^^^^^^^^^
|
= note: this link partially resolves to the struct `S`,
= note: `S` has no field, variant, or associated item named `h`
```
Instead it should suggest changing the disambiguator, the way it currently does for macros:
```
error: unresolved link to `S`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:38:6
|
38 | /// [S!]
| ^^ help: to link to the unit struct, use its disambiguator: `value@S`
|
= note: this link resolves to the unit struct `S`, which is not in the macro namespace
```
</details>
2. ~~Associated items for values. It says that the value isn't in scope; instead it should say that values can't have associated items.~~ Fixed.
<details>
```
error: unresolved link to `f::A`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:14:6
|
14 | /// [f::A]
| ^^^^
|
= note: no item named `f` is in scope
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
```
This is _mostly_ fixed, it now says
```rust
warning: unresolved link to `f::A`
--> /home/joshua/test-rustdoc/f.rs:1:6
|
1 | /// [f::A]
| ^^^^
|
= note: this link partially resolves to the function `f`
= note: `f` is a function, not a module
```
'function, not a module' seems awfully terse when what I actually mean is '`::` isn't allowed here', though.
</details>
It looks a lot nicer now, it says
```
error: unresolved link to `f::A`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:13:6
|
13 | /// [f::A]
| ^^^^
|
= note: `f` is a function, not a module or type, and cannot have associated items
```
3. ~~I'm also not very happy with the second note for this error:~~
<details>
```
error: unresolved link to `S::A`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:19:6
|
19 | /// [S::A]
| ^^^^
|
= note: this link partially resolves to the struct `S`,
= note: `S` has no field, variant, or associated item named `A`
```
but I'm not sure how better to word it.
I ended up going with 'no `A` in `S`' to match `rustc_resolve` but that seems terse as well.
</details>
This now says
```
error: unresolved link to `S::A`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:17:6
|
17 | /// [S::A]
| ^^^^
|
= note: the struct `S` has no field or associated item named `A`
```
which I think looks pretty good :)
4. This is minor, but it would be nice to say that `path` wasn't found instead of the full thing:
```
error: unresolved link to `path::to::nonexistent::module`
--> /home/joshua/rustc/src/test/rustdoc-ui/intra-link-errors.rs:8:6
|
8 | /// [path::to::nonexistent::module]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
It will now look at most 3 paths up (so it reports `path::to` as not in scope), but it doesn't work with arbitrarily many paths.
</details>
~~I recommend only reviewing the last few commits - the first 7 are all from #74489.~~ Rebased so that only the relevant commits are shown. Let me know if I should squash the history some more.
r? `@estebank`
|
|
'not in scope' -> 'not in `module`'
|
|
This puts the error message closer to the link, making it easier to see
what went wrong.
|
|
|
|
Moves this detection into `resolution_failure` to avoid doing
unnecessary work and make the control flow a little easier to work with.
|
|
|
|
Previously, this called `check_full_res` for values and types, but not
macros. This would result in not showing when there was a partial
resolution for a parent of the item.
This now calls `check_full_res`. Additionally, it checks if there was a
disambiguator, and if so, says that specific kind wasn't found instead
of saying generically 'associated item'.
|
|
This is both more specific and easier to read.
|
|
|
|
Before, it would arbitrarily pick the third-to-last if the last three or
more did not resolve.
|
|
Before:
```
warning: unresolved link to `m`
--> m.rs:1:6
|
1 | /// [value@m]
| ^^^^^^^
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= note: no item named `m` is in scope
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
```
After:
```
warning: unresolved link to `m`
--> m.rs:1:6
|
1 | /// [value@m]
| ^^^^^^^ help: to link to the macro, use its disambiguator: `m!`
|
= note: `#[warn(broken_intra_doc_links)]` on by default
= note: this link resolves to the macro `m`, which is not in the value namespace
```
|
|
|
|
Before:
```
= note: this link partially resolves to the struct `S`
= note: no `fmt` in `S`
```
After:
```
= note: the struct `S` has no field or associated item named `fmt`
```
|
|
|
|
|
|
|
|
Look at this beauty:
```rust
error: unresolved link to `S::h`
--> intra-link-errors.rs:51:6
|
51 | /// [type@S::h]
| ^^^^^^^^^ help: to link to the associated function, use its disambiguator: `S::h()`
|
= note: this link resolves to the associated function `h`, which is not in the type namespace
```
|
|
|
|
|
|
|
|
|
|
Unify error reporting for intra-doc links
- Give a suggestion even if there is no span available
- Give a more accurate description of the change than 'use the
disambiguator'
- Write much less code
Closes #75836.
r? @euclio
cc @pickfire - this gets rid of 'disambiguator' like you suggested in https://github.com/rust-lang/rust/pull/75079#discussion_r464464195.
|
|
- Give a suggestion even if there is no span available
- Give a more accurate description of the change than 'use the
disambiguator'
- Write much less code
|
|
Originally I tried to do a much broader refactoring that got rid of `init_lints` altogether. My reasoning is that now the lints aren't being run anymore (after https://github.com/rust-lang/rust/pull/73566), there's no need to ignore them explicitly. But it seems there are still some lints that aren't affected by setting `lint_mod` to a no-op:
```
deny(pub_use_of_private_extern_crate)
deny(const_err)
warn(unused_imports)
```
(there are possibly more, these are just the ones that failed in the rustdoc test suite).
Some of these seem like we really should be warning about, but that's a much larger change and I don't propose to make it here. So for the time being, this just adds the `unknown_lints` and `renamed_or_removed_lints` passes to the list of lints rustdoc warns about.
|
|
- Add a new `prim@` disambiguator, since both modules and primitives are
in the same namespace
- Refactor `report_ambiguity` into a closure
Additionally, I noticed that rustdoc would previously allow
`[struct@char]` if `char` resolved to a primitive (not if it had a
DefId). I fixed that and added a test case.
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
Doc alias checks: ensure only items appearing in search index can use it
Following the discussion in #73721, I added checks to ensure that only items appearing in the search are allowed to have doc alias.
r? @ollie27
|
|
|
|
|
|
|
|
|
|
|
|
|