about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-21 21:14:53 +0000
committerbors <bors@rust-lang.org>2018-04-21 21:14:53 +0000
commitaa7ce896f2c41550f7f6cf3dadb21bacc69cc912 (patch)
tree421b5b857e218551788d71342af7e7d7abb7cde0
parent699eb95ae3dae023cddca85facf6660b196bd0d1 (diff)
parent42b6d4653a2ad22be695760aba3514fc64c18d66 (diff)
downloadrust-aa7ce896f2c41550f7f6cf3dadb21bacc69cc912.tar.gz
rust-aa7ce896f2c41550f7f6cf3dadb21bacc69cc912.zip
Auto merge of #50121 - pnkfelix:revert-stabilization-of-never-type-et-al, r=alexcrichton
Revert stabilization of never_type (!) et al

Fix #49691

I *think* this correctly adopts @nikomatsakis 's desired fix of:
 * reverting stabilization of `!` and `TryFrom`, and
 * returning to the previous fallback semantics (i.e. it is once again dependent on whether the crate has opted into `#[feature(never_type)]`,
 * **without** attempting to put back in the previous future-proofing warnings regarding the change in fallback semantics.

(I'll be away from computers for a week starting now, so any updates to this PR should be either pushed into it, or someone else should adopt the task of polishing this fix and put up their own PR.)
-rw-r--r--src/libcore/array.rs6
-rw-r--r--src/libcore/char/convert.rs6
-rw-r--r--src/libcore/char/mod.rs2
-rw-r--r--src/libcore/clone.rs2
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/convert.rs12
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/num/mod.rs12
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc_apfloat/lib.rs1
-rw-r--r--src/librustc_mir/build/matches/simplify.rs1
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_typeck/check/mod.rs5
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/libstd/error.rs8
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/libsyntax/feature_gate.rs7
-rw-r--r--src/test/compile-fail/call-fn-never-arg-wrong-type.rs2
-rw-r--r--src/test/compile-fail/coerce-to-bang-cast.rs2
-rw-r--r--src/test/compile-fail/coerce-to-bang.rs2
-rw-r--r--src/test/compile-fail/defaulted-never-note.rs4
-rw-r--r--src/test/compile-fail/inhabitedness-infinite-loop.rs1
-rw-r--r--src/test/compile-fail/loop-break-value.rs2
-rw-r--r--src/test/compile-fail/match-privately-empty.rs1
-rw-r--r--src/test/compile-fail/never-assign-dead-code.rs1
-rw-r--r--src/test/compile-fail/never-assign-wrong-type.rs1
-rw-r--r--src/test/compile-fail/uninhabited-irrefutable.rs1
-rw-r--r--src/test/compile-fail/uninhabited-patterns.rs1
-rw-r--r--src/test/compile-fail/unreachable-loop-patterns.rs1
-rw-r--r--src/test/compile-fail/unreachable-try-pattern.rs1
-rw-r--r--src/test/run-fail/adjust_never.rs3
-rw-r--r--src/test/run-fail/call-fn-never-arg.rs1
-rw-r--r--src/test/run-fail/cast-never.rs3
-rw-r--r--src/test/run-fail/never-associated-type.rs2
-rw-r--r--src/test/run-fail/never-type-arg.rs2
-rw-r--r--src/test/run-pass/diverging-fallback-control-flow.rs2
-rw-r--r--src/test/run-pass/empty-types-in-patterns.rs1
-rw-r--r--src/test/run-pass/impl-for-never.rs2
-rw-r--r--src/test/run-pass/issue-44402.rs1
-rw-r--r--src/test/run-pass/loop-break-value.rs2
-rw-r--r--src/test/run-pass/mir_calls_to_shims.rs1
-rw-r--r--src/test/run-pass/never-result.rs2
-rw-r--r--src/test/run-pass/type-sizes.rs1
-rw-r--r--src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs2
-rw-r--r--src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr4
-rw-r--r--src/test/ui/e0119/conflict-with-std.rs2
-rw-r--r--src/test/ui/e0119/conflict-with-std.stderr6
-rw-r--r--src/test/ui/feature-gate-exhaustive-patterns.rs2
-rw-r--r--src/test/ui/feature-gate-never_type.rs27
-rw-r--r--src/test/ui/feature-gate-never_type.stderr43
-rw-r--r--src/test/ui/print_type_sizes/uninhabited.rs1
-rw-r--r--src/test/ui/reachable/expr_add.rs2
-rw-r--r--src/test/ui/reachable/expr_assign.rs2
-rw-r--r--src/test/ui/reachable/expr_call.rs2
-rw-r--r--src/test/ui/reachable/expr_cast.rs2
-rw-r--r--src/test/ui/reachable/expr_method.rs2
-rw-r--r--src/test/ui/reachable/expr_type.rs2
-rw-r--r--src/test/ui/reachable/expr_unary.rs2
63 files changed, 188 insertions, 49 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 87144c27c9e..3d24f8902bd 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -59,7 +59,7 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
 }
 
 /// The error type returned when a conversion from a slice to an array fails.
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromSliceError(());
 
@@ -148,7 +148,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[stable(feature = "try_from", since = "1.26.0")]
+            #[unstable(feature = "try_from", issue = "33417")]
             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
                 type Error = TryFromSliceError;
 
@@ -162,7 +162,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[stable(feature = "try_from", since = "1.26.0")]
+            #[unstable(feature = "try_from", issue = "33417")]
             impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
                 type Error = TryFromSliceError;
 
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index 150562a4a9b..803a924eb3a 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -204,7 +204,7 @@ impl FromStr for char {
 }
 
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl TryFrom<u32> for char {
     type Error = CharTryFromError;
 
@@ -219,11 +219,11 @@ impl TryFrom<u32> for char {
 }
 
 /// The error type returned when a conversion from u32 to char fails.
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct CharTryFromError(());
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl fmt::Display for CharTryFromError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         "converted integer out of range for `char`".fmt(f)
diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs
index 9edc0c88756..210eceebc51 100644
--- a/src/libcore/char/mod.rs
+++ b/src/libcore/char/mod.rs
@@ -40,7 +40,7 @@ pub use self::convert::{from_u32, from_digit};
 pub use self::convert::from_u32_unchecked;
 #[stable(feature = "char_from_str", since = "1.20.0")]
 pub use self::convert::ParseCharError;
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 pub use self::convert::CharTryFromError;
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 58a8439162c..f79f7351698 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -179,7 +179,7 @@ mod impls {
         bool char
     }
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl Clone for ! {
         #[inline]
         fn clone(&self) -> Self {
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 3ae9b05b865..c91aa06609d 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -881,24 +881,24 @@ mod impls {
 
     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl PartialEq for ! {
         fn eq(&self, _: &!) -> bool {
             *self
         }
     }
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl Eq for ! {}
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl PartialOrd for ! {
         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
             *self
         }
     }
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl Ord for ! {
         fn cmp(&self, _: &!) -> Ordering {
             *self
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 63721395784..7324df95bc5 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -322,26 +322,22 @@ pub trait From<T>: Sized {
 ///
 /// [`TryFrom`]: trait.TryFrom.html
 /// [`Into`]: trait.Into.html
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
-    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
-    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_into(self) -> Result<T, Self::Error>;
 }
 
 /// Attempt to construct `Self` via a conversion.
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
-    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
-    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_from(value: T) -> Result<Self, Self::Error>;
 }
 
@@ -409,7 +405,7 @@ impl<T> From<T> for T {
 
 
 // TryFrom implies TryInto
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl<T, U> TryInto<U> for T where U: TryFrom<T>
 {
     type Error = U::Error;
@@ -421,7 +417,7 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
 
 // Infallible conversions are semantically equivalent to fallible conversions
 // with an uninhabited error type.
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl<T, U> TryFrom<U> for T where T: From<U> {
     type Error = !;
 
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 277bef2bf66..a8430f14410 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1780,14 +1780,14 @@ macro_rules! fmt_refs {
 
 fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
 
-#[stable(feature = "never_type", since = "1.26.0")]
+#[unstable(feature = "never_type", issue = "35121")]
 impl Debug for ! {
     fn fmt(&self, _: &mut Formatter) -> Result {
         *self
     }
 }
 
-#[stable(feature = "never_type", since = "1.26.0")]
+#[unstable(feature = "never_type", issue = "35121")]
 impl Display for ! {
     fn fmt(&self, _: &mut Formatter) -> Result {
         *self
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ea7a46f44ae..ac1a8091eb3 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -82,6 +82,7 @@
 #![feature(iterator_repeat_with)]
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![feature(macro_at_most_once_rep)]
 #![feature(no_core)]
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 885aabe0806..feb689dbc1f 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -630,7 +630,7 @@ mod copy_impls {
         bool char
     }
 
-    #[stable(feature = "never_type", since = "1.26.0")]
+    #[unstable(feature = "never_type", issue = "35121")]
     impl Copy for ! {}
 
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index f2e8caaad14..801e2328a4b 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -4192,7 +4192,7 @@ macro_rules! from_str_radix_int_impl {
 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
 
 /// The error type returned when a checked integral type conversion fails.
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromIntError(());
 
@@ -4207,14 +4207,14 @@ impl TryFromIntError {
     }
 }
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl fmt::Display for TryFromIntError {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         self.__description().fmt(fmt)
     }
 }
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl From<!> for TryFromIntError {
     fn from(never: !) -> TryFromIntError {
         never
@@ -4224,7 +4224,7 @@ impl From<!> for TryFromIntError {
 // only negative bounds
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[stable(feature = "try_from", since = "1.26.0")]
+        #[unstable(feature = "try_from", issue = "33417")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -4243,7 +4243,7 @@ macro_rules! try_from_lower_bounded {
 // unsigned to signed (only positive bound)
 macro_rules! try_from_upper_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[stable(feature = "try_from", since = "1.26.0")]
+        #[unstable(feature = "try_from", issue = "33417")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -4262,7 +4262,7 @@ macro_rules! try_from_upper_bounded {
 // all other cases
 macro_rules! try_from_both_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[stable(feature = "try_from", since = "1.26.0")]
+        #[unstable(feature = "try_from", issue = "33417")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index bb875c7219a..3b080689cb3 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -36,6 +36,7 @@
 #![feature(str_internals)]
 #![feature(test)]
 #![feature(trusted_len)]
+#![feature(try_from)]
 #![feature(try_trait)]
 #![feature(exact_chunks)]
 #![cfg_attr(stage0, feature(atomic_nand))]
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index a2cefe488c6..bb495049483 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -52,6 +52,7 @@
 #![cfg_attr(windows, feature(libc))]
 #![feature(macro_lifetime_matcher)]
 #![feature(macro_vis_matcher)]
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![feature(non_exhaustive)]
 #![feature(nonzero)]
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 28ad5edbd2d..f3a2aa51946 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2374,6 +2374,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.intern_tup(&[])
     }
 
+    pub fn mk_diverging_default(self) -> Ty<'tcx> {
+        if self.features().never_type {
+            self.types.never
+        } else {
+            self.intern_tup(&[])
+        }
+    }
+
     pub fn mk_bool(self) -> Ty<'tcx> {
         self.mk_ty(TyBool)
     }
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index 0f051ea5981..08438805a70 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -45,6 +45,7 @@
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![forbid(unsafe_code)]
 
+#![feature(try_from)]
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
 #[allow(unused_extern_crates)]
 extern crate rustc_cratesio_shim;
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index 4e95ee6444d..147b8cc2175 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -113,6 +113,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
                 let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| {
                     i == variant_index || {
+                        self.hir.tcx().features().never_type &&
                         self.hir.tcx().features().exhaustive_patterns &&
                         self.hir.tcx().is_variant_uninhabited_from_all_modules(v, substs)
                     }
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index de3063a5756..a47b3cacc51 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -33,6 +33,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(nonzero)]
 #![feature(inclusive_range_fields)]
 #![feature(crate_visibility_modifier)]
+#![feature(never_type)]
 #![cfg_attr(stage0, feature(try_trait))]
 
 extern crate arena;
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index ca35153d571..acde10a6396 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2217,7 +2217,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     }
 
     // Tries to apply a fallback to `ty` if it is an unsolved variable.
-    // Non-numerics get replaced with !, unconstrained ints with i32,
+    // Non-numerics get replaced with ! or () (depending on whether
+    // feature(never_type) is enabled, unconstrained ints with i32,
     // unconstrained floats with f64.
     // Fallback becomes very dubious if we have encountered type-checking errors.
     // In that case, fallback to TyError.
@@ -2231,7 +2232,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             _ if self.is_tainted_by_errors() => self.tcx().types.err,
             UnconstrainedInt => self.tcx.types.i32,
             UnconstrainedFloat => self.tcx.types.f64,
-            Neither if self.type_var_diverges(ty) => self.tcx.types.never,
+            Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
             Neither => return false,
         };
         debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 4b66939963e..ed0cfe38a7a 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -82,6 +82,7 @@ This API is completely unstable and subject to change.
 #![feature(slice_patterns)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(dyn_trait)]
+#![feature(never_type)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 3c209928d43..749b8ccc13d 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -233,7 +233,7 @@ impl<'a> From<Cow<'a, str>> for Box<Error> {
     }
 }
 
-#[stable(feature = "never_type", since = "1.26.0")]
+#[unstable(feature = "never_type", issue = "35121")]
 impl Error for ! {
     fn description(&self) -> &str { *self }
 }
@@ -284,14 +284,14 @@ impl Error for num::ParseIntError {
     }
 }
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl Error for num::TryFromIntError {
     fn description(&self) -> &str {
         self.__description()
     }
 }
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl Error for array::TryFromSliceError {
     fn description(&self) -> &str {
         self.__description()
@@ -365,7 +365,7 @@ impl Error for cell::BorrowMutError {
     }
 }
 
-#[stable(feature = "try_from", since = "1.26.0")]
+#[unstable(feature = "try_from", issue = "33417")]
 impl Error for char::CharTryFromError {
     fn description(&self) -> &str {
         "converted integer out of range for `char`"
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 7d896695311..e53e009678c 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -275,6 +275,7 @@
 #![feature(macro_reexport)]
 #![feature(macro_vis_matcher)]
 #![feature(needs_panic_runtime)]
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![feature(nonzero)]
 #![feature(num_bits_bytes)]
@@ -306,6 +307,7 @@
 #![feature(test, rustc_private)]
 #![feature(thread_local)]
 #![feature(toowned_clone_into)]
+#![feature(try_from)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(untagged_unions)]
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index ce4bbfffc2e..42bac605511 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -79,6 +79,7 @@ mod prim_bool { }
 /// write:
 ///
 /// ```
+/// #![feature(never_type)]
 /// # fn foo() -> u32 {
 /// let x: ! = {
 ///     return 123
@@ -155,6 +156,7 @@ mod prim_bool { }
 /// for example:
 ///
 /// ```
+/// #![feature(never_type)]
 /// # use std::fmt;
 /// # trait Debug {
 /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 6426c9a92f2..fe2466ff005 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -272,6 +272,9 @@ declare_features! (
     // Allows cfg(target_has_atomic = "...").
     (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
 
+    // The `!` type. Does not imply exhaustive_patterns (below) any more.
+    (active, never_type, "1.13.0", Some(35121), None),
+
     // Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", None, None),
 
@@ -1644,6 +1647,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
                 self.check_abi(bare_fn_ty.abi, ty.span);
             }
+            ast::TyKind::Never => {
+                gate_feature_post!(&self, never_type, ty.span,
+                                   "The `!` type is experimental");
+            }
             ast::TyKind::TraitObject(_, ast::TraitObjectSyntax::Dyn) => {
                 gate_feature_post!(&self, dyn_trait, ty.span,
                                    "`dyn Trait` syntax is unstable");
diff --git a/src/test/compile-fail/call-fn-never-arg-wrong-type.rs b/src/test/compile-fail/call-fn-never-arg-wrong-type.rs
index c2f157cd35c..583befed1e8 100644
--- a/src/test/compile-fail/call-fn-never-arg-wrong-type.rs
+++ b/src/test/compile-fail/call-fn-never-arg-wrong-type.rs
@@ -10,6 +10,8 @@
 
 // Test that we can't pass other types for !
 
+#![feature(never_type)]
+
 fn foo(x: !) -> ! {
     x
 }
diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs
index 5efb4dadc64..14a06b306d8 100644
--- a/src/test/compile-fail/coerce-to-bang-cast.rs
+++ b/src/test/compile-fail/coerce-to-bang-cast.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
+
 fn foo(x: usize, y: !, z: usize) { }
 
 fn cast_a() {
diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs
index 15049232a4d..62ff09f4616 100644
--- a/src/test/compile-fail/coerce-to-bang.rs
+++ b/src/test/compile-fail/coerce-to-bang.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
+
 fn foo(x: usize, y: !, z: usize) { }
 
 fn call_foo_a() {
diff --git a/src/test/compile-fail/defaulted-never-note.rs b/src/test/compile-fail/defaulted-never-note.rs
index 798544f1649..ac8ac85824e 100644
--- a/src/test/compile-fail/defaulted-never-note.rs
+++ b/src/test/compile-fail/defaulted-never-note.rs
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// We need to opt inot the `!` feature in order to trigger the
+// requirement that this is testing.
+#![feature(never_type)]
+
 #![allow(unused)]
 
 trait Deserialize: Sized {
diff --git a/src/test/compile-fail/inhabitedness-infinite-loop.rs b/src/test/compile-fail/inhabitedness-infinite-loop.rs
index b9741e0add6..d11aacec196 100644
--- a/src/test/compile-fail/inhabitedness-infinite-loop.rs
+++ b/src/test/compile-fail/inhabitedness-infinite-loop.rs
@@ -10,6 +10,7 @@
 
 // error-pattern:reached recursion limit
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
 struct Foo<'a, T: 'a> {
diff --git a/src/test/compile-fail/loop-break-value.rs b/src/test/compile-fail/loop-break-value.rs
index 5ef46bb27fd..938f7fba2a0 100644
--- a/src/test/compile-fail/loop-break-value.rs
+++ b/src/test/compile-fail/loop-break-value.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
+
 fn main() {
     let val: ! = loop { break break; };
     //~^ ERROR mismatched types
diff --git a/src/test/compile-fail/match-privately-empty.rs b/src/test/compile-fail/match-privately-empty.rs
index e18c7d77ce3..8777ef2ffe3 100644
--- a/src/test/compile-fail/match-privately-empty.rs
+++ b/src/test/compile-fail/match-privately-empty.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
 mod private {
diff --git a/src/test/compile-fail/never-assign-dead-code.rs b/src/test/compile-fail/never-assign-dead-code.rs
index 4e987d1ddce..0fb75b535c6 100644
--- a/src/test/compile-fail/never-assign-dead-code.rs
+++ b/src/test/compile-fail/never-assign-dead-code.rs
@@ -10,6 +10,7 @@
 
 // Test that an assignment of type ! makes the rest of the block dead code.
 
+#![feature(never_type)]
 #![feature(rustc_attrs)]
 #![warn(unused)]
 
diff --git a/src/test/compile-fail/never-assign-wrong-type.rs b/src/test/compile-fail/never-assign-wrong-type.rs
index 8c2de7d68d3..c0dd2cab749 100644
--- a/src/test/compile-fail/never-assign-wrong-type.rs
+++ b/src/test/compile-fail/never-assign-wrong-type.rs
@@ -10,6 +10,7 @@
 
 // Test that we can't use another type in place of !
 
+#![feature(never_type)]
 #![deny(warnings)]
 
 fn main() {
diff --git a/src/test/compile-fail/uninhabited-irrefutable.rs b/src/test/compile-fail/uninhabited-irrefutable.rs
index 72b0afa6bd3..05a97b855e7 100644
--- a/src/test/compile-fail/uninhabited-irrefutable.rs
+++ b/src/test/compile-fail/uninhabited-irrefutable.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
 mod foo {
diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs
index e130df5c845..2cf4b78bdff 100644
--- a/src/test/compile-fail/uninhabited-patterns.rs
+++ b/src/test/compile-fail/uninhabited-patterns.rs
@@ -10,6 +10,7 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![feature(slice_patterns)]
 #![deny(unreachable_patterns)]
diff --git a/src/test/compile-fail/unreachable-loop-patterns.rs b/src/test/compile-fail/unreachable-loop-patterns.rs
index dca79bdfb87..cfd829e416e 100644
--- a/src/test/compile-fail/unreachable-loop-patterns.rs
+++ b/src/test/compile-fail/unreachable-loop-patterns.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 
diff --git a/src/test/compile-fail/unreachable-try-pattern.rs b/src/test/compile-fail/unreachable-try-pattern.rs
index 0caf7d51234..df340095bb4 100644
--- a/src/test/compile-fail/unreachable-try-pattern.rs
+++ b/src/test/compile-fail/unreachable-try-pattern.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns, rustc_attrs)]
 #![warn(unreachable_code)]
 #![warn(unreachable_patterns)]
diff --git a/src/test/run-fail/adjust_never.rs b/src/test/run-fail/adjust_never.rs
index 7a4b5e59eeb..da68dc39f85 100644
--- a/src/test/run-fail/adjust_never.rs
+++ b/src/test/run-fail/adjust_never.rs
@@ -11,6 +11,9 @@
 // Test that a variable of type ! can coerce to another type.
 
 // error-pattern:explicit
+
+#![feature(never_type)]
+
 fn main() {
     let x: ! = panic!();
     let y: u32 = x;
diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs
index 56454586bb9..95101e70db9 100644
--- a/src/test/run-fail/call-fn-never-arg.rs
+++ b/src/test/run-fail/call-fn-never-arg.rs
@@ -12,6 +12,7 @@
 
 // error-pattern:wowzers!
 
+#![feature(never_type)]
 #![allow(unreachable_code)]
 
 fn foo(x: !) -> ! {
diff --git a/src/test/run-fail/cast-never.rs b/src/test/run-fail/cast-never.rs
index 0155332c51d..8f7b0c40538 100644
--- a/src/test/run-fail/cast-never.rs
+++ b/src/test/run-fail/cast-never.rs
@@ -11,6 +11,9 @@
 // Test that we can explicitly cast ! to another type
 
 // error-pattern:explicit
+
+#![feature(never_type)]
+
 fn main() {
     let x: ! = panic!();
     let y: u32 = x as u32;
diff --git a/src/test/run-fail/never-associated-type.rs b/src/test/run-fail/never-associated-type.rs
index d9b8461a1d0..fdd21e08c20 100644
--- a/src/test/run-fail/never-associated-type.rs
+++ b/src/test/run-fail/never-associated-type.rs
@@ -12,6 +12,8 @@
 
 // error-pattern:kapow!
 
+#![feature(never_type)]
+
 trait Foo {
     type Wow;
 
diff --git a/src/test/run-fail/never-type-arg.rs b/src/test/run-fail/never-type-arg.rs
index 0fe10d43910..826ca3a08c0 100644
--- a/src/test/run-fail/never-type-arg.rs
+++ b/src/test/run-fail/never-type-arg.rs
@@ -12,6 +12,8 @@
 
 // error-pattern:oh no!
 
+#![feature(never_type)]
+
 struct Wub;
 
 impl PartialEq<!> for Wub {
diff --git a/src/test/run-pass/diverging-fallback-control-flow.rs b/src/test/run-pass/diverging-fallback-control-flow.rs
index a96f98b9efd..723a98bcdfa 100644
--- a/src/test/run-pass/diverging-fallback-control-flow.rs
+++ b/src/test/run-pass/diverging-fallback-control-flow.rs
@@ -14,6 +14,8 @@
 // These represent current behavior, but are pretty dubious.  I would
 // like to revisit these and potentially change them. --nmatsakis
 
+#![feature(never_type)]
+
 trait BadDefault {
     fn default() -> Self;
 }
diff --git a/src/test/run-pass/empty-types-in-patterns.rs b/src/test/run-pass/empty-types-in-patterns.rs
index 87db4401929..86cf9b5ec47 100644
--- a/src/test/run-pass/empty-types-in-patterns.rs
+++ b/src/test/run-pass/empty-types-in-patterns.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 #![feature(slice_patterns)]
 #![allow(unreachable_patterns)]
diff --git a/src/test/run-pass/impl-for-never.rs b/src/test/run-pass/impl-for-never.rs
index cf54e1c3bd5..794f5969bff 100644
--- a/src/test/run-pass/impl-for-never.rs
+++ b/src/test/run-pass/impl-for-never.rs
@@ -10,6 +10,8 @@
 
 // Test that we can call static methods on ! both directly and when it appears in a generic
 
+#![feature(never_type)]
+
 trait StringifyType {
     fn stringify_type() -> &'static str;
 }
diff --git a/src/test/run-pass/issue-44402.rs b/src/test/run-pass/issue-44402.rs
index a5a0a5a5794..5cbd3446d9b 100644
--- a/src/test/run-pass/issue-44402.rs
+++ b/src/test/run-pass/issue-44402.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
 // Regression test for inhabitedness check. The old
diff --git a/src/test/run-pass/loop-break-value.rs b/src/test/run-pass/loop-break-value.rs
index ffdd99ebf6e..39053769b24 100644
--- a/src/test/run-pass/loop-break-value.rs
+++ b/src/test/run-pass/loop-break-value.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
+
 #[allow(unused)]
 fn never_returns() {
     loop {
diff --git a/src/test/run-pass/mir_calls_to_shims.rs b/src/test/run-pass/mir_calls_to_shims.rs
index dda7a46f325..9641ed28293 100644
--- a/src/test/run-pass/mir_calls_to_shims.rs
+++ b/src/test/run-pass/mir_calls_to_shims.rs
@@ -11,6 +11,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(fn_traits)]
+#![feature(never_type)]
 
 use std::panic;
 
diff --git a/src/test/run-pass/never-result.rs b/src/test/run-pass/never-result.rs
index 8aa2a13ed8c..5c0af392f44 100644
--- a/src/test/run-pass/never-result.rs
+++ b/src/test/run-pass/never-result.rs
@@ -10,6 +10,8 @@
 
 // Test that we can extract a ! through pattern matching then use it as several different types.
 
+#![feature(never_type)]
+
 fn main() {
     let x: Result<u32, !> = Ok(123);
     match x {
diff --git a/src/test/run-pass/type-sizes.rs b/src/test/run-pass/type-sizes.rs
index 0bb18d8729a..7bd9a1703ee 100644
--- a/src/test/run-pass/type-sizes.rs
+++ b/src/test/run-pass/type-sizes.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(never_type)]
 
 use std::mem::size_of;
 
diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs
index 052575de4c2..75b60aa8d10 100644
--- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs
@@ -31,5 +31,5 @@ trait Add<RHS=Self> {
 fn ice<A>(a: A) {
     let r = loop {};
     r = r + a;
-    //~^ ERROR the trait bound `!: Add<A>` is not satisfied
+    //~^ ERROR the trait bound `(): Add<A>` is not satisfied
 }
diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr
index c22a645385a..7924ab74444 100644
--- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr
+++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `!: Add<A>` is not satisfied
+error[E0277]: the trait bound `(): Add<A>` is not satisfied
   --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11
    |
 LL |     r = r + a;
-   |           ^ the trait `Add<A>` is not implemented for `!`
+   |           ^ the trait `Add<A>` is not implemented for `()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs
index a9f747d09ec..ed9033ad53d 100644
--- a/src/test/ui/e0119/conflict-with-std.rs
+++ b/src/test/ui/e0119/conflict-with-std.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(try_from)]
+
 use std::marker::PhantomData;
 use std::convert::{TryFrom, AsRef};
 
diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr
index 417ff1de3f8..e8b2c84c0df 100644
--- a/src/test/ui/e0119/conflict-with-std.stderr
+++ b/src/test/ui/e0119/conflict-with-std.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`:
-  --> $DIR/conflict-with-std.rs:15:1
+  --> $DIR/conflict-with-std.rs:17:1
    |
 LL | impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
              where T: ?Sized;
 
 error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`:
-  --> $DIR/conflict-with-std.rs:22:1
+  --> $DIR/conflict-with-std.rs:24:1
    |
 LL | impl From<S> for S { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | impl From<S> for S { //~ ERROR conflicting implementations
            - impl<T> std::convert::From<T> for T;
 
 error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`:
-  --> $DIR/conflict-with-std.rs:29:1
+  --> $DIR/conflict-with-std.rs:31:1
    |
 LL | impl TryFrom<X> for X { //~ ERROR conflicting implementations
    | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gate-exhaustive-patterns.rs
index 477dd1b38eb..c83d9b56bc3 100644
--- a/src/test/ui/feature-gate-exhaustive-patterns.rs
+++ b/src/test/ui/feature-gate-exhaustive-patterns.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 fn foo() -> Result<u32, !> {
     Ok(123)
 }
diff --git a/src/test/ui/feature-gate-never_type.rs b/src/test/ui/feature-gate-never_type.rs
new file mode 100644
index 00000000000..ebbe17a821f
--- /dev/null
+++ b/src/test/ui/feature-gate-never_type.rs
@@ -0,0 +1,27 @@
+// Copyright 2012 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.
+
+// Test that ! errors when used in illegal positions with feature(never_type) disabled
+
+trait Foo {
+    type Wub;
+}
+
+type Ma = (u32, !, i32); //~ ERROR type is experimental
+type Meeshka = Vec<!>; //~ ERROR type is experimental
+type Mow = &fn(!) -> !; //~ ERROR type is experimental
+type Skwoz = &mut !; //~ ERROR type is experimental
+
+impl Foo for Meeshka {
+    type Wub = !; //~ ERROR type is experimental
+}
+
+fn main() {
+}
diff --git a/src/test/ui/feature-gate-never_type.stderr b/src/test/ui/feature-gate-never_type.stderr
new file mode 100644
index 00000000000..187be6d8291
--- /dev/null
+++ b/src/test/ui/feature-gate-never_type.stderr
@@ -0,0 +1,43 @@
+error[E0658]: The `!` type is experimental (see issue #35121)
+  --> $DIR/feature-gate-never_type.rs:17:17
+   |
+LL | type Ma = (u32, !, i32); //~ ERROR type is experimental
+   |                 ^
+   |
+   = help: add #![feature(never_type)] to the crate attributes to enable
+
+error[E0658]: The `!` type is experimental (see issue #35121)
+  --> $DIR/feature-gate-never_type.rs:18:20
+   |
+LL | type Meeshka = Vec<!>; //~ ERROR type is experimental
+   |                    ^
+   |
+   = help: add #![feature(never_type)] to the crate attributes to enable
+
+error[E0658]: The `!` type is experimental (see issue #35121)
+  --> $DIR/feature-gate-never_type.rs:19:16
+   |
+LL | type Mow = &fn(!) -> !; //~ ERROR type is experimental
+   |                ^
+   |
+   = help: add #![feature(never_type)] to the crate attributes to enable
+
+error[E0658]: The `!` type is experimental (see issue #35121)
+  --> $DIR/feature-gate-never_type.rs:20:19
+   |
+LL | type Skwoz = &mut !; //~ ERROR type is experimental
+   |                   ^
+   |
+   = help: add #![feature(never_type)] to the crate attributes to enable
+
+error[E0658]: The `!` type is experimental (see issue #35121)
+  --> $DIR/feature-gate-never_type.rs:23:16
+   |
+LL |     type Wub = !; //~ ERROR type is experimental
+   |                ^
+   |
+   = help: add #![feature(never_type)] to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs
index 1908ef244cf..9ae86136a90 100644
--- a/src/test/ui/print_type_sizes/uninhabited.rs
+++ b/src/test/ui/print_type_sizes/uninhabited.rs
@@ -11,6 +11,7 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
 
+#![feature(never_type)]
 #![feature(start)]
 
 #[start]
diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs
index 3e39b75d8c0..26760cfea44 100644
--- a/src/test/ui/reachable/expr_add.rs
+++ b/src/test/ui/reachable/expr_add.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 #![allow(unused_variables)]
 #![deny(unreachable_code)]
 
diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs
index 73083af34d9..308f2483be5 100644
--- a/src/test/ui/reachable/expr_assign.rs
+++ b/src/test/ui/reachable/expr_assign.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
 #![allow(dead_code)]
diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs
index 2772dd429d1..9696bdadf87 100644
--- a/src/test/ui/reachable/expr_call.rs
+++ b/src/test/ui/reachable/expr_call.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
 #![allow(dead_code)]
diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs
index 88846b63841..fc0041daf7c 100644
--- a/src/test/ui/reachable/expr_cast.rs
+++ b/src/test/ui/reachable/expr_cast.rs
@@ -12,7 +12,7 @@
 #![allow(unused_assignments)]
 #![allow(dead_code)]
 #![deny(unreachable_code)]
-#![feature(type_ascription)]
+#![feature(never_type, type_ascription)]
 
 fn a() {
     // the cast is unreachable:
diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs
index 7dabb307097..c91646cfa1e 100644
--- a/src/test/ui/reachable/expr_method.rs
+++ b/src/test/ui/reachable/expr_method.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
 #![allow(dead_code)]
diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs
index 2381ea2ac7a..ce12412ba74 100644
--- a/src/test/ui/reachable/expr_type.rs
+++ b/src/test/ui/reachable/expr_type.rs
@@ -12,7 +12,7 @@
 #![allow(unused_assignments)]
 #![allow(dead_code)]
 #![deny(unreachable_code)]
-#![feature(type_ascription)]
+#![feature(never_type, type_ascription)]
 
 fn a() {
     // the cast is unreachable:
diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs
index 4096865f4c6..5b7ea57b166 100644
--- a/src/test/ui/reachable/expr_unary.rs
+++ b/src/test/ui/reachable/expr_unary.rs
@@ -7,7 +7,7 @@
 // <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.
-
+#![feature(never_type)]
 #![allow(unused_variables)]
 #![allow(unused_assignments)]
 #![allow(dead_code)]