From 98d06f27f1a9e05c9b820590a1765bb3e4bb8bf0 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Tue, 7 Mar 2017 12:07:09 +0100 Subject: [PATCH 01/16] Intra Rustdoc Links Add a notation how to create relative links in documentation comments (based on Rust item paths) and extend Rustdoc to automatically turn this into working links. --- text/0000-intra-rustdoc-links.md | 227 +++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 text/0000-intra-rustdoc-links.md diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md new file mode 100644 index 00000000000..77004e080da --- /dev/null +++ b/text/0000-intra-rustdoc-links.md @@ -0,0 +1,227 @@ +- Feature Name: `intra_rustdoc_links` +- Start Date: 2017-03-06 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +Add a notation how to create relative links in documentation comments +(based on Rust item paths) +and extend Rustdoc to automatically turn this into working links. + + +# Motivation +[motivation]: #motivation + +It is good practice in the Rust community to +add documentation to all public items of a crate, +as the API documentation as rendered by Rustdoc is the main documentation of most libaries. +Documentation comments at the module (or crate) level are used to +give an overview of the module (or crate) +and describe how the items of a crate can be used together. +To make navigating the documentation easy, +crate authors make these items link to their individual entries +in the API docs. + +Currently, these links are plain Markdown links, +and the URLs are the (relative) paths of the items' pages +in the rendered Rustdoc output. +This is sadly very fragile in several ways: + +1. As the same doc comment can be rendered on several Rustdoc pages + and thus on separate directory levels + (e.g., the summary page of a module, and a struct's own page), + it is not possible to confidently use relative paths. + For example, + adding a link to `../foo/struct.Bar.html` + to the first paragraph of the doc comment of the module `lorem` + will work on the rendered `/lorem/index.html` page, + but not on the crate's summary page `/index.html`. +2. Using absolute paths in links + (like `/crate-name/foo/struct.Bar.html`) + to circumvent the previous issue + might work for the author's own hosted version, + but will break when + looking at the documentation using `cargo doc --open` + (which uses `file:///` URLs) + or when using docs.rs. +3. Should Rustdoc's file name scheme ever change + (it has change before^(citation needed)), + all manually created links need to be updated. + +To solve this dilemma, +we propose extending Rustdoc +to be able to generate relative links that work in all contexts. + + +# Detailed design +[design]: #detailed-design + +Markdown allows writing links in several forms: + +1. `[Human readable name](URL)` +2. `[Human readable name][label]`, + and somewhere else in the document: `[label]: URL` +3. `` which will be turned into the equivalent of `[URL](URL)` + (some renderer will automatically prepend `http://` as a schema if necessary) + +We prospose that +in each occurance of `URL` in the above list, +it should also be possible to write a Rust path +(as defined [in the reference][ref-paths]). + +[ref-paths]: https://github.com/rust-lang-nursery/reference/blob/2d23ea601f017c106a2303094ee1c57ba856d246/src/paths.md + +## Additions to the documentation syntax + +1. `[Iterator](std::iter::Iterator)` +2. `[Iterator][iter]`, + and somewhere else in the document: `[iter]: std::iter::Iterator` +3. `` + +## How it will be rendered + +The following: + +```rust +The offers several ways to fooify [Bars](bars::Bar). +``` + +should be rendered as: + +```html +The offers several ways to fooify Bars. +``` + +when on the crates index page (`index.html`), +and as this +when on the page for the `foos` module (`foos/index.html`): + +```html +The offers several ways to fooify Bars. +``` + +## Inline paths + +When using the third link syntax (``), +a link like `` +will be converted to ```[`bars::Bar`](bars::Bar)```. + +This means that + +``` +You can use for that. +``` + +will be rendered as + +```html +You can use bars::Bar for that. +``` + +## Linking to methods + +To link to methods, it may be necessary to use fully-qualified paths, +like `::bar`. +We have yet to analyse in which cases this is necessary, +and this syntax is currently not described in [the reference's section on paths][ref-paths]. + +## Errors + +Ideally, Rustdoc would be able to recognize Rust path syntax, +and if the path cannot be resolved, +print a warning (or an error). + +## Complex example + +(Excerpt from Diesel's [`expression`][diesel-expression] module.) + +[diesel-expression]: https://github.com/diesel-rs/diesel/blob/1daf2581919d82b80c18f00957e5c3d35375c4c0/diesel/src/expression/mod.rs + +```rust +// diesel/src/expression/mod.rs + +//! AST types representing various typed SQL expressions. Almost all types +//! implement either [`Expression`] or [`AsExpression`]. +//! +//! [`Expression`]: Expression +//! [`AsExpression`]: AsExpression + +/// Represents a typed fragment of SQL. Apps should not need to implement this +/// type directly, but it may be common to use this as type boundaries. +/// Libraries should consider using or +/// instead of implementing this directly. +pub trait Expression { + type SqlType; +} + +/// Describes how a type can be represented as an expression for a given type. +/// These types couldn't just implement [`Expression`] directly, as many things +/// can be used as an expression of multiple types. ( for example, can +/// be used as either [`VarChar`] or [`Text`]). +/// +/// [`Expression`]: Expression +/// [`VarChar`]: diesel::types::VarChar +/// [`Text`]: diesel::types::Text +pub trait AsExpression { + type Expression: Expression; + fn as_expression(self) -> Self::Expression; +} +``` + +Please note: + +- This uses reference-style Markdown links most often. + This is considered a good practice is official Rust documentation, + as it is easier to read than having long URLs in the same line as regular text. +- Even though inline links could be used throughout, we only used them for + the macro links + and the link to the `String` type (from `std`, available via the prelude). + These are all items whose path is either obvious + (from a documentation perspective, macros currently always live in the crate's root) + or well known + (the `String` type is used in most Rust code bases). + + +# How We Teach This +[how-we-teach-this]: #how-we-teach-this + +Extend the documentation chapter of the book with a subchapter on How to Link to Items. +Reference the chapter on the module system. +Maybe present an example use case of a module whose documentation links to several related items. + + +# Drawbacks +[drawbacks]: #drawbacks + +- Rustdoc gets more complex. +- These links won't work when the doc comments are rendered with a default Markdown renderer. +- The Rust paths might conflict with other valid links, + though we could not think of any. + +# Alternatives +[alternatives]: #alternatives + +## Syntax alternatives + +Introduce special syntax for this: + +- [javadoc] and [jsdoc] + use `{@link java.awt.Panel}` + or `[link text]{@link namepathOrURL}` + +[javadoc]: http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html +[jsdoc]: http://usejsdoc.org/tags-inline-link.html + + +# Unresolved questions +[unresolved]: #unresolved-questions + +- Is it possible for Rustdoc to resolve paths? + Is it easy to implement this? +- There is talk about switching Rustdoc to a different markdown renderer ([pulldown-cmark]). + Does it support this? + Does the current renderer? + +[pulldown-cmark]: https://github.com/google/pulldown-cmark/ From 0483d34fc8bb9867a664c02a4716ac381acdae9b Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Tue, 7 Mar 2017 15:03:26 +0100 Subject: [PATCH 02/16] Update intra_rustdoc_links - Resolving paths - Path ambiguities - Linking to external crates --- text/0000-intra-rustdoc-links.md | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 77004e080da..2a95a6c8a69 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -120,6 +120,62 @@ will be rendered as You can use bars::Bar for that. ``` +## Resolving paths + +The Rust paths used in links are resolved +relative to the item in whose documentation they appear. + +For example: + +```rust +/// Container for a [Dolor](ipsum::Dolor). +struct Lorem(ipsum::Dolor); + +/// Contains various things, mostly [Dolor](ipsum::Dolor) and a helper function, +/// [sit](ipsum::sit). +mod ipsum { + struct Dolor; + + /// Takes a and does things. + fn sit(d: Dolor) {} +} + +mod amet { + //! Helper types, can be used with the [ipsum](super::ipsum) module. +} +``` + +## Path ambiguities + +Rust allows items to have the same name. A short evaluation revealed that + +- unit and tuple struct names + can conflict with + function names, +- unit and tuple struct names + can conflict with + enum names, +- and regular struct, enum, and trait names + can conflict with + each other + (but not function names). + +It appears the ambiguity can resolved +by being able to restrict the path to function names. +We propose that in case of ambiguity, +you can add `()` as a suffix to path +to only search for functions. +(Additionally, to link to macros, you must add `!` to the path.) + +This was originally proposed by +[@kennytm](https://github.com/kennytm) +[here](https://github.com/rust-lang/rfcs/pull/1946#issuecomment-284719684), +going into more details: + +> `` — First search for type-like items. If not found, search for value-like items +> `` — Only search for functions. +> `` — Only search for macros. + ## Linking to methods To link to methods, it may be necessary to use fully-qualified paths, @@ -127,6 +183,17 @@ like `::bar`. We have yet to analyse in which cases this is necessary, and this syntax is currently not described in [the reference's section on paths][ref-paths]. +## Linking to external crates + +Rustdoc is already able to link to external crates, +and renders documentation for all dependencies by default. +Referencing the standard library (or `core`) +should generate links with a well-known base path, +e.g. `https://doc.rust-lang.org/nightly/`. +Referencing other external crates +links to the pages Rustdoc has already rendered (or will render) for them. +Special flags (e.g. `cargo doc --no-deps`) will not change this behavior. + ## Errors Ideally, Rustdoc would be able to recognize Rust path syntax, @@ -200,6 +267,7 @@ Maybe present an example use case of a module whose documentation links to sever - The Rust paths might conflict with other valid links, though we could not think of any. + # Alternatives [alternatives]: #alternatives From 2dd1ed27043726b02ed8a8d766da7b0aa61539a9 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Tue, 7 Mar 2017 15:27:47 +0100 Subject: [PATCH 03/16] Update intra_rustdoc_links - Mention this is valid Markdown - Add more alternatives --- text/0000-intra-rustdoc-links.md | 41 ++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 2a95a6c8a69..c1bbf3757f8 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -80,6 +80,16 @@ it should also be possible to write a Rust path and somewhere else in the document: `[iter]: std::iter::Iterator` 3. `` +All additions are already valid Markdown, +as defined by the orginal [Markdown syntax definition][md] +as well as the [CommonMark] project. +Especially, Rust paths are valid CommonMark [link destinations], +even with the suffixes described [below][path-ambiguities]. + +[md]: https://daringfireball.net/projects/markdown/syntax +[CommonMark]: http://commonmark.org +[link destinations]: http://spec.commonmark.org/0.27/#link-destination + ## How it will be rendered The following: @@ -146,6 +156,7 @@ mod amet { ``` ## Path ambiguities +[path-ambiguities]: #path-ambiguities Rust allows items to have the same name. A short evaluation revealed that @@ -173,7 +184,9 @@ This was originally proposed by going into more details: > `` — First search for type-like items. If not found, search for value-like items +> > `` — Only search for functions. +> > `` — Only search for macros. ## Linking to methods @@ -271,9 +284,29 @@ Maybe present an example use case of a module whose documentation links to sever # Alternatives [alternatives]: #alternatives -## Syntax alternatives +- Use reference-style links and automatically generate the references. + For example, the Markdown snippet + + ```md + This is of type [`String`]. + ``` + + expects a link reference definition like -Introduce special syntax for this: + ```md + [`String`]: https://doc.rust-lang.org/nightly/std/string/struct.String.html + ``` + + to follow (or precede) it. + This link reference definition can be automatially generated by Rustdoc + with the (relative) URL to the page of the item. + This was suggested in [the CommonMark forum] + as well as + by [GuillaumeGomez](https://github.com/GuillaumeGomez). + + We consider this equivalent to the `` syntax this RFC proposes. + +[cm-forum]: https://talk.commonmark.org/t/what-should-the-rust-community-do-for-linkage/2141 - [javadoc] and [jsdoc] use `{@link java.awt.Panel}` @@ -282,6 +315,10 @@ Introduce special syntax for this: [javadoc]: http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html [jsdoc]: http://usejsdoc.org/tags-inline-link.html +- [@kennytm](https://github.com/kennytm) + listed other syntax alternatives + [here](https://github.com/rust-lang/rfcs/pull/1946#issuecomment-284718018). + # Unresolved questions [unresolved]: #unresolved-questions From e004ea150505cea6be832ff6a3f96cc7166d34d8 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Thu, 9 Mar 2017 18:20:09 +0100 Subject: [PATCH 04/16] Update intra_rustdoc_links: No more Autolinks - Autolinks no out - Implied Shortcut Reference Links are in --- text/0000-intra-rustdoc-links.md | 195 ++++++++++++++++++++----------- 1 file changed, 126 insertions(+), 69 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index c1bbf3757f8..346375541e8 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -47,9 +47,11 @@ This is sadly very fragile in several ways: (which uses `file:///` URLs) or when using docs.rs. 3. Should Rustdoc's file name scheme ever change - (it has change before^(citation needed)), + (it has change before, cf. [Rust issue #35236]), all manually created links need to be updated. +[Rust issue #35236]: https://github.com/rust-lang/rust/pull/35236 + To solve this dilemma, we propose extending Rustdoc to be able to generate relative links that work in all contexts. @@ -58,39 +60,101 @@ to be able to generate relative links that work in all contexts. # Detailed design [design]: #detailed-design -Markdown allows writing links in several forms: +[Markdown][md]/[CommonMark] allow writing links in several forms +(the names are from the [CommonMark spec][cm-spec] in version 0.27): -1. `[Human readable name](URL)` -2. `[Human readable name][label]`, - and somewhere else in the document: `[label]: URL` +[md]: https://daringfireball.net/projects/markdown/syntax +[CommonMark]: http://commonmark.org +[cm-spec]: http://spec.commonmark.org/0.27/ + +1. `[link text](URL)` + ([inline link][il]) +2. `[link text][link label]` + ([reference link][rl], + link label can also be omitted, cf. [shortcut reference links][srl]) + and somewhere else in the document: `[link label]: URL` + (this part is called [link reference definition][lrd]) 3. `` which will be turned into the equivalent of `[URL](URL)` - (some renderer will automatically prepend `http://` as a schema if necessary) + ([autolink][al], required to start with a schema) + +[il]: http://spec.commonmark.org/0.27/#inline-link +[rl]: http://spec.commonmark.org/0.27/#reference-link +[srl]: http://spec.commonmark.org/0.27/#shortcut-reference-link +[al]: http://spec.commonmark.org/0.27/#autolinks +[lrd]: http://spec.commonmark.org/0.27/#link-reference-definitions We prospose that -in each occurance of `URL` in the above list, +in each occurance of `URL` +of inline links and link reference definitions, it should also be possible to write a Rust path (as defined [in the reference][ref-paths]). +Additionally, automatic [link reference definitions][lrd] should be generated +to allow easy linking to obvious targets. [ref-paths]: https://github.com/rust-lang-nursery/reference/blob/2d23ea601f017c106a2303094ee1c57ba856d246/src/paths.md ## Additions to the documentation syntax +Rust paths as URLs in inline and reference links: + 1. `[Iterator](std::iter::Iterator)` 2. `[Iterator][iter]`, and somewhere else in the document: `[iter]: std::iter::Iterator` -3. `` +3. `[Iterator]`, + and somewhere else in the document: `[Iterator]: std::iter::Iterator` + +## Implied Shortcut Reference Links +[isrl]: #implied-shortcut-reference-links + +The third syntax example above shows a +[shortcut reference link][srl], +which is a reference link +whose link text and link label are the same, +and there exists a link reference definition for that label. +For example: `[HashMap]` will be rendered as a link +given a link reference definition like ```[HashMap]: std::collections::HashMap```. + +To make linking to items easier, +we introduce "implied link reference definitions": + +1. `[std::iter::Iterator]`, + without having a link reference definition for `Iterator` anywhere else in the document +2. ```[`std::iter::Iterator`]```, + without having a link reference definition for `Iterator` anywhere else in the document + (same as previous style but with back ticks to format link as inline code) + +If Rustdoc finds a shortcut reference link + +1. without a matching link reference definition +2. whose link label, + after stripping leading and trailing back ticks, + is a valid Rust path -All additions are already valid Markdown, +it will add a link reference definition +for this link label pointing to the Rust path. + +[Collapsed reference links][crf] (`[link label][]`) are handled analogously. + +[crf]: http://spec.commonmark.org/0.27/#collapsed-reference-link + +(This was one of the first ideas suggested +by [CommonMark forum] members +as well as by [Guillaume Gomez].) + +[CommonMark forum]: https://talk.commonmark.org/t/what-should-the-rust-community-do-for-linkage/2141 +[Guillaume Gomez]: https://github.com/GuillaumeGomez + +## Standard-conform Markdown + +These additions are valid Markdown, as defined by the orginal [Markdown syntax definition][md] as well as the [CommonMark] project. Especially, Rust paths are valid CommonMark [link destinations], even with the suffixes described [below][path-ambiguities]. -[md]: https://daringfireball.net/projects/markdown/syntax -[CommonMark]: http://commonmark.org [link destinations]: http://spec.commonmark.org/0.27/#link-destination -## How it will be rendered +## How links will be rendered The following: @@ -112,22 +176,37 @@ when on the page for the `foos` module (`foos/index.html`): The offers several ways to fooify Bars. ``` -## Inline paths +## No Autolinks Style + +When using the autolink syntax (``), +the URL has to be an [absolute URI], +i.e., it has to start with an URI scheme. +Thus, it will not be possible to write `` +to link to a Rust item called `Foo` +that is in scope +(this also conflicts with Markdown ability to contain arbitrary HTML elements). +And while `` is a valid URI +(treating `std:` as the scheme), +to avoid confusion, the RFC does not propose adding any support for autolinks. + +[absolute URI]: http://spec.commonmark.org/0.27/#absolute-uri -When using the third link syntax (``), -a link like `` -will be converted to ```[`bars::Bar`](bars::Bar)```. +This means that this will not render a valid link: -This means that +``` +Does not work: :( +``` + +We suggest to use [Implied Shortcut Reference Links][isrl] instead: ``` -You can use for that. +Does work: [`bars::Bar`] :) ``` -will be rendered as +which will be rendered as ```html -You can use bars::Bar for that. +Does work: bars::Bar :) ``` ## Resolving paths @@ -146,7 +225,7 @@ struct Lorem(ipsum::Dolor); mod ipsum { struct Dolor; - /// Takes a and does things. + /// Takes a [Dolor] and does things. fn sit(d: Dolor) {} } @@ -189,13 +268,6 @@ going into more details: > > `` — Only search for macros. -## Linking to methods - -To link to methods, it may be necessary to use fully-qualified paths, -like `::bar`. -We have yet to analyse in which cases this is necessary, -and this syntax is currently not described in [the reference's section on paths][ref-paths]. - ## Linking to external crates Rustdoc is already able to link to external crates, @@ -224,24 +296,20 @@ print a warning (or an error). //! AST types representing various typed SQL expressions. Almost all types //! implement either [`Expression`] or [`AsExpression`]. -//! -//! [`Expression`]: Expression -//! [`AsExpression`]: AsExpression /// Represents a typed fragment of SQL. Apps should not need to implement this /// type directly, but it may be common to use this as type boundaries. -/// Libraries should consider using or -/// instead of implementing this directly. +/// Libraries should consider using [`infix_predicate!`] or +/// [`postfix_predicate!`] instead of implementing this directly. pub trait Expression { type SqlType; } /// Describes how a type can be represented as an expression for a given type. /// These types couldn't just implement [`Expression`] directly, as many things -/// can be used as an expression of multiple types. ( for example, can +/// can be used as an expression of multiple types. ([`String`] for example, can /// be used as either [`VarChar`] or [`Text`]). /// -/// [`Expression`]: Expression /// [`VarChar`]: diesel::types::VarChar /// [`Text`]: diesel::types::Text pub trait AsExpression { @@ -252,24 +320,22 @@ pub trait AsExpression { Please note: -- This uses reference-style Markdown links most often. - This is considered a good practice is official Rust documentation, - as it is easier to read than having long URLs in the same line as regular text. -- Even though inline links could be used throughout, we only used them for - the macro links - and the link to the `String` type (from `std`, available via the prelude). - These are all items whose path is either obvious - (from a documentation perspective, macros currently always live in the crate's root) - or well known - (the `String` type is used in most Rust code bases). +- This uses implied shortcut reference links most often. + Since the original documentation put the type/trait names in back ticks to render them as code, we preserved this style. + (We don't propose this as a general convention, though.) +- Even though implied shortcut reference links could be used throughout, + they are not used for the last two links (to `VarChar` and `Text`), + which are not in scope and need to be linked to by their absolute Rust path. + To make reading easier and less noisy, reference links are used to rename the links. + (An assumption is that most readers will recognize these names and know they are part of `diesel::types`.) # How We Teach This [how-we-teach-this]: #how-we-teach-this -Extend the documentation chapter of the book with a subchapter on How to Link to Items. -Reference the chapter on the module system. -Maybe present an example use case of a module whose documentation links to several related items. +- Extend the documentation chapter of the book with a subchapter on How to Link to Items. +- Reference the chapter on the module system, to let reads familiarize themselves with Rust paths. +- Maybe present an example use case of a module whose documentation links to several related items. # Drawbacks @@ -281,32 +347,23 @@ Maybe present an example use case of a module whose documentation links to sever though we could not think of any. -# Alternatives -[alternatives]: #alternatives - -- Use reference-style links and automatically generate the references. - For example, the Markdown snippet - - ```md - This is of type [`String`]. - ``` +# Possible Extensions +[possible-extensions]: #possible-extensions - expects a link reference definition like +## Linking to methods - ```md - [`String`]: https://doc.rust-lang.org/nightly/std/string/struct.String.html - ``` +To link to methods, it may be necessary to use fully-qualified paths, +like `::bar`. +We have yet to analyse in which cases this is necessary, +and this syntax is currently not described in [the reference's section on paths][ref-paths]. - to follow (or precede) it. - This link reference definition can be automatially generated by Rustdoc - with the (relative) URL to the page of the item. - This was suggested in [the CommonMark forum] - as well as - by [GuillaumeGomez](https://github.com/GuillaumeGomez). - We consider this equivalent to the `` syntax this RFC proposes. +# Alternatives +[alternatives]: #alternatives -[cm-forum]: https://talk.commonmark.org/t/what-should-the-rust-community-do-for-linkage/2141 +- Prefix Rust paths with a URI scheme, e.g. `rust:` + (cf. [path ambiguities][path-ambiguities]). +- Prefix Rust paths with a URI scheme for the item type, e.g. `struct:`, `enum:`, `trait:`, or `fn:`. - [javadoc] and [jsdoc] use `{@link java.awt.Panel}` From 71f7f5f01b50e375ba5504395680fc562476979f Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Sun, 28 May 2017 11:44:13 +0200 Subject: [PATCH 05/16] Expand 'linking to external docs' - move to 'Possible extensions' - suggest generalized approach --- text/0000-intra-rustdoc-links.md | 66 +++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 346375541e8..e41c0934ee0 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -268,16 +268,6 @@ going into more details: > > `` — Only search for macros. -## Linking to external crates - -Rustdoc is already able to link to external crates, -and renders documentation for all dependencies by default. -Referencing the standard library (or `core`) -should generate links with a well-known base path, -e.g. `https://doc.rust-lang.org/nightly/`. -Referencing other external crates -links to the pages Rustdoc has already rendered (or will render) for them. -Special flags (e.g. `cargo doc --no-deps`) will not change this behavior. ## Errors @@ -357,6 +347,62 @@ like `::bar`. We have yet to analyse in which cases this is necessary, and this syntax is currently not described in [the reference's section on paths][ref-paths]. +## Linking to external documentation + +Currently, Rustdoc is able to link to external crates, +and renders documentation for all dependencies by default. +Referencing the standard library (or `core`) +generates links with a well-known base path, +e.g. `https://doc.rust-lang.org/nightly/`. +Referencing other external crates +links to the pages Rustdoc has already rendered (or will render) for them. +Special flags (e.g. `cargo doc --no-deps`) will not change this behavior. + +We propose to generalize this approach +by adding parameters to rustdoc +that allow overwriting the base URLs +it used for external crate links. +(These paramters will at first +be supplied as CLI flags +but could also be given via a config file, +environment variables, +or other means in the future.) + +We suggest the following syntax: + +```sh +rustdoc --extern-base-url="regex=https://docs.rs/regex/0.2.2/regex/" [...] +``` + +By default, the core/std libraries should have a default base URL +set to the latest known Rust release when the version of rustdoc was built. + +In addition to that, +`cargo doc` _may_ be extended with CLI flags +to allow shortcuts to some common usages. +E.g., a `--external-docs` flag may add base URLs using [docs.rs] +for all crates that are from the crates.io repository +(docs.rs automatically renders documentation for crates published to crates.io). + +[docs.rs]: https://docs.rs/ + +### Known issues + +Automatically linking to external docs has the following known tradeoffs: + +- The generated URLs may not/no longer exist + - Not all crate documentation can be rendered without a known local setup, + e.g., for crates that use procedural macros/build scripts + to generate code based on the local environment. + - Not all crate documentation can be rendered without having 3rd-party tools installed. +- The generated URLs may not/no have the expected content, because + - The exact Cargo features used to build a crate locally + were not used when building the docs available at the given URL. + - The crate has platform-specific items, + and the local platform and the platform + used to render the docs available at the given URL + differ + (note that docs.rs renders docs for multiple platforms, though). # Alternatives [alternatives]: #alternatives From ceb020405648326ca0e431acdbf3c1f535ab26dd Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Sun, 28 May 2017 11:44:13 +0200 Subject: [PATCH 06/16] Rewrite 'path ambiguities' --- text/0000-intra-rustdoc-links.md | 63 +++++++++++++++++--------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index e41c0934ee0..a2f49b0ff03 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -237,37 +237,40 @@ mod amet { ## Path ambiguities [path-ambiguities]: #path-ambiguities -Rust allows items to have the same name. A short evaluation revealed that - -- unit and tuple struct names - can conflict with - function names, -- unit and tuple struct names - can conflict with - enum names, -- and regular struct, enum, and trait names - can conflict with - each other - (but not function names). - -It appears the ambiguity can resolved -by being able to restrict the path to function names. -We propose that in case of ambiguity, -you can add `()` as a suffix to path -to only search for functions. -(Additionally, to link to macros, you must add `!` to the path.) - -This was originally proposed by -[@kennytm](https://github.com/kennytm) -[here](https://github.com/rust-lang/rfcs/pull/1946#issuecomment-284719684), -going into more details: - -> `` — First search for type-like items. If not found, search for value-like items -> -> `` — Only search for functions. -> -> `` — Only search for macros. +Rust has three different namespaces that items can be in, +types, values, and macros. +That means that in a given source file, +three items with the same name can be used, +as long as they are in different namespaces. +To illustrate, in the following example +we introduce an item called `FOO` in each namespace: + +```rust +pub trait FOO {} + +pub const FOO: i32 = 42; + +macro_rules! FOO { () => () } +``` + +To be able to link to each item, +we'll need a way to disabiguate the namespaces. +Our proposal is this: + +- Links to types are written as described earlier, + with no pre- or suffix, + e.g., `Look at the [FOO] trait`. +- In links to macros, + the link label must end with a `!`, + e.g., `Look at the [FOO!] macro`. +- For values, we differentiate three cases: + - Links to functions are written with a `()` suffix, + e.g., `Also see the [FOO()] function`. + - Links to constants are prefixed with `const `, + e.g., `As defined in [const FOO].` + - Links to statics are prefixed with `static `, + e.g., `See [static FOO]`. ## Errors From 04f9003d4530fe3322fb8655b1e2ddf30f605e1b Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Sun, 28 May 2017 11:50:25 +0200 Subject: [PATCH 07/16] Expand link to associated items --- text/0000-intra-rustdoc-links.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index a2f49b0ff03..5ebd70ad72e 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -343,10 +343,12 @@ Please note: # Possible Extensions [possible-extensions]: #possible-extensions -## Linking to methods +## Linking to associated items -To link to methods, it may be necessary to use fully-qualified paths, -like `::bar`. +To link to associated items, +i.e., the associated functions, types, and constants of a trait, +it may be necessary to use fully-qualified paths, +like `See the [::bar()] method`. We have yet to analyse in which cases this is necessary, and this syntax is currently not described in [the reference's section on paths][ref-paths]. From 82ea2bc6ef0b9f00c383558cf11eecc46556ea8e Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Sun, 28 May 2017 11:45:13 +0200 Subject: [PATCH 08/16] fix typos --- text/0000-intra-rustdoc-links.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 5ebd70ad72e..b50949fb223 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -16,7 +16,7 @@ and extend Rustdoc to automatically turn this into working links. It is good practice in the Rust community to add documentation to all public items of a crate, -as the API documentation as rendered by Rustdoc is the main documentation of most libaries. +as the API documentation as rendered by Rustdoc is the main documentation of most libraries. Documentation comments at the module (or crate) level are used to give an overview of the module (or crate) and describe how the items of a crate can be used together. @@ -83,8 +83,8 @@ to be able to generate relative links that work in all contexts. [al]: http://spec.commonmark.org/0.27/#autolinks [lrd]: http://spec.commonmark.org/0.27/#link-reference-definitions -We prospose that -in each occurance of `URL` +We propose that +in each occurrence of `URL` of inline links and link reference definitions, it should also be possible to write a Rust path (as defined [in the reference][ref-paths]). @@ -144,10 +144,10 @@ as well as by [Guillaume Gomez].) [CommonMark forum]: https://talk.commonmark.org/t/what-should-the-rust-community-do-for-linkage/2141 [Guillaume Gomez]: https://github.com/GuillaumeGomez -## Standard-conform Markdown +## Standard-conforming Markdown These additions are valid Markdown, -as defined by the orginal [Markdown syntax definition][md] +as defined by the original [Markdown syntax definition][md] as well as the [CommonMark] project. Especially, Rust paths are valid CommonMark [link destinations], even with the suffixes described [below][path-ambiguities]. @@ -191,7 +191,7 @@ to avoid confusion, the RFC does not propose adding any support for autolinks. [absolute URI]: http://spec.commonmark.org/0.27/#absolute-uri -This means that this will not render a valid link: +This means that this **will not** render a valid link: ``` Does not work: :( @@ -255,7 +255,7 @@ macro_rules! FOO { () => () } ``` To be able to link to each item, -we'll need a way to disabiguate the namespaces. +we'll need a way to disambiguate the namespaces. Our proposal is this: - Links to types are written as described earlier, @@ -273,12 +273,14 @@ Our proposal is this: e.g., `See [static FOO]`. ## Errors +[errors]: #errors Ideally, Rustdoc would be able to recognize Rust path syntax, and if the path cannot be resolved, print a warning (or an error). ## Complex example +[complex-example]: #complex-example (Excerpt from Diesel's [`expression`][diesel-expression] module.) @@ -349,7 +351,7 @@ To link to associated items, i.e., the associated functions, types, and constants of a trait, it may be necessary to use fully-qualified paths, like `See the [::bar()] method`. -We have yet to analyse in which cases this is necessary, +We have yet to analyze in which cases this is necessary, and this syntax is currently not described in [the reference's section on paths][ref-paths]. ## Linking to external documentation @@ -367,7 +369,7 @@ We propose to generalize this approach by adding parameters to rustdoc that allow overwriting the base URLs it used for external crate links. -(These paramters will at first +(These parameters will at first be supplied as CLI flags but could also be given via a config file, environment variables, From 78eb62d5cbd1276d826d0317540d3b89a522308a Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Sun, 28 May 2017 12:08:12 +0200 Subject: [PATCH 09/16] Add Linking to fields and variants --- text/0000-intra-rustdoc-links.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index b50949fb223..7c47c72d2f1 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -345,6 +345,29 @@ Please note: # Possible Extensions [possible-extensions]: #possible-extensions +## Linking to fields and variants + +To link to the fields of a `struct` +we propose to write the path to the struct, +followed by a dot, followed by the field name. + +For example: + +```markdown +This is stored in the [`size`](storage::Filesystem.size) field. +``` + +To link to the variants of an `enum`, +we propose to write the path to the enum, +followed by two colons, followed by the field name, +just like `use Foo::Bar` can be used to import the `Bar` variant of an `enum Foo`. + +For example: + +```markdown +For custom settings, supply the [`Custom`](storage::Engine::Other) field. +``` + ## Linking to associated items To link to associated items, From 4e2288348ed07669309c13c801da1c6a689cff83 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 12 Jun 2017 14:55:22 +0200 Subject: [PATCH 10/16] Style fixes --- text/0000-intra-rustdoc-links.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 7c47c72d2f1..fa578c7ca7b 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -57,7 +57,7 @@ we propose extending Rustdoc to be able to generate relative links that work in all contexts. -# Detailed design +# Detailed Design [design]: #detailed-design [Markdown][md]/[CommonMark] allow writing links in several forms @@ -93,7 +93,7 @@ to allow easy linking to obvious targets. [ref-paths]: https://github.com/rust-lang-nursery/reference/blob/2d23ea601f017c106a2303094ee1c57ba856d246/src/paths.md -## Additions to the documentation syntax +## Additions To The Documentation Syntax Rust paths as URLs in inline and reference links: @@ -154,7 +154,7 @@ even with the suffixes described [below][path-ambiguities]. [link destinations]: http://spec.commonmark.org/0.27/#link-destination -## How links will be rendered +## How Links Will Be Rendered The following: @@ -193,13 +193,13 @@ to avoid confusion, the RFC does not propose adding any support for autolinks. This means that this **will not** render a valid link: -``` +```markdown Does not work: :( ``` We suggest to use [Implied Shortcut Reference Links][isrl] instead: -``` +```markdown Does work: [`bars::Bar`] :) ``` @@ -209,7 +209,7 @@ which will be rendered as Does work: bars::Bar :) ``` -## Resolving paths +## Resolving Paths The Rust paths used in links are resolved relative to the item in whose documentation they appear. @@ -234,7 +234,7 @@ mod amet { } ``` -## Path ambiguities +## Path Ambiguities [path-ambiguities]: #path-ambiguities Rust has three different namespaces that items can be in, @@ -279,7 +279,7 @@ Ideally, Rustdoc would be able to recognize Rust path syntax, and if the path cannot be resolved, print a warning (or an error). -## Complex example +## Complex Example [complex-example]: #complex-example (Excerpt from Diesel's [`expression`][diesel-expression] module.) @@ -345,7 +345,7 @@ Please note: # Possible Extensions [possible-extensions]: #possible-extensions -## Linking to fields and variants +## Linking to Fields To link to the fields of a `struct` we propose to write the path to the struct, @@ -357,6 +357,8 @@ For example: This is stored in the [`size`](storage::Filesystem.size) field. ``` +## Linking to Enum Variants + To link to the variants of an `enum`, we propose to write the path to the enum, followed by two colons, followed by the field name, @@ -368,7 +370,7 @@ For example: For custom settings, supply the [`Custom`](storage::Engine::Other) field. ``` -## Linking to associated items +## Linking to associated Items To link to associated items, i.e., the associated functions, types, and constants of a trait, @@ -377,7 +379,7 @@ like `See the [::bar()] method`. We have yet to analyze in which cases this is necessary, and this syntax is currently not described in [the reference's section on paths][ref-paths]. -## Linking to external documentation +## Linking to External Documentation Currently, Rustdoc is able to link to external crates, and renders documentation for all dependencies by default. @@ -416,7 +418,7 @@ for all crates that are from the crates.io repository [docs.rs]: https://docs.rs/ -### Known issues +### Known Issues Automatically linking to external docs has the following known tradeoffs: @@ -453,7 +455,7 @@ Automatically linking to external docs has the following known tradeoffs: [here](https://github.com/rust-lang/rfcs/pull/1946#issuecomment-284718018). -# Unresolved questions +# Unresolved Questions [unresolved]: #unresolved-questions - Is it possible for Rustdoc to resolve paths? From 3841e436328a38f1470408ce023e6d46dd93dc2e Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 12 Jun 2017 16:45:51 +0200 Subject: [PATCH 11/16] Reword UFCS section --- text/0000-intra-rustdoc-links.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index fa578c7ca7b..ef49bf6dc5b 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -374,10 +374,15 @@ For custom settings, supply the [`Custom`](storage::Engine::Other) field. To link to associated items, i.e., the associated functions, types, and constants of a trait, -it may be necessary to use fully-qualified paths, +we propose to write the path to the trait, +followed by two colons, followed by the associated item's name. +It may be necessary to use fully-qualified paths +(cf. [the reference's section on disambiguating function calls][ref-ufcs]), like `See the [::bar()] method`. We have yet to analyze in which cases this is necessary, -and this syntax is currently not described in [the reference's section on paths][ref-paths]. +and what syntax should be used. + +[ref-ufcs]: https://github.com/rust-lang-nursery/reference/blob/96e976d32a0a6927dd26c2ee805aaf44ef3bef2d/src/expressions.md#disambiguating-function-calls ## Linking to External Documentation From f7509c2d44ffc10172d408dacfb0845a37090583 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 12 Jun 2017 17:03:34 +0200 Subject: [PATCH 12/16] Expand section on namespace disambiguation --- text/0000-intra-rustdoc-links.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index ef49bf6dc5b..e633a069b95 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -261,17 +261,36 @@ Our proposal is this: - Links to types are written as described earlier, with no pre- or suffix, e.g., `Look at the [FOO] trait`. + For consistency, + it is also possible to prefix the type with the concrete item type: + - Links to `struct`s can be prefixed with `struct `, + e.g., `See [struct Foo]`. + - Links to `enum`s can be prefixed with `enum `, + e.g., `See [enum foo]`. + - Links to type aliases can be prefixed with `type `, + e.g., `See [type foo]`. + - Links to modules can be prefixed with `mod `, + e.g., `See [mod foo]`. - In links to macros, the link label must end with a `!`, e.g., `Look at the [FOO!] macro`. -- For values, we differentiate three cases: +- For links to values, we differentiate three cases: - Links to functions are written with a `()` suffix, - e.g., `Also see the [FOO()] function`. + e.g., `Also see the [foo()] function`. - Links to constants are prefixed with `const `, e.g., `As defined in [const FOO].` - Links to statics are prefixed with `static `, e.g., `See [static FOO]`. +It should be noted that in the RFC discussion it was determined +that exact knowledge of the item type +should not be necessary; only knowing the namespace should suffice. +Thus, we do not require the tool resolving the links +to reject links with the wrong prefix that is in the same namespace. +E.g., given an `struct Foo`, it may be possible to link to it using `[enum Foo]`, +or, given a `mod bar`, it may be possible to link to that using `[struct bar]`. + + ## Errors [errors]: #errors From 591b663710cbcdf82abe52e6fe5c3814969188db Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 19 Jun 2017 21:41:44 +0200 Subject: [PATCH 13/16] Be a bit more specific --- text/0000-intra-rustdoc-links.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index e633a069b95..70d5e862374 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -197,6 +197,12 @@ This means that this **will not** render a valid link: Does not work: :( ``` +It will just output what any CommonMark compliant renderer would generate: + +```html +Does not work: bars::Bar :( +``` + We suggest to use [Implied Shortcut Reference Links][isrl] instead: ```markdown @@ -297,6 +303,9 @@ or, given a `mod bar`, it may be possible to link to that using `[struct bar]`. Ideally, Rustdoc would be able to recognize Rust path syntax, and if the path cannot be resolved, print a warning (or an error). +These diagnostic messages should highlight the specific link +that Rustdoc was not able to resolve, +using the original Markdown source from the comment and correct line numbers. ## Complex Example [complex-example]: #complex-example From 8397992ab6d4e687174f908db73c3da738b80581 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 19 Jun 2017 21:42:08 +0200 Subject: [PATCH 14/16] Add resolution edge case example --- text/0000-intra-rustdoc-links.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 70d5e862374..bc0d5a31af1 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -219,8 +219,11 @@ Does work: bars::Bar :) The Rust paths used in links are resolved relative to the item in whose documentation they appear. +Specifically, when using inner doc comments (`//!`, `/*!`), +the paths are resolved from the inside of the item, +while regular doc comments (`///`, `/**`) start from the "parent scope. -For example: +Here's an example: ```rust /// Container for a [Dolor](ipsum::Dolor). @@ -229,10 +232,10 @@ struct Lorem(ipsum::Dolor); /// Contains various things, mostly [Dolor](ipsum::Dolor) and a helper function, /// [sit](ipsum::sit). mod ipsum { - struct Dolor; + pub struct Dolor; /// Takes a [Dolor] and does things. - fn sit(d: Dolor) {} + pub fn sit(d: Dolor) {} } mod amet { @@ -240,6 +243,23 @@ mod amet { } ``` +And here's an edge case: + +```rust +use foo::Iterator; + +/// Uses `[Iterator]`. <- This resolves to `foo::Iterator` because it starts +/// at the same scope as `foo1`. +fn foo1() { } + +fn foo2() { + //! Uses `[Iterator]`. <- This resolves to `bar::Iterator` because it starts + //! with the inner scope of `foo2`'s body. + + use bar::Iterator; +} +``` + ## Path Ambiguities [path-ambiguities]: #path-ambiguities From 2622c1dc56ad5b589c5bfdab0f40dfd17775645b Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 19 Jun 2017 21:44:14 +0200 Subject: [PATCH 15/16] Give tools permission to be lenient --- text/0000-intra-rustdoc-links.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index bc0d5a31af1..3ebea31e248 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -311,8 +311,9 @@ Our proposal is this: It should be noted that in the RFC discussion it was determined that exact knowledge of the item type should not be necessary; only knowing the namespace should suffice. -Thus, we do not require the tool resolving the links -to reject links with the wrong prefix that is in the same namespace. +It is acceptable that the tool resolving the links +allows (and successfully resolves) a link +with the wrong prefix that is in the same namespace. E.g., given an `struct Foo`, it may be possible to link to it using `[enum Foo]`, or, given a `mod bar`, it may be possible to link to that using `[struct bar]`. From 6af994db3d05a550d318dc1fa6b39db539167726 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Tue, 20 Jun 2017 13:07:24 +0200 Subject: [PATCH 16/16] Remove a stray quotation mark --- text/0000-intra-rustdoc-links.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-intra-rustdoc-links.md b/text/0000-intra-rustdoc-links.md index 3ebea31e248..41fda317bfc 100644 --- a/text/0000-intra-rustdoc-links.md +++ b/text/0000-intra-rustdoc-links.md @@ -221,7 +221,7 @@ The Rust paths used in links are resolved relative to the item in whose documentation they appear. Specifically, when using inner doc comments (`//!`, `/*!`), the paths are resolved from the inside of the item, -while regular doc comments (`///`, `/**`) start from the "parent scope. +while regular doc comments (`///`, `/**`) start from the parent scope. Here's an example: