about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-13 17:49:15 +0000
committerbors <bors@rust-lang.org>2015-03-13 17:49:15 +0000
commit9eb69abad8ffbce840e7dc7038ddea434dc987f1 (patch)
tree217b64e9e1271d2be83dfb091044432928861520
parentee7696383f3423cdd17373ff9e75c01acd8e3417 (diff)
parent40b64645fecbee4e11da1ea4328c1b1ab4b9b8a0 (diff)
downloadrust-9eb69abad8ffbce840e7dc7038ddea434dc987f1.tar.gz
rust-9eb69abad8ffbce840e7dc7038ddea434dc987f1.zip
Auto merge of #23337 - Manishearth:rollup, r=Manishearth
r? @Manishearth
-rw-r--r--mk/llvm.mk6
-rw-r--r--mk/main.mk4
-rw-r--r--mk/target.mk2
-rw-r--r--src/doc/trpl/hello-cargo.md6
-rwxr-xr-xsrc/etc/gdb_rust_pretty_printing.py89
-rw-r--r--src/liballoc/heap.rs1
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/libcore/hash/mod.rs4
-rw-r--r--src/libcore/ptr.rs29
-rw-r--r--src/librustc/metadata/csearch.rs5
-rw-r--r--src/librustc/metadata/decoder.rs7
-rw-r--r--src/librustc/middle/dead.rs28
-rw-r--r--src/librustc/middle/pat_util.rs24
-rw-r--r--src/librustc_trans/trans/base.rs15
-rw-r--r--src/librustc_trans/trans/foreign.rs4
-rw-r--r--src/librustdoc/clean/inline.rs41
-rw-r--r--src/librustdoc/clean/mod.rs27
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/item_type.rs1
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/libsyntax/feature_gate.rs3
-rw-r--r--src/libsyntax/parse/mod.rs1
-rw-r--r--src/libtest/lib.rs1
-rw-r--r--src/test/compile-fail/lint-dead-code-variant.rs42
-rw-r--r--src/test/debuginfo/gdb-pretty-std.rs60
-rw-r--r--src/test/run-make/rustdoc-default-impl/Makefile5
-rw-r--r--src/test/run-make/rustdoc-default-impl/bar.rs17
-rw-r--r--src/test/run-make/rustdoc-default-impl/foo.rs33
29 files changed, 417 insertions, 47 deletions
diff --git a/mk/llvm.mk b/mk/llvm.mk
index b07c2a1d62f..1861dd313ce 100644
--- a/mk/llvm.mk
+++ b/mk/llvm.mk
@@ -44,10 +44,10 @@ $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
 	touch -r $$@.start_time $$@ && rm $$@.start_time
 
 ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
-LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-					-print-file-name=libstdc++.a)
+LLVM_STDCPP_RUSTFLAGS_$(1) = -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
+					-print-file-name=libstdc++.a))"
 else
-LLVM_STDCPP_LOCATION_$(1) =
+LLVM_STDCPP_RUSTFLAGS_$(1) =
 endif
 
 
diff --git a/mk/main.mk b/mk/main.mk
index 4bfc65ad843..ad9d0d0ca5e 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),beta)
-CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION)
-CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION)
+CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
+CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),nightly)
diff --git a/mk/target.mk b/mk/target.mk
index 2435edfb9dc..4182ec81a7e 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -85,7 +85,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
 		$$(RUST_LIB_FLAGS_ST$(1)) \
 		-L "$$(RT_OUTPUT_DIR_$(2))" \
 		-L "$$(LLVM_LIBDIR_$(2))" \
-		-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
+		$$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
 		$$(RUSTFLAGS_$(4)) \
 		--out-dir $$(@D) \
 		-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
diff --git a/src/doc/trpl/hello-cargo.md b/src/doc/trpl/hello-cargo.md
index d077aac7c2d..b45211e3a08 100644
--- a/src/doc/trpl/hello-cargo.md
+++ b/src/doc/trpl/hello-cargo.md
@@ -85,9 +85,11 @@ Hello, world!
 Bam! We build our project with `cargo build`, and run it with
 `./target/debug/hello_world`. This hasn't bought us a whole lot over our simple use
 of `rustc`, but think about the future: when our project has more than one
