Skip to content

rustdoc: Incorrect parsing of links followed by parens #90811

Open
@lilyball

Description

@lilyball

rustdoc seems to be parsing links incorrectly when they're followed by parens. The general theme is that part of rustdoc is right-biased in parsing links, e.g. [Foo][](bar) is parsed like [Foo] and [](bar), but part of rustdoc parses it correctly. The observed behavior here is rather confusing, and it gets worse once you nest another link in the parens.

Examples

Basic link

//! [Some][](value)
Output: Some(value)
<a href="https://doc.rust-lang.org/1.56.1/core/option/enum.Option.html#variant.Some" title="Some">Some</a>
(value)

The HTML output is correct but it emits a spurious warning:

warning: unresolved link to `value`
 --> src/lib.rs:1:14
  |
1 | //! [Some][](value)
  |              ^^^^^ no item named `value` in scope
  |
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

Nested link

If we put another link inside the parens, the warning goes away but the nested link is not parsed:

//! [Some][]([Ok][])
Output: Some([Ok][])
<a href="https://doc.rust-lang.org/1.56.1/core/option/enum.Option.html#variant.Some" title="Some">Some</a>
([Ok][])

Nested link with parens

If we put parens after the nested link, the nested link is then parsed, but parsed incorrectly. The output makes this clear. Again, no warnings:

//! [Some][]([Ok][](value))
Output: Some([Ok])

HTML Output:

<a href="https://doc.rust-lang.org/1.56.1/core/option/enum.Option.html#variant.Some" title="Some">Some</a>
([Ok]
<a href="value"></a>
)

Nested link with parens followed by link to same item

Perhaps the most bizarre behavior here is if I simply include the nested link again elsewhere in the same doc comment, it parses correctly (and with no warnings). I've placed it on the same line for simplicity in this example, but the link can be anywhere in the doc comment.

//! [Some][]([Ok][](value)) or maybe [Ok][]
Output: Some(Ok(value)) or maybe Ok
<a href="https://doc.rust-lang.org/1.56.1/core/option/enum.Option.html#variant.Some" title="Some">Some</a>
(
<a href="https://doc.rust-lang.org/1.56.1/core/result/enum.Result.html#variant.Ok" title="Ok">Ok</a>
(value)) or maybe 
<a href="https://doc.rust-lang.org/1.56.1/core/result/enum.Result.html#variant.Ok" title="Ok">Ok</a>

Interestingly, it's not the link text that has to be the same, but the link destination. This example works equally well if I replace the second link with [Nope][Ok] but breaks if I use e.g. [Ok](http://example.com).

Meta

rustc --version --verbose:

rustc 1.56.1 (59eed8a2a 2021-11-01)
binary: rustc
commit-hash: 59eed8a2aac0230a8b53e89d4e99d55912ba6b35
commit-date: 2021-11-01
host: x86_64-apple-darwin
release: 1.56.1
LLVM version: 13.0.0

This occurs on nightly too

rustc +nightly --version --verbose:

rustc 1.58.0-nightly (82af160c2 2021-11-10)
binary: rustc
commit-hash: 82af160c2cb9c349a0373cba98d8ad7f911f0d34
commit-date: 2021-11-10
host: x86_64-apple-darwin
release: 1.58.0-nightly
LLVM version: 13.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-intra-doc-linksArea: Intra-doc links, the ability to link to items in docs by nameA-markdown-parsingArea: Markdown parsing for doc-commentsC-discussionCategory: Discussion or questions that doesn't represent real issues.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions