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. +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]. 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::()` /// 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); 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 { 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 { 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/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 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() } 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() {}