Auto merge of #36805 - jonathandturner:rollup, r=jonathandturner

Rollup of 11 pull requests

- Successful merges: #36376, #36672, #36740, #36757, #36765, #36769, #36782, #36783, #36784, #36795, #36796
- Failed merges:
This commit is contained in:
bors 2016-09-28 15:03:26 -07:00 committed by GitHub
commit 86affcdf6c
19 changed files with 299 additions and 134 deletions

View File

@ -659,12 +659,6 @@ impl Build {
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
}
// If we're building for OSX, inform the compiler and the linker that
// we want to build a compiler runnable on 10.7
if target.contains("apple-darwin") {
cargo.env("MACOSX_DEPLOYMENT_TARGET", "10.7");
}
// Environment variables *required* needed throughout the build
//
// FIXME: should update code to not require this env var
@ -933,7 +927,6 @@ impl Build {
// LLVM/jemalloc/etc are all properly compiled.
if target.contains("apple-darwin") {
base.push("-stdlib=libc++".into());
base.push("-mmacosx-version-min=10.7".into());
}
// This is a hack, because newer binutils broke things on some vms/distros
// (i.e., linking against unknown relocs disabled by the following flag)

View File

@ -166,12 +166,22 @@ you can find the Rust executables in a directory like
`"C:\Program Files\Rust stable GNU 1.x\bin"`.
Rust does not do its own linking, and so youll need to have a linker
installed. Doing so will depend on your specific system, consult its
documentation for more details.
installed. Doing so will depend on your specific system. For
Linux-based systems, Rust will attempt to call `cc` for linking. On
`windows-msvc` (Rust built on Windows with Microsoft Visual Studio),
this depends on having [Microsoft Visual C++ Build Tools][msvbt]
installed. These do not need to be in `%PATH%` as `rustc` will find
them automatically. In general, if you have your linker in a
non-traditional location you can call `rustc
linker=/path/to/cc`, where `/path/to/cc` should point to your linker path.
If not, there are a number of places where we can get help. The easiest is
[the #rust-beginners IRC channel on irc.mozilla.org][irc-beginners] and for
general discussion [the #rust IRC channel on irc.mozilla.org][irc], which we
[msvbt]: http://landinghub.visualstudio.com/visual-cpp-build-tools
If you are still stuck, there are a number of places where we can get
help. The easiest is
[the #rust-beginners IRC channel on irc.mozilla.org][irc-beginners]
and for general discussion
[the #rust IRC channel on irc.mozilla.org][irc], which we
can access through [Mibbit][mibbit]. Then we'll be chatting with other
Rustaceans (a silly nickname we call ourselves) who can help us out. Other great
resources include [the users forum][users] and [Stack Overflow][stackoverflow].

View File

@ -161,7 +161,7 @@ Could not compile `hello_world`.
Rust will not let us use a value that has not been initialized.
Let take a minute to talk about this stuff we've added to `println!`.
Let us take a minute to talk about this stuff we've added to `println!`.
If you include two curly braces (`{}`, some call them moustaches...) in your
string to print, Rust will interpret this as a request to interpolate some sort

View File

@ -596,6 +596,19 @@ extern "rust-intrinsic" {
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `val`.
///
/// # Examples
///
/// ```
/// use std::ptr;
///
/// let mut vec = vec![0; 4];
/// unsafe {
/// let vec_ptr = vec.as_mut_ptr();
/// ptr::write_bytes(vec_ptr, b'a', 2);
/// }
/// assert_eq!(vec, [b'a', b'a', 0, 0]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);

View File

@ -260,7 +260,7 @@ impl<'ast> Map<'ast> {
EntryVariant(p, _) |
EntryExpr(p, _) |
EntryStmt(p, _) |
EntryTy(p, _) |
EntryTy(p, _) |
EntryLocal(p, _) |
EntryPat(p, _) |
EntryBlock(p, _) |

View File

@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
llvm_target: "mips64-unknown-linux-gnuabi64".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),

View File

@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
llvm_target: "mips64el-unknown-linux-gnuabi64".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),

View File

@ -675,14 +675,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
for &Spanned { node: ref field, span } in fields {
let field_ty = match used_fields.entry(field.name) {
Occupied(occupied) => {
let mut err = struct_span_err!(tcx.sess, span, E0025,
"field `{}` bound multiple times \
in the pattern",
field.name);
span_note!(&mut err, *occupied.get(),
"field `{}` previously bound here",
field.name);
err.emit();
struct_span_err!(tcx.sess, span, E0025,
"field `{}` bound multiple times \
in the pattern",
field.name)
.span_label(span,
&format!("multiple uses of `{}` in pattern", field.name))
.span_label(*occupied.get(), &format!("first use of `{}`", field.name))
.emit();
tcx.types.err
}
Vacant(vacant) => {

View File

@ -148,14 +148,70 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
if impl_m.fty.sig.0.inputs.len() != trait_m.fty.sig.0.inputs.len() {
span_err!(tcx.sess, impl_m_span, E0050,
let trait_number_args = trait_m.fty.sig.0.inputs.len();
let impl_number_args = impl_m.fty.sig.0.inputs.len();
let trait_m_node_id = tcx.map.as_local_node_id(trait_m.def_id);
let trait_span = if let Some(trait_id) = trait_m_node_id {
match tcx.map.expect_trait_item(trait_id).node {
TraitItem_::MethodTraitItem(ref trait_m_sig, _) => {
if let Some(arg) = trait_m_sig.decl.inputs.get(
if trait_number_args > 0 {
trait_number_args - 1
} else {
0
}) {
Some(arg.pat.span)
} else {
trait_item_span
}
}
_ => bug!("{:?} is not a method", impl_m)
}
} else {
trait_item_span
};
let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap();
let impl_span = match tcx.map.expect_impl_item(impl_m_node_id).node {
ImplItemKind::Method(ref impl_m_sig, _) => {
if let Some(arg) = impl_m_sig.decl.inputs.get(
if impl_number_args > 0 {
impl_number_args - 1
} else {
0
}) {
arg.pat.span
} else {
impl_m_span
}
}
_ => bug!("{:?} is not a method", impl_m)
};
let mut err = struct_span_err!(tcx.sess, impl_span, E0050,
"method `{}` has {} parameter{} \
but the declaration in trait `{}` has {}",
trait_m.name,
impl_m.fty.sig.0.inputs.len(),
if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"},
impl_number_args,
if impl_number_args == 1 {""} else {"s"},
tcx.item_path_str(trait_m.def_id),
trait_m.fty.sig.0.inputs.len());
trait_number_args);
if let Some(trait_span) = trait_span {
err.span_label(trait_span,
&format!("trait requires {}",
&if trait_number_args != 1 {
format!("{} parameters", trait_number_args)
} else {
format!("{} parameter", trait_number_args)
}));
}
err.span_label(impl_span,
&format!("expected {}, found {}",
&if trait_number_args != 1 {
format!("{} parameters", trait_number_args)
} else {
format!("{} parameter", trait_number_args)
},
impl_number_args));
err.emit();
return;
}

View File

@ -335,6 +335,22 @@ fn test_resize_policy() {
/// println!("{:?} has {} hp", viking, health);
/// }
/// ```
///
/// A HashMap with fixed list of elements can be initialized from an array:
///
/// ```
/// use std::collections::HashMap;
///
/// fn main() {
/// let timber_resources: HashMap<&str, i32> =
/// [("Norway", 100),
/// ("Denmark", 50),
/// ("Iceland", 10)]
/// .iter().cloned().collect();
/// // use the values stored in map
/// }
/// ```
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct HashMap<K, V, S = RandomState> {

View File

@ -98,6 +98,20 @@ use super::map::{self, HashMap, Keys, RandomState};
/// println!("{:?}", x);
/// }
/// ```
///
/// HashSet with fixed list of elements can be initialized from an array:
///
/// ```
/// use std::collections::HashSet;
///
/// fn main() {
/// let viking_names: HashSet<&str> =
/// [ "Einar", "Olaf", "Harald" ].iter().cloned().collect();
/// // use the values stored in the set
/// }
/// ```
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct HashSet<T, S = RandomState> {

View File

@ -108,11 +108,109 @@ pub fn expand_derive(cx: &mut ExtCtxt,
cx.span_err(mitem.span, "unexpected value in `derive`");
}
let traits = mitem.meta_item_list().unwrap_or(&[]);
let mut traits = mitem.meta_item_list().unwrap_or(&[]).to_owned();
if traits.is_empty() {
cx.span_warn(mitem.span, "empty trait list in `derive`");
}
// First, weed out malformed #[derive]
traits.retain(|titem| {
if titem.word().is_none() {
cx.span_err(titem.span, "malformed `derive` entry");
false
} else {
true
}
});
// Next, check for old-style #[derive(Foo)]
//
// These all get expanded to `#[derive_Foo]` and will get expanded first. If
// we actually add any attributes here then we return to get those expanded
// and then eventually we'll come back to finish off the other derive modes.
let mut new_attributes = Vec::new();
traits.retain(|titem| {
let tword = titem.word().unwrap();
let tname = tword.name();
let derive_mode = ast::Ident::with_empty_ctxt(intern(&tname));
let derive_mode = cx.resolver.resolve_derive_mode(derive_mode);
if is_builtin_trait(&tname) || derive_mode.is_some() {
return true
}
if !cx.ecfg.enable_custom_derive() {
feature_gate::emit_feature_err(&cx.parse_sess,
"custom_derive",
titem.span,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_CUSTOM_DERIVE);
} else {
let name = intern_and_get_ident(&format!("derive_{}", tname));
let mitem = cx.meta_word(titem.span, name);
new_attributes.push(cx.attribute(mitem.span, mitem));
}
false
});
if new_attributes.len() > 0 {
item = item.map(|mut i| {
let list = cx.meta_list(mitem.span,
intern_and_get_ident("derive"),
traits);
i.attrs.extend(new_attributes);
i.attrs.push(cx.attribute(mitem.span, list));
i
});
return vec![Annotatable::Item(item)]
}
// Now check for macros-1.1 style custom #[derive].
//
// Expand each of them in order given, but *before* we expand any built-in
// derive modes. The logic here is to:
//
// 1. Collect the remaining `#[derive]` annotations into a list. If
// there are any left, attach a `#[derive]` attribute to the item
// that we're currently expanding with the remaining derive modes.
// 2. Manufacture a `#[derive(Foo)]` attribute to pass to the expander.
// 3. Expand the current item we're expanding, getting back a list of
// items that replace it.
// 4. Extend the returned list with the current list of items we've
// collected so far.
// 5. Return everything!
//
// If custom derive extensions end up threading through the `#[derive]`
// attribute, we'll get called again later on to continue expanding
// those modes.
let macros_11_derive = traits.iter()
.cloned()
.enumerate()
.filter(|&(_, ref name)| !is_builtin_trait(&name.name().unwrap()))
.next();
if let Some((i, titem)) = macros_11_derive {
let tname = ast::Ident::with_empty_ctxt(intern(&titem.name().unwrap()));
let ext = cx.resolver.resolve_derive_mode(tname).unwrap();
traits.remove(i);
if traits.len() > 0 {
item = item.map(|mut i| {
let list = cx.meta_list(mitem.span,
intern_and_get_ident("derive"),
traits);
i.attrs.push(cx.attribute(mitem.span, list));
i
});
}
let titem = cx.meta_list_item_word(titem.span, titem.name().unwrap());
let mitem = cx.meta_list(titem.span,
intern_and_get_ident("derive"),
vec![titem]);
let item = Annotatable::Item(item);
return ext.expand(cx, mitem.span, &mitem, item)
}
// Ok, at this point we know that there are no old-style `#[derive_Foo]` nor
// any macros-1.1 style `#[derive(Foo)]`. Expand all built-in traits here.
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
// `#[structural_match]` attribute.
if traits.iter().filter_map(|t| t.name()).any(|t| t == "PartialEq") &&
@ -141,103 +239,33 @@ pub fn expand_derive(cx: &mut ExtCtxt,
});
}
let mut other_items = Vec::new();
let mut items = Vec::new();
for titem in traits.iter() {
let tname = titem.word().unwrap().name();
let name = intern_and_get_ident(&format!("derive({})", tname));
let mitem = cx.meta_word(titem.span, name);
let mut iter = traits.iter();
while let Some(titem) = iter.next() {
let tword = match titem.word() {
Some(name) => name,
None => {
cx.span_err(titem.span, "malformed `derive` entry");
continue
}
let span = Span {
expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: titem.span,
callee: codemap::NameAndSpan {
format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
span: Some(titem.span),
allow_internal_unstable: true,
},
}),
..titem.span
};
let tname = tword.name();
// If this is a built-in derive mode, then we expand it immediately
// here.
if is_builtin_trait(&tname) {
let name = intern_and_get_ident(&format!("derive({})", tname));
let mitem = cx.meta_word(titem.span, name);
let span = Span {
expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: titem.span,
callee: codemap::NameAndSpan {
format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
span: Some(titem.span),
allow_internal_unstable: true,
},
}),
..titem.span
};
let my_item = Annotatable::Item(item);
expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| {
other_items.push(a);
});
item = my_item.expect_item();
// Otherwise if this is a `rustc_macro`-style derive mode, we process it
// here. The logic here is to:
//
// 1. Collect the remaining `#[derive]` annotations into a list. If
// there are any left, attach a `#[derive]` attribute to the item
// that we're currently expanding with the remaining derive modes.
// 2. Manufacture a `#[derive(Foo)]` attribute to pass to the expander.
// 3. Expand the current item we're expanding, getting back a list of
// items that replace it.
// 4. Extend the returned list with the current list of items we've
// collected so far.
// 5. Return everything!
//
// If custom derive extensions end up threading through the `#[derive]`
// attribute, we'll get called again later on to continue expanding
// those modes.
} else if let Some(ext) =
cx.resolver.resolve_derive_mode(ast::Ident::with_empty_ctxt(intern(&tname))) {
let remaining_derives = iter.cloned().collect::<Vec<_>>();
if remaining_derives.len() > 0 {
let list = cx.meta_list(titem.span,
intern_and_get_ident("derive"),
remaining_derives);
let attr = cx.attribute(titem.span, list);
item = item.map(|mut i| {
i.attrs.push(attr);
i
});
}
let titem = cx.meta_list_item_word(titem.span, tname.clone());
let mitem = cx.meta_list(titem.span,
intern_and_get_ident("derive"),
vec![titem]);
let item = Annotatable::Item(item);
let mut items = ext.expand(cx, mitem.span, &mitem, item);
items.extend(other_items);
return items
// If we've gotten this far then it means that we're in the territory of
// the old custom derive mechanism. If the feature isn't enabled, we
// issue an error, otherwise manufacture the `derive_Foo` attribute.
} else if !cx.ecfg.enable_custom_derive() {
feature_gate::emit_feature_err(&cx.parse_sess,
"custom_derive",
titem.span,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_CUSTOM_DERIVE);
} else {
let name = intern_and_get_ident(&format!("derive_{}", tname));
let mitem = cx.meta_word(titem.span, name);
item = item.map(|mut i| {
i.attrs.push(cx.attribute(mitem.span, mitem));
i
});
}
let my_item = Annotatable::Item(item);
expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| {
items.push(a);
});
item = my_item.expect_item();
}
other_items.insert(0, Annotatable::Item(item));
return other_items
items.insert(0, Annotatable::Item(item));
return items
}
macro_rules! derive_traits {

View File

@ -15,5 +15,8 @@ struct Foo {
fn main() {
let x = Foo { a:1, b:2 };
let Foo { a: x, a: y, b: 0 } = x; //~ ERROR E0025
let Foo { a: x, a: y, b: 0 } = x;
//~^ ERROR field `a` bound multiple times in the pattern
//~| NOTE multiple uses of `a` in pattern
//~| NOTE first use of `a`
}

View File

@ -9,13 +9,20 @@
// except according to those terms.
trait Foo {
fn foo(&self, x: u8) -> bool;
fn foo(&self, x: u8) -> bool; //~ NOTE trait requires 2 parameters
fn bar(&self, x: u8, y: u8, z: u8); //~ NOTE trait requires 4 parameters
fn less(&self); //~ NOTE trait requires 1 parameter
}
struct Bar;
impl Foo for Bar {
fn foo(&self) -> bool { true } //~ ERROR E0050
//~| NOTE expected 2 parameters, found 1
fn bar(&self) { } //~ ERROR E0050
//~| NOTE expected 4 parameters, found 1
fn less(&self, x: u8, y: u8, z: u8) { } //~ ERROR E0050
//~| NOTE expected 1 parameter, found 4
}
fn main() {

View File

@ -14,19 +14,28 @@ struct Foo {
fn main() {
let Foo {
a: _, //~ NOTE field `a` previously bound here
a: _ //~ ERROR field `a` bound multiple times in the pattern
a: _, //~ NOTE first use of `a`
a: _
//~^ ERROR field `a` bound multiple times in the pattern
//~| NOTE multiple uses of `a` in pattern
} = Foo { a: 29 };
let Foo {
a, //~ NOTE field `a` previously bound here
a: _ //~ ERROR field `a` bound multiple times in the pattern
a, //~ NOTE first use of `a`
a: _
//~^ ERROR field `a` bound multiple times in the pattern
//~| NOTE multiple uses of `a` in pattern
} = Foo { a: 29 };
let Foo {
a, //~ NOTE field `a` previously bound here
//~^ NOTE field `a` previously bound here
a: _, //~ ERROR field `a` bound multiple times in the pattern
a: x //~ ERROR field `a` bound multiple times in the pattern
a,
//~^ NOTE first use of `a`
//~| NOTE first use of `a`
a: _,
//~^ ERROR field `a` bound multiple times in the pattern
//~| NOTE multiple uses of `a` in pattern
a: x
//~^ ERROR field `a` bound multiple times in the pattern
//~| NOTE multiple uses of `a` in pattern
} = Foo { a: 29 };
}

View File

@ -24,7 +24,6 @@ trait Append {
Append,
Eq)]
struct A {
//~^ ERROR: the semantics of constant patterns is not yet settled
inner: u32,
}

View File

@ -22,6 +22,6 @@ use rustc_macro::TokenStream;
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("struct A;"));
assert!(input.contains("#[derive(Eq, Copy, Clone)]"));
"#[derive(Eq, Copy, Clone)] struct A;".parse().unwrap()
assert!(input.contains("#[derive(Debug, PartialEq, Eq, Copy, Clone)]"));
"#[derive(Debug, PartialEq, Eq, Copy, Clone)] struct A;".parse().unwrap()
}

View File

@ -0,0 +1,17 @@
// 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 trait Indexable<T>: std::ops::Index<usize, Output = T> {
fn index2(&self, i: usize) -> &T {
&self[i]
}
}
fn main() {}