Skip to content

Commit

Permalink
Auto merge of #51854 - davidtwco:rfc-2008-rustdoc, r=QuietMisdreavus
Browse files Browse the repository at this point in the history
RFC 2008 non-exhaustive enums/structs: Rustdoc

Part of #44109. Not sure how those who maintain rustdoc primarily would prefer this addition look or where it should be placed, happy to make any changes required.

r? @QuietMisdreavus (not sure if this is the right person, just guessing)
  • Loading branch information
bors committed Jul 19, 2018
2 parents a8247dd + b671bdc commit 11864c4
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/librustdoc/clean/mod.rs
Expand Up @@ -496,6 +496,11 @@ impl Item {
self.stability.as_ref().map(|s| &s.since[..])
}

pub fn is_non_exhaustive(&self) -> bool {
self.attrs.other_attrs.iter()
.any(|a| a.name().as_str() == "non_exhaustive")
}

/// Returns a documentation-level item type from the item.
pub fn type_(&self) -> ItemType {
ItemType::from(self)
Expand Down
11 changes: 10 additions & 1 deletion src/librustdoc/fold.rs
Expand Up @@ -92,7 +92,16 @@ pub trait DocFolder : Sized {

/// don't override!
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item;
let Item {
attrs,
name,
source,
visibility,
def_id,
inner,
stability,
deprecation,
} = item;

let inner = match inner {
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
Expand Down
42 changes: 39 additions & 3 deletions src/librustdoc/html/render.rs
Expand Up @@ -2276,6 +2276,37 @@ fn document_stability(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item)
Ok(())
}

fn document_non_exhaustive_header(item: &clean::Item) -> &str {
if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" }
}

fn document_non_exhaustive(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
if item.is_non_exhaustive() {
write!(w, "<div class='docblock non-exhaustive non-exhaustive-{}'>", {
if item.is_struct() { "struct" } else if item.is_enum() { "enum" } else { "type" }
})?;

if item.is_struct() {
write!(w, "Non-exhaustive structs could have additional fields added in future. \
Therefore, non-exhaustive structs cannot be constructed in external crates \
using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \
matched against without a wildcard <code>..</code>; and \
struct update syntax will not work.")?;
} else if item.is_enum() {
write!(w, "Non-exhaustive enums could have additional variants added in future. \
Therefore, when matching against variants of non-exhaustive enums, an \
extra wildcard arm must be added to account for any future variants.")?;
} else {
write!(w, "This type will require a wildcard arm in any match statements or \
constructors.")?;
}

write!(w, "</div>")?;
}

Ok(())
}

fn name_key(name: &str) -> (&str, u64, usize) {
// find number at end
let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1);
Expand Down Expand Up @@ -3136,7 +3167,9 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
if let doctree::Plain = s.struct_type {
if fields.peek().is_some() {
write!(w, "<h2 id='fields' class='fields small-section-header'>
Fields<a href='#fields' class='anchor'></a></h2>")?;
Fields{}<a href='#fields' class='anchor'></a></h2>",
document_non_exhaustive_header(it))?;
document_non_exhaustive(w, it)?;
for (field, ty) in fields {
let id = derive_id(format!("{}.{}",
ItemType::StructField,
Expand Down Expand Up @@ -3268,7 +3301,9 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
document(w, cx, it)?;
if !e.variants.is_empty() {
write!(w, "<h2 id='variants' class='variants small-section-header'>
Variants<a href='#variants' class='anchor'></a></h2>\n")?;
Variants{}<a href='#variants' class='anchor'></a></h2>\n",
document_non_exhaustive_header(it))?;
document_non_exhaustive(w, it)?;
for variant in &e.variants {
let id = derive_id(format!("{}.{}",
ItemType::Variant,
Expand Down Expand Up @@ -3369,7 +3404,8 @@ const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
"must_use",
"no_mangle",
"repr",
"unsafe_destructor_blind_to_params"
"unsafe_destructor_blind_to_params",
"non_exhaustive"
];

fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
Expand Down
23 changes: 20 additions & 3 deletions src/librustdoc/html/static/main.js
Expand Up @@ -2001,15 +2001,18 @@
onEach(e.getElementsByClassName('associatedconstant'), func);
});

function createToggle(otherMessage, extraClass) {
function createToggle(otherMessage, fontSize, extraClass) {
var span = document.createElement('span');
span.className = 'toggle-label';
span.style.display = 'none';
if (!otherMessage) {
span.innerHTML = '&nbsp;Expand&nbsp;description';
} else {
span.innerHTML = otherMessage;
span.style.fontSize = '20px';
}

if (fontSize) {
span.style.fontSize = fontSize;
}

var mainToggle = toggle.cloneNode(true);
Expand Down Expand Up @@ -2048,13 +2051,27 @@
}
if (e.parentNode.id === "main") {
var otherMessage;
var fontSize;
var extraClass;

if (hasClass(e, "type-decl")) {
fontSize = "20px";
otherMessage = '&nbsp;Show&nbsp;declaration';
} else if (hasClass(e, "non-exhaustive")) {
otherMessage = '&nbsp;This&nbsp;';
if (hasClass(e, "non-exhaustive-struct")) {
otherMessage += 'struct';
} else if (hasClass(e, "non-exhaustive-enum")) {
otherMessage += 'enum';
} else if (hasClass(e, "non-exhaustive-type")) {
otherMessage += 'type';
}
otherMessage += '&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive';
} else if (hasClass(e.childNodes[0], "impl-items")) {
extraClass = "marg-left";
}
e.parentNode.insertBefore(createToggle(otherMessage, extraClass), e);

e.parentNode.insertBefore(createToggle(otherMessage, fontSize, extraClass), e);
if (otherMessage && getCurrentValue('rustdoc-item-declarations') !== "false") {
collapseDocs(e.previousSibling.childNodes[0], "toggle");
}
Expand Down
6 changes: 5 additions & 1 deletion src/librustdoc/html/static/rustdoc.css
Expand Up @@ -1358,4 +1358,8 @@ kbd {
}
#all-types > p {
margin: 5px 0;
}
}

.non-exhaustive {
margin-bottom: 1em;
}
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/themes/dark.css
Expand Up @@ -406,4 +406,4 @@ kbd {
}
.search-results td span.grey {
color: #ccc;
}
}
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/themes/light.css
Expand Up @@ -400,4 +400,4 @@ kbd {
}
.search-results td span.grey {
color: #999;
}
}

0 comments on commit 11864c4

Please sign in to comment.