about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-14 17:24:18 +0000
committerbors <bors@rust-lang.org>2018-08-14 17:24:18 +0000
commita5733050de780ae4d11e3a7af615df792fdf908e (patch)
treedf7f2e100045edfc854e480aaf204711b6560626
parent23f09bbed4ef12c5f9db198c22f50b608ea6c6d5 (diff)
parent8e7f69af9ce5ec270b79a5125635cacfaeb936ba (diff)
downloadrust-a5733050de780ae4d11e3a7af615df792fdf908e.tar.gz
rust-a5733050de780ae4d11e3a7af615df792fdf908e.zip
Auto merge of #53354 - kennytm:rollup, r=kennytm
Rollup of 11 pull requests

Successful merges:

 - #53112 (pretty print BTreeSet)
 - #53208 (Don't panic on std::env::vars() when env is null.)
 - #53226 (driver: set the syntax edition in phase 1)
 - #53229 (Make sure rlimit is only ever increased)
 - #53233 (targets: aarch64: Add bare-metal aarch64 target)
 - #53239 (rustc_codegen_llvm: Restore the closure env alloca hack for LLVM 5.)
 - #53246 (A few cleanups)
 - #53257 (Idiomatic improvements to IP method)
 - #53274 (Remove statics field from CodegenCx)
 - #53290 (Make LLVM emit assembly comments with -Z asm-comments)
 - #53317 (Mark prior failure to avoid ICE)
-rw-r--r--src/etc/debugger_pretty_printers_common.py22
-rwxr-xr-xsrc/etc/gdb_rust_pretty_printing.py26
-rw-r--r--src/libfmt_macros/lib.rs12
-rw-r--r--src/libgraphviz/lib.rs11
-rw-r--r--src/librustc_apfloat/ieee.rs91
-rw-r--r--src/librustc_codegen_llvm/back/write.rs3
-rw-r--r--src/librustc_codegen_llvm/consts.rs1
-rw-r--r--src/librustc_codegen_llvm/context.rs5
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs3
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs26
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs1
-rw-r--r--src/librustc_driver/driver.rs3
-rw-r--r--src/librustc_driver/lib.rs7
-rw-r--r--src/librustc_target/spec/aarch64_unknown_none.rs46
-rw-r--r--src/librustc_target/spec/mod.rs14
-rw-r--r--src/librustc_typeck/check/mod.rs1
-rw-r--r--src/librustdoc/test.rs3
-rw-r--r--src/libserialize/hex.rs2
-rw-r--r--src/libserialize/json.rs58
-rw-r--r--src/libserialize/leb128.rs4
-rw-r--r--src/libstd/net/ip.rs97
-rw-r--r--src/libstd/sys/unix/os.rs6
-rw-r--r--src/libterm/terminfo/mod.rs16
-rw-r--r--src/libterm/terminfo/parm.rs84
-rw-r--r--src/libterm/win.rs4
-rw-r--r--src/rustllvm/PassWrapper.cpp5
-rw-r--r--src/test/debuginfo/pretty-std-collections.rs50
-rw-r--r--src/test/run-pass/env-null-vars.rs29
-rw-r--r--src/test/rustdoc/async-fn.rs24
-rw-r--r--src/test/ui/issue-53251.rs28
-rw-r--r--src/test/ui/issue-53251.stderr17
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs16
32 files changed, 486 insertions, 229 deletions
diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py
index 87c7b21bb8a..e64d863717d 100644
--- a/src/etc/debugger_pretty_printers_common.py
+++ b/src/etc/debugger_pretty_printers_common.py
@@ -48,6 +48,7 @@ TYPE_KIND_FIXED_SIZE_VEC    = 16
 TYPE_KIND_REGULAR_UNION     = 17
 TYPE_KIND_OS_STRING         = 18
 TYPE_KIND_STD_VECDEQUE      = 19
+TYPE_KIND_STD_BTREESET      = 20
 
 ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
 ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR"
@@ -71,6 +72,9 @@ STD_VECDEQUE_FIELD_NAMES = [STD_VECDEQUE_FIELD_NAME_TAIL,
                             STD_VECDEQUE_FIELD_NAME_HEAD,
                             STD_VECDEQUE_FIELD_NAME_BUF]
 
+# std::collections::BTreeSet<> related constants
+STD_BTREESET_FIELD_NAMES = ["map"]
+
 # std::String related constants
 STD_STRING_FIELD_NAMES = ["vec"]
 
@@ -175,6 +179,11 @@ class Type(object):
             self.__conforms_to_field_layout(STD_VECDEQUE_FIELD_NAMES)):
             return TYPE_KIND_STD_VECDEQUE
 
+        # STD COLLECTION BTREESET
+        if (unqualified_type_name.startswith("BTreeSet<") and
+                self.__conforms_to_field_layout(STD_BTREESET_FIELD_NAMES)):
+            return TYPE_KIND_STD_BTREESET
+
         # STD STRING
         if (unqualified_type_name.startswith("String") and
             self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)):
@@ -358,6 +367,19 @@ def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val):
     return (tail, head, data_ptr, capacity)
 
 
+def extract_length_and_ptr_from_std_btreeset(vec_val):
+    assert vec_val.type.get_type_kind() == TYPE_KIND_STD_BTREESET
+    map = vec_val.get_child_at_index(0)
+    root = map.get_child_at_index(0)
+    length = map.get_child_at_index(1).as_integer()
+    node = root.get_child_at_index(0)
+    ptr = node.get_child_at_index(0)
+    unique_ptr_val = ptr.get_child_at_index(0)
+    data_ptr = unique_ptr_val.get_child_at_index(0)
+    assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
+    return (length, data_ptr)
+
+
 def extract_length_and_ptr_from_slice(slice_val):
     assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or
             slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE)
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index b7de42a9384..fae1fd0cac3 100755
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -127,6 +127,9 @@ def rust_pretty_printer_lookup_function(gdb_val):
     if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE:
         return RustStdVecDequePrinter(val)
 
+    if type_kind == rustpp.TYPE_KIND_STD_BTREESET:
+        return RustStdBTreeSetPrinter(val)
+
     if type_kind == rustpp.TYPE_KIND_STD_STRING:
         return RustStdStringPrinter(val)
 
@@ -299,6 +302,29 @@ class RustStdVecDequePrinter(object):
             yield (str(index), (gdb_ptr + index).dereference())
 
 
