From aed99c800e03bcda172ee3b5505ebcab8c5060e9 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Mon, 26 Sep 2016 13:39:31 +0200 Subject: [PATCH 01/16] Document init of HashSet/HashMap from vector --- src/libstd/collections/hash/map.rs | 17 +++++++++++++++++ src/libstd/collections/hash/set.rs | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index eb1653f18cb..698ce8815bd 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -335,6 +335,23 @@ fn test_resize_policy() { /// println!("{:?} has {} hp", viking, health); /// } /// ``` +/// A HashMap with fixed list of elements can be initialized from vector: +/// ``` +/// use std::collections::HashMap; +/// +/// fn main() { +/// let timber_resources: HashMap<&str, i32> = +/// [ ("Norway", 100), +/// ("Denmark", 50), +/// ("Iceland", 10) ] +/// .iter().map(|&x| x).collect(); +/// // use the values store in map +/// } +/// ``` +/// This works for Copy types, if you want to cover non-copy types then you need to replace +/// the map(|&x| x) with map(|x| x.clone()) + + #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct HashMap { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index ff56747fee6..568163b77de 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -100,6 +100,20 @@ const INITIAL_CAPACITY: usize = 32; /// println!("{:?}", x); /// } /// ``` +/// HashSet with fixed list of elements can be initialized from vector: +/// ``` +/// use std::collections::HashSet; +/// +/// fn main() { +/// let viking_names: HashSet<&str> = +/// [ "Einar", "Olaf", "Harald" ].iter().map(|&x| x).collect(); +/// // use the values store in the set +/// } +/// ``` +/// This works for Copy types, if you want to cover non-copy types then you need to replace +/// the map(|&x| x) with map(|x| x.clone()) + + #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct HashSet { From bd80e7bce77aae5a7d515a1113ae3a471d4ce6e2 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Mon, 26 Sep 2016 16:00:24 +0200 Subject: [PATCH 02/16] Update map.rs --- src/libstd/collections/hash/map.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 698ce8815bd..776643b7866 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -344,13 +344,10 @@ fn test_resize_policy() { /// [ ("Norway", 100), /// ("Denmark", 50), /// ("Iceland", 10) ] -/// .iter().map(|&x| x).collect(); -/// // use the values store in map +/// .iter().cloned().collect(); +/// // use the values stored in map /// } /// ``` -/// This works for Copy types, if you want to cover non-copy types then you need to replace -/// the map(|&x| x) with map(|x| x.clone()) - #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] From 35510080220fc4f586075dd483ae1bbb67503c44 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Mon, 26 Sep 2016 16:03:37 +0200 Subject: [PATCH 03/16] Update set.rs --- src/libstd/collections/hash/set.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 568163b77de..572e333def4 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -106,12 +106,10 @@ const INITIAL_CAPACITY: usize = 32; /// /// fn main() { /// let viking_names: HashSet<&str> = -/// [ "Einar", "Olaf", "Harald" ].iter().map(|&x| x).collect(); -/// // use the values store in the set +/// [ "Einar", "Olaf", "Harald" ].iter().cloned().collect(); +/// // use the values stored in the set /// } /// ``` -/// This works for Copy types, if you want to cover non-copy types then you need to replace -/// the map(|&x| x) with map(|x| x.clone()) #[derive(Clone)] From ba84d4ff817e724b3a910ec4187cb6418e037b5b Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Mon, 26 Sep 2016 18:15:27 +0200 Subject: [PATCH 04/16] Update map.rs --- src/libstd/collections/hash/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 776643b7866..b884b60365b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -335,7 +335,7 @@ fn test_resize_policy() { /// println!("{:?} has {} hp", viking, health); /// } /// ``` -/// A HashMap with fixed list of elements can be initialized from vector: +/// A HashMap with fixed list of elements can be initialized from an array: /// ``` /// use std::collections::HashMap; /// From 6c4616c72d8f845d2a0555b8f1610c4bf5ca7525 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Mon, 26 Sep 2016 18:16:06 +0200 Subject: [PATCH 05/16] Update set.rs --- src/libstd/collections/hash/set.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 572e333def4..505bbb33b20 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -100,7 +100,7 @@ const INITIAL_CAPACITY: usize = 32; /// println!("{:?}", x); /// } /// ``` -/// HashSet with fixed list of elements can be initialized from vector: +/// HashSet with fixed list of elements can be initialized from an array: /// ``` /// use std::collections::HashSet; /// From fd7314f53480872d3379e853e48a4ca7871f9140 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 26 Sep 2016 13:00:37 -0700 Subject: [PATCH 06/16] Update E0025 to new error format --- src/librustc_typeck/check/_match.rs | 16 ++++++++-------- src/test/compile-fail/E0025.rs | 5 ++++- src/test/compile-fail/issue-15260.rs | 25 +++++++++++++++++-------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index de7ca479b0b..5d6d21bb6f8 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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) => { diff --git a/src/test/compile-fail/E0025.rs b/src/test/compile-fail/E0025.rs index 3f5922cdc02..1d15cef8bc9 100644 --- a/src/test/compile-fail/E0025.rs +++ b/src/test/compile-fail/E0025.rs @@ -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` } diff --git a/src/test/compile-fail/issue-15260.rs b/src/test/compile-fail/issue-15260.rs index 5ec82326d6c..5f816d34c84 100644 --- a/src/test/compile-fail/issue-15260.rs +++ b/src/test/compile-fail/issue-15260.rs @@ -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 }; } From 2ba02a773e8e4f5bd5032a8305a8ba1eda7967c6 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 26 Sep 2016 23:11:47 -0400 Subject: [PATCH 07/16] Add basic doc example for `core::ptr::write_bytes`. --- src/libcore/intrinsics.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 22abe7a99b1..6c4da2a8851 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -596,6 +596,19 @@ extern "rust-intrinsic" { /// Invokes memset on the specified pointer, setting `count * size_of::()` /// 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(dst: *mut T, val: u8, count: usize); From 81c47d591a90cea7c374cfd893eca2cc67aac284 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Tue, 27 Sep 2016 10:31:25 +0200 Subject: [PATCH 08/16] Update map.rs --- src/libstd/collections/hash/map.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index b884b60365b..044d5e4ed36 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -335,16 +335,18 @@ 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(); +/// [("Norway", 100), +/// ("Denmark", 50), +/// ("Iceland", 10)] +/// .iter().cloned().collect(); /// // use the values stored in map /// } /// ``` From f953d2564e2ebb79a20809c7cff85ccbcfc77d14 Mon Sep 17 00:00:00 2001 From: Frank Rehberger Date: Tue, 27 Sep 2016 10:32:21 +0200 Subject: [PATCH 09/16] Update set.rs --- src/libstd/collections/hash/set.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 505bbb33b20..5a88367e8f4 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -100,7 +100,9 @@ const INITIAL_CAPACITY: usize = 32; /// println!("{:?}", x); /// } /// ``` +/// /// HashSet with fixed list of elements can be initialized from an array: +/// /// ``` /// use std::collections::HashSet; /// From 73e5a98e71f1f4fa948f0f2111b4c5688c0ee6dc Mon Sep 17 00:00:00 2001 From: Nathan Musoke Date: Tue, 27 Sep 2016 23:20:50 +1300 Subject: [PATCH 10/16] doc: Fix minor typo in book/variable-bindings.md --- src/doc/book/variable-bindings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/variable-bindings.md b/src/doc/book/variable-bindings.md index 30e922d7f4d..03f17371de6 100644 --- a/src/doc/book/variable-bindings.md +++ b/src/doc/book/variable-bindings.md @@ -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 From e5e7021ca5b67c17fa116a971c3204bd147a1f0d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 27 Sep 2016 11:51:56 -0700 Subject: [PATCH 11/16] rustc: Tweak expansion order of custom derive This commit alters the expansion order of custom macros-1.1 style `#[derive]` modes. Instead of left-to-right the expansion now happens in three categories, each of which is internally left-to-right: * Old-style custom derive (`#[derive_Foo]`) is expanded * New-style custom derive (macros 1.1) is expanded * Built in derive modes are expanded This gives built in derive modes maximal knowledge about the struct that's being expanded and also avoids pesky issues like exposing `#[structural_match]` or `#[rustc_copy_clone_marker]`. cc #35900 --- src/libsyntax_ext/deriving/mod.rs | 214 ++++++++++-------- .../rustc-macro/append-impl.rs | 1 - .../rustc-macro/auxiliary/append-impl.rs | 0 .../rustc-macro/auxiliary/derive-a.rs | 4 +- 4 files changed, 123 insertions(+), 96 deletions(-) rename src/test/{compile-fail-fulldeps => run-pass-fulldeps}/rustc-macro/append-impl.rs (91%) rename src/test/{compile-fail-fulldeps => run-pass-fulldeps}/rustc-macro/auxiliary/append-impl.rs (100%) diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index e3a38d568d3..111596cfe88 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -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::>(); - 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 { diff --git a/src/test/compile-fail-fulldeps/rustc-macro/append-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/append-impl.rs similarity index 91% rename from src/test/compile-fail-fulldeps/rustc-macro/append-impl.rs rename to src/test/run-pass-fulldeps/rustc-macro/append-impl.rs index 1300fe66585..b7025c61fb6 100644 --- a/src/test/compile-fail-fulldeps/rustc-macro/append-impl.rs +++ b/src/test/run-pass-fulldeps/rustc-macro/append-impl.rs @@ -24,7 +24,6 @@ trait Append { Append, Eq)] struct A { -//~^ ERROR: the semantics of constant patterns is not yet settled inner: u32, } diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/append-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs similarity index 100% rename from src/test/compile-fail-fulldeps/rustc-macro/auxiliary/append-impl.rs rename to src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs index 4dd6ad88b75..42155383dec 100644 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs +++ b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs @@ -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() } From 5b6638ace0e615b3f271467cbf614d130b24db38 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 27 Sep 2016 13:13:09 -0700 Subject: [PATCH 12/16] Remove requirement to use 10.7 (fixes macOS) --- src/bootstrap/lib.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bcc53129f8d..784ca6f5cc4 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -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) From cb3b03c2a9372bae2974652ab72809f3e6258f22 Mon Sep 17 00:00:00 2001 From: Paulo Matos Date: Fri, 23 Sep 2016 17:38:20 +0200 Subject: [PATCH 13/16] Improve documention troubleshooting missing linker. Fix #32208. --- src/doc/book/getting-started.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/doc/book/getting-started.md b/src/doc/book/getting-started.md index bff448aadd5..22db70e605b 100644 --- a/src/doc/book/getting-started.md +++ b/src/doc/book/getting-started.md @@ -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. +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 user’s forum][users] and [Stack Overflow][stackoverflow]. From 3a276471f69a70b804359a4df2289e79061218dc Mon Sep 17 00:00:00 2001 From: Tim Neumann Date: Wed, 28 Sep 2016 08:06:49 +0200 Subject: [PATCH 14/16] update mips64* data-layout --- src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs | 2 +- src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs index 83785634428..7e45b320653 100644 --- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs @@ -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(), diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs index e1340e8e127..338a5da1e1d 100644 --- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs @@ -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(), From 61cbf414d7f4ea19de66da25d0ea034541e31750 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Sep 2016 15:27:33 +0200 Subject: [PATCH 15/16] Update E0050 to new error format --- src/librustc/hir/map/mod.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 64 +++++++++++++++++++-- src/test/compile-fail/E0050.rs | 9 ++- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b351bd427ac..b2ae0b7b609 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -260,7 +260,7 @@ impl<'ast> Map<'ast> { EntryVariant(p, _) | EntryExpr(p, _) | EntryStmt(p, _) | - EntryTy(p, _) | + EntryTy(p, _) | EntryLocal(p, _) | EntryPat(p, _) | EntryBlock(p, _) | diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 4a631493398..b44ff5ce07e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -138,14 +138,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; } diff --git a/src/test/compile-fail/E0050.rs b/src/test/compile-fail/E0050.rs index 2f7dc96361f..5c53d62709a 100644 --- a/src/test/compile-fail/E0050.rs +++ b/src/test/compile-fail/E0050.rs @@ -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() { From b543f3a4b29f15d6db7fb0ccab8bdc9900cbf84e Mon Sep 17 00:00:00 2001 From: ParkHanbum Date: Wed, 28 Sep 2016 22:44:28 +0900 Subject: [PATCH 16/16] Add testcase for issue-18088. ref : https://github.com/rust-lang/rust/issues/18088. --- src/test/run-pass/issue-18088.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/run-pass/issue-18088.rs diff --git a/src/test/run-pass/issue-18088.rs b/src/test/run-pass/issue-18088.rs new file mode 100644 index 00000000000..a45256387d6 --- /dev/null +++ b/src/test/run-pass/issue-18088.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +pub trait Indexable: std::ops::Index { + fn index2(&self, i: usize) -> &T { + &self[i] + } +} +fn main() {}