Auto merge of #32454 - eddyb:rollup, r=eddyb

Rollup of 11 pull requests

- Successful merges: #32404, #32420, #32423, #32425, #32429, #32430, #32431, #32434, #32437, #32441, #32443
- Failed merges:
This commit is contained in:
bors 2016-03-23 12:33:04 -07:00
commit 98f0a9128f
19 changed files with 173 additions and 32 deletions

2
configure vendored
View File

@ -1034,7 +1034,7 @@ then
if [ -n "$CFG_OSX_CLANG_VERSION" ] if [ -n "$CFG_OSX_CLANG_VERSION" ]
then then
case $CFG_OSX_CLANG_VERSION in case $CFG_OSX_CLANG_VERSION in
(7.0* | 7.1* | 7.2*) (7.0* | 7.1* | 7.2* | 7.3*)
step_msg "found ok version of APPLE CLANG: $CFG_OSX_CLANG_VERSION" step_msg "found ok version of APPLE CLANG: $CFG_OSX_CLANG_VERSION"
;; ;;
(*) (*)

View File

@ -282,14 +282,12 @@ to it.
## Lifetime Elision ## Lifetime Elision
Rust supports powerful local type inference in function bodies, but its Rust supports powerful local type inference in the bodies of functions but not in their item signatures.
forbidden in item signatures to allow reasoning about the types based on It's forbidden to allow reasoning about types based on the item signature alone.
the item signature alone. However, for ergonomic reasons a very restricted However, for ergonomic reasons, a very restricted secondary inference algorithm called
secondary inference algorithm called “lifetime elision” applies in function “lifetime elision” does apply when judging lifetimes. Lifetime elision is concerned solely to infer
signatures. It infers only based on the signature components themselves and not lifetime parameters using three easily memorizable and unambiguous rules. This means lifetime elision
based on the body of the function, only infers lifetime parameters, and does acts as a shorthand for writing an item signature, while not hiding
this with only three easily memorizable and unambiguous rules. This makes
lifetime elision a shorthand for writing an item signature, while not hiding
away the actual types involved as full local inference would if applied to it. away the actual types involved as full local inference would if applied to it.
When talking about lifetime elision, we use the term *input lifetime* and When talking about lifetime elision, we use the term *input lifetime* and

View File

@ -1,7 +1,7 @@
% Patterns % Patterns
Patterns are quite common in Rust. We use them in [variable Patterns are quite common in Rust. We use them in [variable
bindings][bindings], [match statements][match], and other places, too. Lets go bindings][bindings], [match expressions][match], and other places, too. Lets go
on a whirlwind tour of all of the things patterns can do! on a whirlwind tour of all of the things patterns can do!
[bindings]: variable-bindings.html [bindings]: variable-bindings.html

View File

