rust/compiler
bors 0f5c769513 Auto merge of #75756 - jyn514:diagnostic-suggestions, r=estebank
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`
2020-09-12 05:52:14 +00:00
..
rustc cleanup: Remove duplicate library names from Cargo.tomls 2020-08-30 22:57:54 +03:00
rustc_apfloat mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_arena mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_ast Fully integrate token collection for additional AST structs 2020-09-10 17:58:14 -04:00
rustc_ast_lowering Attach TokenStream to ast::Visibility 2020-09-10 17:33:06 -04:00
rustc_ast_passes Attach TokenStream to ast::Visibility 2020-09-10 17:33:06 -04:00
rustc_ast_pretty Fully integrate token collection for additional AST structs 2020-09-10 17:58:14 -04:00
rustc_attr mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_builtin_macros Attach tokens to ast::Stmt 2020-09-10 17:33:06 -04:00
rustc_codegen_llvm Rollup merge of #74787 - petrochenkov:rustllvm, r=cuviper 2020-09-09 21:02:24 -07:00
rustc_codegen_ssa use push(char) instead of push_str(&str) to add single chars to strings 2020-09-10 13:58:41 +02:00
rustc_data_structures Capitalize safety comments 2020-09-08 22:37:18 -04:00
rustc_driver Auto merge of #73996 - da-x:short-unique-paths, r=petrochenkov 2020-09-03 23:27:45 +00:00
rustc_error_codes Rollup merge of #75984 - kornelski:typeormodule, r=matthewjasper 2020-09-09 15:05:45 -07:00
rustc_errors rustc_{errors,session}: add delay_good_path_bug 2020-09-02 10:43:17 +03:00
rustc_expand Attach tokens to ast::Stmt 2020-09-10 17:33:06 -04:00
rustc_feature fix tidy, small cleanup 2020-09-10 09:48:02 +02:00
rustc_fs_util mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_graphviz Also fixed monospace font for d3-graphviz engine 2020-09-09 14:49:32 -07:00
rustc_hir [WIP] give better errors for broken intra doc links 2020-09-05 13:48:19 -04:00
rustc_hir_pretty mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_incremental mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_index Improve BitSet APIs 2020-08-30 11:13:18 -07:00
rustc_infer use push(char) instead of push_str(&str) to add single chars to strings 2020-09-10 13:58:41 +02:00
rustc_interface Attach tokens to ast::Stmt 2020-09-10 17:33:06 -04:00
rustc_lexer lexer: Tiny improvement to shebang detection 2020-09-02 00:40:19 +03:00
rustc_lint Change ty.kind to a method 2020-09-04 17:47:51 +02:00
rustc_llvm Move rustllvm into rustc_llvm 2020-09-09 23:05:43 +03:00
rustc_macros Fix non-determinism in generated format string. 2020-09-09 21:23:25 +10:00
rustc_metadata Attach TokenStream to ast::Visibility 2020-09-10 17:33:06 -04:00
rustc_middle Auto merge of #75573 - Aaron1011:feature/const-mutation-lint, r=oli-obk 2020-09-10 05:54:26 +00:00
rustc_mir Rollup merge of #76567 - matthiaskrgr:clone_on_copy, r=varkor 2020-09-10 12:20:12 -07:00
rustc_mir_build Auto merge of #75573 - Aaron1011:feature/const-mutation-lint, r=oli-obk 2020-09-10 05:54:26 +00:00
rustc_parse Attach tokens to ast::Stmt 2020-09-10 17:33:06 -04:00
rustc_parse_format mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_passes Auto merge of #75888 - GuillaumeGomez:trait-impl-assoc-const-doc-alias, r=ollie27 2020-09-05 09:35:17 +00:00
rustc_plugin_impl mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_privacy Change ty.kind to a method 2020-09-04 17:47:51 +02:00
rustc_query_system mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_resolve Auto merge of #76499 - guswynn:priv_des, r=petrochenkov 2020-09-11 20:01:31 +00:00
rustc_save_analysis use push(char) instead of push_str(&str) to add single chars to strings 2020-09-10 13:58:41 +02:00
rustc_serialize mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
rustc_session use push(char) instead of push_str(&str) to add single chars to strings 2020-09-10 13:58:41 +02:00
rustc_span implement const_evaluatable_checked feature MVP 2020-09-10 08:52:02 +02:00
rustc_symbol_mangling Change ty.kind to a method 2020-09-04 17:47:51 +02:00
rustc_target remove redundant clones 2020-09-09 16:32:55 +02:00
rustc_trait_selection fix tidy, small cleanup 2020-09-10 09:48:02 +02:00
rustc_traits kind -> kind() 2020-09-04 19:17:57 -04:00
rustc_ty Change ty.kind to a method 2020-09-04 17:47:51 +02:00
rustc_typeck Auto merge of #75611 - JulianKnodt:cg_enum_err, r=lcnr 2020-09-11 08:40:07 +00:00