about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-14 07:18:25 +0000
committerbors <bors@rust-lang.org>2018-09-14 07:18:25 +0000
commitfccde0018a618eb6f45d2a3c97f629809994dff6 (patch)
treed4c725cd7dfd72336822e39f899c27dbf13a6d99
parent6ff0b2ed163dab4389d88b14b5729514c11c682e (diff)
parentdd4f5a2d48d986e0bf23b7cc690d3c2422d4391a (diff)
downloadrust-fccde0018a618eb6f45d2a3c97f629809994dff6.tar.gz
rust-fccde0018a618eb6f45d2a3c97f629809994dff6.zip
Auto merge of #54215 - kennytm:rollup, r=kennytm
Rollup of 8 pull requests

Successful merges:

 - #53218 (Add a implementation of `From` for converting `&'a Option<T>` into `Option<&'a T>`)
 - #54024 (Fix compiling some rustc crates to wasm)
 - #54095 (Rename all mentions of `nil` to `unit`)
 - #54173 (Suggest valid crate type if invalid crate type is found)
 - #54194 (Remove println!() statement from HashMap unit test)
 - #54203 (Fix the stable release of os_str_str_ref_eq)
 - #54207 (re-mark the never docs as unstable)
 - #54210 (Update Cargo)

Failed merges:

r? @ghost
-rw-r--r--src/libcore/option.rs14
-rw-r--r--src/librustc/lint/builtin.rs9
-rw-r--r--src/librustc/traits/error_reporting.rs2
-rw-r--r--src/librustc/ty/context.rs4
-rw-r--r--src/librustc/ty/layout.rs4
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs2
-rw-r--r--src/librustc/ty/sty.rs2
-rw-r--r--src/librustc/util/ppaux.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/type_names.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/rvalue.rs4
-rw-r--r--src/librustc_data_structures/flock.rs590
-rw-r--r--src/librustc_driver/driver.rs48
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustc_errors/lock.rs2
-rw-r--r--src/librustc_lint/types.rs4
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_mir/build/block.rs2
-rw-r--r--src/librustc_mir/hair/cx/mod.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs2
-rw-r--r--src/librustc_mir/monomorphize/item.rs2
-rw-r--r--src/librustc_mir/transform/generator.rs4
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs4
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs6
-rw-r--r--src/librustc_typeck/check/coercion.rs6
-rw-r--r--src/librustc_typeck/check/intrinsic.rs28
-rw-r--r--src/librustc_typeck/check/mod.rs26
-rw-r--r--src/librustc_typeck/check/op.rs2
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/libserialize/json.rs10
-rw-r--r--src/libserialize/opaque.rs2
-rw-r--r--src/libserialize/serialize.rs4
-rw-r--r--src/libstd/collections/hash/map.rs3
-rw-r--r--src/libstd/ffi/os_str.rs4
-rw-r--r--src/libstd/primitive_docs.rs1
-rw-r--r--src/test/ui/invalid/invalid-crate-type.rs42
-rw-r--r--src/test/ui/invalid/invalid-crate-type.stderr54
m---------src/tools/cargo0
39 files changed, 528 insertions, 375 deletions
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 53cf626bb1c..dfdc375765d 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1062,6 +1062,20 @@ impl<T> From<T> for Option<T> {
     }
 }
 
+#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
+impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
+    fn from(o: &'a Option<T>) -> Option<&'a T> {
+        o.as_ref()
+    }
+}
+
+#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
+impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
+    fn from(o: &'a mut Option<T>) -> Option<&'a mut T> {
+        o.as_mut()
+    }
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // The Option Iterators
 /////////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 6783415619f..e6452ad0927 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -422,6 +422,7 @@ pub enum BuiltinLintDiagnostics {
     ProcMacroDeriveResolutionFallback(Span),
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
     ElidedLifetimesInPaths(usize, Span, bool, Span, String),
+    UnknownCrateTypes(Span, String, String),
 }
 
 impl BuiltinLintDiagnostics {
@@ -500,6 +501,14 @@ impl BuiltinLintDiagnostics {
                     Applicability::MachineApplicable
                 );
             }
+            BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
+                db.span_suggestion_with_applicability(
+                    span,
+                    &note,
+                    sugg,
+                    Applicability::MaybeIncorrect
+                );
+            }
         }
     }
 }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index a7c697c1cba..466d472cca3 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -661,7 +661,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                         {
                             let predicate = trait_predicate.map_bound(|mut trait_pred| {
                                 trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
-                                    self.tcx.mk_nil(),
+                                    self.tcx.mk_unit(),
                                     &trait_pred.trait_ref.substs[1..],
                                 );
                                 trait_pred
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 83d6b715e95..6cc648b572c 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2492,7 +2492,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn mk_nil_ptr(self) -> Ty<'tcx> {
-        self.mk_imm_ptr(self.mk_nil())
+        self.mk_imm_ptr(self.mk_unit())
     }
 
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
@@ -2511,7 +2511,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(ts))))
     }
 
-    pub fn mk_nil(self) -> Ty<'tcx> {
+    pub fn mk_unit(self) -> Ty<'tcx> {
         self.intern_tup(&[])
     }
 
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 17d613a2b18..a3316c2b8e2 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -132,7 +132,7 @@ impl PrimitiveExt for Primitive {
             Int(i, signed) => i.to_ty(tcx, signed),
             Float(FloatTy::F32) => tcx.types.f32,
             Float(FloatTy::F64) => tcx.types.f64,
-            Pointer => tcx.mk_mut_ptr(tcx.mk_nil()),
+            Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
         }
     }
 }
@@ -1606,7 +1606,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
                 // (which may have no non-DST form), and will work as long
                 // as the `Abi` or `FieldPlacement` is checked by users.
                 if i == 0 {
-                    let nil = tcx.mk_nil();
+                    let nil = tcx.mk_unit();
                     let ptr_ty = if this.ty.is_unsafe_ptr() {
                         tcx.mk_mut_ptr(nil)
                     } else {
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 6e16d92ba0c..19e235154cb 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -1020,7 +1020,7 @@ impl<'enc, 'a, 'tcx, E> Encoder for CacheEncoder<'enc, 'a, 'tcx, E>
 {
     type Error = E::Error;
 
-    fn emit_nil(&mut self) -> Result<(), Self::Error> {
+    fn emit_unit(&mut self) -> Result<(), Self::Error> {
         Ok(())
     }
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 962b115f187..ea547c592d0 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1458,7 +1458,7 @@ impl RegionKind {
 
 /// Type utilities
 impl<'a, 'gcx, 'tcx> TyS<'tcx> {
-    pub fn is_nil(&self) -> bool {
+    pub fn is_unit(&self) -> bool {
         match self.sty {
             Tuple(ref tys) => tys.is_empty(),
             _ => false,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index ddcc0fa9c92..3d7117dd46a 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -234,7 +234,7 @@ impl PrintContext {
             }
         }
         write!(f, ")")?;
-        if !output.is_nil() {
+        if !output.is_unit() {
             print!(f, self, write(" -> "), print_display(output))?;
         }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs
index 95a094bf909..f9eb80a1988 100644
--- a/src/librustc_codegen_llvm/debuginfo/type_names.rs
+++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs
@@ -160,7 +160,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 
             output.push(')');
 
-            if !sig.output().is_nil() {
+            if !sig.output().is_unit() {
                 output.push_str(" -> ");
                 push_debuginfo_type_name(cx, sig.output(), true, output);
             }
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 5d00e080799..5ec934ebd06 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -968,7 +968,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
     let i8p = tcx.mk_mut_ptr(tcx.types.i8);
     let fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
         iter::once(i8p),
-        tcx.mk_nil(),
+        tcx.mk_unit(),
         false,
         hir::Unsafety::Unsafe,
         Abi::Rust
diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs
index e301e5ae70b..c3ec347f608 100644
--- a/src/librustc_codegen_llvm/mir/rvalue.rs
+++ b/src/librustc_codegen_llvm/mir/rvalue.rs
@@ -566,7 +566,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
     ) -> &'ll Value {
         let is_float = input_ty.is_fp();
         let is_signed = input_ty.is_signed();
-        let is_nil = input_ty.is_nil();
+        let is_unit = input_ty.is_unit();
         match op {
             mir::BinOp::Add => if is_float {
                 bx.fadd(lhs, rhs)
@@ -604,7 +604,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
             mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs),
             mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs),
             mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
-            mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_nil {
+            mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_unit {
                 C_bool(bx.cx, match op {
                     mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false,
                     mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true,
diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs
index f10a9a68bed..38ce331051f 100644
--- a/src/librustc_data_structures/flock.rs
+++ b/src/librustc_data_structures/flock.rs
@@ -15,345 +15,351 @@
 //! librustdoc, it is not production quality at all.
 
 #![allow(non_camel_case_types)]
-use std::path::Path;
-
-pub use self::imp::Lock;
+#![allow(nonstandard_style)]
 
-#[cfg(unix)]
-mod imp {
-    use std::ffi::{CString, OsStr};
-    use std::os::unix::prelude::*;
-    use std::path::Path;
-    use std::io;
-    use libc;
+use std::io;
+use std::path::Path;
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
-    mod os {
+cfg_if! {
+    if #[cfg(unix)] {
+        use std::ffi::{CString, OsStr};
+        use std::os::unix::prelude::*;
         use libc;
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_pid: libc::pid_t,
-
-            // not actually here, but brings in line with freebsd
-            pub l_sysid: libc::c_int,
-        }
+        #[cfg(any(target_os = "linux", target_os = "android"))]
+        mod os {
+            use libc;
 
-        pub const F_RDLCK: libc::c_short = 0;
-        pub const F_WRLCK: libc::c_short = 1;
-        pub const F_UNLCK: libc::c_short = 2;
-        pub const F_SETLK: libc::c_int = 6;
-        pub const F_SETLKW: libc::c_int = 7;
-    }
+            #[repr(C)]
+            pub struct flock {
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_pid: libc::pid_t,
 
-    #[cfg(target_os = "freebsd")]
-    mod os {
-        use libc;
+                // not actually here, but brings in line with freebsd
+                pub l_sysid: libc::c_int,
+            }
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_pid: libc::pid_t,
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-            pub l_sysid: libc::c_int,
+            pub const F_RDLCK: libc::c_short = 0;
+            pub const F_WRLCK: libc::c_short = 1;
+            pub const F_UNLCK: libc::c_short = 2;
+            pub const F_SETLK: libc::c_int = 6;
+            pub const F_SETLKW: libc::c_int = 7;
         }
 
-        pub const F_RDLCK: libc::c_short = 1;
-        pub const F_UNLCK: libc::c_short = 2;
-        pub const F_WRLCK: libc::c_short = 3;
-        pub const F_SETLK: libc::c_int = 12;
-        pub const F_SETLKW: libc::c_int = 13;
-    }
-
-    #[cfg(any(target_os = "dragonfly",
-              target_os = "bitrig",
-              target_os = "netbsd",
-              target_os = "openbsd"))]
-    mod os {
-        use libc;
+        #[cfg(target_os = "freebsd")]
+        mod os {
+            use libc;
+
+            #[repr(C)]
+            pub struct flock {
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_pid: libc::pid_t,
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
+                pub l_sysid: libc::c_int,
+            }
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_pid: libc::pid_t,
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-
-            // not actually here, but brings in line with freebsd
-            pub l_sysid: libc::c_int,
+            pub const F_RDLCK: libc::c_short = 1;
+            pub const F_UNLCK: libc::c_short = 2;
+            pub const F_WRLCK: libc::c_short = 3;
+            pub const F_SETLK: libc::c_int = 12;
+            pub const F_SETLKW: libc::c_int = 13;
         }
 
-        pub const F_RDLCK: libc::c_short = 1;
-        pub const F_UNLCK: libc::c_short = 2;
-        pub const F_WRLCK: libc::c_short = 3;
-        pub const F_SETLK: libc::c_int = 8;
-        pub const F_SETLKW: libc::c_int = 9;
-    }
-
-    #[cfg(target_os = "haiku")]
-    mod os {
-        use libc;
+        #[cfg(any(target_os = "dragonfly",
+                  target_os = "bitrig",
+                  target_os = "netbsd",
+                  target_os = "openbsd"))]
+        mod os {
+            use libc;
+
+            #[repr(C)]
+            pub struct flock {
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_pid: libc::pid_t,
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
+
+                // not actually here, but brings in line with freebsd
+                pub l_sysid: libc::c_int,
+            }
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_pid: libc::pid_t,
-
-            // not actually here, but brings in line with freebsd
-            pub l_sysid: libc::c_int,
+            pub const F_RDLCK: libc::c_short = 1;
+            pub const F_UNLCK: libc::c_short = 2;
+            pub const F_WRLCK: libc::c_short = 3;
+            pub const F_SETLK: libc::c_int = 8;
+            pub const F_SETLKW: libc::c_int = 9;
         }
 
-        pub const F_RDLCK: libc::c_short = 0x0040;
-        pub const F_UNLCK: libc::c_short = 0x0200;
-        pub const F_WRLCK: libc::c_short = 0x0400;
-        pub const F_SETLK: libc::c_int = 0x0080;
-        pub const F_SETLKW: libc::c_int = 0x0100;
-    }
+        #[cfg(target_os = "haiku")]
+        mod os {
+            use libc;
 
-    #[cfg(any(target_os = "macos", target_os = "ios"))]
-    mod os {
-        use libc;
+            #[repr(C)]
+            pub struct flock {
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_pid: libc::pid_t,
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_pid: libc::pid_t,
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-
-            // not actually here, but brings in line with freebsd
-            pub l_sysid: libc::c_int,
+                // not actually here, but brings in line with freebsd
+                pub l_sysid: libc::c_int,
+            }
+
+            pub const F_RDLCK: libc::c_short = 0x0040;
+            pub const F_UNLCK: libc::c_short = 0x0200;
+            pub const F_WRLCK: libc::c_short = 0x0400;
+            pub const F_SETLK: libc::c_int = 0x0080;
+            pub const F_SETLKW: libc::c_int = 0x0100;
         }
 
-        pub const F_RDLCK: libc::c_short = 1;
-        pub const F_UNLCK: libc::c_short = 2;
-        pub const F_WRLCK: libc::c_short = 3;
-        pub const F_SETLK: libc::c_int = 8;
-        pub const F_SETLKW: libc::c_int = 9;
-    }
+        #[cfg(any(target_os = "macos", target_os = "ios"))]
+        mod os {
+            use libc;
 
-    #[cfg(target_os = "solaris")]
-    mod os {
-        use libc;
+            #[repr(C)]
+            pub struct flock {
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_pid: libc::pid_t,
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
 
-        #[repr(C)]
-        pub struct flock {
-            pub l_type: libc::c_short,
-            pub l_whence: libc::c_short,
-            pub l_start: libc::off_t,
-            pub l_len: libc::off_t,
-            pub l_sysid: libc::c_int,
-            pub l_pid: libc::pid_t,
+                // not actually here, but brings in line with freebsd
+                pub l_sysid: libc::c_int,
+            }
+
+            pub const F_RDLCK: libc::c_short = 1;
+            pub const F_UNLCK: libc::c_short = 2;
+            pub const F_WRLCK: libc::c_short = 3;
+            pub const F_SETLK: libc::c_int = 8;
+            pub const F_SETLKW: libc::c_int = 9;
         }
 
-        pub const F_RDLCK: libc::c_short = 1;
-        pub const F_WRLCK: libc::c_short = 2;
-        pub const F_UNLCK: libc::c_short = 3;
-        pub const F_SETLK: libc::c_int = 6;
-        pub const F_SETLKW: libc::c_int = 7;
-    }
+        #[cfg(target_os = "solaris")]
+        mod os {
+            use libc;
+
+            #[repr(C)]
+            pub struct flock {
+                pub l_type: libc::c_short,
+                pub l_whence: libc::c_short,
+                pub l_start: libc::off_t,
+                pub l_len: libc::off_t,
+                pub l_sysid: libc::c_int,
+                pub l_pid: libc::pid_t,
+            }
 
-    #[derive(Debug)]
-    pub struct Lock {
-        fd: libc::c_int,
-    }
+            pub const F_RDLCK: libc::c_short = 1;
+            pub const F_WRLCK: libc::c_short = 2;
+            pub const F_UNLCK: libc::c_short = 3;
+            pub const F_SETLK: libc::c_int = 6;
+            pub const F_SETLKW: libc::c_int = 7;
+        }
 
-    impl Lock {
-        pub fn new(p: &Path,
-                   wait: bool,
-                   create: bool,
-                   exclusive: bool)
-                   -> io::Result<Lock> {
-            let os: &OsStr = p.as_ref();
-            let buf = CString::new(os.as_bytes()).unwrap();
-            let open_flags = if create {
-                libc::O_RDWR | libc::O_CREAT
-            } else {
-                libc::O_RDWR
-            };
-
-            let fd = unsafe {
-                libc::open(buf.as_ptr(), open_flags,
-                           libc::S_IRWXU as libc::c_int)
-            };
-
-            if fd < 0 {
-                return Err(io::Error::last_os_error());
-            }
+        #[derive(Debug)]
+        pub struct Lock {
+            fd: libc::c_int,
+        }
 
-            let lock_type = if exclusive {
-                os::F_WRLCK
-            } else {
-                os::F_RDLCK
-            };
-
-            let flock = os::flock {
-                l_start: 0,
-                l_len: 0,
-                l_pid: 0,
-                l_whence: libc::SEEK_SET as libc::c_short,
-                l_type: lock_type,
-                l_sysid: 0,
-            };
-            let cmd = if wait { os::F_SETLKW } else { os::F_SETLK };
-            let ret = unsafe {
-                libc::fcntl(fd, cmd, &flock)
-            };
-            if ret == -1 {
-                let err = io::Error::last_os_error();
-                unsafe { libc::close(fd); }
-                Err(err)
-            } else {
-                Ok(Lock { fd: fd })
+        impl Lock {
+            pub fn new(p: &Path,
+                       wait: bool,
+                       create: bool,
+                       exclusive: bool)
+                       -> io::Result<Lock> {
+                let os: &OsStr = p.as_ref();
+                let buf = CString::new(os.as_bytes()).unwrap();
+                let open_flags = if create {
+                    libc::O_RDWR | libc::O_CREAT
+                } else {
+                    libc::O_RDWR
+                };
+
+                let fd = unsafe {
+                    libc::open(buf.as_ptr(), open_flags,
+                               libc::S_IRWXU as libc::c_int)
+                };
+
+                if fd < 0 {
+                    return Err(io::Error::last_os_error());
+                }
+
+                let lock_type = if exclusive {
+                    os::F_WRLCK
+                } else {
+                    os::F_RDLCK
+                };
+
+                let flock = os::flock {
+                    l_start: 0,
+                    l_len: 0,
+                    l_pid: 0,
+                    l_whence: libc::SEEK_SET as libc::c_short,
+                    l_type: lock_type,
+                    l_sysid: 0,
+                };
+                let cmd = if wait { os::F_SETLKW } else { os::F_SETLK };
+                let ret = unsafe {
+                    libc::fcntl(fd, cmd, &flock)
+                };
+                if ret == -1 {
+                    let err = io::Error::last_os_error();
+                    unsafe { libc::close(fd); }
+                    Err(err)
+                } else {
+                    Ok(Lock { fd: fd })
+                }
             }
         }
-    }
 
-    impl Drop for Lock {
-        fn drop(&mut self) {
-            let flock = os::flock {
-                l_start: 0,
-                l_len: 0,
-                l_pid: 0,
-                l_whence: libc::SEEK_SET as libc::c_short,
-                l_type: os::F_UNLCK,
-                l_sysid: 0,
-            };
-            unsafe {
-                libc::fcntl(self.fd, os::F_SETLK, &flock);
-                libc::close(self.fd);
+        impl Drop for Lock {
+            fn drop(&mut self) {
+                let flock = os::flock {
+                    l_start: 0,
+                    l_len: 0,
+                    l_pid: 0,
+                    l_whence: libc::SEEK_SET as libc::c_short,
+                    l_type: os::F_UNLCK,
+                    l_sysid: 0,
+                };
+                unsafe {
+                    libc::fcntl(self.fd, os::F_SETLK, &flock);
+                    libc::close(self.fd);
+                }
             }
         }
-    }
-}
+    } else if #[cfg(windows)] {
+        use std::mem;
+        use std::os::windows::prelude::*;
+        use std::os::windows::raw::HANDLE;
+        use std::fs::{File, OpenOptions};
+        use std::os::raw::{c_ulong, c_int};
 
-#[cfg(windows)]
-#[allow(nonstandard_style)]
-mod imp {
-    use std::io;
-    use std::mem;
-    use std::os::windows::prelude::*;
-    use std::os::windows::raw::HANDLE;
-    use std::path::Path;
-    use std::fs::{File, OpenOptions};
-    use std::os::raw::{c_ulong, c_int};
-
-    type DWORD = c_ulong;
-    type BOOL = c_int;
-    type ULONG_PTR = usize;
-
-    type LPOVERLAPPED = *mut OVERLAPPED;
-    const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
-    const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;
-
-    const FILE_SHARE_DELETE: DWORD = 0x4;
-    const FILE_SHARE_READ: DWORD = 0x1;
-    const FILE_SHARE_WRITE: DWORD = 0x2;
-
-    #[repr(C)]
-    struct OVERLAPPED {
-        Internal: ULONG_PTR,
-        InternalHigh: ULONG_PTR,
-        Offset: DWORD,
-        OffsetHigh: DWORD,
-        hEvent: HANDLE,
-    }
+        type DWORD = c_ulong;
+        type BOOL = c_int;
+        type ULONG_PTR = usize;
 
-    extern "system" {
-        fn LockFileEx(hFile: HANDLE,
-                      dwFlags: DWORD,
-                      dwReserved: DWORD,
-                      nNumberOfBytesToLockLow: DWORD,
-                      nNumberOfBytesToLockHigh: DWORD,
-                      lpOverlapped: LPOVERLAPPED) -> BOOL;
-    }
+        type LPOVERLAPPED = *mut OVERLAPPED;
+        const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
+        const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;
 
-    #[derive(Debug)]
-    pub struct Lock {
-        _file: File,
-    }
+        const FILE_SHARE_DELETE: DWORD = 0x4;
+        const FILE_SHARE_READ: DWORD = 0x1;
+        const FILE_SHARE_WRITE: DWORD = 0x2;
 
-    impl Lock {
-        pub fn new(p: &Path,
-                   wait: bool,
-                   create: bool,
-                   exclusive: bool)
-                   -> io::Result<Lock> {
-            assert!(p.parent().unwrap().exists(),
-                "Parent directory of lock-file must exist: {}",
-                p.display());
-
-            let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
-
-            let mut open_options = OpenOptions::new();
-            open_options.read(true)
-                        .share_mode(share_mode);
-
-            if create {
-                open_options.create(true)
-                            .write(true);
-            }
+        #[repr(C)]
+        struct OVERLAPPED {
+            Internal: ULONG_PTR,
+            InternalHigh: ULONG_PTR,
+            Offset: DWORD,
+            OffsetHigh: DWORD,
+            hEvent: HANDLE,
+        }
 
-            debug!("Attempting to open lock file `{}`", p.display());
-            let file = match open_options.open(p) {
-                Ok(file) => {
-                    debug!("Lock file opened successfully");
-                    file
-                }
-                Err(err) => {
-                    debug!("Error opening lock file: {}", err);
-                    return Err(err)
-                }
-            };
+        extern "system" {
+            fn LockFileEx(hFile: HANDLE,
+                          dwFlags: DWORD,
+                          dwReserved: DWORD,
+                          nNumberOfBytesToLockLow: DWORD,
+                          nNumberOfBytesToLockHigh: DWORD,
+                          lpOverlapped: LPOVERLAPPED) -> BOOL;
+        }
 
-            let ret = unsafe {
-                let mut overlapped: OVERLAPPED = mem::zeroed();
+        #[derive(Debug)]
+        pub struct Lock {
+            _file: File,
+        }
 
-                let mut dwFlags = 0;
-                if !wait {
-                    dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
+        impl Lock {
+            pub fn new(p: &Path,
+                       wait: bool,
+                       create: bool,
+                       exclusive: bool)
+                       -> io::Result<Lock> {
+                assert!(p.parent().unwrap().exists(),
+                    "Parent directory of lock-file must exist: {}",
+                    p.display());
+
+                let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
+
+                let mut open_options = OpenOptions::new();
+                open_options.read(true)
+                            .share_mode(share_mode);
+
+                if create {
+                    open_options.create(true)
+                                .write(true);
                 }
 
-                if exclusive {
-                    dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
+                debug!("Attempting to open lock file `{}`", p.display());
+                let file = match open_options.open(p) {
+                    Ok(file) => {
+                        debug!("Lock file opened successfully");
+                        file
+                    }
+                    Err(err) => {
+                        debug!("Error opening lock file: {}", err);
+                        return Err(err)
+                    }
+                };
+
+                let ret = unsafe {
+                    let mut overlapped: OVERLAPPED = mem::zeroed();
+
+                    let mut dwFlags = 0;
+                    if !wait {
+                        dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
+                    }
+
+                    if exclusive {
+                        dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
+                    }
+
+                    debug!("Attempting to acquire lock on lock file `{}`",
+                           p.display());
+                    LockFileEx(file.as_raw_handle(),
+                               dwFlags,
+                               0,
+                               0xFFFF_FFFF,
+                               0xFFFF_FFFF,
+                               &mut overlapped)
+                };
+                if ret == 0 {
+                    let err = io::Error::last_os_error();
+                    debug!("Failed acquiring file lock: {}", err);
+                    Err(err)
+                } else {
+                    debug!("Successfully acquired lock.");
+                    Ok(Lock { _file: file })
                 }
+            }
+        }
 
-                debug!("Attempting to acquire lock on lock file `{}`",
-                       p.display());
-                LockFileEx(file.as_raw_handle(),
-                           dwFlags,
-                           0,
-                           0xFFFF_FFFF,
-                           0xFFFF_FFFF,
-                           &mut overlapped)
-            };
-            if ret == 0 {
-                let err = io::Error::last_os_error();
-                debug!("Failed acquiring file lock: {}", err);
-                Err(err)
-            } else {
-                debug!("Successfully acquired lock.");
-                Ok(Lock { _file: file })
+        // Note that we don't need a Drop impl on the Windows: The file is unlocked
+        // automatically when it's closed.
+    } else {
+        #[derive(Debug)]
+        pub struct Lock(());
+
+        impl Lock {
+            pub fn new(_p: &Path, _wait: bool, _create: bool, _exclusive: bool)
+                -> io::Result<Lock>
+            {
+                let msg = "file locks not supported on this platform";
+                Err(io::Error::new(io::ErrorKind::Other, msg))
             }
         }
     }
-
-    // Note that we don't need a Drop impl on the Windows: The file is unlocked
-    // automatically when it's closed.
 }
 
-impl imp::Lock {
+impl Lock {
     pub fn panicking_new(p: &Path,
                          wait: bool,
                          create: bool,
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index d27b0856c15..7fb66ea97f2 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -57,6 +57,8 @@ use syntax::ext::base::ExtCtxt;
 use syntax::fold::Folder;
 use syntax::parse::{self, PResult};
 use syntax::util::node_count::NodeCounter;
+use syntax::util::lev_distance::find_best_match_for_name;
+use syntax::symbol::Symbol;
 use syntax_pos::{FileName, hygiene};
 use syntax_ext;
 
@@ -1508,13 +1510,45 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
                     Some(ref n) if *n == "staticlib" => Some(config::CrateType::Staticlib),
                     Some(ref n) if *n == "proc-macro" => Some(config::CrateType::ProcMacro),
                     Some(ref n) if *n == "bin" => Some(config::CrateType::Executable),
-                    Some(_) => {
-                        session.buffer_lint(
-                            lint::builtin::UNKNOWN_CRATE_TYPES,
-                            ast::CRATE_NODE_ID,
-                            a.span,
-                            "invalid `crate_type` value",
-                        );
+                    Some(ref n) => {
+                        let crate_types = vec![
+                            Symbol::intern("rlib"),
+                            Symbol::intern("dylib"),
+                            Symbol::intern("cdylib"),
+                            Symbol::intern("lib"),
+                            Symbol::intern("staticlib"),
+                            Symbol::intern("proc-macro"),
+                            Symbol::intern("bin")
+                        ];
+                        if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
+                            let span = spanned.span;
+                            let lev_candidate = find_best_match_for_name(
+                                crate_types.iter(),
+                                &n.as_str(),
+                                None
+                            );
+                            if let Some(candidate) = lev_candidate {
+                                session.buffer_lint_with_diagnostic(
+                                    lint::builtin::UNKNOWN_CRATE_TYPES,
+                                    ast::CRATE_NODE_ID,
+                                    span,
+                                    "invalid `crate_type` value",
+                                    lint::builtin::BuiltinLintDiagnostics::
+                                        UnknownCrateTypes(
+                                            span,
+                                            "did you mean".to_string(),
+                                            format!("\"{}\"", candidate)
+                                        )
+                                );
+                            } else {
+                                session.buffer_lint(
+                                    lint::builtin::UNKNOWN_CRATE_TYPES,
+                                    ast::CRATE_NODE_ID,
+                                    span,
+                                    "invalid `crate_type` value"
+                                );
+                            }
+                        }
                         None
                     }
                     _ => {
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 57c00f252ef..ff35371976a 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -309,7 +309,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
     }
 
     pub fn t_nil(&self) -> Ty<'tcx> {
-        self.infcx.tcx.mk_nil()
+        self.infcx.tcx.mk_unit()
     }
 
     pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs
index e5baf93b000..ff323073c62 100644
--- a/src/librustc_errors/lock.rs
+++ b/src/librustc_errors/lock.rs
@@ -109,7 +109,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
     }
 }
 
-#[cfg(unix)]
+#[cfg(not(windows))]
 pub fn acquire_global_lock(_name: &str) -> Box<dyn Any> {
     Box::new(())
 }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 33181bd80e9..2bec9203e9e 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -691,7 +691,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 }
 
                 let sig = cx.erase_late_bound_regions(&sig);
-                if !sig.output().is_nil() {
+                if !sig.output().is_unit() {
                     let r = self.check_type_for_ffi(cache, sig.output());
                     match r {
                         FfiSafe => {}
@@ -767,7 +767,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
         if let hir::Return(ref ret_hir) = decl.output {
             let ret_ty = sig.output();
-            if !ret_ty.is_nil() {
+            if !ret_ty.is_unit() {
                 self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
             }
         }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index aae45c17c67..56b38cfbc87 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -75,7 +75,7 @@ macro_rules! encoder_methods {
 impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
     type Error = <opaque::Encoder as Encoder>::Error;
 
-    fn emit_nil(&mut self) -> Result<(), Self::Error> {
+    fn emit_unit(&mut self) -> Result<(), Self::Error> {
         Ok(())
     }
 
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index bfb6daee604..c4cb7958fd3 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             // the case of `!`, no return value is required, as the block will never return.
             let tcx = this.hir.tcx();
             let ty = destination.ty(&this.local_decls, tcx).to_ty(tcx);
-            if ty.is_nil() {
+            if ty.is_unit() {
                 // We only want to assign an implicit `()` as the return value of the block if the
                 // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
                 this.cfg.push_assign_unit(block, source_info, destination);
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index b4257a40e38..4d4a89fca8b 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -118,7 +118,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
     }
 
     pub fn unit_ty(&mut self) -> Ty<'tcx> {
-        self.tcx.mk_nil()
+        self.tcx.mk_unit()
     }
 
     pub fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> {
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index de868106274..7ce96b1f626 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -436,7 +436,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?,
         };
 
-        let ty = self.tcx.mk_nil(); // return type is ()
+        let ty = self.tcx.mk_unit(); // return type is ()
         let dest = PlaceTy::null(&self, self.layout_of(ty)?);
 
         self.eval_fn_call(
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index dc437ee8510..3f5a05f9d0e 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -368,7 +368,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
 
                 output.push(')');
 
-                if !sig.output().is_nil() {
+                if !sig.output().is_unit() {
                     output.push_str(" -> ");
                     self.push_type_name(sig.output(), output);
                 }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index f1f42768ce3..01edfd2bfc9 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -518,7 +518,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     let upvar_len = mir.upvar_decls.len();
-    let dummy_local = LocalDecl::new_internal(tcx.mk_nil(), mir.span);
+    let dummy_local = LocalDecl::new_internal(tcx.mk_unit(), mir.span);
 
     // Gather live locals and their indices replacing values in mir.local_decls with a dummy
     // to avoid changing local indices
@@ -656,7 +656,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
     // Replace the return variable
     mir.local_decls[RETURN_PLACE] = LocalDecl {
         mutability: Mutability::Mut,
-        ty: tcx.mk_nil(),
+        ty: tcx.mk_unit(),
         user_ty: None,
         name: None,
         source_info,
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 1c0c98d621c..50bdc14d509 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -529,7 +529,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             mutbl: hir::Mutability::MutMutable
         });
         let ref_place = self.new_temp(ref_ty);
-        let unit_temp = Place::Local(self.new_temp(tcx.mk_nil()));
+        let unit_temp = Place::Local(self.new_temp(tcx.mk_unit()));
 
         let result = BasicBlockData {
             statements: vec![self.assign(
@@ -891,7 +891,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         unwind: Unwind
     ) -> BasicBlock {
         let tcx = self.tcx();
-        let unit_temp = Place::Local(self.new_temp(tcx.mk_nil()));
+        let unit_temp = Place::Local(self.new_temp(tcx.mk_unit()));
         let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
         let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| {
             let field = Field::new(i);
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index eaf1d03de7d..72502cda6e0 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1575,7 +1575,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
 
         let output_ty = match decl.output {
             hir::Return(ref output) => self.ast_ty_to_ty(output),
-            hir::DefaultReturn(..) => tcx.mk_nil(),
+            hir::DefaultReturn(..) => tcx.mk_unit(),
         };
 
         debug!("ty_of_fn: output_ty={:?}", output_ty);
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 6189c120a80..0d2bc575401 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -666,7 +666,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 // us to give better error messages (pointing to a usually better
                 // arm for inconsistent arms or to the whole match when a `()` type
                 // is required).
-                Expectation::ExpectHasType(ety) if ety != self.tcx.mk_nil() => ety,
+                Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety,
                 _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
             };
             CoerceMany::with_coercion_sites(coerce_first, arms)
@@ -687,14 +687,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
             // Handle the fallback arm of a desugared if-let like a missing else.
             let is_if_let_fallback = match match_src {
                 hir::MatchSource::IfLetDesugar { contains_else_clause: false } => {
-                    i == arms.len() - 1 && arm_ty.is_nil()
+                    i == arms.len() - 1 && arm_ty.is_unit()
                 }
                 _ => false
             };
 
             if is_if_let_fallback {
                 let cause = self.cause(expr.span, ObligationCauseCode::IfExpressionWithNoElse);
-                assert!(arm_ty.is_nil());
+                assert!(arm_ty.is_unit());
                 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
             } else {
                 let cause = self.cause(expr.span, ObligationCauseCode::MatchExpressionArm {
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 763adb007c3..9604eb3420f 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -1077,7 +1077,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
         self.coerce_inner(fcx,
                           cause,
                           None,
-                          fcx.tcx.mk_nil(),
+                          fcx.tcx.mk_unit(),
                           Some(augment_error),
                           label_unit_as_expected)
     }
@@ -1146,8 +1146,8 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
             // `expression_ty` will be unit).
             //
             // Another example is `break` with no argument expression.
-            assert!(expression_ty.is_nil());
-            assert!(expression_ty.is_nil(), "if let hack without unit type");
+            assert!(expression_ty.is_unit());
+            assert!(expression_ty.is_unit(), "if let hack without unit type");
             fcx.at(cause, fcx.param_env)
                .eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
                .map(|infer_ok| {
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index c7db3debf5a..8215ae211c0 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -94,7 +94,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             "load" => (1, vec![tcx.mk_imm_ptr(param(0))],
                        param(0)),
             "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)],
-                        tcx.mk_nil()),
+                        tcx.mk_unit()),
 
             "xchg" | "xadd" | "xsub" | "and"  | "nand" | "or" | "xor" | "max" |
             "min"  | "umax" | "umin" => {
@@ -102,7 +102,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                  param(0))
             }
             "fence" | "singlethreadfence" => {
-                (0, Vec::new(), tcx.mk_nil())
+                (0, Vec::new(), tcx.mk_unit())
             }
             op => {
                 struct_span_err!(tcx.sess, it.span, E0092,
@@ -121,7 +121,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             _ => hir::Unsafety::Unsafe,
         };
         let (n_tps, inputs, output) = match &name[..] {
-            "breakpoint" => (0, Vec::new(), tcx.mk_nil()),
+            "breakpoint" => (0, Vec::new(), tcx.mk_unit()),
             "size_of" |
             "pref_align_of" | "min_align_of" => (1, Vec::new(), tcx.types.usize),
             "size_of_val" |  "min_align_of_val" => {
@@ -141,7 +141,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     tcx.mk_mut_ptr(param(0)),
                     param(0)
                   ],
-               tcx.mk_nil())
+               tcx.mk_unit())
             }
             "prefetch_read_data" | "prefetch_write_data" |
             "prefetch_read_instruction" | "prefetch_write_instruction" => {
@@ -149,10 +149,10 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           ty: param(0),
                           mutbl: hir::MutImmutable
                          }), tcx.types.i32],
-                    tcx.mk_nil())
+                    tcx.mk_unit())
             }
             "drop_in_place" => {
-                (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_nil())
+                (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit())
             }
             "needs_drop" => (1, Vec::new(), tcx.types.bool),
 
@@ -185,7 +185,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                   }),
                   tcx.types.usize,
                ],
-               tcx.mk_nil())
+               tcx.mk_unit())
             }
             "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
               (1,
@@ -200,7 +200,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                   }),
                   tcx.types.usize,
                ],
-               tcx.mk_nil())
+               tcx.mk_unit())
             }
             "write_bytes" | "volatile_set_memory" => {
               (1,
@@ -212,7 +212,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                   tcx.types.u8,
                   tcx.types.usize,
                ],
-               tcx.mk_nil())
+               tcx.mk_unit())
             }
             "sqrtf32" => (0, vec![ tcx.types.f32 ], tcx.types.f32),
             "sqrtf64" => (0, vec![ tcx.types.f64 ], tcx.types.f64),
@@ -280,7 +280,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             "volatile_load" | "unaligned_volatile_load" =>
                 (1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)),
             "volatile_store" | "unaligned_volatile_store" =>
-                (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
+                (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_unit()),
 
             "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
             "bswap" | "bitreverse" =>
@@ -300,7 +300,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" =>
                 (1, vec![param(0), param(0)], param(0)),
 
-            "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()),
+            "assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
             "likely" => (0, vec![tcx.types.bool], tcx.types.bool),
             "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
 
@@ -313,7 +313,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
                 let fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
                     iter::once(mut_u8),
-                    tcx.mk_nil(),
+                    tcx.mk_unit(),
                     false,
                     hir::Unsafety::Normal,
                     Abi::Rust,
@@ -322,7 +322,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
 
             "nontemporal_store" => {
-                (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil())
+                (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_unit())
             }
 
             ref other => {
@@ -376,7 +376,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             (3, vec![param(0), param(1), param(2)], param(0))
         }
         "simd_scatter" => {
-            (3, vec![param(0), param(1), param(2)], tcx.mk_nil())
+            (3, vec![param(0), param(1), param(2)], tcx.mk_unit())
         }
         "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
         "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)),
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6a8860a3d9d..0305489b707 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2808,9 +2808,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         } else {
             // is the missing argument of type `()`?
             let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
-                self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
+                self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_unit()
             } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
-                self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
+                self.resolve_type_vars_if_possible(&fn_inputs[0]).is_unit()
             } else {
                 false
             };
@@ -3918,7 +3918,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 for input in inputs {
                     self.check_expr(input);
                 }
-                tcx.mk_nil()
+                tcx.mk_unit()
             }
             hir::ExprKind::Break(destination, ref expr_opt) => {
                 if let Ok(target_id) = destination.target_id {
@@ -3945,7 +3945,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     } else {
                         // Otherwise, this is a break *without* a value. That's
                         // always legal, and is equivalent to `break ()`.
-                        e_ty = tcx.mk_nil();
+                        e_ty = tcx.mk_unit();
                         cause = self.misc(expr.span);
                     }
 
@@ -3958,7 +3958,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         if let Some(ref e) = *expr_opt {
                             coerce.coerce(self, &cause, e, e_ty);
                         } else {
-                            assert!(e_ty.is_nil());
+                            assert!(e_ty.is_unit());
                             coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
                         }
                     } else {
@@ -4052,7 +4052,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 if lhs_ty.references_error() || rhs_ty.references_error() {
                     tcx.types.err
                 } else {
-                    tcx.mk_nil()
+                    tcx.mk_unit()
                 }
             }
             hir::ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => {
@@ -4081,7 +4081,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     self.diverges.set(Diverges::Maybe);
                 }
 
-                self.tcx.mk_nil()
+                self.tcx.mk_unit()
             }
             hir::ExprKind::Loop(ref body, _, source) => {
                 let coerce = match source {
@@ -4121,7 +4121,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     // [1]
                     self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
                 }
-                ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
+                ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_unit())
             }
             hir::ExprKind::Match(ref discrim, ref arms, match_src) => {
                 self.check_match(expr, &discrim, arms, expected, match_src)
@@ -4352,7 +4352,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         "yield statement outside of generator literal").emit();
                     }
                 }