@ -381,7 +381,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
llconst = addr_of(cx, llconst, type_of::align_of(cx, ty), "autoref"); llconst = addr_of(cx, llconst, type_of::align_of(cx, ty), "autoref");
ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReStatic), ty); ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReStatic), ty);
} }
} else { } else if adj.autoderefs > 0 {
let (dv, dt) = const_deref(cx, llconst, ty); let (dv, dt) = const_deref(cx, llconst, ty);
llconst = dv; llconst = dv;

View File

@ -256,7 +256,7 @@ pub fn build_impls(cx: &DocContext,
cstore::DlImpl(did) => build_impl(cx, tcx, did, impls), cstore::DlImpl(did) => build_impl(cx, tcx, did, impls),
cstore::DlDef(Def::Mod(did)) => { cstore::DlDef(Def::Mod(did)) => {
// Don't recurse if this is a #[doc(hidden)] module // Don't recurse if this is a #[doc(hidden)] module
if load_attrs(cx, tcx, did).list_def("doc").has_word("hidden") { if load_attrs(cx, tcx, did).list("doc").has_word("hidden") {
return; return;
} }
@ -299,7 +299,7 @@ pub fn build_impl(cx: &DocContext,
if let Some(ref t) = associated_trait { if let Some(ref t) = associated_trait {
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline // If this is an impl for a #[doc(hidden)] trait, be sure to not inline
let trait_attrs = load_attrs(cx, tcx, t.def_id); let trait_attrs = load_attrs(cx, tcx, t.def_id);
if trait_attrs.list_def("doc").has_word("hidden") { if trait_attrs.list("doc").has_word("hidden") {
return return
} }
} }

View File

@ -418,7 +418,7 @@ impl Clean<Item> for doctree::Module {
pub trait Attributes { pub trait Attributes {
fn has_word(&self, &str) -> bool; fn has_word(&self, &str) -> bool;
fn value<'a>(&'a self, &str) -> Option<&'a str>; fn value<'a>(&'a self, &str) -> Option<&'a str>;
fn list_def<'a>(&'a self, &str) -> &'a [Attribute]; fn list<'a>(&'a self, &str) -> &'a [Attribute];
} }
impl Attributes for [Attribute] { impl Attributes for [Attribute] {
@ -447,7 +447,7 @@ impl Attributes for [Attribute] {
} }
/// Finds an attribute as List and returns the list of attributes nested inside. /// Finds an attribute as List and returns the list of attributes nested inside.
fn list_def<'a>(&'a self, name: &str) -> &'a [Attribute] { fn list<'a>(&'a self, name: &str) -> &'a [Attribute] {
for attr in self { for attr in self {
if let List(ref x, ref list) = *attr { if let List(ref x, ref list) = *attr {
if name == *x { if name == *x {
@ -1535,7 +1535,7 @@ impl PrimitiveType {
} }
fn find(attrs: &[Attribute]) -> Option<PrimitiveType> { fn find(attrs: &[Attribute]) -> Option<PrimitiveType> {
for attr in attrs.list_def("doc") { for attr in attrs.list("doc") {
if let NameValue(ref k, ref v) = *attr { if let NameValue(ref k, ref v) = *attr {
if "primitive" == *k { if "primitive" == *k {
if let ret@Some(..) = PrimitiveType::from_str(v) { if let ret@Some(..) = PrimitiveType::from_str(v) {
@ -1885,7 +1885,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
source: Span::empty(), source: Span::empty(),
name: Some(field.name.clean(cx)), name: Some(field.name.clean(cx)),
attrs: Vec::new(), attrs: Vec::new(),
visibility: Some(hir::Public), visibility: Some(field.vis),
// FIXME: this is not accurate, we need an id for // FIXME: this is not accurate, we need an id for
// the specific field but we're using the id // the specific field but we're using the id
// for the whole variant. Thus we read the // for the whole variant. Thus we read the

View File

@ -432,7 +432,7 @@ pub fn run(mut krate: clean::Crate,
// Crawl the crate attributes looking for attributes which control how we're // Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML // going to emit HTML
if let Some(attrs) = krate.module.as_ref().map(|m| m.attrs.list_def("doc")) { if let Some(attrs) = krate.module.as_ref().map(|m| m.attrs.list("doc")) {
for attr in attrs { for attr in attrs {
match *attr { match *attr {
clean::NameValue(ref x, ref s) clean::NameValue(ref x, ref s)
@ -832,7 +832,7 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
// Failing that, see if there's an attribute specifying where to find this // Failing that, see if there's an attribute specifying where to find this
// external crate // external crate
e.attrs.list_def("doc").value("html_root_url").map(|url| { e.attrs.list("doc").value("html_root_url").map(|url| {
let mut url = url.to_owned(); let mut url = url.to_owned();
if !url.ends_with("/") { if !url.ends_with("/") {
url.push('/') url.push('/')
@ -1845,6 +1845,7 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
f: &clean::Function) -> fmt::Result { f: &clean::Function) -> fmt::Result {
// FIXME(#24111): remove when `const_fn` is stabilized
let vis_constness = match get_unstable_features_setting() { let vis_constness = match get_unstable_features_setting() {
UnstableFeatures::Allow => f.constness, UnstableFeatures::Allow => f.constness,
_ => hir::Constness::NotConst _ => hir::Constness::NotConst

View File

@ -384,7 +384,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
// Process all of the crate attributes, extracting plugin metadata along // Process all of the crate attributes, extracting plugin metadata along
// with the passes which we are supposed to run. // with the passes which we are supposed to run.
for attr in krate.module.as_ref().unwrap().attrs.list_def("doc") { for attr in krate.module.as_ref().unwrap().attrs.list("doc") {
match *attr { match *attr {
clean::Word(ref w) if "no_default_passes" == *w => { clean::Word(ref w) if "no_default_passes" == *w => {
default_passes = false; default_passes = false;

View File

@ -33,7 +33,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
} }
impl<'a> fold::DocFolder for Stripper<'a> { impl<'a> fold::DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> { fn fold_item(&mut self, i: Item) -> Option<Item> {
if i.attrs.list_def("doc").has_word("hidden") { if i.attrs.list("doc").has_word("hidden") {
debug!("found one in strip_hidden; removing"); debug!("found one in strip_hidden; removing");
self.stripped.insert(i.def_id); self.stripped.insert(i.def_id);

View File

@ -229,7 +229,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
while let Some(id) = cx.map.get_enclosing_scope(node) { while let Some(id) = cx.map.get_enclosing_scope(node) {
node = id; node = id;
let attrs = cx.map.attrs(node).clean(cx); let attrs = cx.map.attrs(node).clean(cx);
if attrs.list_def("doc").has_word("hidden") { if attrs.list("doc").has_word("hidden") {
return true; return true;
} }
if node == ast::CRATE_NODE_ID { if node == ast::CRATE_NODE_ID {
@ -251,11 +251,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
Some(analysis) => analysis, None => return false Some(analysis) => analysis, None => return false
}; };
let use_attrs = tcx.map.attrs(id).clean(self.cx);
let is_private = !analysis.access_levels.is_public(def); let is_private = !analysis.access_levels.is_public(def);
let is_hidden = inherits_doc_hidden(self.cx, def_node_id); let is_hidden = inherits_doc_hidden(self.cx, def_node_id);
let is_no_inline = use_attrs.list("doc").has_word("no_inline");
// Only inline if requested or if the item would otherwise be stripped // Only inline if requested or if the item would otherwise be stripped
if !please_inline && !is_private && !is_hidden { if (!please_inline && !is_private && !is_hidden) || is_no_inline {
return false return false
} }

View File

@ -173,6 +173,14 @@ impl ops::Deref for OsString {
} }
} }
#[stable(feature = "osstring_default", since = "1.9.0")]
impl Default for OsString {
#[inline]
fn default() -> OsString {
OsString::new()
}
}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString { impl Debug for OsString {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@ -302,6 +310,14 @@ impl OsStr {
} }
} }
#[stable(feature = "osstring_default", since = "1.9.0")]
impl<'a> Default for &'a OsStr {
#[inline]
fn default() -> &'a OsStr {
OsStr::new("")
}
}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr { impl PartialEq for OsStr {
fn eq(&self, other: &OsStr) -> bool { fn eq(&self, other: &OsStr) -> bool {
@ -554,6 +570,12 @@ mod tests {
assert!(os_string.capacity() >= 33) assert!(os_string.capacity() >= 33)
} }
#[test]
fn test_os_string_default() {
let os_string: OsString = Default::default();
assert_eq!("", &os_string);
}
#[test] #[test]
fn test_os_str_is_empty() { fn test_os_str_is_empty() {
let mut os_string = OsString::new(); let mut os_string = OsString::new();
@ -577,4 +599,10 @@ mod tests {
os_string.clear(); os_string.clear();
assert_eq!(0, os_string.len()); assert_eq!(0, os_string.len());
} }
#[test]
fn test_os_str_default() {
let os_str: &OsStr = Default::default();
assert_eq!("", os_str);
}
} }

View File

@ -143,8 +143,8 @@ impl SocketAddrV6 {
sin6_family: c::AF_INET6 as c::sa_family_t, sin6_family: c::AF_INET6 as c::sa_family_t,
sin6_port: hton(port), sin6_port: hton(port),
sin6_addr: *ip.as_inner(), sin6_addr: *ip.as_inner(),
sin6_flowinfo: hton(flowinfo), sin6_flowinfo: flowinfo,
sin6_scope_id: hton(scope_id), sin6_scope_id: scope_id,
.. unsafe { mem::zeroed() } .. unsafe { mem::zeroed() }
}, },
} }
@ -173,23 +173,23 @@ impl SocketAddrV6 {
/// Returns the flow information associated with this address, /// Returns the flow information associated with this address,
/// corresponding to the `sin6_flowinfo` field in C. /// corresponding to the `sin6_flowinfo` field in C.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) } pub fn flowinfo(&self) -> u32 { self.inner.sin6_flowinfo }
/// Change the flow information associated with this socket address. /// Change the flow information associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_flowinfo(&mut self, new_flowinfo: u32) { pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
self.inner.sin6_flowinfo = hton(new_flowinfo) self.inner.sin6_flowinfo = new_flowinfo;
} }
/// Returns the scope ID associated with this address, /// Returns the scope ID associated with this address,
/// corresponding to the `sin6_scope_id` field in C. /// corresponding to the `sin6_scope_id` field in C.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) } pub fn scope_id(&self) -> u32 { self.inner.sin6_scope_id }
/// Change the scope ID associated with this socket address. /// Change the scope ID associated with this socket address.
#[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")] #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
pub fn set_scope_id(&mut self, new_scope_id: u32) { pub fn set_scope_id(&mut self, new_scope_id: u32) {
self.inner.sin6_scope_id = hton(new_scope_id) self.inner.sin6_scope_id = new_scope_id;
} }
} }

View File

@ -77,7 +77,7 @@ mod prim_bool { }
/// # Representation /// # Representation
/// ///
/// `char` is always four bytes in size. This is a different representation than /// `char` is always four bytes in size. This is a different representation than
/// a given character would have as part of a [`String`], for example: /// a given character would have as part of a [`String`]. For example:
/// ///
/// ``` /// ```
/// let v = vec!['h', 'e', 'l', 'l', 'o']; /// let v = vec!['h', 'e', 'l', 'l', 'o'];
@ -116,8 +116,8 @@ mod prim_bool { }
/// ^~ /// ^~
/// ``` /// ```
/// ///
/// Another implication of the 4-byte fixed size of a `char`, is that /// Another implication of the 4-byte fixed size of a `char` is that
/// per-`char`acter processing can end up using a lot more memory: /// per-`char` processing can end up using a lot more memory:
/// ///
/// ``` /// ```
/// let s = String::from("love: ❤️"); /// let s = String::from("love: ❤️");

View File

@ -0,0 +1,15 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub enum Foo {
Bar {
qux: (),
}
}

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![feature(rustc_attrs)]
// no-pretty-expanded FIXME #15189 // no-pretty-expanded FIXME #15189
// ignore-android FIXME #17520 // ignore-android FIXME #17520
// compile-flags:-g // compile-flags:-g
@ -16,6 +18,8 @@ use std::env;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use std::str; use std::str;
// FIXME #31005 MIR missing debuginfo currently.
#[cfg_attr(target_env = "msvc", rustc_no_mir)]
#[inline(never)] #[inline(never)]
fn foo() { fn foo() {
let _v = vec![1, 2, 3]; let _v = vec![1, 2, 3];
@ -24,6 +28,8 @@ fn foo() {
} }
} }
// FIXME #31005 MIR missing debuginfo currently.
#[cfg_attr(target_env = "msvc", rustc_no_mir)]
#[inline(never)] #[inline(never)]
fn double() { fn double() {
struct Double; struct Double;

View File

@ -0,0 +1,22 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub struct Foo {
x: isize,
y: isize
}
impl Foo {
pub extern fn foo_new() -> Foo {
Foo { x: 21, y: 33 }
}
}
fn main() {}

View File

@ -0,0 +1,14 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
&0u8 as *const u8 as *const PartialEq<u8>;
&[0u8] as *const [u8; 1] as *const [u8];
}

View File

@ -0,0 +1,33 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// @!has issue_32343/struct.Foo.html
// @has issue_32343/index.html
// @has - '//code' 'pub use foo::Foo'
// @!has - '//code/a' 'Foo'
#[doc(no_inline)]
pub use foo::Foo;
// @!has issue_32343/struct.Bar.html
// @has issue_32343/index.html
// @has - '//code' 'pub use foo::Bar'
// @has - '//code/a' 'Bar'
#[doc(no_inline)]
pub use foo::Bar;
mod foo {
pub struct Foo;
pub struct Bar;
}
pub mod bar {
// @has issue_32343/bar/struct.Bar.html
pub use ::foo::Bar;
}

View File

@ -0,0 +1,21 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:variant-struct.rs
// build-aux-docs
// ignore-cross-compile
// @has variant_struct/enum.Foo.html
// @!has - 'pub qux'
extern crate variant_struct;
// @has issue_32395/enum.Foo.html
// @!has - 'pub qux'
pub use variant_struct::Foo;