Skip to content

Rollup of 4 pull requests #45862

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

Merged
merged 8 commits into from
Nov 8, 2017
2 changes: 1 addition & 1 deletion src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ r##"<!DOCTYPE html>
<dd>Switch tab</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dt style="width:31px;">+ / -</dt>
<dd>Collapse/expand all sections</dd>
</dl>
</div>
Expand Down
170 changes: 139 additions & 31 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2498,7 +2498,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,

if !foreign.is_empty() {
write!(w, "
<h2 id='foreign-impls' class='section-header'>
<h2 id='foreign-impls' class='small-section-header'>
Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a>
</h2>
")?;
Expand Down Expand Up @@ -3591,7 +3591,8 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
let mut links = HashSet::new();
let ret = v.iter()
.filter_map(|i| if let Some(ref i) = i.inner_impl().trait_ {
let out = format!("{:#}", i).replace("<", "&lt;").replace(">", "&gt;");
let i_display = format!("{:#}", i);
let out = Escape(&i_display);
let encoded = small_url_encode(&format!("{:#}", i));
let generated = format!("<a href=\"#impl-{}\">{}</a>", encoded, out);
if !links.contains(&generated) && links.insert(generated.clone()) {
Expand All @@ -3617,11 +3618,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
s: &clean::Struct) -> fmt::Result {
let mut sidebar = String::new();
let fields = get_struct_fields_name(&s.fields);

if s.fields.iter()
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
if !fields.is_empty() {
if let doctree::Plain = s.struct_type {
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
<div class=\"sidebar-links\">{}</div>", fields));
}
}

Expand All @@ -3633,40 +3635,122 @@ fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
Ok(())
}

fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
match item.inner {
clean::ItemEnum::ImplItem(ref i) => {
if let Some(ref trait_) = i.trait_ {
Some((format!("{:#}", i.for_), format!("{:#}", trait_)))
} else {
None
}
},
_ => None,
}
}

fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
t: &clean::Trait) -> fmt::Result {
let mut sidebar = String::new();

let has_types = t.items.iter().any(|m| m.is_associated_type());
let has_consts = t.items.iter().any(|m| m.is_associated_const());
let has_required = t.items.iter().any(|m| m.is_ty_method());
let has_provided = t.items.iter().any(|m| m.is_method());
let types = t.items
.iter()
.filter_map(|m| {
match m.name {
Some(ref name) if m.is_associated_type() => {
Some(format!("<a href=\"#associatedtype.{name}\">{name}</a>",
name=name))
}
_ => None,
}
})
.collect::<String>();
let consts = t.items
.iter()
.filter_map(|m| {
match m.name {
Some(ref name) if m.is_associated_const() => {
Some(format!("<a href=\"#associatedconstant.{name}\">{name}</a>",
name=name))
}
_ => None,
}
})
.collect::<String>();
let required = t.items
.iter()
.filter_map(|m| {
match m.name {
Some(ref name) if m.is_ty_method() => {
Some(format!("<a href=\"#tymethod.{name}\">{name}</a>",
name=name))
}
_ => None,
}
})
.collect::<String>();
let provided = t.items
.iter()
.filter_map(|m| {
match m.name {
Some(ref name) if m.is_method() => {
Some(format!("<a href=\"#method.{name}\">{name}</a>", name=name))
}
_ => None,
}
})
.collect::<String>();

if has_types {
sidebar.push_str("<li><a href=\"#associated-types\">Associated Types</a></li>");
if !types.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-types\">\
Associated Types</a><div class=\"sidebar-links\">{}</div>",
types));
}
if has_consts {
sidebar.push_str("<li><a href=\"#associated-const\">Associated Constants</a></li>");
if !consts.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#associated-const\">\
Associated Constants</a><div class=\"sidebar-links\">{}</div>",
consts));
}
if has_required {
sidebar.push_str("<li><a href=\"#required-methods\">Required Methods</a></li>");
if !required.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#required-methods\">\
Required Methods</a><div class=\"sidebar-links\">{}</div>",
required));
}
if has_provided {
sidebar.push_str("<li><a href=\"#provided-methods\">Provided Methods</a></li>");
if !provided.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#provided-methods\">\
Provided Methods</a><div class=\"sidebar-links\">{}</div>",
provided));
}

