about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-11-01 07:04:17 +0000
committerbors <bors@rust-lang.org>2017-11-01 07:04:17 +0000
commit740286657a97770eca193062fd5e127c08c0808c (patch)
tree889864eeb724100b60d489f6435e7b22af7b9cc7
parent31bbe57c79112e91d2d8783032231c7e1d22855b (diff)
parent028455082e3e478ca01780862b324838a60c85fc (diff)
downloadrust-740286657a97770eca193062fd5e127c08c0808c.tar.gz
rust-740286657a97770eca193062fd5e127c08c0808c.zip
Auto merge of #45674 - kennytm:rollup, r=kennytm
Rollup of 14 pull requests

- Successful merges: #45450, #45579, #45602, #45619, #45624, #45644, #45646, #45648, #45649, #45650, #45652, #45660, #45664, #45671
- Failed merges:
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/native.rs1
m---------src/liblibc0
-rw-r--r--src/librustc/hir/mod.rs4
-rw-r--r--src/librustc/ich/hcx.rs11
-rw-r--r--src/librustc/middle/dead.rs12
-rw-r--r--src/librustc_resolve/lib.rs26
-rw-r--r--src/librustc_trans/back/linker.rs2
-rw-r--r--src/librustdoc/html/static/rustdoc.css12
-rw-r--r--src/libstd/io/mod.rs13
-rw-r--r--src/libstd/sys/unix/ext/mod.rs10
-rw-r--r--src/libstd/sys/unix/rand.rs4
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/libsyntax/parse/attr.rs9
-rw-r--r--src/libsyntax_pos/lib.rs77
-rw-r--r--src/test/run-make/symbol-visibility/Makefile14
-rw-r--r--src/test/run-pass/dead-code-alias-in-pat.rs18
-rw-r--r--src/test/ui/issue-45296.stderr3
-rw-r--r--src/test/ui/suggestions/issue-32354-suggest-import-rename.rs22
-rw-r--r--src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr16
-rw-r--r--src/tools/tidy/src/features.rs20
21 files changed, 220 insertions, 60 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 0ab4c79e3b2..707aceebb1e 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -294,7 +294,7 @@ def default_build_triple():
             raise ValueError('unknown byteorder: {}'.format(sys.byteorder))
         # only the n64 ABI is supported, indicate it
         ostype += 'abi64'
-    elif cputype == 'sparcv9':
+    elif cputype == 'sparcv9' or cputype == 'sparc64':
         pass
     else:
         err = "unknown cpu type: {}".format(cputype)
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index fb15f767f9e..19409ef779e 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -451,6 +451,7 @@ impl Step for Openssl {
             "x86_64-apple-darwin" => "darwin64-x86_64-cc",
             "x86_64-linux-android" => "linux-x86_64",
             "x86_64-unknown-freebsd" => "BSD-x86_64",
+            "x86_64-unknown-dragonfly" => "BSD-x86_64",
             "x86_64-unknown-linux-gnu" => "linux-x86_64",
             "x86_64-unknown-linux-musl" => "linux-x86_64",
             "x86_64-unknown-netbsd" => "BSD-x86_64",
diff --git a/src/liblibc b/src/liblibc
-Subproject 7e33065ce49759958c0d1c04fcadef961032a94
+Subproject 68f9959e53da6c70bed7119cd09342859d43126
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 58f1b1f9a41..e23e2acefb7 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1054,7 +1054,9 @@ pub enum Expr_ {
     /// A function call
     ///
     /// The first field resolves to the function itself (usually an `ExprPath`),
-    /// and the second field is the list of arguments
+    /// and the second field is the list of arguments.
+    /// This also represents calling the constructor of
+    /// tuple-like ADTs such as tuple structs and enum variants.
     ExprCall(P<Expr>, HirVec<Expr>),
     /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
     ///
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index f46540114f7..d24344e4e21 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -371,17 +371,18 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
         // If this is not an empty or invalid span, we want to hash the last
         // position that belongs to it, as opposed to hashing the first
         // position past it.
-        let span_hi = if self.hi() > self.lo() {
+        let span = self.data();
+        let span_hi = if span.hi > span.lo {
             // We might end up in the middle of a multibyte character here,
             // but that's OK, since we are not trying to decode anything at
             // this position.
-            self.hi() - ::syntax_pos::BytePos(1)
+            span.hi - ::syntax_pos::BytePos(1)
         } else {
-            self.hi()
+            span.hi
         };
 
         {
-            let loc1 = hcx.codemap().byte_pos_to_line_and_col(self.lo());
+            let loc1 = hcx.codemap().byte_pos_to_line_and_col(span.lo);
             let loc1 = loc1.as_ref()
                            .map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize()))
                            .unwrap_or(("???", 0, 0));
@@ -414,7 +415,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
             }
         }
 
-        if self.ctxt() == SyntaxContext::empty() {
+        if span.ctxt == SyntaxContext::empty() {
             0u8.hash_stable(hcx, hasher);
         } else {
             1u8.hash_stable(hcx, hasher);
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index a9d9f6f28ec..259794e9d0e 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -51,7 +51,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     tables: &'a ty::TypeckTables<'tcx>,
     live_symbols: Box<FxHashSet<ast::NodeId>>,
     struct_has_extern_repr: bool,
-    ignore_non_const_paths: bool,
+    in_pat: bool,
     inherited_pub_visibility: bool,
     ignore_variant_stack: Vec<DefId>,
 }
@@ -75,10 +75,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_definition(&mut self, def: Def) {
         match def {
-            Def::Const(_) | Def::AssociatedConst(..) => {
+            Def::Const(_) | Def::AssociatedConst(..) | Def::TyAlias(_) => {
                 self.check_def_id(def.def_id());
             }
-            _ if self.ignore_non_const_paths => (),
+            _ if self.in_pat => (),
             Def::PrimTy(..) | Def::SelfTy(..) |
             Def::Local(..) | Def::Upvar(..) => {}
             Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
@@ -289,9 +289,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
             _ => ()
         }
 
-        self.ignore_non_const_paths = true;
+        self.in_pat = true;
         intravisit::walk_pat(self, pat);
-        self.ignore_non_const_paths = false;
+        self.in_pat = false;
     }
 
     fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) {
@@ -429,7 +429,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         tables: &ty::TypeckTables::empty(None),
         live_symbols: box FxHashSet(),
         struct_has_extern_repr: false,
-        ignore_non_const_paths: false,
+        in_pat: false,
         inherited_pub_visibility: false,
         ignore_variant_stack: vec![],
     };
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 83eeaf551c5..3b27890013a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3606,12 +3606,12 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn report_conflict(&mut self,
+    fn report_conflict<'b>(&mut self,
                        parent: Module,
                        ident: Ident,
                        ns: Namespace,
-                       new_binding: &NameBinding,
-                       old_binding: &NameBinding) {
+                       new_binding: &NameBinding<'b>,
+                       old_binding: &NameBinding<'b>) {
         // Error on the second of two conflicting names
         if old_binding.span.lo() > new_binding.span.lo() {
             return self.report_conflict(parent, ident, ns, old_binding, new_binding);
@@ -3683,6 +3683,26 @@ impl<'a> Resolver<'a> {
                                                       old_noun, old_kind, name));
         }
 
+        // See https://github.com/rust-lang/rust/issues/32354
+        if old_binding.is_import() || new_binding.is_import() {
+            let binding = if new_binding.is_import() {
+                new_binding
+            } else {
+                old_binding
+            };
+
+            let cm = self.session.codemap();
+            let rename_msg = "You can use `as` to change the binding name of the import";
+
+            if let Ok(snippet) = cm.span_to_snippet(binding.span) {
+                err.span_suggestion(binding.span,
+                                    rename_msg,
+                                    format!("{} as Other{}", snippet, name));
+            } else {
+                err.span_label(binding.span, rename_msg);
+            }
+        }
+
         err.emit();
         self.name_already_seen.insert(name, span);
     }
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs
index 99422bf8c90..51f89110eb4 100644
--- a/src/librustc_trans/back/linker.rs
+++ b/src/librustc_trans/back/linker.rs
@@ -747,7 +747,7 @@ impl<'a> Linker for EmLinker<'a> {
 fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
     let mut symbols = Vec::new();
 
-    let export_threshold = symbol_export::threshold(tcx);
+    let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
     for &(ref name, _, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
         if level.is_below_threshold(export_threshold) {
             symbols.push(name.clone());
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index dcb0de3bb92..398a692f8df 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -545,7 +545,8 @@ a {
 .content .search-results td:first-child { padding-right: 0; }
 .content .search-results td:first-child a { padding-right: 10px; }
 
-tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; color: black;
+tr.result span.primitive::after {
+	content: ' (primitive type)'; font-style: italic; color: black;
 }
 
 body.blur > :not(#help) {
@@ -761,6 +762,15 @@ span.since {
 	margin-top: 5px;
 }
 
+.docblock > .section-header:first-child {
+	margin-left: 15px;
+	margin-top: 0;
+}
+
+.docblock > .section-header:first-child:hover > a:before {
+	left: -10px;
+}
+
 .enum > .collapsed, .struct > .collapsed {
 	margin-bottom: 25px;
 }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 074ab3ebd8f..dec281212a5 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -736,10 +736,10 @@ pub trait Read {
 
     /// Transforms this `Read` instance to an [`Iterator`] over its bytes.
     ///
-    /// The returned type implements [`Iterator`] where the `Item` is [`Result`]`<`[`u8`]`,
-    /// R::Err>`. The yielded item is [`Ok`] if a byte was successfully read and
-    /// [`Err`] otherwise for I/O errors. EOF is mapped to returning [`None`] from
-    /// this iterator.
+    /// The returned type implements [`Iterator`] where the `Item` is
+    /// [`Result`]`<`[`u8`]`, `[`io::Error`]>`.
+    /// The yielded item is [`Ok`] if a byte was successfully read and [`Err`]
+    /// otherwise. EOF is mapped to returning [`None`] from this iterator.
     ///
     /// # Examples
     ///
@@ -748,6 +748,7 @@ pub trait Read {
     /// [file]: ../fs/struct.File.html
     /// [`Iterator`]: ../../std/iter/trait.Iterator.html
     /// [`Result`]: ../../std/result/enum.Result.html
+    /// [`io::Error``]: ../../std/io/struct.Error.html
     /// [`u8`]: ../../std/primitive.u8.html
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
@@ -1410,6 +1411,8 @@ pub trait BufRead: Read {
     ///
     /// If successful, this function will return the total number of bytes read.
     ///
+    /// An empty buffer returned indicates that the stream has reached EOF.
+    ///
     /// # Errors
     ///
     /// This function will ignore all instances of [`ErrorKind::Interrupted`] and
@@ -1470,6 +1473,8 @@ pub trait BufRead: Read {
     ///
     /// If successful, this function will return the total number of bytes read.
     ///
+    /// An empty buffer returned indicates that the stream has reached EOF.
+    ///
     /// # Errors
     ///
     /// This function has the same error semantics as [`read_until`] and will
diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs
index 98bc90dd4e1..c221f7c8cfe 100644
--- a/src/libstd/sys/unix/ext/mod.rs
+++ b/src/libstd/sys/unix/ext/mod.rs
@@ -10,8 +10,14 @@
 
 //! Experimental extensions to `std` for Unix platforms.
 //!
-//! For now, this module is limited to extracting file descriptors,
-//! but its functionality will grow over time.
+//! Provides access to platform-level information on Unix platforms, and
+//! exposes Unix-specific functions that would otherwise be inappropriate as
+//! part of the core `std` library.
+//!
+//! It exposes more ways to deal with platform-specific strings (`OsStr`,
+//! `OsString`), allows to set permissions more granularly, extract low-level
+//! file descriptors from files and sockets, and has platform-specific helpers
+//! for spawning processes.
 //!
 //! # Examples
 //!
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index fd066c9cdbe..e2d40742c71 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -49,7 +49,9 @@ mod imp {
                   target_arch = "powerpc64",
                   target_arch = "s390x")))]
     fn getrandom(buf: &mut [u8]) -> libc::c_long {
-        #[cfg(target_arch = "x86_64")]
+        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
+        const NR_GETRANDOM: libc::c_long = 0x40000000 + 318;
+        #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
         const NR_GETRANDOM: libc::c_long = 318;
         #[cfg(target_arch = "x86")]
         const NR_GETRANDOM: libc::c_long = 355;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index d3995d95792..be0af8052eb 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -901,7 +901,9 @@ pub enum ExprKind {
     /// A function call
     ///
     /// The first field resolves to the function itself,
-    /// and the second field is the list of arguments
+    /// and the second field is the list of arguments.
+    /// This also represents calling the constructor of
+    /// tuple-like ADTs such as tuple structs and enum variants.
     Call(P<Expr>, Vec<P<Expr>>),
     /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
     ///
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 48c92873e14..053746b579d 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -105,11 +105,10 @@ impl<'a> Parser<'a> {
                         let span = self.span;
                         self.diagnostic()
                             .struct_span_err(span, reason)
-                            .note("inner attributes and doc comments, like `#![no_std]` or \
-                                   `//! My crate`, annotate the item enclosing them, and are \
-                                   usually found at the beginning of source files. Outer \
-                                   attributes and doc comments, like `#[test]` and
-                                   `/// My function`, annotate the item following them.")
+                            .note("inner attributes, like `#![no_std]`, annotate the item \
+                                   enclosing them, and are usually found at the beginning of \
+                                   source files. Outer attributes, like `#[test]`, annotate the \
+                                   item following them.")
                             .emit()
                     }
                     ast::AttrStyle::Inner
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index d30d79ece15..44e73d876e8 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -75,6 +75,21 @@ pub struct SpanData {
     pub ctxt: SyntaxContext,
 }
 
+impl SpanData {
+    #[inline]
+    pub fn with_lo(&self, lo: BytePos) -> Span {
+        Span::new(lo, self.hi, self.ctxt)
+    }
+    #[inline]
+    pub fn with_hi(&self, hi: BytePos) -> Span {
+        Span::new(self.lo, hi, self.ctxt)
+    }
+    #[inline]
+    pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span {
+        Span::new(self.lo, self.hi, ctxt)
+    }
+}
+
 // The interner in thread-local, so `Span` shouldn't move between threads.
 impl !Send for Span {}
 impl !Sync for Span {}
@@ -109,8 +124,7 @@ impl Span {
     }
     #[inline]
     pub fn with_lo(self, lo: BytePos) -> Span {
-        let base = self.data();
-        Span::new(lo, base.hi, base.ctxt)
+        self.data().with_lo(lo)
     }
     #[inline]
     pub fn hi(self) -> BytePos {
@@ -118,8 +132,7 @@ impl Span {
     }
     #[inline]
     pub fn with_hi(self, hi: BytePos) -> Span {
-        let base = self.data();
-        Span::new(base.lo, hi, base.ctxt)
+        self.data().with_hi(hi)
     }
     #[inline]
     pub fn ctxt(self) -> SyntaxContext {
@@ -127,20 +140,21 @@ impl Span {
     }
     #[inline]
     pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
-        let base = self.data();
-        Span::new(base.lo, base.hi, ctxt)
+        self.data().with_ctxt(ctxt)
     }
 
     /// Returns a new span representing just the end-point of this span
     pub fn end_point(self) -> Span {
-        let lo = cmp::max(self.hi().0 - 1, self.lo().0);
-        self.with_lo(BytePos(lo))
+        let span = self.data();
+        let lo = cmp::max(span.hi.0 - 1, span.lo.0);
+        span.with_lo(BytePos(lo))
     }
 
     /// Returns a new span representing the next character after the end-point of this span
     pub fn next_point(self) -> Span {
-        let lo = cmp::max(self.hi().0, self.lo().0 + 1);
-        Span::new(BytePos(lo), BytePos(lo), self.ctxt())
+        let span = self.data();
+        let lo = cmp::max(span.hi.0, span.lo.0 + 1);
+        Span::new(BytePos(lo), BytePos(lo), span.ctxt)
     }
 
     /// Returns `self` if `self` is not the dummy span, and `other` otherwise.
@@ -150,7 +164,9 @@ impl Span {
 
     /// Return true if `self` fully encloses `other`.
     pub fn contains(self, other: Span) -> bool {
-        self.lo() <= other.lo() && other.hi() <= self.hi()
+        let span = self.data();
+        let other = other.data();
+        span.lo <= other.lo && other.hi <= span.hi
     }
 
     /// Return true if the spans are equal with regards to the source text.
@@ -158,13 +174,17 @@ impl Span {
     /// Use this instead of `==` when either span could be generated code,
     /// and you only care that they point to the same bytes of source text.
     pub fn source_equal(&self, other: &Span) -> bool {
-        self.lo() == other.lo() && self.hi() == other.hi()
+        let span = self.data();
+        let other = other.data();
+        span.lo == other.lo && span.hi == other.hi
     }
 
     /// Returns `Some(span)`, where the start is trimmed by the end of `other`
     pub fn trim_start(self, other: Span) -> Option<Span> {
-        if self.hi() > other.hi() {
-            Some(self.with_lo(cmp::max(self.lo(), other.hi())))
+        let span = self.data();
+        let other = other.data();
+        if span.hi > other.hi {
+            Some(span.with_lo(cmp::max(span.lo, other.hi)))
         } else {
             None
         }
@@ -268,29 +288,35 @@ impl Span {
 
     /// Return a `Span` that would enclose both `self` and `end`.
     pub fn to(self, end: Span) -> Span {
+        let span = self.data();
+        let end = end.data();
         Span::new(
-            cmp::min(self.lo(), end.lo()),
-            cmp::max(self.hi(), end.hi()),
+            cmp::min(span.lo, end.lo),
+            cmp::max(span.hi, end.hi),
             // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
-            if self.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() },
+            if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
         )
     }
 
     /// Return a `Span` between the end of `self` to the beginning of `end`.
     pub fn between(self, end: Span) -> Span {
+        let span = self.data();
+        let end = end.data();
         Span::new(
-            self.hi(),
-            end.lo(),
-            if end.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() },
+            span.hi,
+            end.lo,
+            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
         )
     }
 
     /// Return a `Span` between the beginning of `self` to the beginning of `end`.
     pub fn until(self, end: Span) -> Span {
+        let span = self.data();
+        let end = end.data();
         Span::new(
-            self.lo(),
-            end.lo(),
-            if end.ctxt() == SyntaxContext::empty() { end.ctxt() } else { self.ctxt() },
+            span.lo,
+            end.lo,
+            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
         )
     }
 }
@@ -316,13 +342,14 @@ impl Default for Span {
 
 impl serialize::UseSpecializedEncodable for Span {
     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        let span = self.data();
         s.emit_struct("Span", 2, |s| {
             s.emit_struct_field("lo", 0, |s| {
-                self.lo().encode(s)
+                span.lo.encode(s)
             })?;
 
             s.emit_struct_field("hi", 1, |s| {
-                self.hi().encode(s)
+                span.hi.encode(s)
             })
         })
     }
diff --git a/src/test/run-make/symbol-visibility/Makefile b/src/test/run-make/symbol-visibility/Makefile
index 988c9473f6a..f1ada814bdb 100644
--- a/src/test/run-make/symbol-visibility/Makefile
+++ b/src/test/run-make/symbol-visibility/Makefile
@@ -9,17 +9,17 @@ all:
 else
 
 NM=nm -D
-DYLIB_EXT=so
 CDYLIB_NAME=liba_cdylib.so
 RDYLIB_NAME=liba_rust_dylib.so
 EXE_NAME=an_executable
+COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.so
 
 ifeq ($(UNAME),Darwin)
 NM=nm -gU
-DYLIB_EXT=dylib
 CDYLIB_NAME=liba_cdylib.dylib
 RDYLIB_NAME=liba_rust_dylib.dylib
 EXE_NAME=an_executable
+COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dylib
 endif
 
 all:
@@ -27,6 +27,7 @@ all:
 	$(RUSTC) a_cdylib.rs
 	$(RUSTC) a_rust_dylib.rs
 	$(RUSTC) an_executable.rs
+	$(RUSTC) a_cdylib.rs --crate-name combined_rlib_dylib --crate-type=rlib,cdylib
 
 	# Check that a cdylib exports its public #[no_mangle] functions
 	[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ]
@@ -47,4 +48,13 @@ all:
 	[ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ]
 	[ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_rust_function_from_exe)" -eq "0" ]
 
+
+	# Check the combined case, where we generate a cdylib and an rlib in the same
+	# compilation session:
+	# Check that a cdylib exports its public #[no_mangle] functions
+	[ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_cdylib)" -eq "1" ]
+	# Check that a cdylib exports the public #[no_mangle] functions of dependencies
+	[ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ]
+	# Check that a cdylib DOES NOT export any public Rust functions
+	[ "$$($(NM) $(TMPDIR)/$(COMBINED_CDYLIB_NAME) | grep -c _ZN.*h.*E)" -eq "0" ]
 endif
diff --git a/src/test/run-pass/dead-code-alias-in-pat.rs b/src/test/run-pass/dead-code-alias-in-pat.rs
new file mode 100644
index 00000000000..a37d671e5c1
--- /dev/null
+++ b/src/test/run-pass/dead-code-alias-in-pat.rs
@@ -0,0 +1,18 @@
+// Copyright 2017 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)]
+
+fn main() {
+    struct Foo<T> { x: T }
+    type Bar = Foo<u32>;
+    let spam = |Bar { x }| x != 0;
+    println!("{}", spam(Foo { x: 10 }));
+}
diff --git a/src/test/ui/issue-45296.stderr b/src/test/ui/issue-45296.stderr
index 7bfcac974c5..1a660e4c678 100644
--- a/src/test/ui/issue-45296.stderr
+++ b/src/test/ui/issue-45296.stderr
@@ -4,8 +4,7 @@ error: an inner attribute is not permitted in this context
 14 |     #![allow(unused_variables)]
    |       ^
    |
-   = note: inner attributes and doc comments, like `#![no_std]` or `//! My crate`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes and doc comments, like `#[test]` and
-                                              `/// My function`, annotate the item following them.
+   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs
new file mode 100644
index 00000000000..51aba27498f
--- /dev/null
+++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 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 extension1 {
+    pub trait ConstructorExtension {}
+}
+
+pub mod extension2 {
+    pub trait ConstructorExtension {}
+}
+
+use extension1::ConstructorExtension;
+use extension2::ConstructorExtension;
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr
new file mode 100644
index 00000000000..07985191284
--- /dev/null
+++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr
@@ -0,0 +1,16 @@
+error[E0252]: the name `ConstructorExtension` is defined multiple times
+  --> $DIR/issue-32354-suggest-import-rename.rs:20:5
+   |
+19 | use extension1::ConstructorExtension;
+   |     -------------------------------- previous import of the trait `ConstructorExtension` here
+20 | use extension2::ConstructorExtension;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ConstructorExtension` reimported here
+   |
+   = note: `ConstructorExtension` must be defined only once in the type namespace of this module
+help: You can use `as` to change the binding name of the import
+   |
+20 | use extension2::ConstructorExtension as OtherConstructorExtension;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index a2a264490a1..9736c039930 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -351,6 +351,26 @@ fn map_lib_features(base_src_path: &Path,
                 }
             }
             becoming_feature = None;
+            if line.contains("rustc_const_unstable(") {
+                // const fn features are handled specially
+                let feature_name = match find_attr_val(line, "feature") {
+                    Some(name) => name,
+                    None => err!("malformed stability attribute"),
+                };
+                let feature = Feature {
+                    level: Status::Unstable,
+                    since: "None".to_owned(),
+                    has_gate_test: false,
+                    // Whether there is a common tracking issue
+                    // for these feature gates remains an open question
+                    // https://github.com/rust-lang/rust/issues/24111#issuecomment-340283184
+                    // But we take 24111 otherwise they will be shown as
+                    // "internal to the compiler" which they are not.
+                    tracking_issue: Some(24111),
+                };
+                mf(Ok((feature_name, feature)), file, i + 1);
+                continue;
+            }
             let level = if line.contains("[unstable(") {
                 Status::Unstable
             } else if line.contains("[stable(") {