+class RustStdBTreeSetPrinter(object):
+    def __init__(self, val):
+        self.__val = val
+
+    @staticmethod
+    def display_hint():
+        return "array"
+
+    def to_string(self):
+        (length, data_ptr) = \
+            rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
+        return (self.__val.type.get_unqualified_type_name() +
+                ("(len: %i)" % length))
+
+    def children(self):
+        (length, data_ptr) = \
+            rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
+        val = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3)
+        gdb_ptr = val.get_wrapped_value()
+        for index in xrange(length):
+            yield (str(index), gdb_ptr[index])
+
+
 class RustStdStringPrinter(object):
     def __init__(self, val):
         self.__val = val
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index d2209da0ca3..e2380f0fe2f 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -411,7 +411,7 @@ impl<'a> Parser<'a> {
 
         // fill character
         if let Some(&(_, c)) = self.cur.peek() {
-            match self.cur.clone().skip(1).next() {
+            match self.cur.clone().nth(1) {
                 Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
                     spec.fill = Some(c);
                     self.cur.next();
@@ -504,13 +504,11 @@ impl<'a> Parser<'a> {
             if word.is_empty() {
                 self.cur = tmp;
                 CountImplied
+            } else if self.consume('$') {
+                CountIsName(word)
             } else {
-                if self.consume('$') {
-                    CountIsName(word)
-                } else {
-                    self.cur = tmp;
-                    CountImplied
-                }
+                self.cur = tmp;
+                CountImplied
             }
         }
     }
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index a8eea18e464..9fa48adebdf 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -420,7 +420,8 @@ impl<'a> Id<'a> {
         if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' ) {
             return Err(());
         }
-        return Ok(Id { name: name });
+
+        Ok(Id { name })
     }
 
     pub fn as_slice(&'a self) -> &'a str {
@@ -533,10 +534,10 @@ impl<'a> LabelText<'a> {
     /// Renders text as string suitable for a label in a .dot file.
     /// This includes quotes or suitable delimiters.
     pub fn to_dot_string(&self) -> String {
-        match self {
-            &LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
-            &EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
-            &HtmlStr(ref s) => format!("<{}>", s),
+        match *self {
+            LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
+            EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
+            HtmlStr(ref s) => format!("<{}>", s),
         }
     }
 
diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs
index b21448df582..45279f18117 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/src/librustc_apfloat/ieee.rs
@@ -536,23 +536,21 @@ impl<S: Semantics> fmt::Display for IeeeFloat<S> {
         // Check whether we should use scientific notation.
         let scientific = if width == 0 {
             true
+        } else if exp >= 0 {
+            // 765e3 --> 765000
+            //              ^^^
+            // But we shouldn't make the number look more precise than it is.
+            exp as usize > width || digits + exp as usize > precision
         } else {
-            if exp >= 0 {
-                // 765e3 --> 765000
-                //              ^^^
-                // But we shouldn't make the number look more precise than it is.
-                exp as usize > width || digits + exp as usize > precision
+            // Power of the most significant digit.
+            let msd = exp + (digits - 1) as ExpInt;
+            if msd >= 0 {
+                // 765e-2 == 7.65
+                false
             } else {
-                // Power of the most significant digit.
-                let msd = exp + (digits - 1) as ExpInt;
-                if msd >= 0 {
-                    // 765e-2 == 7.65
-                    false
-                } else {
-                    // 765e-5 == 0.00765
-                    //           ^ ^^
-                    -msd as usize > width
-                }
+                // 765e-5 == 0.00765
+                //           ^ ^^
+                -msd as usize > width
             }
         };
 
@@ -702,7 +700,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
         //   exponent = 1..10
         //   significand = 1..1
         IeeeFloat {
-            sig: [!0 & ((1 << S::PRECISION) - 1)],
+            sig: [(1 << S::PRECISION) - 1],
             exp: S::MAX_EXP,
             category: Category::Normal,
             sign: false,
@@ -1507,10 +1505,11 @@ impl<S: Semantics, T: Semantics> FloatConvert<IeeeFloat<T>> for IeeeFloat<S> {
         }
 
         // If this is a truncation, perform the shift.
-        let mut loss = Loss::ExactlyZero;
-        if shift < 0 && (r.is_finite_non_zero() || r.category == Category::NaN) {
-            loss = sig::shift_right(&mut r.sig, &mut 0, -shift as usize);
-        }
+        let loss = if shift < 0 && (r.is_finite_non_zero() || r.category == Category::NaN) {
+            sig::shift_right(&mut r.sig, &mut 0, -shift as usize)
+        } else {
+            Loss::ExactlyZero
+        };
 
         // If this is an extension, perform the shift.
         if shift > 0 && (r.is_finite_non_zero() || r.category == Category::NaN) {
@@ -1738,27 +1737,25 @@ impl<S: Semantics> IeeeFloat<S> {
                 bit_pos -= 4;
                 if bit_pos >= 0 {
                     r.sig[0] |= (hex_value as Limb) << bit_pos;
-                } else {
-                    // If zero or one-half (the hexadecimal digit 8) are followed
-                    // by non-zero, they're a little more than zero or one-half.
-                    if let Some(ref mut loss) = loss {
-                        if hex_value != 0 {
-                            if *loss == Loss::ExactlyZero {
-                                *loss = Loss::LessThanHalf;
-                            }
-                            if *loss == Loss::ExactlyHalf {
-                                *loss = Loss::MoreThanHalf;
-                            }
+                // If zero or one-half (the hexadecimal digit 8) are followed
+                // by non-zero, they're a little more than zero or one-half.
+                } else if let Some(ref mut loss) = loss {
+                    if hex_value != 0 {
+                        if *loss == Loss::ExactlyZero {
+                            *loss = Loss::LessThanHalf;
+                        }
+                        if *loss == Loss::ExactlyHalf {
+                            *loss = Loss::MoreThanHalf;
                         }
-                    } else {
-                        loss = Some(match hex_value {
-                            0 => Loss::ExactlyZero,
-                            1..=7 => Loss::LessThanHalf,
-                            8 => Loss::ExactlyHalf,
-                            9..=15 => Loss::MoreThanHalf,
-                            _ => unreachable!(),
-                        });
                     }
+                } else {
+                    loss = Some(match hex_value {
+                        0 => Loss::ExactlyZero,
+                        1..=7 => Loss::LessThanHalf,
+                        8 => Loss::ExactlyHalf,
+                        9..=15 => Loss::MoreThanHalf,
+                        _ => unreachable!(),
+                    });
                 }
             } else if c == 'p' || c == 'P' {
                 if !any_digits {
@@ -2309,9 +2306,9 @@ mod sig {
 
     /// One, not zero, based LSB. That is, returns 0 for a zeroed significand.
     pub(super) fn olsb(limbs: &[Limb]) -> usize {
-        for i in 0..limbs.len() {
-            if limbs[i] != 0 {
-                return i * LIMB_BITS + limbs[i].trailing_zeros() as usize + 1;
+        for (i, &limb) in limbs.iter().enumerate() {
+            if limb != 0 {
+                return i * LIMB_BITS + limb.trailing_zeros() as usize + 1;
             }
         }
 
@@ -2320,9 +2317,9 @@ mod sig {
 
     /// One, not zero, based MSB. That is, returns 0 for a zeroed significand.
     pub(super) fn omsb(limbs: &[Limb]) -> usize {
-        for i in (0..limbs.len()).rev() {
-            if limbs[i] != 0 {
-                return (i + 1) * LIMB_BITS - limbs[i].leading_zeros() as usize;
+        for (i, &limb) in limbs.iter().enumerate().rev() {
+            if limb != 0 {
+                return (i + 1) * LIMB_BITS - limb.leading_zeros() as usize;
             }
         }
 
@@ -2378,7 +2375,7 @@ mod sig {
                     limb = dst[i - jump];
                     if shift > 0 {
                         limb <<= shift;
-                        if i >= jump + 1 {
+                        if i > jump {
                             limb |= dst[i - jump - 1] >> (LIMB_BITS - shift);
                         }
                     }
@@ -2448,7 +2445,7 @@ mod sig {
         let n = dst_limbs * LIMB_BITS - shift;
         if n < src_bits {
             let mask = (1 << (src_bits - n)) - 1;
-            dst[dst_limbs - 1] |= (src[dst_limbs] & mask) << n % LIMB_BITS;
+            dst[dst_limbs - 1] |= (src[dst_limbs] & mask) << (n % LIMB_BITS);
         } else if n > src_bits && src_bits % LIMB_BITS > 0 {
             dst[dst_limbs - 1] &= (1 << (src_bits % LIMB_BITS)) - 1;
         }
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index ebe8b797414..d60983d7697 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -180,6 +180,8 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
     let is_pie_binary = !find_features && is_pie_binary(sess);
     let trap_unreachable = sess.target.target.options.trap_unreachable;
 
+    let asm_comments = sess.asm_comments();
+
     Arc::new(move || {
         let tm = unsafe {
             llvm::LLVMRustCreateTargetMachine(
@@ -193,6 +195,7 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
                 fdata_sections,
                 trap_unreachable,
                 singlethread,
+                asm_comments,
             )
         };
 
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 5501e915976..770a22ad658 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -230,7 +230,6 @@ pub fn get_static(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll Value {
     }
 
     cx.instances.borrow_mut().insert(instance, g);
-    cx.statics.borrow_mut().insert(g, def_id);
     g
 }
 
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 781f8ebbb78..32ea2c5eb8f 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -13,7 +13,6 @@ use common;
 use llvm;
 use rustc::dep_graph::DepGraphSafe;
 use rustc::hir;
-use rustc::hir::def_id::DefId;
 use debuginfo;
 use callee;
 use base;
@@ -78,9 +77,6 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
     /// Cache of emitted const globals (value -> global)
     pub const_globals: RefCell<FxHashMap<&'a Value, &'a Value>>,
 
-    /// Mapping from static definitions to their DefId's.
-    pub statics: RefCell<FxHashMap<&'a Value, DefId>>,
-
     /// List of globals for static variables which need to be passed to the
     /// LLVM function ReplaceAllUsesWith (RAUW) when codegen is complete.
     /// (We have to make sure we don't invalidate any Values referring
@@ -297,7 +293,6 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
             const_cstr_cache: RefCell::new(FxHashMap()),
             const_unsized: RefCell::new(FxHashMap()),
             const_globals: RefCell::new(FxHashMap()),
-            statics: RefCell::new(FxHashMap()),
             statics_to_rauw: RefCell::new(Vec::new()),
             used_statics: RefCell::new(Vec::new()),
             lltypes: RefCell::new(FxHashMap()),
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 68a21a53707..eec8a3a169c 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1455,7 +1455,8 @@ extern "C" {
                                        FunctionSections: bool,
                                        DataSections: bool,
                                        TrapUnreachable: bool,
-                                       Singlethread: bool)
+                                       Singlethread: bool,
+                                       AsmComments: bool)
                                        -> Option<&'static mut TargetMachine>;
     pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
     pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module);
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index 8fdb67f5930..8bb049be305 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -574,6 +574,25 @@ fn arg_local_refs(
             };
             let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
 
+            // Store the pointer to closure data in an alloca for debuginfo
+            // because that's what the llvm.dbg.declare intrinsic expects.
+
+            // FIXME(eddyb) this shouldn't be necessary but SROA seems to
+            // mishandle DW_OP_plus not preceded by DW_OP_deref, i.e. it
+            // doesn't actually strip the offset when splitting the closure
+            // environment into its components so it ends up out of bounds.
+            // (cuviper) It seems to be fine without the alloca on LLVM 6 and later.
+            let env_alloca = !env_ref && unsafe { llvm::LLVMRustVersionMajor() < 6 };
+            let env_ptr = if env_alloca {
+                let scratch = PlaceRef::alloca(bx,
+                    bx.cx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
+                    "__debuginfo_env_ptr");
+                bx.store(place.llval, scratch.llval, scratch.align);
+                scratch.llval
+            } else {
+                place.llval
+            };
+
             for (i, (decl, ty)) in mir.upvar_decls.iter().zip(upvar_tys).enumerate() {
                 let byte_offset_of_var_in_env = closure_layout.fields.offset(i).bytes();
 
@@ -585,7 +604,10 @@ fn arg_local_refs(
                 };
 
                 // The environment and the capture can each be indirect.
-                let mut ops = if env_ref { &ops[..] } else { &ops[1..] };
+
+                // FIXME(eddyb) see above why we sometimes have to keep
+                // a pointer in an alloca for debuginfo atm.
+                let mut ops = if env_ref || env_alloca { &ops[..] } else { &ops[1..] };
 
                 let ty = if let (true, &ty::TyRef(_, ty, _)) = (decl.by_ref, &ty.sty) {
                     ty
@@ -595,7 +617,7 @@ fn arg_local_refs(
                 };
 
                 let variable_access = VariableAccess::IndirectVariable {
-                    alloca: place.llval,
+                    alloca: env_ptr,
                     address_operations: &ops
                 };
                 declare_local(
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index a528008e3b4..80c4df1d6b0 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -143,7 +143,6 @@ fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
     }
 
     cx.instances.borrow_mut().insert(instance, g);
-    cx.statics.borrow_mut().insert(g, def_id);
 }
 
 fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index ee98cc6cf92..e5042a4a020 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -57,7 +57,7 @@ use syntax::ext::base::ExtCtxt;
 use syntax::fold::Folder;
 use syntax::parse::{self, PResult};
 use syntax::util::node_count::NodeCounter;
-use syntax_pos::FileName;
+use syntax_pos::{FileName, hygiene};
 use syntax_ext;
 
 use derive_registrar;
@@ -670,6 +670,7 @@ pub fn phase_1_parse_input<'a>(
 ) -> PResult<'a, ast::Crate> {
     sess.diagnostic()
         .set_continue_after_error(control.continue_parse_after_error);
+    hygiene::set_default_edition(sess.edition());
 
     if sess.profile_queries() {
         profile::begin(sess);
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index c3bdf07cd20..d25d57a004b 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -110,7 +110,7 @@ use syntax::ast;
 use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
 use syntax::parse::{self, PResult};
-use syntax_pos::{hygiene, DUMMY_SP, MultiSpan, FileName};
+use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
 
 #[cfg(test)]
 mod test;
@@ -478,7 +478,6 @@ pub fn run_compiler<'a>(args: &[String],
         };
 
         let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
-        hygiene::set_default_edition(sopts.edition);
 
         driver::spawn_thread_pool(sopts, |sopts| {
             run_compiler_with_pool(matches, sopts, cfg, callbacks, file_loader, emitter_dest)
@@ -1513,7 +1512,7 @@ pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any
             true
         } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t {
             true
-        } else {
+        } else if rlim.rlim_cur < STACK_SIZE as libc::rlim_t {
             std::rt::deinit_stack_guard();
             rlim.rlim_cur = STACK_SIZE as libc::rlim_t;
             if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
@@ -1525,6 +1524,8 @@ pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any
                 std::rt::update_stack_guard();
                 false
             }
+        } else {
+            false
         }
     };
 
diff --git a/src/librustc_target/spec/aarch64_unknown_none.rs b/src/librustc_target/spec/aarch64_unknown_none.rs
new file mode 100644
index 00000000000..cfba0614adc
--- /dev/null
+++ b/src/librustc_target/spec/aarch64_unknown_none.rs
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+
+// Generic AArch64 target for bare-metal code
+//
+// Can be used in conjunction with the `target-feature` and
+// `target-cpu` compiler flags to opt-in more hardware-specific
+// features.
+//
+// For example, `-C target-cpu=cortex-a53`.
+
+use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy};
+
+pub fn target() -> Result<Target, String> {
+    let opts = TargetOptions {
+        linker: Some("rust-lld".to_owned()),
+        executables: true,
+        relocation_model: "static".to_string(),
+        disable_redzone: true,
+        linker_is_gnu: true,
+        max_atomic_width: Some(128),
+        panic_strategy: PanicStrategy::Abort,
+        abi_blacklist: super::arm_base::abi_blacklist(),
+        .. Default::default()
+    };
+    Ok(Target {
+        llvm_target: "aarch64-unknown-none".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        target_os: "none".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "".to_string(),
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+        options: opts,
+    })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index ce3d61cecbb..d55762e03ee 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -380,6 +380,8 @@ supported_targets! {
     ("x86_64-unknown-hermit", x86_64_unknown_hermit),
 
     ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
+
+    ("aarch64-unknown-none", aarch64_unknown_none),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
@@ -765,14 +767,10 @@ impl Target {
         // the JSON parser is not updated to match the structs.
 
         let get_req_field = |name: &str| {
-            match obj.find(name)
-                     .map(|s| s.as_string())
-                     .and_then(|os| os.map(|s| s.to_string())) {
-                Some(val) => Ok(val),
-                None => {
-                    return Err(format!("Field {} in target specification is required", name))
-                }
-            }
+            obj.find(name)
+               .map(|s| s.as_string())
+               .and_then(|os| os.map(|s| s.to_string()))
+               .ok_or_else(|| format!("Field {} in target specification is required", name))
         };
 
         let get_opt_field = |name: &str, default: &str| {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9b6772e2dbb..43edb235044 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5154,6 +5154,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         } else {
             None
         } {
+            self.set_tainted_by_errors(); // #53251
             err.span_label(span, format!("expected {}", expected_text)).emit();
         }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index d8e382f6998..569815c833a 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -37,7 +37,7 @@ use syntax::codemap::CodeMap;
 use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::with_globals;
-use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName, hygiene};
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
 use errors;
 use errors::emitter::ColorConfig;
 
@@ -562,7 +562,6 @@ impl Collector {
                     rustc_driver::in_named_rustc_thread(name, move || with_globals(move || {
                         io::set_panic(panic);
                         io::set_print(print);
-                        hygiene::set_default_edition(edition);
                         run_test(&test,
                                  &cratename,
                                  &filename,
diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs
index 4c306d9b2d3..7f3736e82ca 100644
--- a/src/libserialize/hex.rs
+++ b/src/libserialize/hex.rs
@@ -22,7 +22,7 @@ pub trait ToHex {
     fn to_hex(&self) -> String;
 }
 
-const CHARS: &'static [u8] = b"0123456789abcdef";
+const CHARS: &[u8] = b"0123456789abcdef";
 
 impl ToHex for [u8] {
     /// Turn a vector of `u8` bytes into a hexadecimal string.
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index d4213244016..0361718eb73 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -438,7 +438,7 @@ fn escape_char(writer: &mut dyn fmt::Write, v: char) -> EncodeResult {
 }
 
 fn spaces(wr: &mut dyn fmt::Write, mut n: usize) -> EncodeResult {
-    const BUF: &'static str = "                ";
+    const BUF: &str = "                ";
 
     while n >= BUF.len() {
         wr.write_str(BUF)?;
@@ -799,21 +799,21 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
             escape_str(self.writer, name)
         } else {
             if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
-            write!(self.writer, "{{\n")?;
+            writeln!(self.writer, "{{")?;
             self.curr_indent += self.indent;
             spaces(self.writer, self.curr_indent)?;
             write!(self.writer, "\"variant\": ")?;
             escape_str(self.writer, name)?;
-            write!(self.writer, ",\n")?;
+            writeln!(self.writer, ",")?;
             spaces(self.writer, self.curr_indent)?;
-            write!(self.writer, "\"fields\": [\n")?;
+            writeln!(self.writer, "\"fields\": [")?;
             self.curr_indent += self.indent;
             f(self)?;
             self.curr_indent -= self.indent;
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
             spaces(self.writer, self.curr_indent)?;
             self.curr_indent -= self.indent;
-            write!(self.writer, "]\n")?;
+            writeln!(self.writer, "]")?;
             spaces(self.writer, self.curr_indent)?;
             write!(self.writer, "}}")?;
             Ok(())
@@ -825,7 +825,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         if idx != 0 {
-            write!(self.writer, ",\n")?;
+            writeln!(self.writer, ",")?;
         }
         spaces(self.writer, self.curr_indent)?;
         f(self)
@@ -864,7 +864,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
             self.curr_indent += self.indent;
             f(self)?;
             self.curr_indent -= self.indent;
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
             spaces(self.writer, self.curr_indent)?;
             write!(self.writer, "}}")?;
         }
@@ -876,9 +876,9 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         if idx == 0 {
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
         } else {
-            write!(self.writer, ",\n")?;
+            writeln!(self.writer, ",")?;
         }
         spaces(self.writer, self.curr_indent)?;
         escape_str(self.writer, name)?;
@@ -940,7 +940,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
             self.curr_indent += self.indent;
             f(self)?;
             self.curr_indent -= self.indent;
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
             spaces(self.writer, self.curr_indent)?;
             write!(self.writer, "]")?;
         }
@@ -952,9 +952,9 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         if idx == 0 {
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
         } else {
-            write!(self.writer, ",\n")?;
+            writeln!(self.writer, ",")?;
         }
         spaces(self.writer, self.curr_indent)?;
         f(self)
@@ -971,7 +971,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
             self.curr_indent += self.indent;
             f(self)?;
             self.curr_indent -= self.indent;
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
             spaces(self.writer, self.curr_indent)?;
             write!(self.writer, "}}")?;
         }
@@ -983,9 +983,9 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         if idx == 0 {
-            write!(self.writer, "\n")?;
+            writeln!(self.writer)?;
         } else {
-            write!(self.writer, ",\n")?;
+            writeln!(self.writer, ",")?;
         }
         spaces(self.writer, self.curr_indent)?;
         self.is_emitting_map_key = true;
@@ -1387,10 +1387,10 @@ impl Stack {
 
     // Used by Parser to test whether the top-most element is an index.
     fn last_is_index(&self) -> bool {
-        if self.is_empty() { return false; }
-        return match *self.stack.last().unwrap() {
-            InternalIndex(_) => true,
-            _ => false,
+        if let Some(InternalIndex(_)) = self.stack.last() {
+            true
+        } else {
+            false
         }
     }
 
@@ -1530,19 +1530,17 @@ impl<T: Iterator<Item=char>> Parser<T> {
             }
 
             F64Value(res)
-        } else {
-            if neg {
-                let res = (res as i64).wrapping_neg();
+        } else if neg {
+            let res = (res as i64).wrapping_neg();
 
-                // Make sure we didn't underflow.
-                if res > 0 {
-                    Error(SyntaxError(InvalidNumber, self.line, self.col))
-                } else {
-                    I64Value(res)
-                }
+            // Make sure we didn't underflow.
+            if res > 0 {
+                Error(SyntaxError(InvalidNumber, self.line, self.col))
             } else {
-                U64Value(res)
+                I64Value(res)
             }
+        } else {
+            U64Value(res)
         }
     }
 
diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs
index ae7f25c7fed..eee95d9fa67 100644
--- a/src/libserialize/leb128.rs
+++ b/src/libserialize/leb128.rs
@@ -103,8 +103,8 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
     loop {
         let mut byte = (value as u8) & 0x7f;
         value >>= 7;
-        let more = !((((value == 0) && ((byte & 0x40) == 0)) ||
-                      ((value == -1) && ((byte & 0x40) != 0))));
+        let more = !(((value == 0) && ((byte & 0x40) == 0)) ||
+                     ((value == -1) && ((byte & 0x40) != 0)));
 
         if more {
             byte |= 0x80; // Mark this byte to show that more bytes will follow.
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index d601a0c42e9..9a610cd7d6b 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -160,9 +160,9 @@ impl IpAddr {
     /// ```
     #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_unspecified(&self) -> bool {
-        match *self {
-            IpAddr::V4(ref a) => a.is_unspecified(),
-            IpAddr::V6(ref a) => a.is_unspecified(),
+        match self {
+            IpAddr::V4(ip) => ip.is_unspecified(),
+            IpAddr::V6(ip) => ip.is_unspecified(),
         }
     }
 
@@ -185,9 +185,9 @@ impl IpAddr {
     /// ```
     #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_loopback(&self) -> bool {
-        match *self {
-            IpAddr::V4(ref a) => a.is_loopback(),
-            IpAddr::V6(ref a) => a.is_loopback(),
+        match self {
+            IpAddr::V4(ip) => ip.is_loopback(),
+            IpAddr::V6(ip) => ip.is_loopback(),
         }
     }
 
@@ -214,9 +214,9 @@ impl IpAddr {
     /// }
     /// ```
     pub fn is_global(&self) -> bool {
-        match *self {
-            IpAddr::V4(ref a) => a.is_global(),
-            IpAddr::V6(ref a) => a.is_global(),
+        match self {
+            IpAddr::V4(ip) => ip.is_global(),
+            IpAddr::V6(ip) => ip.is_global(),
         }
     }
 
@@ -239,9 +239,9 @@ impl IpAddr {
     /// ```
     #[stable(feature = "ip_shared", since = "1.12.0")]
     pub fn is_multicast(&self) -> bool {
-        match *self {
-            IpAddr::V4(ref a) => a.is_multicast(),
-            IpAddr::V6(ref a) => a.is_multicast(),
+        match self {
+            IpAddr::V4(ip) => ip.is_multicast(),
+            IpAddr::V6(ip) => ip.is_multicast(),
         }
     }
 
@@ -268,9 +268,9 @@ impl IpAddr {
     /// }
     /// ```
     pub fn is_documentation(&self) -> bool {
-        match *self {
-            IpAddr::V4(ref a) => a.is_documentation(),
-            IpAddr::V6(ref a) => a.is_documentation(),
+        match self {
+            IpAddr::V4(ip) => ip.is_documentation(),
+            IpAddr::V6(ip) => ip.is_documentation(),
         }
     }
 
@@ -293,7 +293,7 @@ impl IpAddr {
     /// ```
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
     pub fn is_ipv4(&self) -> bool {
-        match *self {
+        match self {
             IpAddr::V4(_) => true,
             IpAddr::V6(_) => false,
         }
@@ -318,7 +318,7 @@ impl IpAddr {
     /// ```
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
     pub fn is_ipv6(&self) -> bool {
-        match *self {
+        match self {
             IpAddr::V4(_) => false,
             IpAddr::V6(_) => true,
         }
@@ -483,11 +483,11 @@ impl Ipv4Addr {
     /// ```
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_private(&self) -> bool {
-        match (self.octets()[0], self.octets()[1]) {
-            (10, _) => true,
-            (172, b) if b >= 16 && b <= 31 => true,
-            (192, 168) => true,
-            _ => false
+        match self.octets() {
+            [10, ..] => true,
+            [172, b, ..] if b >= 16 && b <= 31 => true,
+            [192, 168, ..] => true,
+            _ => false,
         }
     }
 
@@ -509,7 +509,10 @@ impl Ipv4Addr {
     /// ```
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_link_local(&self) -> bool {
-        self.octets()[0] == 169 && self.octets()[1] == 254
+        match self.octets() {
+            [169, 254, ..] => true,
+            _ => false,
+        }
     }
 
     /// Returns [`true`] if the address appears to be globally routable.
@@ -612,11 +615,11 @@ impl Ipv4Addr {
     /// ```
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_documentation(&self) -> bool {
-        match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) {
-            (192, 0, 2, _) => true,
-            (198, 51, 100, _) => true,
-            (203, 0, 113, _) => true,
-            _ => false
+        match self.octets() {
+            [192, 0, 2, _] => true,
+            [198, 51, 100, _] => true,
+            [203, 0, 113, _] => true,
+            _ => false,
         }
     }
 
@@ -666,9 +669,9 @@ impl Ipv4Addr {
 #[stable(feature = "ip_addr", since = "1.7.0")]
 impl fmt::Display for IpAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            IpAddr::V4(ref a) => a.fmt(fmt),
-            IpAddr::V6(ref a) => a.fmt(fmt),
+        match self {
+            IpAddr::V4(ip) => ip.fmt(fmt),
+            IpAddr::V6(ip) => ip.fmt(fmt),
         }
     }
 }
@@ -717,8 +720,8 @@ impl PartialEq for Ipv4Addr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<Ipv4Addr> for IpAddr {
     fn eq(&self, other: &Ipv4Addr) -> bool {
-        match *self {
-            IpAddr::V4(ref v4) => v4 == other,
+        match self {
+            IpAddr::V4(v4) => v4 == other,
             IpAddr::V6(_) => false,
         }
     }
@@ -727,8 +730,8 @@ impl PartialEq<Ipv4Addr> for IpAddr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<IpAddr> for Ipv4Addr {
     fn eq(&self, other: &IpAddr) -> bool {
-        match *other {
-            IpAddr::V4(ref v4) => self == v4,
+        match other {
+            IpAddr::V4(v4) => self == v4,
             IpAddr::V6(_) => false,
         }
     }
@@ -755,8 +758,8 @@ impl PartialOrd for Ipv4Addr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<Ipv4Addr> for IpAddr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
-        match *self {
-            IpAddr::V4(ref v4) => v4.partial_cmp(other),
+        match self {
+            IpAddr::V4(v4) => v4.partial_cmp(other),
             IpAddr::V6(_) => Some(Ordering::Greater),
         }
     }
@@ -765,8 +768,8 @@ impl PartialOrd<Ipv4Addr> for IpAddr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<IpAddr> for Ipv4Addr {
     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
-        match *other {
-            IpAddr::V4(ref v4) => self.partial_cmp(v4),
+        match other {
+            IpAddr::V4(v4) => self.partial_cmp(v4),
             IpAddr::V6(_) => Some(Ordering::Less),
         }
     }
@@ -1335,9 +1338,9 @@ impl PartialEq for Ipv6Addr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<IpAddr> for Ipv6Addr {
     fn eq(&self, other: &IpAddr) -> bool {
-        match *other {
+        match other {
             IpAddr::V4(_) => false,
-            IpAddr::V6(ref v6) => self == v6,
+            IpAddr::V6(v6) => self == v6,
         }
     }
 }
@@ -1345,9 +1348,9 @@ impl PartialEq<IpAddr> for Ipv6Addr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<Ipv6Addr> for IpAddr {
     fn eq(&self, other: &Ipv6Addr) -> bool {
-        match *self {
+        match self {
             IpAddr::V4(_) => false,
-            IpAddr::V6(ref v6) => v6 == other,
+            IpAddr::V6(v6) => v6 == other,
         }
     }
 }
@@ -1372,9 +1375,9 @@ impl PartialOrd for Ipv6Addr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<Ipv6Addr> for IpAddr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
-        match *self {
+        match self {
             IpAddr::V4(_) => Some(Ordering::Less),
-            IpAddr::V6(ref v6) => v6.partial_cmp(other),
+            IpAddr::V6(v6) => v6.partial_cmp(other),
         }
     }
 }
@@ -1382,9 +1385,9 @@ impl PartialOrd<Ipv6Addr> for IpAddr {
 #[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<IpAddr> for Ipv6Addr {
     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
-        match *other {
+        match other {
             IpAddr::V4(_) => Some(Ordering::Greater),
-            IpAddr::V6(ref v6) => self.partial_cmp(v6),
+            IpAddr::V6(v6) => self.partial_cmp(v6),
         }
     }
 }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 08c3e154978..f8f0bbd5bc2 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -414,12 +414,8 @@ pub fn env() -> Env {
     unsafe {
         let _guard = ENV_LOCK.lock();
         let mut environ = *environ();
-        if environ == ptr::null() {
-            panic!("os::env() failure getting env string from OS: {}",
-                   io::Error::last_os_error());
-        }
         let mut result = Vec::new();
-        while *environ != ptr::null() {
+        while environ != ptr::null() && *environ != ptr::null() {
             if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
                 result.push(key_value);
             }
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index 51e0fa315f4..adfc7078eba 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -60,8 +60,8 @@ impl error::Error for Error {
 
     fn cause(&self) -> Option<&dyn error::Error> {
         use self::Error::*;
-        match self {
-            &IoError(ref e) => Some(e),
+        match *self {
+            IoError(ref e) => Some(e),
             _ => None,
         }
     }
@@ -70,10 +70,10 @@ impl error::Error for Error {
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use self::Error::*;
-        match self {
-            &TermUnset => Ok(()),
-            &MalformedTerminfo(ref e) => e.fmt(f),
-            &IoError(ref e) => e.fmt(f),
+        match *self {
+            TermUnset => Ok(()),
+            MalformedTerminfo(ref e) => e.fmt(f),
+            IoError(ref e) => e.fmt(f),
         }
     }
 }
@@ -109,9 +109,9 @@ impl TermInfo {
     }
     // Keep the metadata small
     fn _from_path(path: &Path) -> Result<TermInfo, Error> {
-        let file = File::open(path).map_err(|e| Error::IoError(e))?;
+        let file = File::open(path).map_err(Error::IoError)?;
         let mut reader = BufReader::new(file);
-        parse(&mut reader, false).map_err(|e| Error::MalformedTerminfo(e))
+        parse(&mut reader, false).map_err(Error::MalformedTerminfo)
     }
 }
 
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index b720d55594f..31e1b18485c 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -12,8 +12,6 @@
 
 use self::Param::*;
 use self::States::*;
-use self::FormatState::*;
-use self::FormatOp::*;
 
 use std::iter::repeat;
 
@@ -36,9 +34,9 @@ enum States {
 
 #[derive(Copy, PartialEq, Clone)]
 enum FormatState {
-    FormatStateFlags,
-    FormatStateWidth,
-    FormatStatePrecision,
+    Flags,
+    Width,
+    Precision,
 }
 
 /// Types of parameters a capability can use
@@ -210,22 +208,22 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                         if let Some(arg) = stack.pop() {
                             let flags = Flags::new();
                             let res = format(arg, FormatOp::from_char(cur), flags)?;
-                            output.extend(res.iter().map(|x| *x));
+                            output.extend(res.iter().cloned());
                         } else {
                             return Err("stack is empty".to_string());
                         }
                     }
                     ':' | '#' | ' ' | '.' | '0'..='9' => {
                         let mut flags = Flags::new();
-                        let mut fstate = FormatStateFlags;
+                        let mut fstate = FormatState::Flags;
                         match cur {
                             ':' => (),
                             '#' => flags.alternate = true,
                             ' ' => flags.space = true,
-                            '.' => fstate = FormatStatePrecision,
+                            '.' => fstate = FormatState::Precision,
                             '0'..='9' => {
                                 flags.width = cur as usize - '0' as usize;
-                                fstate = FormatStateWidth;
+                                fstate = FormatState::Width;
                             }
                             _ => unreachable!(),
                         }
@@ -318,43 +316,43 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                     (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
                         if let Some(arg) = stack.pop() {
                             let res = format(arg, FormatOp::from_char(cur), *flags)?;
-                            output.extend(res.iter().map(|x| *x));
+                            output.extend(res.iter().cloned());
                             // will cause state to go to Nothing
                             old_state = FormatPattern(*flags, *fstate);
                         } else {
                             return Err("stack is empty".to_string());
                         }
                     }
-                    (FormatStateFlags, '#') => {
+                    (FormatState::Flags, '#') => {
                         flags.alternate = true;
                     }
-                    (FormatStateFlags, '-') => {
+                    (FormatState::Flags, '-') => {
                         flags.left = true;
                     }
-                    (FormatStateFlags, '+') => {
+                    (FormatState::Flags, '+') => {
                         flags.sign = true;
                     }
-                    (FormatStateFlags, ' ') => {
+                    (FormatState::Flags, ' ') => {
                         flags.space = true;
                     }
-                    (FormatStateFlags, '0'..='9') => {
+                    (FormatState::Flags, '0'..='9') => {
                         flags.width = cur as usize - '0' as usize;
-                        *fstate = FormatStateWidth;
+                        *fstate = FormatState::Width;
                     }
-                    (FormatStateFlags, '.') => {
-                        *fstate = FormatStatePrecision;
+                    (FormatState::Flags, '.') => {
+                        *fstate = FormatState::Precision;
                     }
-                    (FormatStateWidth, '0'..='9') => {
+                    (FormatState::Width, '0'..='9') => {
                         let old = flags.width;
                         flags.width = flags.width * 10 + (cur as usize - '0' as usize);
                         if flags.width < old {
                             return Err("format width overflow".to_string());
                         }
                     }
-                    (FormatStateWidth, '.') => {
-                        *fstate = FormatStatePrecision;
+                    (FormatState::Width, '.') => {
+                        *fstate = FormatState::Precision;
                     }
-                    (FormatStatePrecision, '0'..='9') => {
+                    (FormatState::Precision, '0'..='9') => {
                         let old = flags.precision;
                         flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
                         if flags.precision < old {
@@ -437,31 +435,31 @@ impl Flags {
 
 #[derive(Copy, Clone)]
 enum FormatOp {
-    FormatDigit,
-    FormatOctal,
-    FormatHex,
-    FormatHEX,
-    FormatString,
+    Digit,
+    Octal,
+    LowerHex,
+    UpperHex,
+    String,
 }
 
 impl FormatOp {
     fn from_char(c: char) -> FormatOp {
         match c {
-            'd' => FormatDigit,
-            'o' => FormatOctal,
-            'x' => FormatHex,
-            'X' => FormatHEX,
-            's' => FormatString,
+            'd' => FormatOp::Digit,
+            'o' => FormatOp::Octal,
+            'x' => FormatOp::LowerHex,
+            'X' => FormatOp::UpperHex,
+            's' => FormatOp::String,
             _ => panic!("bad FormatOp char"),
         }
     }
     fn to_char(self) -> char {
         match self {
-            FormatDigit => 'd',
-            FormatOctal => 'o',
-            FormatHex => 'x',
-            FormatHEX => 'X',
-            FormatString => 's',
+            FormatOp::Digit => 'd',
+            FormatOp::Octal => 'o',
+            FormatOp::LowerHex => 'x',
+            FormatOp::UpperHex => 'X',
+            FormatOp::String => 's',
         }
     }
 }
@@ -470,7 +468,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
     let mut s = match val {
         Number(d) => {
             match op {
-                FormatDigit => {
+                FormatOp::Digit => {
                     if flags.sign {
                         format!("{:+01$}", d, flags.precision)
                     } else if d < 0 {
@@ -482,7 +480,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
                         format!("{:01$}", d, flags.precision)
                     }
                 }
-                FormatOctal => {
+                FormatOp::Octal => {
                     if flags.alternate {
                         // Leading octal zero counts against precision.
                         format!("0{:01$o}", d, flags.precision.saturating_sub(1))
@@ -490,27 +488,27 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
                         format!("{:01$o}", d, flags.precision)
                     }
                 }
-                FormatHex => {
+                FormatOp::LowerHex => {
                     if flags.alternate && d != 0 {
                         format!("0x{:01$x}", d, flags.precision)
                     } else {
                         format!("{:01$x}", d, flags.precision)
                     }
                 }
-                FormatHEX => {
+                FormatOp::UpperHex => {
                     if flags.alternate && d != 0 {
                         format!("0X{:01$X}", d, flags.precision)
                     } else {
                         format!("{:01$X}", d, flags.precision)
                     }
                 }
-                FormatString => return Err("non-number on stack with %s".to_string()),
+                FormatOp::String => return Err("non-number on stack with %s".to_string()),
             }
             .into_bytes()
         }
         Words(s) => {
             match op {
-                FormatString => {
+                FormatOp::String => {
                     let mut s = s.into_bytes();
                     if flags.precision > 0 && flags.precision < s.len() {
                         s.truncate(flags.precision);
diff --git a/src/libterm/win.rs b/src/libterm/win.rs
index d36b182710b..e0b60eead49 100644
--- a/src/libterm/win.rs
+++ b/src/libterm/win.rs
@@ -198,11 +198,11 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
         Ok(true)
     }
 
-    fn get_ref<'a>(&'a self) -> &'a T {
+    fn get_ref(&self) -> &T {
         &self.buf
     }
 
-    fn get_mut<'a>(&'a mut self) -> &'a mut T {
+    fn get_mut(&mut self) -> &mut T {
         &mut self.buf
     }
 
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 7305dc71cbf..d9fbd494ab3 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -366,7 +366,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     bool PositionIndependentExecutable, bool FunctionSections,
     bool DataSections,
     bool TrapUnreachable,
-    bool Singlethread) {
+    bool Singlethread,
+    bool AsmComments) {
 
   auto OptLevel = fromRust(RustOptLevel);
   auto RM = fromRust(RustReloc);
@@ -393,6 +394,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   }
   Options.DataSections = DataSections;
   Options.FunctionSections = FunctionSections;
+  Options.MCOptions.AsmVerbose = AsmComments;
+  Options.MCOptions.PreserveAsmComments = AsmComments;
 
   if (TrapUnreachable) {
     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs
new file mode 100644
index 00000000000..18d73bf5677
--- /dev/null
+++ b/src/test/debuginfo/pretty-std-collections.rs
@@ -0,0 +1,50 @@
+// Copyright 2018 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-android: FIXME(#10381)
+// compile-flags:-g
+// min-gdb-version 7.7
+// min-lldb-version: 310
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command: run
+
+// gdb-command: print btree_set
+// gdb-check:$1 = BTreeSet<i32>(len: 3) = {3, 5, 7}
+
+// gdb-command: print vec_deque
+// gdb-check:$2 = VecDeque<i32>(len: 3, cap: 8) = {5, 3, 7}
+
+#![allow(unused_variables)]
+use std::collections::BTreeSet;
+use std::collections::VecDeque;
+
+
+fn main() {
+
+    // BTreeSet
+    let mut btree_set = BTreeSet::new();
+    btree_set.insert(5);
+    btree_set.insert(3);
+    btree_set.insert(7);
+
+    // VecDeque
+    let mut vec_deque = VecDeque::new();
+    vec_deque.push_back(5);
+    vec_deque.push_back(3);
+    vec_deque.push_back(7);
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/run-pass/env-null-vars.rs b/src/test/run-pass/env-null-vars.rs
new file mode 100644
index 00000000000..296764269de
--- /dev/null
+++ b/src/test/run-pass/env-null-vars.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 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
+// ignore-wasm32-bare no libc to test ffi with
+
+// issue-53200
+
+#![feature(libc)]
+extern crate libc;
+
+use std::env;
+
+// FIXME: more platforms?
+#[cfg(target_os = "linux")]
+fn main() {
+    unsafe { libc::clearenv(); }
+    assert_eq!(env::vars().count(), 0);
+}
+
+#[cfg(not(target_os = "linux"))]
+fn main() {}
diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs
new file mode 100644
index 00000000000..21ad5159946
--- /dev/null
+++ b/src/test/rustdoc/async-fn.rs
@@ -0,0 +1,24 @@
+// Copyright 2018 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.
+
+// edition:2018
+// compile-flags:-Z unstable-options
+
+// FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive
+
+#![feature(rust_2018_preview, async_await, futures_api)]
+
+// @has async_fn/struct.S.html
+// @has - '//code' 'pub async fn f()'
+pub struct S;
+
+impl S {
+    pub async fn f() {}
+}
diff --git a/src/test/ui/issue-53251.rs b/src/test/ui/issue-53251.rs
new file mode 100644
index 00000000000..aa9da744566
--- /dev/null
+++ b/src/test/ui/issue-53251.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+struct S;
+
+impl S {
+    fn f() {}
+}
+
+macro_rules! impl_add {
+    ($($n:ident)*) => {
+        $(
+            fn $n() {
+                S::f::<i64>();
+                //~^ ERROR too many type parameters provided
+            }
+        )*
+    }
+}
+
+impl_add!(a b);
diff --git a/src/test/ui/issue-53251.stderr b/src/test/ui/issue-53251.stderr
new file mode 100644
index 00000000000..bf99e73f0d9
--- /dev/null
+++ b/src/test/ui/issue-53251.stderr
@@ -0,0 +1,17 @@
+error[E0601]: `main` function not found in crate `issue_53251`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-53251.rs`
+
+error[E0087]: too many type parameters provided: expected at most 0 type parameters, found 1 type parameter
+  --> $DIR/issue-53251.rs:21:24
+   |
+LL |                 S::f::<i64>();
+   |                        ^^^ expected 0 type parameters
+...
+LL | impl_add!(a b);
+   | --------------- in this macro invocation
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0087, E0601.
+For more information about an error, try `rustc --explain E0087`.
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index 220082799a8..d1071231530 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -57,14 +57,16 @@ pub unsafe fn raise_fd_limit() {
         panic!("raise_fd_limit: error calling getrlimit: {}", err);
     }
 
-    // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard
-    // limit
-    rlim.rlim_cur = cmp::min(maxfiles as libc::rlim_t, rlim.rlim_max);
+    // Make sure we're only ever going to increase the rlimit.
+    if rlim.rlim_cur < maxfiles as libc::rlim_t {
+        // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit.
+        rlim.rlim_cur = cmp::min(maxfiles as libc::rlim_t, rlim.rlim_max);
 
-    // Set our newly-increased resource limit
-    if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 {
-        let err = io::Error::last_os_error();
-        panic!("raise_fd_limit: error calling setrlimit: {}", err);
+        // Set our newly-increased resource limit.
+        if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) != 0 {
+            let err = io::Error::last_os_error();
+            panic!("raise_fd_limit: error calling setrlimit: {}", err);
+        }
     }
 }