-file, we would need to call `rustc` more than once, and pass it a bunch of options to
+file, we would need to call `rustc` more than once and pass it a bunch of options to
 tell it to build everything together. With Cargo, as our project grows, we can
-just `cargo build` and it'll work the right way. When you're project is finally ready for release, you can use `cargo build --release` to compile your crates with optimizations.
+just `cargo build`, and it'll work the right way. When your project is finally
+ready for release, you can use `cargo build --release` to compile your crates with
+optimizations.
 
 You'll also notice that Cargo has created a new file: `Cargo.lock`.
 
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index c5587bb10d1..dbf27e88c14 100755
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -27,9 +27,18 @@ def rust_pretty_printer_lookup_function(val):
     if type_code == gdb.TYPE_CODE_STRUCT:
         struct_kind = classify_struct(val.type)
 
+        if struct_kind == STRUCT_KIND_SLICE:
+            return RustSlicePrinter(val)
+
         if struct_kind == STRUCT_KIND_STR_SLICE:
             return RustStringSlicePrinter(val)
 
+        if struct_kind == STRUCT_KIND_STD_VEC:
+            return RustStdVecPrinter(val)
+
+        if struct_kind == STRUCT_KIND_STD_STRING:
+            return RustStdStringPrinter(val)
+
         if struct_kind == STRUCT_KIND_TUPLE:
             return RustTuplePrinter(val)
 
@@ -172,6 +181,28 @@ class RustTupleStructPrinter:
     def display_hint(self):
         return "array"
 
+class RustSlicePrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def display_hint(self):
+        return "array"
+
+    def to_string(self):
+        length = int(self.val["length"])
+        return self.val.type.tag + ("(len: %i)" % length)
+
+    def children(self):
+        cs = []
+        length = int(self.val["length"])
+        data_ptr = self.val["data_ptr"]
+        assert data_ptr.type.code == gdb.TYPE_CODE_PTR
+        pointee_type = data_ptr.type.target()
+
+        for index in range(0, length):
+            cs.append((str(index), (data_ptr + index).dereference()))
+
+        return cs
 
 class RustStringSlicePrinter:
     def __init__(self, val):
@@ -181,6 +212,35 @@ class RustStringSlicePrinter:
         slice_byte_len = self.val["length"]
         return '"%s"' % self.val["data_ptr"].string(encoding="utf-8", length=slice_byte_len)
 
+class RustStdVecPrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def display_hint(self):
+        return "array"
+
+    def to_string(self):
+        length = int(self.val["len"])
+        cap = int(self.val["cap"])
+        return self.val.type.tag + ("(len: %i, cap: %i)" % (length, cap))
+
+    def children(self):
+        cs = []
+        (length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val)
+        pointee_type = data_ptr.type.target()
+
+        for index in range(0, length):
+            cs.append((str(index), (data_ptr + index).dereference()))
+        return cs
+
+class RustStdStringPrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        (length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val["vec"])
+        return '"%s"' % data_ptr.string(encoding="utf-8", length=length)
+
 
 class RustCStyleEnumPrinter:
     def __init__(self, val):
@@ -204,19 +264,38 @@ STRUCT_KIND_TUPLE           = 2
 STRUCT_KIND_TUPLE_VARIANT   = 3
 STRUCT_KIND_STRUCT_VARIANT  = 4
 STRUCT_KIND_CSTYLE_VARIANT  = 5
-STRUCT_KIND_STR_SLICE       = 6
+STRUCT_KIND_SLICE           = 6
+STRUCT_KIND_STR_SLICE       = 7
+STRUCT_KIND_STD_VEC         = 8
+STRUCT_KIND_STD_STRING      = 9
 
 
 def classify_struct(type):
+    # print("\nclassify_struct: tag=%s\n" % type.tag)
     if type.tag == "&str":
         return STRUCT_KIND_STR_SLICE
 
+    if type.tag.startswith("&[") and type.tag.endswith("]"):
+        return STRUCT_KIND_SLICE
+
     fields = list(type.fields())
     field_count = len(fields)
 
     if field_count == 0:
         return STRUCT_KIND_REGULAR_STRUCT
 