let c = cache();

if let Some(implementors) = c.implementors.get(&it.def_id) {
if implementors.iter().any(|i| i.impl_.for_.def_id()
.map_or(false, |d| !c.paths.contains_key(&d)))
{
sidebar.push_str("<li><a href=\"#foreign-impls\">\
Implementations on Foreign Types</a></li>");
}
}

sidebar.push_str("<li><a href=\"#implementors\">Implementors</a></li>");
let res = implementors.iter()
.filter(|i| i.impl_.for_.def_id()
.map_or(false, |d| !c.paths.contains_key(&d)))
.filter_map(|i| {
if let Some(item) = implementor2item(&c, i) {
match extract_for_impl_name(&item) {
Some((ref name, ref url)) => {
Some(format!("<a href=\"#impl-{}\">{}</a>",
small_url_encode(url),
Escape(name)))
}
_ => None,
}
} else {
None
}
})
.collect::<String>();
if !res.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#foreign-impls\">\
Implementations on Foreign Types</a><div \
class=\"sidebar-links\">{}</div>",
res));
}
}

sidebar.push_str("<a class=\"sidebar-title\" href=\"#implementors\">Implementors</a>");

sidebar.push_str(&sidebar_assoc_items(it));

Expand All @@ -3693,13 +3777,29 @@ fn sidebar_typedef(fmt: &mut fmt::Formatter, it: &clean::Item,
Ok(())
}

fn get_struct_fields_name(fields: &[clean::Item]) -> String {
fields.iter()
.filter(|f| if let clean::StructFieldItem(..) = f.inner {
true
} else {
false
})
.filter_map(|f| match f.name {
Some(ref name) => Some(format!("<a href=\"#structfield.{name}\">\
{name}</a>", name=name)),
_ => None,
})
.collect()
}

fn sidebar_union(fmt: &mut fmt::Formatter, it: &clean::Item,
u: &clean::Union) -> fmt::Result {
let mut sidebar = String::new();
let fields = get_struct_fields_name(&u.fields);

if u.fields.iter()
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
if !fields.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\
<div class=\"sidebar-links\">{}</div>", fields));
}

