Skip to content

RFC: rustdoc meta tags #1713

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

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions text/0000-rustdoc-meta-tags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
- Feature Name: rustdoc\_meta\_tags
- Start Date: 2016-08-11
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

# Summary
[summary]: #summary

This RFC proposes to add a notion of "meta tags" to Rust documentation conventions and to the rustdoc tool.
Meta tags are lines in an item's doc comments that begin with a special tag to denote documentation for a particular aspect of the item, such as its parameters, return values, or possible errors.
Meta tags will allow information to be displayed differently by rustdoc depending on what aspect of an item the information pertains to.
The proposal here is to come to agreement on the use of this format as officially recommended, with plans for rustdoc to recognize and visually distinguish six initial meta tags:

* `@param`, for function parameters
* `@return`, for return values
* `@error`, for error conditions
* `@panic`, for panic conditions
* `@safety`, for invariants the caller must uphold for safety
* `@example`, for code examples

# Motivation
[motivation]: #motivation

Items in Rust programs can be documented using doc comments (lines prefixed with /// above the item).
Certain items, such as structs and enums, can also have their fields/variants individually documented with the same syntax.
When rustdoc is used to generate HTML documentation from source code, struct fields and enum variants are enumerated in their own section, which is easy to read and provides a helpful reference.
However, there are other aspects of items that the developer may wish to call out specifically, to provide similar visual distinction in generated HTML documentation, and there is no mechanism for doing so.
Instead, the developer must use a freeform style.

The Rust book suggests some common topics (indicated by a Markdown heading) for this freeform documentation, which it calls "special sections," such as panics, errors, safety, and examples.
However, there is nothing inherent to rustdoc that provides any semantics for these sections.
They are merely a guideline suggested by the book.
In particular, using these special sections does not result in any special visual distinction in generated HTML documentation.
The lack of ability to associate parts of an item's documentation with metadata means it is harder to build consensus around the style of Rust documentation.
Some may follow the guidelines in the book and some may follow their own conventions.

Meta tags provide the necessary hook for pieces of documentation to associate with particular aspects of the item.
Since meta tags themselves are just text within the documentation comments, developers can begin using them right away whether or not the tags they use provide any sort of visual distinction in HTML documentation generated by rustdoc.
Over time, and by separate proposal, additional meta tags may be recognized by rustdoc.

The six meta tags proposed in this RFC codify the "special sections" in the Rust book's documentation chapter as well as adding an official way to document method parameters and return values.
This proposal does not include how this information should be visually distinguished by rustdoc's generated HTML.
("Visually" is also intended to include any semantic markup necessary to distinguish these for people using assistive devices.)

# Detailed design
[design]: #detailed-design

Meta tags are lines in a documentation comment that begin with the @ symbol followed by a tag name (using the same grammar as Rust identifiers), one or more spaces, and then freeform documentation to serve as the value for that tag.
Meta tags must come at the end of any general freeform documentation for the item.
(Freeform documentation after any meta tags will be interpreted as part of the value for the last tag.)
The value of an individual meta tag is terminated either when the entire doc comment ends or another meta tag begins on a subsequent line.
If the developer wants to start a line with a literal `@whatever` and not have it interpreted as a meta tag by rustdoc, they can prefix the @ symbol with a backslash.
Leading whitespace is ignored on both initial and subsequent lines of meta tags.
This allows subsequent lines to be indented for better readability.

Certain meta tags may have parameters that provide further metadata about the tag.
In this proposal, only the `@param` meta tag has a parameter, which is the name of the function parameter it documents.
Meta tag parameters use syntax similar to Rust attributes, with a parenthesized, comma-separated list of names.
Like meta tag names themselves, the parameters to meta tags must be valid Rust identifiers.

In general, meta tags should be applicable to any type of item.
However, the meta tags introduced in this proposal only make sense for functions.
It is possible that future meta tags could be applicable to multiple types of items.
In other words, meta tags are not inherently bound to one item type.
See [unresolved questions](#unresolved-questions) for more on this.

In terms of rustdoc's behavior concerning documentation containing meta tags, it should provide a generic form of visual distinction for meta tags it doesn't know.
If it encounters a meta tag it knows but that is missing a required parameter or that parameter is somehow invalid, a warning should be emitted during generation and the tag should be treated as generic and unknown.
The goal here is that using meta tags adds additional benefit if present, but doesn't restrict the user from writing whatever they want in their documentation comments.
The meta tags and their values should be removed from the freeform documentation for the item in the generated HTML.

The idea for meta tags is borrowed from the long history of similar features in other languages or tools for other languages like Java, Ruby, and Python.
It is inspired in particular by [YARD](http://yardoc.org/) from the Ruby ecosystem.

## Examples

These examples are intended to show only what documentation with meta tags looks like.
The code examples are very trivial, so assume the meanings of the items is less obvious and that documentation is more useful.

``` rust
/// A human user of the application.
struct Person {
/// The person's name.
name: String,
/// The person's gender.
gender: Gender
/// The person's age.
age: u8,
}

impl Person {
/// Creates a new person.
///
/// @param(name) The person's name.
/// @param(gender) The person's gender.
/// @param(age) The person's age.
/// @return The new person or an error message.
/// @error If the person's age is above 150, as a very simple check for a
/// realistic age.
/// @example Creating a new person:
/// ```
/// assert!(Person::new("Jimmy".to_string(), Gender::Male, 34).is_ok());
/// ```
/// @example Failing to create a person because the age is too high:
/// ```
/// assert_eq!(
/// Person::new("Jimmy".to_string(), Gender::Male, 200).err().unwrap(),
/// "Age cannot be above 150"
/// );
/// ```
pub fn new(name: String, gender: Gender, age: u8)
-> Result<Person, &'static str> {
// ...
}
}
```

# Drawbacks
[drawbacks]: #drawbacks

* Introduces data within documentation comments, which so far have only been freeform text.
* Introduces additionally complexity to rustdoc.
* The textual form of documentation with meta tags might be considered verbose or hard to read.
* Discussion of this feature may lead to accidentally mentioning people on GitHub. :laughing:

# Alternatives
[alternatives]: #alternatives

The status quo is that there is no official way to provide documentation for Rust code more granular than at the item level, with the exception of struct fields and enum variants.
Instead of this proposal, we could:

* Do nothing.
* Continue to just recommend "special sections" in the Rust book, and perhaps add an official guideline for parameters and return values.
* Introduce the convention of using meta tags without actually changing rustdoc to officially recognize and visually distinguish them.
* Introduce only a subset of the propose meta tags to rustdoc.
* Use an entirely different syntax for meta tags, their parameters, and their values.

# Unresolved questions
[unresolved]: #unresolved-questions

* How should rustdoc behave when one of the six meta tags introduced in this proposal is used on a non-function item?
* How might the future addition of keyword, default, or variadic parameters affect the `@param` meta tag proposed here?