-                tcx.mk_nil()
+                tcx.mk_unit()
             }
         }
     }
@@ -4516,7 +4516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             }
             hir::StmtKind::Expr(ref expr, _) => {
                 // Check with expected type of ()
-                self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
+                self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
             }
             hir::StmtKind::Semi(ref expr, _) => {
                 self.check_expr(&expr);
@@ -4529,7 +4529,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn check_block_no_value(&self, blk: &'gcx hir::Block)  {
-        let unit = self.tcx.mk_nil();
+        let unit = self.tcx.mk_unit();
         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
 
         // if the block produces a `!` value, that can always be
@@ -4752,7 +4752,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                  expression: &'gcx hir::Expr,
                                  expected: Ty<'tcx>,
                                  cause_span: Span) {
-        if expected.is_nil() {
+        if expected.is_unit() {
             // `BlockTailExpression` only relevant if the tail expr would be
             // useful on its own.
             match expression.node {
@@ -4795,7 +4795,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                    can_suggest: bool) {
         // Only suggest changing the return type for methods that
         // haven't set a return type at all (and aren't `fn main()` or an impl).
-        match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_nil()) {
+        match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
             (&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
                 err.span_suggestion_with_applicability(
                     span,
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index edfa62f1095..5004880ce47 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -35,7 +35,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let ty = if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var()
                     && is_builtin_binop(lhs_ty, rhs_ty, op) {
             self.enforce_builtin_binop_types(lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
-            self.tcx.mk_nil()
+            self.tcx.mk_unit()
         } else {
             return_ty
         };
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index aaa42f8d412..c9aa0339dd4 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -224,7 +224,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 actual.output().skip_binder()
             } else {
                 // standard () main return type
-                tcx.mk_nil()
+                tcx.mk_unit()
             };
 
             let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 35ef6327de5..9439dc78d3c 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -490,7 +490,7 @@ macro_rules! emit_enquoted_if_mapkey {
 impl<'a> ::Encoder for Encoder<'a> {
     type Error = EncoderError;
 
-    fn emit_nil(&mut self) -> EncodeResult {
+    fn emit_unit(&mut self) -> EncodeResult {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         write!(self.writer, "null")?;
         Ok(())
@@ -648,7 +648,7 @@ impl<'a> ::Encoder for Encoder<'a> {
     }
     fn emit_option_none(&mut self) -> EncodeResult {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
-        self.emit_nil()
+        self.emit_unit()
     }
     fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
@@ -740,7 +740,7 @@ impl<'a> PrettyEncoder<'a> {
 impl<'a> ::Encoder for PrettyEncoder<'a> {
     type Error = EncoderError;
 
-    fn emit_nil(&mut self) -> EncodeResult {
+    fn emit_unit(&mut self) -> EncodeResult {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         write!(self.writer, "null")?;
         Ok(())
@@ -923,7 +923,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     }
     fn emit_option_none(&mut self) -> EncodeResult {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
-        self.emit_nil()
+        self.emit_unit()
     }
     fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
@@ -1016,7 +1016,7 @@ impl Encodable for Json {
             Json::Boolean(v) => v.encode(e),
             Json::Array(ref v) => v.encode(e),
             Json::Object(ref v) => v.encode(e),
-            Json::Null => e.emit_nil(),
+            Json::Null => e.emit_unit(),
         }
     }
 }
diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs
index c71f4748911..4ce80bc36a0 100644
--- a/src/libserialize/opaque.rs
+++ b/src/libserialize/opaque.rs
@@ -55,7 +55,7 @@ impl serialize::Encoder for Encoder {
     type Error = !;
 
     #[inline]
-    fn emit_nil(&mut self) -> EncodeResult {
+    fn emit_unit(&mut self) -> EncodeResult {
         Ok(())
     }
 
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 416be50bfe9..f0b49c3d9bc 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -25,7 +25,7 @@ pub trait Encoder {
     type Error;
 
     // Primitive types:
-    fn emit_nil(&mut self) -> Result<(), Self::Error>;
+    fn emit_unit(&mut self) -> Result<(), Self::Error>;
     fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error>;
     fn emit_u128(&mut self, v: u128) -> Result<(), Self::Error>;
     fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
@@ -537,7 +537,7 @@ impl Decodable for char {
 
 impl Encodable for () {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_nil()
+        s.emit_unit()
     }
 }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 804d43f4fc6..ef5dae724b2 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -3532,12 +3532,11 @@ mod test_map {
             m.insert(x, ());
         }
 
-        for i in 0..1000 {
+        for _ in 0..1000 {
             let x = rng.gen_range(-10, 10);
             match m.entry(x) {
                 Vacant(_) => {}
                 Occupied(e) => {
-                    println!("{}: remove {}", i, x);
                     e.remove();
                 }
             }
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 8ae5e20dac5..237af2f04e5 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -420,14 +420,14 @@ impl PartialEq<OsString> for str {
     }
 }
 
-#[stable(feature = "os_str_str_ref_eq", since = "1.28.0")]
+#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
 impl<'a> PartialEq<&'a str> for OsString {
     fn eq(&self, other: &&'a str) -> bool {
         **self == **other
     }
 }
 
-#[stable(feature = "os_str_str_ref_eq", since = "1.28.0")]
+#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
 impl<'a> PartialEq<OsString> for &'a str {
     fn eq(&self, other: &OsString) -> bool {
         **other == **self
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 7074928eaf6..4c1fdc4f895 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -250,6 +250,7 @@ mod prim_bool { }
 /// [`Default`]: default/trait.Default.html
 /// [`default()`]: default/trait.Default.html#tymethod.default
 ///
+#[unstable(feature = "never_type", issue = "35121")]
 mod prim_never { }
 
 #[doc(primitive = "char")]
diff --git a/src/test/ui/invalid/invalid-crate-type.rs b/src/test/ui/invalid/invalid-crate-type.rs
index 4b6b6c2fe76..e7f4e32dc7c 100644
--- a/src/test/ui/invalid/invalid-crate-type.rs
+++ b/src/test/ui/invalid/invalid-crate-type.rs
@@ -11,6 +11,48 @@
 // regression test for issue 11256
 #![crate_type="foo"]    //~ ERROR invalid `crate_type` value
 
+// Tests for suggestions (#53958)
+
+#![crate_type="statoclib"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION staticlib
+
+#![crate_type="procmacro"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION proc-macro
+
+#![crate_type="static-lib"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION staticlib
+
+#![crate_type="drylib"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION dylib
+
+#![crate_type="dlib"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION rlib
+
+#![crate_type="lob"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION lib
+
+#![crate_type="bon"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION bin
+
+#![crate_type="cdalib"]
+//~^ ERROR invalid `crate_type` value
+//~| HELP did you mean
+//~| SUGGESTION cdylib
+
 fn main() {
     return
 }
diff --git a/src/test/ui/invalid/invalid-crate-type.stderr b/src/test/ui/invalid/invalid-crate-type.stderr
index 6dc8a0f2bbb..c82da865f33 100644
--- a/src/test/ui/invalid/invalid-crate-type.stderr
+++ b/src/test/ui/invalid/invalid-crate-type.stderr
@@ -1,10 +1,58 @@
 error: invalid `crate_type` value
-  --> $DIR/invalid-crate-type.rs:12:1
+  --> $DIR/invalid-crate-type.rs:12:15
    |
 LL | #![crate_type="foo"]    //~ ERROR invalid `crate_type` value
-   | ^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^
    |
    = note: #[deny(unknown_crate_types)] on by default
 
-error: aborting due to previous error
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:16:15
+   |
+LL | #![crate_type="statoclib"]
+   |               ^^^^^^^^^^^ help: did you mean: `"staticlib"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:21:15
+   |
+LL | #![crate_type="procmacro"]
+   |               ^^^^^^^^^^^ help: did you mean: `"proc-macro"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:26:15
+   |
+LL | #![crate_type="static-lib"]
+   |               ^^^^^^^^^^^^ help: did you mean: `"staticlib"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:31:15
+   |
+LL | #![crate_type="drylib"]
+   |               ^^^^^^^^ help: did you mean: `"dylib"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:36:15
+   |
+LL | #![crate_type="dlib"]
+   |               ^^^^^^ help: did you mean: `"rlib"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:41:15
+   |
+LL | #![crate_type="lob"]
+   |               ^^^^^ help: did you mean: `"lib"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:46:15
+   |
+LL | #![crate_type="bon"]
+   |               ^^^^^ help: did you mean: `"bin"`
+
+error: invalid `crate_type` value
+  --> $DIR/invalid-crate-type.rs:51:15
+   |
+LL | #![crate_type="cdalib"]
+   |               ^^^^^^^^ help: did you mean: `"cdylib"`
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject b917e35248fe57d11765c5a835de33e335babb7
+Subproject a5d82949485802abb45f888d5b8b7f23927f031