sidebar.push_str(&sidebar_assoc_items(it));
Expand All @@ -3714,8 +3814,16 @@ fn sidebar_enum(fmt: &mut fmt::Formatter, it: &clean::Item,
e: &clean::Enum) -> fmt::Result {
let mut sidebar = String::new();

if !e.variants.is_empty() {
sidebar.push_str("<li><a href=\"#variants\">Variants</a></li>");
let variants = e.variants.iter()
.filter_map(|v| match v.name {
Some(ref name) => Some(format!("<a href=\"#variant.{name}\">{name}\
</a>", name = name)),
_ => None,
})
.collect::<String>();
if !variants.is_empty() {
sidebar.push_str(&format!("<a class=\"sidebar-title\" href=\"#variants\">Variants</a>\
<div class=\"sidebar-links\">{}</div>", variants));
}

sidebar.push_str(&sidebar_assoc_items(it));
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
break;

case "+":
case "-":
ev.preventDefault();
toggleAllDocs();
break;
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/html/static/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -582,13 +582,14 @@ body.blur > :not(#help) {
display: block;
margin-top: -1px;
}
#help dd { margin: 5px 33px; }
#help dd { margin: 5px 35px; }
#help .infos { padding-left: 0; }
#help h1, #help h2 { margin-top: 0; }
#help > div div {
width: 50%;
float: left;
padding: 20px;
padding-left: 17px;
}

.stab {
Expand Down
4 changes: 4 additions & 0 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ pub struct ArgsOs { inner: sys::args::Args }
/// set to arbitrary text, and may not even exist. This means this property should
/// not be relied upon for security purposes.
///
/// On Unix systems shell usually expands unquoted arguments with glob patterns
/// (such as `*` and `?`). On Windows this is not done, and such arguments are
/// passed as-is.
///
/// # Panics
///
/// The returned iterator will panic during iteration if any argument to the
Expand Down
74 changes: 70 additions & 4 deletions src/libstd/sys/unix/ext/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use sys;
use sys_common::{FromInner, AsInner, AsInnerMut};
use sys::platform::fs::MetadataExt as UnixMetadataExt;

/// Unix-specific extensions to `File`
/// Unix-specific extensions to [`File`].
///
/// [`File`]: ../../../../std/fs/struct.File.html
#[stable(feature = "file_offset", since = "1.15.0")]
pub trait FileExt {
/// Reads a number of bytes starting from a given offset.
Expand Down Expand Up @@ -515,19 +517,79 @@ impl MetadataExt for fs::Metadata {
fn blocks(&self) -> u64 { self.st_blocks() }
}

/// Add special unix types (block/char device, fifo and socket)
/// Add support for special unix types (block/char device, fifo and socket).
#[stable(feature = "file_type_ext", since = "1.5.0")]
pub trait FileTypeExt {
/// Returns whether this file type is a block device.
///
/// # Examples
///
/// ```
/// use std::fs;
/// use std::os::unix::fs::FileTypeExt;
///
/// # use std::io;
/// # fn f() -> io::Result<()> {
/// let meta = fs::metadata("block_device_file")?;
/// let file_type = meta.file_type();
/// assert!(file_type.is_block_device());
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_type_ext", since = "1.5.0")]
fn is_block_device(&self) -> bool;
/// Returns whether this file type is a char device.
///
/// # Examples
///
/// ```
/// use std::fs;
/// use std::os::unix::fs::FileTypeExt;
///
/// # use std::io;
/// # fn f() -> io::Result<()> {
/// let meta = fs::metadata("char_device_file")?;
/// let file_type = meta.file_type();
/// assert!(file_type.is_char_device());
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_type_ext", since = "1.5.0")]
fn is_char_device(&self) -> bool;
/// Returns whether this file type is a fifo.
///
/// # Examples
///
/// ```
/// use std::fs;
/// use std::os::unix::fs::FileTypeExt;
///
/// # use std::io;
/// # fn f() -> io::Result<()> {
/// let meta = fs::metadata("fifo_file")?;
/// let file_type = meta.file_type();
/// assert!(file_type.is_fifo());
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_type_ext", since = "1.5.0")]
fn is_fifo(&self) -> bool;
/// Returns whether this file type is a socket.
///
/// # Examples
///
/// ```
/// use std::fs;
/// use std::os::unix::fs::FileTypeExt;
///
/// # use std::io;
/// # fn f() -> io::Result<()> {
/// let meta = fs::metadata("unix.socket")?;
/// let file_type = meta.file_type();
/// assert!(file_type.is_socket());
/// # Ok(())
/// # }
/// ```
#[stable(feature = "file_type_ext", since = "1.5.0")]
fn is_socket(&self) -> bool;
}
Expand All @@ -540,7 +602,9 @@ impl FileTypeExt for fs::FileType {
fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
}

/// Unix-specific extension methods for `fs::DirEntry`
/// Unix-specific extension methods for [`fs::DirEntry`].
///
/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub trait DirEntryExt {
/// Returns the underlying `d_ino` field in the contained `dirent`
Expand Down Expand Up @@ -600,7 +664,9 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
}

#[stable(feature = "dir_builder", since = "1.6.0")]
/// An extension trait for `fs::DirBuilder` for unix-specific options.
/// An extension trait for [`fs::DirBuilder`] for unix-specific options.
///
/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
pub trait DirBuilderExt {
/// Sets the mode to create new directories with. This option defaults to
/// 0o777.
Expand Down
Loading