Pre-RFC: standard form to reference things


#1

In javadoc, it’s easy and useful to link to types, functions and/or fields. I think that Rust would do well to follow that example and define a canonical link format that could be used in rustdoc and annotations (I’d like to use it in my proposed deprecation feature).

The format should:

  • use the current namespace so things in scope can be used directly; this reduces duplication and allows to reference extern crates (however, those crates would then become a doc dependency)
  • be readable as-is, so it should be as near as possible to our x::y syntax
  • be unambiguous
  • be easy to learn and reasonably hard to get wrong

What do you folks think?


#2

:+1: from me, even though this seems a bit late, so it might take a (long) while to transition.

Possible syntax: {path::to::Thing#method_or_field}. I don’t think this has any meaning in markdown, so we should be able to use it for our own purposes. Rustdoc should convert all of these into links to the respective page and strip the {}. This can possibly even be done inside of code blocks, since it either isn’t very useful Rust or even illegal Rust (and it would be whitespace-sensitive to enforce a common style for readability and to further differentiate from Rust code).

Some more thoughts:

  • If a path isn’t resolved, should it be a hard error (generate no docs) or generate broken docs? Or should rustdoc generate broken docs, print an error and return an error code?
  • Paths into std and other included-by-default crates must be handled differently (the link has to point to the official documentation, since local docs don’t exist)
  • We have to watch out for references to private fields/items, obviously, but these might be useful when generating internal documentation for an executable - in fact, their availability depends on which rustdoc passes are run on the crate that contains them

I’m not sure what you mean by this. Are there special-cased doc dependencies? Rustdoc will already build docs for all dependencies, so they are available.


#3

No, I meant dev-dependency, but I could imagine making a special rustdoc-only extern crate syntax, which would reduce the dependency to doc builds.


#4

FTR, the javadoc syntax is:

Use the {@link #getComponentAt(int, int) getComponentAt} method.

jsdoc is the same, but also allows this to be used in markdown links ([text]{@link namepathOrURL}).

This syntax could also work for Rust, though I’d like to not use # for methods as we can already access those with :: (and fields with .).


#5

Does markdown have any facility for extension syntax, or some recommendation for this?

Would it be possible to just use URLs, with the rustdoc: scheme? For example: [link title](rustdoc: std::io::Read),


#6

Why not rust:Read (as long as std::io::Read is in scope)?


#7

Using a new URL schema like rustdoc://std::path::Path might be a good idea. (Where the part after the rustdoc:// can be anything that could also be resolved by a use.)

We might want differentiate between named links like [the Path docs](rustdoc://std::path::Path) and “plain” references, though (e.g. <rustdoc://std::path::Path>, rendered as “Path”).

(The nice thing is that these do not require us to invent new Markdown-compatible syntax.)


#8

Yeah, that’s mostly what I thought, though I’m not keen on rustdoc://, that seems a bit long. As I said before, rust: as a prefix should be sufficient, the double slashes aren’t actually required for a link, AFAIK.


#9

Markdown itself does not. I haven’t checked CommonMark lately, but I think it was stated to be one of the goals of the project.

I think that having something like this would be nice, but I really want Rust to play nicely with the rest of the universe. So if we do have to blaze a trail here, I want to make sure that it fits with whatever happens upstream in markdown proper.


#10

Feel free to bikeshed the URL schema, rust:std::path::Path might work as well but to me looks weird because of the single colon at the start when all other components use two.


#11

So I think we should have some clear and unambiguous form to link, but I’d also like it if rustdoc could make a best effort guess at linking things as well. i.e., if I write foo, and there is a fn or module called foo in scope, I want it to just link. Maybe if there is ambiguity it could link to a search, as well.


#12

Neither Markdown nor CommonMark specify any form for extension (I briefly followed this idea in the CommonMark forums but it was a worthless conversation).

However a custom uri isn’t really an extension IMO.

AFAIK we’ve just been blocked on “ugh hoedown is C bleugh”. This is why I was excited about pulldown-cmark getting relicensed. Someone just needs to swap hoedown out with it, and then we can easily extend the whole thing by mapping over its token stream.


#13

Note that this is non-trivial since cmark has two deps. It may involve solving the “bootstrap with cargo” problem.


#14

That is the reason why I would like to opt in for using ASCIIDoc wirh Markdown compatibility layer (yes, this is an official thing).


#15

Here is how this is done in Kotlin: https://kotlinlang.org/docs/reference/kotlin-doc.html#linking-to-elements

The interesting pieces are minimal syntax [some_thing] and

Names in links are resolved using the same rules as if the name was used inside the element being documented. In particular, this means that if you have imported a name into the current file, you don’t need to fully qualify it when you use it in a KDoc comment.


#16

Hm, and what about this horrible hack? You type

`foo`

to get a code snippet and

` foo`

with a leading space to get a link (provided that foo is in scope). This is backwards compatible with stock markdown, uses code syntax for code, and allows detection of broken links in docs.


#17

I don’t like it, it’s too easy to link by accident.


#18

I would say that it’s too easy not to link by accident with this syntax, which is worse. If accidental link works, then it may be a good thing. If it does not work, then it is detected by rustdoc.


#19

I have actually supported the link label syntax ([foo::bar]) for a long time. It is natural in Markdown/CommonMark, as one may suppose that there is an implicit label target for such labels, and the link label can contain any kind of letters required for full qualification (spec). The main issue on supporting this syntax was that I’m not sure if Hoedown is capable for customizing link targets before the resolution.