+    if (field_count == 3 and
+        fields[0].name == "ptr" and
+        fields[1].name == "len" and
+        fields[2].name == "cap" and
+        type.tag.startswith("Vec<")):
+        return STRUCT_KIND_STD_VEC
+
+    if (field_count == 1 and
+        fields[0].name == "vec" and
+        type.tag == "String"):
+        return STRUCT_KIND_STD_STRING
+
     if fields[0].name == "RUST$ENUM$DISR":
         if field_count == 1:
             return STRUCT_KIND_CSTYLE_VARIANT
@@ -254,3 +333,11 @@ def get_field_at_index(val, index):
             return field
         i += 1
     return None
+
+def extract_length_and_data_ptr_from_std_vec(vec_val):
+    length = int(vec_val["len"])
+    vec_ptr_val = vec_val["ptr"]
+    unique_ptr_val = vec_ptr_val[first_field(vec_ptr_val)]
+    data_ptr = unique_ptr_val[first_field(unique_ptr_val)]
+    assert data_ptr.type.code == gdb.TYPE_CODE_PTR
+    return (length, data_ptr)
\ No newline at end of file
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index 3b93171386a..f9936b7a16a 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -198,6 +198,7 @@ mod imp {
     extern {}
 
     extern {
+        #[allocator]
         fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
         fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
         fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 5c9a42a8a71..34c0686fe37 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -69,6 +69,7 @@
 
 #![feature(no_std)]
 #![no_std]
+#![feature(allocator)]
 #![feature(lang_items, unsafe_destructor)]
 #![feature(box_syntax)]
 #![feature(optin_builtin_traits)]
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 4b545435ea1..fdc0020dfcd 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -70,9 +70,7 @@ mod sip;
 /// A hashable type.
 ///
 /// The `H` type parameter is an abstract hash state that is used by the `Hash`
-/// to compute the hash. Specific implementations of this trait may specialize
-/// for particular instances of `H` in order to be able to optimize the hashing
-/// behavior.
+/// to compute the hash.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hash {
     /// Feeds this value into the state given, updating the hasher as necessary.
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 0625c3c7d60..32123a8271c 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -33,31 +33,34 @@
 //! let my_speed_ptr: *mut i32 = &mut my_speed;
 //! ```
 //!
+//! To get a pointer to a boxed value, dereference the box:
+//!
+//! ```
+//! let my_num: Box<i32> = Box::new(10);
+//! let my_num_ptr: *const i32 = &*my_num;
+//! let mut my_speed: Box<i32> = Box::new(88);
+//! let my_speed_ptr: *mut i32 = &mut *my_speed;
+//! ```
+//!
 //! This does not take ownership of the original allocation
 //! and requires no resource management later,
 //! but you must not use the pointer after its lifetime.
 //!
-//! ## 2. Transmute an owned box (`Box<T>`).
+//! ## 2. Consume a box (`Box<T>`).
 //!
-//! The `transmute` function takes, by value, whatever it's given
-//! and returns it as whatever type is requested, as long as the
-//! types are the same size. Because `Box<T>` and `*mut T` have the same
-//! representation they can be trivially,
-//! though unsafely, transformed from one type to the other.
+//! The `into_raw` function consumes a box and returns
+//! the raw pointer. It doesn't destroy `T` or deallocate any memory.
 //!
 //! ```
-//! use std::mem;
+//! use std::boxed;
 //!
 //! unsafe {
-//!     let my_num: Box<i32> = Box::new(10);
-//!     let my_num: *const i32 = mem::transmute(my_num);
 //!     let my_speed: Box<i32> = Box::new(88);
-//!     let my_speed: *mut i32 = mem::transmute(my_speed);
+//!     let my_speed: *mut i32 = boxed::into_raw(my_speed);
 //!
 //!     // By taking ownership of the original `Box<T>` though
-//!     // we are obligated to transmute it back later to be destroyed.
-//!     drop(mem::transmute::<_, Box<i32>>(my_speed));
-//!     drop(mem::transmute::<_, Box<i32>>(my_num));
+//!     // we are obligated to put it together later to be destroyed.
+//!     drop(Box::from_raw(my_speed));
 //! }
 //! ```
 //!
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index ed5783c8dba..ca8ae83ab80 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -411,3 +411,8 @@ pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) ->
     let cdata = cstore.get_crate_data(trait_def_id.krate);
     decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
 }
