Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rustdoc: only report broken ref-style links once #77859

Merged
merged 1 commit into from
Jan 3, 2021

Conversation

bugadani
Copy link
Contributor

@bugadani bugadani commented Oct 12, 2020

This PR assigns the markdown LinkType to each parsed link and passes this information into the link collector.
If a link can't be resolved in resolve_with_disambiguator, the failure is cached for the link types where we only want to report the error once (namely Shortcut and Reference).

Fixes #77681

@rust-highfive
Copy link
Collaborator

Some changes occurred in intra-doc-links.

cc @jyn514

@rust-highfive
Copy link
Collaborator

r? @jyn514

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 12, 2020
@bugadani bugadani marked this pull request as draft October 12, 2020 17:37
@jyn514 jyn514 added A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Oct 13, 2020
src/librustdoc/html/markdown.rs Outdated Show resolved Hide resolved
src/librustdoc/html/markdown.rs Outdated Show resolved Hide resolved
src/librustdoc/passes/collect_intra_doc_links.rs Outdated Show resolved Hide resolved
src/librustdoc/passes/collect_intra_doc_links.rs Outdated Show resolved Hide resolved
src/librustdoc/passes/collect_intra_doc_links.rs Outdated Show resolved Hide resolved
@bugadani bugadani force-pushed the no-duplicate-ref-link-error branch 2 times, most recently from c69d3eb to 025d676 Compare October 13, 2020 09:52
@jyn514 jyn514 added S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 30, 2020
@bors

This comment has been minimized.

@bugadani bugadani force-pushed the no-duplicate-ref-link-error branch 4 times, most recently from 6aac7f5 to 093f190 Compare December 6, 2020 11:05
@bors

This comment has been minimized.

@bors

This comment has been minimized.

@jyn514 jyn514 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Dec 15, 2020
@rust-log-analyzer
Copy link
Collaborator

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    Checking rustc-rayon v0.3.0
    Checking regex v1.3.9
    Checking tempfile v3.1.0
    Checking rustdoc v0.0.0 (/checkout/src/librustdoc)
error[E0599]: no method named `as_deref` found for enum `std::option::Option<rustc_span::Symbol>` in the current scope
    --> src/librustdoc/passes/collect_intra_doc_links.rs:1984:31
     |
1984 |     let item_name = item.name.as_deref().unwrap_or("<unknown>");
     |                               ^^^^^^^^ help: there is an associated function with a similar name: `as_ref`
    ::: /checkout/compiler/rustc_span/src/symbol.rs:1438:1
     |
     |
1438 | pub struct Symbol(SymbolIndex);
     | |
     | |
     | doesn't satisfy `<rustc_span::Symbol as __Deref>::Target = _`
     | doesn't satisfy `rustc_span::Symbol: __Deref`
     |
     = note: the method `as_deref` exists but the following trait bounds were not satisfied:
             `rustc_span::Symbol: __Deref`
             `<rustc_span::Symbol as __Deref>::Target = _`
error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `rustdoc`

