Skip to content

Rollup of 11 pull requests #36805

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 28 commits into from
Sep 29, 2016
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
aed99c8
Document init of HashSet/HashMap from vector
frehberg Sep 26, 2016
bd80e7b
Update map.rs
frehberg Sep 26, 2016
3551008
Update set.rs
frehberg Sep 26, 2016
ba84d4f
Update map.rs
frehberg Sep 26, 2016
6c4616c
Update set.rs
frehberg Sep 26, 2016
fd7314f
Update E0025 to new error format
KiChjang Sep 26, 2016
2ba02a7
Add basic doc example for `core::ptr::write_bytes`.
frewsxcv Sep 27, 2016
81c47d5
Update map.rs
frehberg Sep 27, 2016
f953d25
Update set.rs
frehberg Sep 27, 2016
73e5a98
doc: Fix minor typo in book/variable-bindings.md
musoke Sep 27, 2016
e5e7021
rustc: Tweak expansion order of custom derive
alexcrichton Sep 27, 2016
5b6638a
Remove requirement to use 10.7 (fixes macOS)
Sep 27, 2016
cb3b03c
Improve documention troubleshooting missing linker. Fix #32208.
Sep 23, 2016
4053af9
TypeIdHasher: hash usize as u64
TimNN Sep 28, 2016
3a27647
update mips64* data-layout
TimNN Sep 28, 2016
61cbf41
Update E0050 to new error format
GuillaumeGomez Sep 10, 2016
b543f3a
Add testcase for issue-18088.
ParkHanbum Sep 28, 2016
475a41b
Rollup merge of #36376 - GuillaumeGomez:e0050, r=jonathandturner
Sep 28, 2016
fe0729d
Rollup merge of #36672 - LinkiTools:master, r=steveklabnik
Sep 28, 2016
4676bb0
Rollup merge of #36740 - frehberg:apidoc, r=steveklabnik
Sep 28, 2016
224e882
Rollup merge of #36757 - KiChjang:E0025-format, r=jonathandturner
Sep 28, 2016
9a17da2
Rollup merge of #36765 - frewsxcv:ptr-write-bytes, r=steveklabnik
Sep 28, 2016
f7f1903
Rollup merge of #36769 - nathanmusoke:master, r=apasel422
Sep 28, 2016
f819b4d
Rollup merge of #36782 - alexcrichton:rustc-macro-expand-order, r=nrc
Sep 28, 2016
452bb07
Rollup merge of #36783 - die4taoam:master, r=alexcrichton
Sep 28, 2016
723ddd1
Rollup merge of #36784 - jonathandturner:env_var, r=alexcrichton
Sep 28, 2016
4674601
Rollup merge of #36795 - TimNN:fix-36793, r=eddyb
Sep 28, 2016
ac82eaa
Rollup merge of #36796 - TimNN:mips64-data-layout, r=japaric
Sep 28, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -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)
22 changes: 16 additions & 6 deletions src/doc/book/getting-started.md
Original file line number Diff line number Diff line change
@@ -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 you’ll need to have a linker
installed. Doing so will depend on your specific system, consult its
documentation for more details.

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
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.

[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 user’s forum][users] and [Stack Overflow][stackoverflow].
2 changes: 1 addition & 1 deletion src/doc/book/variable-bindings.md
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -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);

2 changes: 1 addition & 1 deletion src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ impl<'ast> Map<'ast> {
EntryVariant(p, _) |
EntryExpr(p, _) |
EntryStmt(p, _) |
EntryTy(p, _) |
EntryTy(p, _) |
EntryLocal(p, _) |
EntryPat(p, _) |
EntryBlock(p, _) |
6 changes: 3 additions & 3 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
@@ -436,7 +436,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
TyInt(i) => self.hash(i),
TyUint(u) => self.hash(u),
TyFloat(f) => self.hash(f),
TyArray(_, n) => self.hash(n),
TyArray(_, n) => self.hash(n as u64),
TyRawPtr(m) |
TyRef(_, m) => self.hash(m.mutbl),
TyClosure(def_id, _) |
@@ -447,14 +447,14 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
self.hash(f.unsafety);
self.hash(f.abi);
self.hash(f.sig.variadic());
self.hash(f.sig.inputs().skip_binder().len());
self.hash(f.sig.inputs().skip_binder().len() as u64);
}
TyTrait(ref data) => {
self.def_id(data.principal.def_id());
self.hash(data.builtin_bounds);
}
TyTuple(tys) => {
self.hash(tys.len());
self.hash(tys.len() as u64);
}
TyParam(p) => {
self.hash(p.idx);
2 changes: 1 addition & 1 deletion src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
Original file line number Diff line number Diff line change
@@ -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(),
Original file line number Diff line number Diff line change
@@ -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(),
16 changes: 8 additions & 8 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
@@ -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) => {
64 changes: 60 additions & 4 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -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;
}

16 changes: 16 additions & 0 deletions src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
@@ -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> {
14 changes: 14 additions & 0 deletions src/libstd/collections/hash/set.rs
Original file line number Diff line number Diff line change
@@ -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> {
216 changes: 122 additions & 94 deletions src/libsyntax_ext/deriving/mod.rs
Original file line number Diff line number Diff line change
@@ -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 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 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 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 {
5 changes: 4 additions & 1 deletion src/test/compile-fail/E0025.rs
Original file line number Diff line number Diff line change
@@ -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`
}
9 changes: 8 additions & 1 deletion src/test/compile-fail/E0050.rs
Original file line number Diff line number Diff line change
@@ -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() {
25 changes: 17 additions & 8 deletions src/test/compile-fail/issue-15260.rs
Original file line number Diff line number Diff line change
@@ -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 };
}
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@ trait Append {
Append,
Eq)]
struct A {
//~^ ERROR: the semantics of constant patterns is not yet settled
inner: u32,
}

4 changes: 2 additions & 2 deletions src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs
Original file line number Diff line number Diff line change
@@ -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()
}
17 changes: 17 additions & 0 deletions src/test/run-pass/issue-18088.rs
Original file line number Diff line number Diff line change
@@ -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() {}