+
+pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(impl_did.krate);
+    decoder::is_default_impl(&*cdata, impl_did.node)
+}
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index dbbc17c018a..c0bad80ab59 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -1537,13 +1537,18 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
     }
 }
 
-pub fn is_defaulted_trait<'tcx>(cdata: Cmd, trait_id: ast::NodeId) -> bool {
+pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool {
     let trait_doc = lookup_item(trait_id, cdata.data());
     assert!(item_family(trait_doc) == Family::Trait);
     let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
     reader::doc_as_u8(defaulted_doc) != 0
 }
 
+pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool {
+    let impl_doc = lookup_item(impl_id, cdata.data());
+    item_family(impl_doc) == Family::DefaultImpl
+}
+
 pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
     let crate_doc = rbml::Doc::new(metadata);
     let cm_doc = reader::get_doc(crate_doc, tag_codemap);
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 5efea66ab0c..09378f2c973 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -47,6 +47,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     struct_has_extern_repr: bool,
     ignore_non_const_paths: bool,
     inherited_pub_visibility: bool,
+    ignore_variant_stack: Vec<ast::NodeId>,
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@@ -59,6 +60,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             struct_has_extern_repr: false,
             ignore_non_const_paths: false,
             inherited_pub_visibility: false,
+            ignore_variant_stack: vec![],
         }
     }
 
@@ -79,7 +81,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 def::DefPrimTy(_) => (),
                 def::DefVariant(enum_id, variant_id, _) => {
                     self.check_def_id(enum_id);
-                    self.check_def_id(variant_id);
+                    if !self.ignore_variant_stack.contains(&variant_id.node) {
+                        self.check_def_id(variant_id);
+                    }
                 }
                 _ => {
                     self.check_def_id(def.def_id());
@@ -278,6 +282,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         visit::walk_expr(self, expr);
     }
 
+    fn visit_arm(&mut self, arm: &ast::Arm) {
+        if arm.pats.len() == 1 {
+            let pat = &*arm.pats[0];
+            let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
+
+            // Inside the body, ignore constructions of variants
+            // necessary for the pattern to match. Those construction sites
+            // can't be reached unless the variant is constructed elsewhere.
+            let len = self.ignore_variant_stack.len();
+            self.ignore_variant_stack.push_all(&*variants);
+            visit::walk_arm(self, arm);
+            self.ignore_variant_stack.truncate(len);
+        } else {
+            visit::walk_arm(self, arm);
+        }
+    }
+
     fn visit_pat(&mut self, pat: &ast::Pat) {
         let def_map = &self.tcx.def_map;
         match pat.node {
@@ -397,6 +418,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
         worklist.push(*id);
     }
     for id in reachable_symbols {
+        // Reachable variants can be dead, because we warn about
+        // variants never constructed, not variants never used.
+        if let Some(ast_map::NodeVariant(..)) = tcx.map.find(*id) {
+            continue;
+        }
         worklist.push(*id);
     }
 
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index c5abff3b963..eca3296e65c 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -155,3 +155,27 @@ pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
         span: DUMMY_SP,
     })
 }
+
+/// Return variants that are necessary to exist for the pattern to match.
+pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
+    let mut variants = vec![];
+    walk_pat(pat, |p| {
+        match p.node {
+            ast::PatEnum(_, _) |
+            ast::PatIdent(_, _, None) |
+            ast::PatStruct(..) => {
+                match dm.borrow().get(&p.id) {
+                    Some(&PathResolution {base_def: DefVariant(_, id, _), ..}) => {
+                        variants.push(id.node);
+                    }
+                    _ => ()
+                }
+            }
+            _ => ()
+        }
+        true
+    });
+    variants.sort();
+    variants.dedup();
+    variants
+}
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 74326d4ea91..ccf24f7e859 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -33,7 +33,7 @@ use super::ModuleTranslation;
 use back::link::{mangle_exported_name};
 use back::{link, abi};
 use lint;
-use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
+use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
 use llvm;
 use metadata::{csearch, encoder, loader};
 use middle::astencode;
@@ -456,6 +456,9 @@ pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: Val
                                                llvm::FunctionIndex as c_uint,
                                                llvm::ColdAttribute as uint64_t)
             },
