")?;
@@ -3963,7 +3979,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
clean::TypedefItem(ref tydef, _) => {
let id = cx.derive_id(format!("{}.{}", ItemType::AssociatedType, name));
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
- write!(w, "", id, item_type)?;
+ write!(w, "", id, item_type, extra_class)?;
write!(w, "", ns_id)?;
assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
write!(w, " \n")?;
@@ -3971,7 +3987,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
clean::AssociatedConstItem(ref ty, ref default) => {
let id = cx.derive_id(format!("{}.{}", item_type, name));
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
- write!(w, "", id, item_type)?;
+ write!(w, "", id, item_type, extra_class)?;
write!(w, "", ns_id)?;
assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
let src = if let Some(l) = (Item { cx, item }).src_href() {
@@ -3985,7 +4001,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
clean::AssociatedTypeItem(ref bounds, ref default) => {
let id = cx.derive_id(format!("{}.{}", item_type, name));
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
- write!(w, "", id, item_type)?;
+ write!(w, "", id, item_type, extra_class)?;
write!(w, "", ns_id)?;
assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
write!(w, " \n")?;
@@ -4002,25 +4018,25 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
// We need the stability of the item from the trait
// because impls can't have a stability.
- document_stability(w, cx, it)?;
+ document_stability(w, cx, it, is_hidden)?;
if item.doc_value().is_some() {
- document_full(w, item, cx, "")?;
+ document_full(w, item, cx, "", is_hidden)?;
} else if show_def_docs {
// In case the item isn't documented,
// provide short documentation from the trait.
- document_short(w, cx, it, link, "")?;
+ document_short(w, cx, it, link, "", is_hidden)?;
}
}
} else {
- document_stability(w, cx, item)?;
+ document_stability(w, cx, item, is_hidden)?;
if show_def_docs {
- document_full(w, item, cx, "")?;
+ document_full(w, item, cx, "", is_hidden)?;
}
}
} else {
- document_stability(w, cx, item)?;
+ document_stability(w, cx, item, is_hidden)?;
if show_def_docs {
- document_short(w, cx, item, link, "")?;
+ document_short(w, cx, item, link, "", is_hidden)?;
}
}
}
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index b31100716397b..4425712eed7a1 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2052,6 +2052,50 @@
onEach(document.getElementsByClassName('method'), func);
onEach(document.getElementsByClassName('associatedconstant'), func);
onEach(document.getElementsByClassName('impl'), func);
+ onEach(document.getElementsByClassName('impl-items'), function(e) {
+ onEach(e.getElementsByClassName('associatedconstant'), func);
+ var hiddenElems = e.getElementsByClassName('hidden');
+ var needToggle = false;
+
+ for (var i = 0; i < hiddenElems.length; ++i) {
+ if (hasClass(hiddenElems[i], "content") === false &&
+ hasClass(hiddenElems[i], "docblock") === false) {
+ needToggle = true;
+ break;
+ }
+ }
+ if (needToggle === true) {
+ var newToggle = document.createElement('a');
+ newToggle.href = 'javascript:void(0)';
+ newToggle.className = 'collapse-toggle hidden-default collapsed';
+ newToggle.innerHTML = "[" + labelForToggleButton(true) + "" +
+ "] Show hidden undocumented items";
+ newToggle.onclick = function() {
+ if (hasClass(this, "collapsed")) {
+ removeClass(this, "collapsed");
+ onEach(this.parentNode.getElementsByClassName("hidden"), function(x) {
+ if (hasClass(x, "content") === false) {
+ removeClass(x, "hidden");
+ addClass(x, "x");
+ }
+ }, true);
+ this.innerHTML = "[" + labelForToggleButton(false) +
+ "] Hide undocumented items"
+ } else {
+ addClass(this, "collapsed");
+ onEach(this.parentNode.getElementsByClassName("x"), function(x) {
+ if (hasClass(x, "content") === false) {
+ addClass(x, "hidden");
+ removeClass(x, "x");
+ }
+ }, true);
+ this.innerHTML = "[" + labelForToggleButton(true) +
+ "] Show hidden undocumented items";
+ }
+ };
+ e.insertBefore(newToggle, e.firstChild);
+ }
+ });
function createToggle(otherMessage, fontSize, extraClass, show) {
var span = document.createElement('span');
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index ad6cdfd3e733b..8f679b4d22b25 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -479,17 +479,6 @@ h4 > code, h3 > code, .invisible > code {
margin-bottom: 15px;
}
-.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
- margin-left: 20px;
-}
-.content .impl-items .docblock, .content .impl-items .stability {
- margin-bottom: .6em;
-}
-
-.content .impl-items > .stability {
- margin-left: 40px;
-}
-
.content .docblock > .impl-items {
margin-left: 20px;
margin-top: -34px;
@@ -531,7 +520,20 @@ h4 > code, h3 > code, .invisible > code {
top: -9px;
left: -13px;
}
-.methods > .stability {
+
+.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
+ margin-left: 20px;
+}
+
+.content .impl-items .docblock, .content .impl-items .stability {
+ margin-bottom: .6em;
+}
+
+.content .impl-items > .stability {
+ margin-left: 40px;
+}
+
+.methods > .stability, .content .impl-items > .stability {
margin-top: -8px;
}
@@ -839,6 +841,11 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
text-align: center;
}
+.collapse-toggle.hidden-default {
+ position: relative;
+ margin-left: 20px;
+}
+
.ghost {
display: none;
}
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index e10e330402f5e..5f7a8c75d3c5f 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -15,11 +15,19 @@ var mainTheme = document.getElementById("mainThemeStyle");
var savedHref = [];
-function onEach(arr, func) {
+function onEach(arr, func, reversed) {
if (arr && arr.length > 0 && func) {
- for (var i = 0; i < arr.length; i++) {
- if (func(arr[i]) === true) {
- return true;
+ if (reversed !== true) {
+ for (var i = 0; i < arr.length; ++i) {
+ if (func(arr[i]) === true) {
+ return true;
+ }
+ }
+ } else {
+ for (var i = arr.length - 1; i >= 0; --i) {
+ if (func(arr[i]) === true) {
+ return true;
+ }
}
}
}
diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index cbb2a00214a5a..9ace871491824 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -75,8 +75,8 @@ pub trait Qux {
/// Docs for QUX1 in trait.
const QUX1: i8;
// @has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16'
- // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT0 in trait."
- /// Docs for QUX_DEFAULT0 in trait.
+ // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT12 in trait."
+ /// Docs for QUX_DEFAULT12 in trait.
const QUX_DEFAULT0: u16 = 1;
// @has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16'
// @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in trait."
@@ -99,7 +99,7 @@ impl Qux for Bar {
/// Docs for QUX1 in impl.
const QUX1: i8 = 5;
// @has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16'
- // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT0 in trait."
+ // @has - '//*[@class="docblock hidden"]' "Docs for QUX_DEFAULT12 in trait."
const QUX_DEFAULT0: u16 = 6;
// @has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16'
// @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in impl."
diff --git a/src/test/rustdoc/auxiliary/enum_primitive.rs b/src/test/rustdoc/auxiliary/enum_primitive.rs
new file mode 100644
index 0000000000000..c265ae44f0dc0
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/enum_primitive.rs
@@ -0,0 +1,210 @@
+// Copyright (c) 2015 Anders Kaseorg
+
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// βSoftwareβ), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED βAS ISβ, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+//! This crate exports a macro `enum_from_primitive!` that wraps an
+//! `enum` declaration and automatically adds an implementation of
+//! `num::FromPrimitive` (reexported here), to allow conversion from
+//! primitive integers to the enum. It therefore provides an
+//! alternative to the built-in `#[derive(FromPrimitive)]`, which
+//! requires the unstable `std::num::FromPrimitive` and is disabled in
+//! Rust 1.0.
+//!
+//! # Example
+//!
+//! ```
+//! #[macro_use] extern crate enum_primitive;
+//! extern crate num_traits;
+//! use num_traits::FromPrimitive;
+//!
+//! enum_from_primitive! {
+//! #[derive(Debug, PartialEq)]
+//! enum FooBar {
+//! Foo = 17,
+//! Bar = 42,
+//! Baz,
+//! }
+//! }
+//!
+//! fn main() {
+//! assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
+//! assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
+//! assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz));
+//! assert_eq!(FooBar::from_i32(91), None);
+//! }
+//! ```
+
+
+pub mod num_traits {
+ pub trait FromPrimitive: Sized {
+ fn from_i64(n: i64) -> Option;
+ fn from_u64(n: u64) -> Option;
+ }
+}
+
+pub use std::option::Option;
+pub use num_traits::FromPrimitive;
+
+/// Helper macro for internal use by `enum_from_primitive!`.
+#[macro_export]
+macro_rules! enum_from_primitive_impl_ty {
+ ($meth:ident, $ty:ty, $name:ident, $( $variant:ident )*) => {
+ #[allow(non_upper_case_globals, unused)]
+ fn $meth(n: $ty) -> $crate::Option {
+ $( if n == $name::$variant as $ty {
+ $crate::Option::Some($name::$variant)
+ } else )* {
+ $crate::Option::None
+ }
+ }
+ };
+}
+
+/// Helper macro for internal use by `enum_from_primitive!`.
+#[macro_export]
+#[macro_use(enum_from_primitive_impl_ty)]
+macro_rules! enum_from_primitive_impl {
+ ($name:ident, $( $variant:ident )*) => {
+ impl $crate::FromPrimitive for $name {
+ enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant )* }
+ enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant )* }
+ }
+ };
+}
+
+/// Wrap this macro around an `enum` declaration to get an
+/// automatically generated implementation of `num::FromPrimitive`.
+#[macro_export]
+#[macro_use(enum_from_primitive_impl)]
+macro_rules! enum_from_primitive {
+ (
+ $( #[$enum_attr:meta] )*
+ enum $name:ident {
+ $( $( #[$variant_attr:meta] )* $variant:ident ),+
+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ enum $name {
+ $( $( #[$variant_attr] )* $variant ),+
+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
+ }
+ enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ enum $name:ident {
+ $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ enum $name {
+ $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
+ }
+ enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ enum $name:ident {
+ $( $( #[$variant_attr:meta] )* $variant:ident ),+
+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ enum $name {
+ $( $( #[$variant_attr] )* $variant ),+
+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
+ }
+ enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ enum $name:ident {
+ $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ enum $name {
+ $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
+ }
+ enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ pub enum $name:ident {
+ $( $( #[$variant_attr:meta] )* $variant:ident ),+
+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ pub enum $name {
+ $( $( #[$variant_attr] )* $variant ),+
+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
+ }
+ enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ pub enum $name:ident {
+ $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ pub enum $name {
+ $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
+ }
+ enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ pub enum $name:ident {
+ $( $( #[$variant_attr:meta] )* $variant:ident ),+
+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ pub enum $name {
+ $( $( #[$variant_attr] )* $variant ),+
+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
+ }
+ enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+ };
+
+ (
+ $( #[$enum_attr:meta] )*
+ pub enum $name:ident {
+ $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
+ }
+ ) => {
+ $( #[$enum_attr] )*
+ pub enum $name {
+ $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
+ }
+ enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
+ };
+}
+
diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs
index db48a6525230c..949ef11828897 100644
--- a/src/test/rustdoc/manual_impl.rs
+++ b/src/test/rustdoc/manual_impl.rs
@@ -73,7 +73,7 @@ impl T for S2 {
// @has manual_impl/struct.S3.html '//*[@class="trait"]' 'T'
// @has - '//*[@class="docblock"]' 'Docs associated with the S3 trait implementation.'
// @has - '//*[@class="docblock"]' 'Docs associated with the S3 trait b_method implementation.'
-// @has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
+// @has - '//*[@class="docblock hidden"]' 'Docs associated with the trait a_method definition.'
pub struct S3(usize);
/// Docs associated with the S3 trait implementation.
diff --git a/src/test/rustdoc/no-stack-overflow-25295.rs b/src/test/rustdoc/no-stack-overflow-25295.rs
new file mode 100644
index 0000000000000..37b0aca4b00ca
--- /dev/null
+++ b/src/test/rustdoc/no-stack-overflow-25295.rs
@@ -0,0 +1,46 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ensure this code doesn't stack overflow
+// aux-build:enum_primitive.rs
+
+#[macro_use] extern crate enum_primitive;
+
+enum_from_primitive! {
+ pub enum Test {
+ A1,A2,A3,A4,A5,A6,
+ B1,B2,B3,B4,B5,B6,
+ C1,C2,C3,C4,C5,C6,
+ D1,D2,D3,D4,D5,D6,
+ E1,E2,E3,E4,E5,E6,
+ F1,F2,F3,F4,F5,F6,
+ G1,G2,G3,G4,G5,G6,
+ H1,H2,H3,H4,H5,H6,
+ I1,I2,I3,I4,I5,I6,
+ J1,J2,J3,J4,J5,J6,
+ K1,K2,K3,K4,K5,K6,
+ L1,L2,L3,L4,L5,L6,
+ M1,M2,M3,M4,M5,M6,
+ N1,N2,N3,N4,N5,N6,
+ O1,O2,O3,O4,O5,O6,
+ P1,P2,P3,P4,P5,P6,
+ Q1,Q2,Q3,Q4,Q5,Q6,
+ R1,R2,R3,R4,R5,R6,
+ S1,S2,S3,S4,S5,S6,
+ T1,T2,T3,T4,T5,T6,
+ U1,U2,U3,U4,U5,U6,
+ V1,V2,V3,V4,V5,V6,
+ W1,W2,W3,W4,W5,W6,
+ X1,X2,X3,X4,X5,X6,
+ Y1,Y2,Y3,Y4,Y5,Y6,
+ Z1,Z2,Z3,Z4,Z5,Z6,
+ }
+}
+
diff --git a/src/test/ui/derive-uninhabited-enum-38885.rs b/src/test/ui/derive-uninhabited-enum-38885.rs
new file mode 100644
index 0000000000000..dc7f5d60cd82c
--- /dev/null
+++ b/src/test/ui/derive-uninhabited-enum-38885.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+// compile-flags: -Wunused
+
+// ensure there are no special warnings about uninhabited types
+// when deriving Debug on an empty enum
+
+#[derive(Debug)]
+enum Void {} //~ WARN never used
+
+#[derive(Debug)]
+enum Foo { //~ WARN never used
+ Bar(u8),
+ Void(Void),
+}
+
+fn main() {}
+
diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr
new file mode 100644
index 0000000000000..11032abfa12ae
--- /dev/null
+++ b/src/test/ui/derive-uninhabited-enum-38885.stderr
@@ -0,0 +1,14 @@
+warning: enum is never used: `Void`
+ --> $DIR/derive-uninhabited-enum-38885.rs:18:1
+ |
+LL | enum Void {} //~ WARN never used
+ | ^^^^^^^^^
+ |
+ = note: `-W dead-code` implied by `-W unused`
+
+warning: enum is never used: `Foo`
+ --> $DIR/derive-uninhabited-enum-38885.rs:21:1
+ |
+LL | enum Foo { //~ WARN never used
+ | ^^^^^^^^
+
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index c794e169fca33..4ade87f5d65bd 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -26,7 +26,7 @@
MAINTAINERS = {
'miri': '@oli-obk @RalfJung @eddyb',
'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk',
- 'rls': '@nrc',
+ 'rls': '@nrc @Xanewok',
'rustfmt': '@nrc',
'book': '@carols10cents @steveklabnik',
'nomicon': '@frewsxcv @Gankro',
@@ -81,8 +81,8 @@ def update_latest(
status[os] = new
if new > old:
changed = True
- message += 'π {} on {}: {} β {}.\n' \
- .format(tool, os, old, new)
+ message += 'π {} on {}: {} β {} (cc {}, @rust-lang/infra).\n' \
+ .format(tool, os, old, new, MAINTAINERS.get(tool))
elif new < old:
changed = True
message += 'π {} on {}: {} β {} (cc {}, @rust-lang/infra).\n' \
|