@bugadani bugadani force-pushed the no-duplicate-ref-link-error branch 2 times, most recently from fd381ab to a91de1a Compare December 20, 2020 10:33
extra_fragment,
cache_resolution_failure: matches!(
ori_link.kind,
LinkType::Reference | LinkType::Shortcut
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't particularly like this, but:

  • LinkType isn't hashable, so it can't be included in the ResolutionInfo struct directly
  • even if LinkType were hashable, including it would result in random test failures (didn't bother investigating)
  • I'm not sure why this doesn't break shortcut links completely (maybe because they are parsed as ShortcutUnknown?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calculating whether to cache it ahead of time seems fine. The reason you check explicitly for the kind is because inline links shouldn't be cached (things like [x](Ok))? Can you check for those explicitly instead? Or if that's not what you meant, maybe Collapsed should also be checked?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I have another question - I don't think this needs to be part of the key, right? It would work if you passed it as a parameter instead? That would avoid having to hash it at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has to be, otherwise "normal" links to the same target as a reference-style link would hit the cache. See the test case for exactly this :) Depends on what you expect, I guess, but this patch aims to emit a single error for each incorrect link definition, or at least that was my goal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it's also not that links don't get cached, but resolution failures don't get cached. Which is only interesting in the reference style links case, where we don't want to emit an error for each usage of the incorrect link. I think :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it's also not that links don't get cached, but resolution failures don't get cached.

Right, that's what I meant, thanks.

It has to be, otherwise "normal" links to the same target as a reference-style link would hit the cache.

Ok, I see the issue: if you have something like

/// [reference][link] and [inline](link)

both links should give an error, but if you don't include cache_resolution_failure in the cache key, then the second link will pick up the None and be returned.

So I have a further question now - when will you hit the cache and not have cache_resolution_failure set? That would only happen for [inline](link) twice in a row, right? But we explicitly choose not to insert it into the cache on error. I think there's an optimization here where you can make the size of the cache smaller by explicitly checking cache_resolution_failure on a cache hit, that way you don't need that extra bit of info; and the logic seems more clear to me too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's an optimization here

Interesting thought, that might be something I missed.

///
/// [a]: ref
//~^ ERROR unresolved link to
/// [b]: ref2
Copy link
Contributor Author

@bugadani bugadani Dec 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current patch, if this is [b]: ref, the error emitted for [reference link][b] will point to the definition of a. This is because the link cache ignores the name of the reference and handles a and b as if identical. This isn't ideal, but I consider this acceptable: we don't report all errors, but if the user fixes link a, we will report an error for link b, so eventually, every error can be caught :)

We could fix this by adding the span to ResolutionInfo (Optionally, only for Shortcut/Reference links), but I'm not sure if the complexity is worth it. This would also make ResolutionInfo and DiagnosticInfo overlap, if only optionally.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, I'm confused what those have to do with each other. We never cache the span, so there's nowhere for it to look up the span of a in the first place, the only span available is that of b.

Can you post the error that's wrong?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assume the following:

[a] [b]

[a]: ref
[b]: ref

We would only report an error for a.

@rust-log-analyzer

This comment has been minimized.

// For reference-style links (where the target is defined in footnote) we want the
// span to point to the definition, not the usage in order to generate useful error
// messages.
let start = link.as_ptr() as usize - md.as_ptr() as usize;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually doesn't work because the parser may clone the string and the pointer will no longer point into md. Sad :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you open an issue for pulldown? I think pointing to the usage is fine for now though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I don't consider this a bug in pulldown. Current behaviour is strange, but unless pulldown can provide two spans for a single event, this is at least consistent enough.

Pointing at the usage feels weird, though. This doesn't point me to what I need to modify:

+ LL | /// Links to [a] [link][a]
+    |              ^^^ no item named `ref` in scope

But I guess we can live with it if we can't fix it.

On the other hand, if it were possible to look up the link's title in the list of definitions, we could maybe point at the definition itself. I guess we can build a collector pass that build a table from footnotes? I need to look into how pulldows actually parses text and which events are relevant here. That will probably have to wait for next year, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah that error is pretty bad. I think I would rather have duplicate errors than an error pointing to the wrong place :/

Copy link
Contributor Author

@bugadani bugadani Dec 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You broke it ;)

To clarify: I believe this is an unintended, unnoticed side effect of the refactor that removed locate(). Maybe we should revert that and add a test? Or is there one and I believe it wrong and this error is my fault, which would be preferable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh oof, you're right, this is latest nightly:

warning: unresolved link to `std::process::Comman`
 --> link.rs:1:14
  |
1 | //! Links to [a] [link][a]
  |              ^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default

warning: unresolved link to `std::process::Comman`
 --> link.rs:1:18
  |
1 | //! Links to [a] [link][a]
  |                  ^^^^^^^^^ no item named `Comman` in module `process`

and this is a couple days ago, before the PR removing locate():

warning: unresolved link to `std::process::Comman`
 --> link.rs:3:10
  |
3 | //! [a]: std::process::Comman
  |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default

warning: unresolved link to `std::process::Comman`
 --> link.rs:3:10
  |
3 | //! [a]: std::process::Comman
  |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`

src/librustdoc/passes/collect_intra_doc_links.rs Outdated Show resolved Hide resolved
///
/// [a]: ref
//~^ ERROR unresolved link to
/// [b]: ref2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, I'm confused what those have to do with each other. We never cache the span, so there's nowhere for it to look up the span of a in the first place, the only span available is that of b.

Can you post the error that's wrong?

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-9 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
.................................................................................................... 9000/11196
.................................................................................................... 9100/11196
......................................................................................i......i...... 9200/11196
.................................................................................................... 9300/11196
.........................iiiiii...iiiiiii........................................................... 9400/11196
.................................................................................................... 9600/11196
..........test [ui] ui/issues/issue-74564-if-expr-stack-overflow.rs has been running for over 60 seconds
.......................................................................................... 9700/11196
.................................................................................................... 9800/11196
---
Suite("src/test/assembly") not skipped for "bootstrap::test::Assembly" -- not in ["src/tools/tidy"]
Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)

running 27 tests
iiiiiiiiiiiiiiiiiiiiiiiiiii

 finished in 0.077 seconds
Suite("src/test/incremental") not skipped for "bootstrap::test::Incremental" -- not in ["src/tools/tidy"]
Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
---
Suite("src/test/debuginfo") not skipped for "bootstrap::test::Debuginfo" -- not in ["src/tools/tidy"]
Check compiletest suite=debuginfo mode=debuginfo (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)

running 116 tests
iiiiiiiiii.i.i..i..i..ii....i.i....ii..........iiii.........i.....i...i.......ii.i.ii.....iiii.....i 100/116
test result: ok. 78 passed; 0 failed; 38 ignored; 0 measured; 0 filtered out; finished in 2.50s

 finished in 2.588 seconds
Suite("src/test/ui-fulldeps") not skipped for "bootstrap::test::UiFullDeps" -- not in ["src/tools/tidy"]
---
---- [rustdoc] rustdoc/link-title-escape.rs stdout ----

error: rustdoc failed!
status: exit code: 101
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc/link-title-escape/auxiliary" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc/link-title-escape" "/checkout/src/test/rustdoc/link-title-escape.rs"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
thread 'rustc' panicked at 'byte index 26538208 is out of bounds of `hello [foo]

[foo]: url 'title & <stuff> & "things"'`', src/librustdoc/passes/mod.rs:189:25

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.
note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.50.0-nightly (ac5890ac3 2020-12-22) running on x86_64-unknown-linux-gnu
query stack during panic:
end of query stack

------------------------------------------
---
test result: FAILED. 401 passed; 1 failed; 2 ignored; 0 measured; 0 filtered out; finished in 44.06s



command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--rustdoc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "--src-base" "/checkout/src/test/rustdoc" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--suite" "rustdoc" "--mode" "rustdoc" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-9/bin/FileCheck" "--nodejs" "/usr/bin/node" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "9.0.0" "--llvm-components" "aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo codegen core coroutines coverage debuginfocodeview debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver engine executionengine fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interpreter ipo irreader jitlink lanai lanaiasmparser lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker lto mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts object objectyaml option orcjit passes perfjitevents powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvutils runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target textapi transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86utils xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"


failed to run: /checkout/obj/build/bootstrap/debug/bootstrap --stage 2 test --exclude src/tools/tidy
Build completed unsuccessfully in 0:22:04

@bors
Copy link
Contributor

bors commented Dec 27, 2020

☔ The latest upstream changes (presumably #80181) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Dec 30, 2020
…llaumeGomez

Revert "Cleanup markdown span handling"

Reverts rust-lang#80244. This caused a diagnostic regression, originally it was:

```
warning: unresolved link to `std::process::Comman`
 --> link.rs:3:10
  |
3 | //! [a]: std::process::Comman
  |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default
```
but after that PR rustdoc now displays
```
warning: unresolved link to `std::process::Comman`
 --> link.rs:1:14
  |
1 | //! Links to [a] [link][a]
  |              ^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default
```
which IMO is much less clear.

cc `@bugadani,` thanks for catching this in rust-lang#77859.
r? `@GuillaumeGomez`
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Dec 30, 2020
…llaumeGomez

Revert "Cleanup markdown span handling"

Reverts rust-lang#80244. This caused a diagnostic regression, originally it was:

```
warning: unresolved link to `std::process::Comman`
 --> link.rs:3:10
  |
3 | //! [a]: std::process::Comman
  |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default
```
but after that PR rustdoc now displays
```
warning: unresolved link to `std::process::Comman`
 --> link.rs:1:14
  |
1 | //! Links to [a] [link][a]
  |              ^^^ no item named `Comman` in module `process`
  |
  = note: `#[warn(broken_intra_doc_links)]` on by default
```
which IMO is much less clear.

cc `@bugadani,` thanks for catching this in rust-lang#77859.
r? `@GuillaumeGomez`
@bugadani bugadani marked this pull request as ready for review January 2, 2021 22:48
@bors
Copy link
Contributor

bors commented Jan 3, 2021

☔ The latest upstream changes (presumably #80261) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Member

@jyn514 jyn514 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with the nits in the test case fixed. Thanks for sticking with this, I know it's been a journey 😆

src/librustdoc/html/markdown.rs Outdated Show resolved Hide resolved
src/test/rustdoc-ui/reference-link-reports-error-once.rs Outdated Show resolved Hide resolved
src/test/rustdoc-ui/reference-link-reports-error-once.rs Outdated Show resolved Hide resolved
src/test/rustdoc-ui/reference-link-reports-error-once.rs Outdated Show resolved Hide resolved
src/test/rustdoc-ui/reference-link-reports-error-once.rs Outdated Show resolved Hide resolved
src/test/rustdoc-ui/reference-link-reports-error-once.rs Outdated Show resolved Hide resolved
@jyn514
Copy link
Member

jyn514 commented Jan 3, 2021

@bors delegate=bugadani

@bors
Copy link
Contributor

bors commented Jan 3, 2021

✌️ @bugadani can now approve this pull request

@bugadani
Copy link
Contributor Author

bugadani commented Jan 3, 2021

Sure thing! Want me to squash before merging?

@jyn514
Copy link
Member

jyn514 commented Jan 3, 2021

Sure, if you think it makes the git history more clear. My idea of 'more clear' is 'no commits that should have just been in the original' (e.g. fixing typos) and "don't have major rewrites of the same functionality".

@bugadani
Copy link
Contributor Author

bugadani commented Jan 3, 2021

Makes sense.

@bors r=jyn514

@bors
Copy link
Contributor

bors commented Jan 3, 2021

📌 Commit 4b612dd has been approved by jyn514

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 3, 2021
@bors
Copy link
Contributor

bors commented Jan 3, 2021

⌛ Testing commit 4b612dd with merge 8018418...

@bors
Copy link
Contributor

bors commented Jan 3, 2021

☀️ Test successful - checks-actions
Approved by: jyn514
Pushing 8018418 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jan 3, 2021
@bors bors merged commit 8018418 into rust-lang:master Jan 3, 2021
@rustbot rustbot added this to the 1.51.0 milestone Jan 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rustdoc reports intradoc link errors twice if there are multiple links
6 participants