+            "allocator" => {
+                llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
+            }
             _ => used = false,
         }
         if used {
@@ -903,8 +906,10 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     ccx.sess().bug("unexpected intrinsic in trans_external_path")
                 }
                 _ => {
-                    foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
-                                                      &name[..])
+                    let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]);
+                    let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
+                    set_llvm_fn_attrs(ccx, &attrs, llfn);
+                    llfn
                 }
             }
         }
@@ -2841,7 +2846,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                     let abi = ccx.tcx().map.get_foreign_abi(id);
                     let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
                     let name = foreign::link_name(&*ni);
-                    foreign::register_foreign_item_fn(ccx, abi, ty, &name)
+                    let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
+                    set_llvm_fn_attrs(ccx, &ni.attrs, llfn);
+                    llfn
                 }
                 ast::ForeignItemStatic(..) => {
                     foreign::register_static(ccx, &*ni)
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index b0383e355e4..dfc7e7f604f 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -470,8 +470,8 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
                                                      "foreign fn's sty isn't a bare_fn_ty?")
                     }
 
-                    register_foreign_item_fn(ccx, abi, ty,
-                                             &lname);
+                    let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
+                    base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn);
                     // Unlike for other items, we shouldn't call
                     // `base::update_linkage` here.  Foreign items have
                     // special linkage requirements, which are handled
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 9f7b68f38fa..aa17bf20d74 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -259,26 +259,43 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
     impls.into_iter().filter_map(|a| a).collect()
 }
 
-fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
+fn build_impl(cx: &DocContext,
+              tcx: &ty::ctxt,
               did: ast::DefId) -> Option<clean::Item> {
     if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
         return None
     }
 
+    let attrs = load_attrs(cx, tcx, did);
     let associated_trait = csearch::get_impl_trait(tcx, did);
-    // If this is an impl for a #[doc(hidden)] trait, be sure to not inline it.
-    match associated_trait {
-        Some(ref t) => {
-            let trait_attrs = load_attrs(cx, tcx, t.def_id);
-            if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
-                return None
-            }
+    if let Some(ref t) = associated_trait {
+        // If this is an impl for a #[doc(hidden)] trait, be sure to not inline
+        let trait_attrs = load_attrs(cx, tcx, t.def_id);
+        if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
+            return None
         }
-        None => {}
     }
 
-    let attrs = load_attrs(cx, tcx, did);
-    let ty = ty::lookup_item_type(tcx, did);
+    // If this is a defaulted impl, then bail out early here
+    if csearch::is_default_impl(&tcx.sess.cstore, did) {
+        return Some(clean::Item {
+            inner: clean::DefaultImplItem(clean::DefaultImpl {
+                // FIXME: this should be decoded
+                unsafety: ast::Unsafety::Normal,
+                trait_: match associated_trait.as_ref().unwrap().clean(cx) {
+                    clean::TraitBound(polyt, _) => polyt.trait_,
+                    clean::RegionBound(..) => unreachable!(),
+                },
+            }),
+            source: clean::Span::empty(),
+            name: None,
+            attrs: attrs,
+            visibility: Some(ast::Inherited),
+            stability: stability::lookup(tcx, did).clean(cx),
+            def_id: did,
+        });
+    }
+
     let predicates = ty::lookup_predicates(tcx, did);
     let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
             .iter()
@@ -330,8 +347,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
         }
     }).collect();
     let polarity = csearch::get_impl_polarity(tcx, did);
+    let ty = ty::lookup_item_type(tcx, did);
     return Some(clean::Item {
         inner: clean::ImplItem(clean::Impl {
+            unsafety: ast::Unsafety::Normal, // FIXME: this should be decoded
             derived: clean::detect_derived(&attrs),
             trait_: associated_trait.clean(cx).map(|bound| {
                 match bound {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e91e95961c5..421549f8b7e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -337,6 +337,7 @@ pub enum ItemEnum {
     MacroItem(Macro),
     PrimitiveItem(PrimitiveType),
     AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
+    DefaultImplItem(DefaultImpl),
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -367,6 +368,7 @@ impl Clean<Item> for doctree::Module {
         items.extend(self.traits.iter().map(|x| x.clean(cx)));
         items.extend(self.impls.iter().map(|x| x.clean(cx)));
         items.extend(self.macros.iter().map(|x| x.clean(cx)));
+        items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
@@ -2079,6 +2081,7 @@ impl Clean<ImplPolarity> for ast::ImplPolarity {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Impl {
+    pub unsafety: ast::Unsafety,
     pub generics: Generics,
     pub trait_: Option<Type>,
     pub for_: Type,
@@ -2101,6 +2104,7 @@ impl Clean<Item> for doctree::Impl {
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             inner: ImplItem(Impl {
+                unsafety: self.unsafety,
                 generics: self.generics.clean(cx),
                 trait_: self.trait_.clean(cx),
                 for_: self.for_.clean(cx),
@@ -2112,6 +2116,29 @@ impl Clean<Item> for doctree::Impl {
     }
 }
 
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub struct DefaultImpl {
+    pub unsafety: ast::Unsafety,
+    pub trait_: Type,
+}
+
+impl Clean<Item> for doctree::DefaultImpl {
+    fn clean(&self, cx: &DocContext) -> Item {
+        Item {
+            name: None,
+            attrs: self.attrs.clean(cx),
+            source: self.whence.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: Some(ast::Public),
+            stability: None,
+            inner: DefaultImplItem(DefaultImpl {
+                unsafety: self.unsafety,
+                trait_: self.trait_.clean(cx),
+            }),
+        }
+    }
+}
+
 impl Clean<Item> for doctree::ExternCrate {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 5a4deaa2e72..c6d8b9428c5 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -202,6 +202,8 @@ pub struct DefaultImpl {
     pub unsafety: ast::Unsafety,
     pub trait_: ast::TraitRef,
     pub id: ast::NodeId,
+    pub attrs: Vec<ast::Attribute>,
+    pub whence: Span,
 }
 
 pub struct Macro {
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index 356be2ffeb0..1d63f01be52 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -64,6 +64,7 @@ impl ItemType {
             clean::MacroItem(..)           => ItemType::Macro,
             clean::PrimitiveItem(..)       => ItemType::Primitive,
             clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
+            clean::DefaultImplItem(..)     => ItemType::Impl,
         }
     }
 
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 722f14fa6d4..953b442bb3c 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -176,7 +176,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                     return None;
                 }
             }
-            clean::ImplItem(..) => {}
+            clean::DefaultImplItem(..) | clean::ImplItem(..) => {}
 
             // tymethods/macros have no control over privacy
             clean::MacroItem(..) | clean::TyMethodItem(..) => {}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 3e998166397..d53954b29b5 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -362,7 +362,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 let i = DefaultImpl {
                     unsafety: unsafety,
                     trait_: trait_ref.clone(),
-                    id: item.id
+                    id: item.id,
+                    attrs: item.attrs.clone(),
+                    whence: item.span,
                 };
                 om.def_traits.push(i);
             }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c3bac0cf57c..0a9980c8925 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -83,6 +83,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("box_syntax", "1.0.0", Active),
     ("on_unimplemented", "1.0.0", Active),
     ("simd_ffi", "1.0.0", Active),
+    ("allocator", "1.0.0", Active),
 
     ("if_let", "1.0.0", Accepted),
     ("while_let", "1.0.0", Accepted),
@@ -230,6 +231,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("rustc_on_unimplemented", Gated("on_unimplemented",
                                      "the `#[rustc_on_unimplemented]` attribute \
                                       is an experimental feature")),
+    ("allocator", Gated("allocator",
+                        "the `#[allocator]` attribute is an experimental feature")),
     ("rustc_variance", Gated("rustc_attrs",
                              "the `#[rustc_variance]` attribute \
                               is an experimental feature")),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index fae305f9551..f542246705c 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -754,7 +754,6 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
 mod test {
     use super::*;
     use std::rc::Rc;
-    use serialize::json;
     use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
     use owned_slice::OwnedSlice;
     use ast;
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 19da658ed4f..80d5ab5baf3 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -121,6 +121,7 @@ impl fmt::Display for TestName {
 #[derive(Clone, Copy)]
 enum NamePadding {
     PadNone,
+    #[allow(dead_code)]
     PadOnLeft,
     PadOnRight,
 }
diff --git a/src/test/compile-fail/lint-dead-code-variant.rs b/src/test/compile-fail/lint-dead-code-variant.rs
new file mode 100644
index 00000000000..6146be65e38
--- /dev/null
+++ b/src/test/compile-fail/lint-dead-code-variant.rs
@@ -0,0 +1,42 @@
+// Copyright 2015 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.
+
+#![deny(dead_code)]
+
+#[derive(Copy)]
+enum Enum {
+    Variant1, //~ ERROR: variant is never used
+    Variant2,
+    Variant3,
+}
+
+fn copy(e: Enum) -> Enum {
+    use Enum::*;
+    match e {
+        Variant1 => Variant1,
+        Variant2 => Variant2,
+        Variant3 => Variant3,
+    }
+}
+
+fn max(e: Enum) -> Enum {
+    use Enum::*;
+    match e {
+        Variant1 => Variant3,
+        Variant2 => Variant3,
+        Variant3 => Variant3,
+    }
+}
+
+fn main() {
+    let e = Enum::Variant2;
+    copy(e);
+    max(e);
+}
diff --git a/src/test/debuginfo/gdb-pretty-std.rs b/src/test/debuginfo/gdb-pretty-std.rs
new file mode 100644
index 00000000000..dbf80a9bccc
--- /dev/null
+++ b/src/test/debuginfo/gdb-pretty-std.rs
@@ -0,0 +1,60 @@
+// Copyright 2013-2015 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.
+
+// ignore-windows failing on win32 bot
+// ignore-freebsd: gdb package too new
+// ignore-tidy-linelength
+// ignore-lldb
+// ignore-android: FIXME(#10381)
+// compile-flags:-g
+// min-gdb-version 7.7
+
+// gdb-command: run
+
+// gdb-command: print slice
+// gdb-check:$1 = &[i32](len: 4) = {0, 1, 2, 3}
+
+// gdb-command: print vec
+// gdb-check:$2 = Vec<u64>(len: 4, cap: [...]) = {4, 5, 6, 7}
+
+// gdb-command: print str_slice
+// gdb-check:$3 = "IAMA string slice!"
+
+// gdb-command: print string
+// gdb-check:$4 = "IAMA string!"
+
+// gdb-command: print some
+// gdb-check:$5 = Some = {8}
+
+// gdb-command: print none
+// gdb-check:$6 = None
+
+fn main() {
+
+    // &[]
+    let slice: &[i32] = &[0, 1, 2, 3];
+
+    // Vec
+    let vec = vec![4u64, 5, 6, 7];
+
+    // &str
+    let str_slice = "IAMA string slice!";
+
+    // String
+    let string = "IAMA string!".to_string();
+
+    // Option
+    let some = Some(8i16);
+    let none: Option<i64> = None;
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/run-make/rustdoc-default-impl/Makefile b/src/test/run-make/rustdoc-default-impl/Makefile
new file mode 100644
index 00000000000..338cf9d2053
--- /dev/null
+++ b/src/test/run-make/rustdoc-default-impl/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all: foo.rs bar.rs
+	$(RUSTC) foo.rs --crate-type lib
+	$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc bar.rs -L $(TMPDIR)
diff --git a/src/test/run-make/rustdoc-default-impl/bar.rs b/src/test/run-make/rustdoc-default-impl/bar.rs
new file mode 100644
index 00000000000..c9fae80d858
--- /dev/null
+++ b/src/test/run-make/rustdoc-default-impl/bar.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+extern crate foo;
+
+pub use foo::bar;
+
+pub fn wut<T: bar::Bar>() {
+}
+
diff --git a/src/test/run-make/rustdoc-default-impl/foo.rs b/src/test/run-make/rustdoc-default-impl/foo.rs
new file mode 100644
index 00000000000..08f3bd10e74
--- /dev/null
+++ b/src/test/run-make/rustdoc-default-impl/foo.rs
@@ -0,0 +1,33 @@
+// Copyright 2015 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 mod bar {
+    use std::marker;
+
+    pub trait Bar: marker::MarkerTrait + 'static {}
+
+    impl Bar for .. {}
+
+    pub trait Foo {
+        fn foo(&self) {}
+    }
+
+    impl Foo {
+        pub fn test<T: Bar>(&self) {}
+    }
+
+    pub struct TypeId;
+
+    impl TypeId {
+        pub fn of<T: Bar + ?Sized>() -> TypeId {
+            panic!()
+        }
+    }
+}