about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-09-28 15:03:26 -0700
committerGitHub <noreply@github.com>2016-09-28 15:03:26 -0700
commit86affcdf6c622278a89b73bb7f1b8ac00e970888 (patch)
treef8f361e0f1dd7ed5980297531f829b13fd0314bc
parentf17b1e03dfb5df1754a7c68bda439ed9c0b51de4 (diff)
parentac82eaaafef1a85c266acfcf659fe62405f1c99f (diff)
downloadrust-86affcdf6c622278a89b73bb7f1b8ac00e970888.tar.gz
rust-86affcdf6c622278a89b73bb7f1b8ac00e970888.zip
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:
-rw-r--r--src/bootstrap/lib.rs7
-rw-r--r--src/doc/book/getting-started.md22
-rw-r--r--src/doc/book/variable-bindings.md2
-rw-r--r--src/libcore/intrinsics.rs13
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs2
-rw-r--r--src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs16
-rw-r--r--src/librustc_typeck/check/compare_method.rs64
-rw-r--r--src/libstd/collections/hash/map.rs16
-rw-r--r--src/libstd/collections/hash/set.rs14
-rw-r--r--src/libsyntax_ext/deriving/mod.rs216
-rw-r--r--src/test/compile-fail/E0025.rs5
-rw-r--r--src/test/compile-fail/E0050.rs9
-rw-r--r--src/test/compile-fail/issue-15260.rs25
-rw-r--r--src/test/run-pass-fulldeps/rustc-macro/append-impl.rs (renamed from src/test/compile-fail-fulldeps/rustc-macro/append-impl.rs)1
-rw-r--r--src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs (renamed from src/test/compile-fail-fulldeps/rustc-macro/auxiliary/append-impl.rs)0
-rw-r--r--src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs4
-rw-r--r--src/test/run-pass/issue-18088.rs17
19 files changed, 301 insertions, 136 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)
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.
-
-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].
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
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::<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);
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index bafb00edc19..39114ec4238 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_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(),
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/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index ffff05885ad..826a88127d8 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -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;
     }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 29a79631535..35f5641679a 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -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> {
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index a5089543980..cb8393ed075 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -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> {
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 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 {
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/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() {
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 };
 }
diff --git a/src/test/compile-fail-fulldeps/rustc-macro/append-impl.rs b/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
index c3d295e02c1..c3d295e02c1 100644
--- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/append-impl.rs
+++ b/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()
 }
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 <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() {}