diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index a14a5d32738b3..5bfb3fce8494c 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -401,6 +401,36 @@ fn test_str_get_maxinclusive() { } } +#[test] +fn test_str_slice_rangetoinclusive_ok() { + let s = "abcαβγ"; + assert_eq!(&s[..=2], "abc"); + assert_eq!(&s[..=4], "abcα"); +} + +#[test] +#[should_panic] +fn test_str_slice_rangetoinclusive_notok() { + let s = "abcαβγ"; + &s[..=3]; +} + +#[test] +fn test_str_slicemut_rangetoinclusive_ok() { + let mut s = "abcαβγ".to_owned(); + let s: &mut str = &mut s; + assert_eq!(&mut s[..=2], "abc"); + assert_eq!(&mut s[..=4], "abcα"); +} + +#[test] +#[should_panic] +fn test_str_slicemut_rangetoinclusive_notok() { + let mut s = "abcαβγ".to_owned(); + let s: &mut str = &mut s; + &mut s[..=3]; +} + #[test] fn test_is_char_boundary() { let s = "ศไทย中华Việt Nam β-release 🐱123"; diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 87144c27c9e11..3d24f8902bd83 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -59,7 +59,7 @@ unsafe impl> FixedSizeArray 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.rs b/src/libcore/char.rs index 718c6b893edf2..c74b23da39cfc 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -265,7 +265,7 @@ impl FromStr for char { } -#[stable(feature = "try_from", since = "1.26.0")] +#[unstable(feature = "try_from", issue = "33417")] impl TryFrom for char { type Error = CharTryFromError; @@ -280,11 +280,11 @@ impl TryFrom 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/cmp.rs b/src/libcore/cmp.rs index 67445daa43602..6602643dc5106 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -882,24 +882,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 { *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 637213957848c..7324df95bc5d5 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -322,26 +322,22 @@ pub trait From: 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: 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; } /// Attempt to construct `Self` via a conversion. -#[stable(feature = "try_from", since = "1.26.0")] +#[unstable(feature = "try_from", issue = "33417")] pub trait TryFrom: 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; } @@ -409,7 +405,7 @@ impl From for T { // TryFrom implies TryInto -#[stable(feature = "try_from", since = "1.26.0")] +#[unstable(feature = "try_from", issue = "33417")] impl TryInto for T where U: TryFrom { type Error = U::Error; @@ -421,7 +417,7 @@ impl TryInto for T where U: TryFrom // 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 TryFrom for T where T: From { type Error = !; diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 62994ed15cc6d..43b3470792883 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1777,14 +1777,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 5a62b8438f93d..842ed24c5b71a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -85,6 +85,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/num/mod.rs b/src/libcore/num/mod.rs index dcda404721c16..08727d5f3d528 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3663,7 +3663,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(()); @@ -3678,14 +3678,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 @@ -3695,7 +3695,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; @@ -3714,7 +3714,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; @@ -3733,7 +3733,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/str/mod.rs b/src/libcore/str/mod.rs index 1185b7acaae1f..553e5c1d0c83d 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2096,18 +2096,13 @@ mod traits { fn index(self, slice: &str) -> &Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); - let end = self.end + 1; - self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end)) + (..self.end+1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); - if slice.is_char_boundary(self.end) { - unsafe { self.get_unchecked_mut(slice) } - } else { - super::slice_error_fail(slice, 0, self.end + 1) - } + (..self.end+1).index_mut(slice) } } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1a68f04532d20..0b70f69240367 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -43,6 +43,7 @@ #![feature(step_trait)] #![feature(test)] #![feature(trusted_len)] +#![feature(try_from)] #![feature(try_trait)] #![feature(exact_chunks)] #![feature(atomic_nand)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index dcad8132c2b24..106c3d51e8464 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -58,6 +58,7 @@ #![cfg_attr(stage0, feature(match_default_bindings))] #![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 d0bb30e3201f5..d0cd4f58b2db7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2181,6 +2181,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/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 50a19526ba8c4..0350b9074b554 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -491,7 +491,16 @@ macro_rules! define_maps { span: Span, dep_node: DepNode) -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> { - debug_assert!(!tcx.dep_graph.dep_node_exists(&dep_node)); + // If the following assertion triggers, it can have two reasons: + // 1. Something is wrong with DepNode creation, either here or + // in DepGraph::try_mark_green() + // 2. Two distinct query keys get mapped to the same DepNode + // (see for example #48923) + assert!(!tcx.dep_graph.dep_node_exists(&dep_node), + "Forcing query with already existing DepNode.\n\ + - query-key: {:?}\n\ + - dep-node: {:?}", + key, dep_node); profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); let res = tcx.cycle_check(span, Query::$name(key), || { diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 6f08fcf702595..2ee7bea84765c 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -48,7 +48,7 @@ #![cfg_attr(stage0, feature(slice_patterns))] #![cfg_attr(stage0, feature(i128_type))] -#![cfg_attr(stage0, feature(try_from))] +#![feature(try_from)] // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c0728cb2b6669..b19cd25c1e62d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1430,3 +1430,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { } } } + +/// Lint constants that are erroneous. +/// Without this lint, we might not get any diagnostic if the constant is +/// unused within this crate, even though downstream crates can't use it +/// without producing an error. +pub struct UnusedBrokenConst; + +impl LintPass for UnusedBrokenConst { + fn get_lints(&self) -> LintArray { + lint_array!() + } +} + +fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) { + let def_id = cx.tcx.hir.body_owner_def_id(body_id); + let param_env = cx.tcx.param_env(def_id); + let cid = ::rustc::mir::interpret::GlobalId { + instance: ty::Instance::mono(cx.tcx, def_id), + promoted: None + }; + if let Err(err) = cx.tcx.const_eval(param_env.and(cid)) { + let span = cx.tcx.def_span(def_id); + let mut diag = cx.struct_span_lint( + CONST_ERR, + span, + &format!("this {} cannot be used", what), + ); + use rustc::middle::const_val::ConstEvalErrDescription; + match err.description() { + ConstEvalErrDescription::Simple(message) => { + diag.span_label(span, message); + } + ConstEvalErrDescription::Backtrace(miri, frames) => { + diag.span_label(span, format!("{}", miri)); + for frame in frames { + diag.span_label(frame.span, format!("inside call to `{}`", frame.location)); + } + } + } + diag.emit() + } +} + +struct UnusedBrokenConstVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>); + +impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> { + fn visit_nested_body(&mut self, id: hir::BodyId) { + check_const(self.0, id, "array length"); + } + fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> { + hir::intravisit::NestedVisitorMap::None + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst { + fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + match it.node { + hir::ItemConst(_, body_id) => { + check_const(cx, body_id, "constant"); + }, + hir::ItemTy(ref ty, _) => hir::intravisit::walk_ty( + &mut UnusedBrokenConstVisitor(cx), + ty + ), + _ => {}, + } + } +} diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index d024adad9d030..a9012ff48268b 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -139,6 +139,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnionsWithDropFields, UnreachablePub, TypeAliasBounds, + UnusedBrokenConst, ); add_builtin_with_new!(sess, diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 4e95ee6444dcf..147b8cc2175af 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/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 954a3dbe5b9ab..6fa68eb6ff1f0 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -56,7 +56,7 @@ pub fn mk_eval_cx<'a, 'tcx>( Ok(ecx) } -pub fn eval_body_with_mir<'a, 'mir, 'tcx>( +pub fn eval_promoted<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cid: GlobalId<'tcx>, mir: &'mir mir::Mir<'tcx>, @@ -66,7 +66,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>( match res { Ok(val) => Some(val), Err(mut err) => { - ecx.report(&mut err, true, None); + ecx.report(&mut err, false, None); None } } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 147db3bdc0e7a..e0e05d6ae60ae 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -19,7 +19,7 @@ pub use self::place::{Place, PlaceExtra}; pub use self::memory::{Memory, MemoryKind, HasMemory}; pub use self::const_eval::{ - eval_body_with_mir, + eval_promoted, mk_borrowck_eval_cx, eval_body, CompileTimeEvaluator, diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 7af3a397666e8..4a1e98a7638f0 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -40,6 +40,9 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![cfg_attr(stage0, feature(underscore_lifetimes))] #![cfg_attr(stage0, feature(never_type))] #![feature(inclusive_range_fields)] +#![feature(crate_visibility_modifier)] +#![feature(never_type)] +#![cfg_attr(stage0, feature(try_trait))] extern crate arena; #[macro_use] diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 7905fe998efc2..a3ef1db13483f 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1146,7 +1146,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_substs: instance.substs, }.visit_mir(&mir); let param_env = ty::ParamEnv::reveal_all(); - for (i, promoted) in mir.promoted.iter().enumerate() { + for i in 0..mir.promoted.len() { use rustc_data_structures::indexed_vec::Idx; let cid = GlobalId { instance, @@ -1154,9 +1154,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; match tcx.const_eval(param_env.and(cid)) { Ok(val) => collect_const(tcx, val, instance.substs, output), - Err(err) => { - err.report(tcx, promoted.span, "promoted"); - } + Err(_) => {}, } } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index f133d6e9c6dee..a3d96f0c0739d 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -20,7 +20,7 @@ use rustc::mir::visit::{Visitor, PlaceContext}; use rustc::middle::const_val::ConstVal; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, PrimVal, GlobalId}; -use interpret::{eval_body_with_mir, mk_borrowck_eval_cx, ValTy}; +use interpret::{eval_promoted, mk_borrowck_eval_cx, ValTy}; use transform::{MirPass, MirSource}; use syntax::codemap::Span; use rustc::ty::subst::Substs; @@ -161,7 +161,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { }; // cannot use `const_eval` here, because that would require having the MIR // for the current function available, but we're producing said MIR right now - let (value, _, ty) = eval_body_with_mir(self.tcx, cid, self.mir, self.param_env)?; + let (value, _, ty) = eval_promoted(self.tcx, cid, self.mir, self.param_env)?; let val = (value, ty, c.span); trace!("evaluated {:?} to {:?}", c, val); Some(val) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 75df349de41ee..656ab95a28cf3 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -399,7 +399,14 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { self.mir_constant_to_miri_value(bx, constant) .and_then(|c| OperandRef::from_const(bx, c, ty)) .unwrap_or_else(|err| { - err.report(bx.tcx(), constant.span, "const operand"); + match constant.literal { + mir::Literal::Promoted { .. } => { + // don't report errors inside promoteds, just warnings. + }, + mir::Literal::Value { .. } => { + err.report(bx.tcx(), constant.span, "const operand") + }, + } // We've errored, so we don't have to produce working code. let layout = bx.cx.layout_of(ty); PlaceRef::new_sized( diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 187f220f7f830..1443672c16178 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2200,7 +2200,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. @@ -2214,7 +2215,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 44ecb32a0bf9b..c4f1d2e05122b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -89,6 +89,7 @@ This API is completely unstable and subject to change. #![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(never_type))] #![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 3d0c96585b552..c4dc113374ed3 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -233,7 +233,7 @@ impl<'a> From> for Box { } } -#[stable(feature = "never_type", since = "1.26.0")] +#[unstable(feature = "never_type", issue = "35121")] impl Error for ! { fn description(&self) -> &str { *self } } @@ -275,14 +275,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() @@ -356,7 +356,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 68d3b946d9ef5..9645f2f043f36 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -280,6 +280,7 @@ #![feature(macro_reexport)] #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] +#![feature(never_type)] #![feature(exhaustive_patterns)] #![feature(nonzero)] #![feature(num_bits_bytes)] @@ -311,6 +312,7 @@ #![feature(test, rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] +#![feature(try_from)] #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode)] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index ce4bbfffc2e47..42bac6055117f 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/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index 33e47ade8cb9c..de8b46d5f1b02 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -42,7 +42,7 @@ pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode}; pub use core::char::ParseCharError; // unstable re-exports -#[stable(feature = "try_from", since = "1.26.0")] +#[unstable(feature = "try_from", issue = "33417")] pub use core::char::CharTryFromError; #[unstable(feature = "decode_utf8", issue = "33906")] pub use core::char::{DecodeUtf8, decode_utf8}; diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index c22ea1671fa59..9b3dbf92fe905 100644 --- a/src/libstd_unicode/lib.rs +++ b/src/libstd_unicode/lib.rs @@ -40,6 +40,7 @@ #![feature(non_exhaustive)] #![feature(staged_api)] #![feature(unboxed_closures)] +#![feature(try_from)] mod bool_trie; mod tables; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 25b392433ec57..2291add0c511b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -276,6 +276,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), @@ -1604,6 +1607,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/array_const_index-0.rs b/src/test/compile-fail/array_const_index-0.rs index 501c66e75cded..9b9deb4ca8d9d 100644 --- a/src/test/compile-fail/array_const_index-0.rs +++ b/src/test/compile-fail/array_const_index-0.rs @@ -12,6 +12,7 @@ const A: &'static [i32] = &[]; const B: i32 = (&A)[1]; //~^ ERROR constant evaluation error //~| index out of bounds: the len is 0 but the index is 1 +//~| WARN this constant cannot be used fn main() { let _ = B; diff --git a/src/test/compile-fail/array_const_index-1.rs b/src/test/compile-fail/array_const_index-1.rs index d3b43e83bfe52..46feb20cf11dd 100644 --- a/src/test/compile-fail/array_const_index-1.rs +++ b/src/test/compile-fail/array_const_index-1.rs @@ -12,6 +12,7 @@ const A: [i32; 0] = []; const B: i32 = A[1]; //~^ ERROR constant evaluation error //~| index out of bounds: the len is 0 but the index is 1 +//~| WARN this constant cannot be used fn main() { let _ = B; 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 c2f157cd35cce..583befed1e828 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 5efb4dadc64bd..14a06b306d82a 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 15049232a4d3f..62ff09f4616b8 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/const-err-early.rs b/src/test/compile-fail/const-err-early.rs index 3de0f1ff61e1c..6caec159d019c 100644 --- a/src/test/compile-fail/const-err-early.rs +++ b/src/test/compile-fail/const-err-early.rs @@ -10,17 +10,17 @@ #![deny(const_err)] -pub const A: i8 = -std::i8::MIN; //~ ERROR E0080 -//~^ ERROR attempt to negate with overflow +pub const A: i8 = -std::i8::MIN; //~ ERROR const_err +//~^ ERROR this constant cannot be used //~| ERROR constant evaluation error -pub const B: u8 = 200u8 + 200u8; //~ ERROR E0080 -//~^ ERROR attempt to add with overflow -pub const C: u8 = 200u8 * 4; //~ ERROR E0080 -//~^ ERROR attempt to multiply with overflow -pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR E0080 -//~^ ERROR attempt to subtract with overflow +pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err +//~^ ERROR this constant cannot be used +pub const C: u8 = 200u8 * 4; //~ ERROR const_err +//~^ ERROR this constant cannot be used +pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err +//~^ ERROR this constant cannot be used pub const E: u8 = [5u8][1]; -//~^ ERROR E0080 +//~^ ERROR const_err fn main() { let _a = A; diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs index d2355f57f1729..6f0281b8bd0ca 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -14,12 +14,13 @@ pub const A: i8 = -std::i8::MIN; //~^ ERROR E0080 //~| ERROR attempt to negate with overflow //~| ERROR constant evaluation error +//~| ERROR this constant cannot be used pub const B: i8 = A; -//~^ ERROR E0080 +//~^ ERROR const_err pub const C: u8 = A as u8; -//~^ ERROR E0080 +//~^ ERROR const_err pub const D: i8 = 50 - A; -//~^ ERROR E0080 +//~^ ERROR const_err fn main() { let _ = (A, B, C, D); diff --git a/src/test/compile-fail/const-eval-overflow2.rs b/src/test/compile-fail/const-eval-overflow2.rs index a0d8f9672c05e..faa8c3039b78c 100644 --- a/src/test/compile-fail/const-eval-overflow2.rs +++ b/src/test/compile-fail/const-eval-overflow2.rs @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize}; use std::{u8, u16, u32, u64, usize}; const VALS_I8: (i8,) = + //~^ ERROR this constant cannot be used ( i8::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_I16: (i16,) = + //~^ ERROR this constant cannot be used ( i16::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_I32: (i32,) = + //~^ ERROR this constant cannot be used ( i32::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_I64: (i64,) = + //~^ ERROR this constant cannot be used ( i64::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_U8: (u8,) = + //~^ ERROR this constant cannot be used ( u8::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_U16: (u16,) = ( + //~^ ERROR this constant cannot be used u16::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_U32: (u32,) = ( + //~^ ERROR this constant cannot be used u32::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); const VALS_U64: (u64,) = + //~^ ERROR this constant cannot be used ( u64::MIN - 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to subtract with overflow + //~^ ERROR attempt to subtract with overflow ); fn main() { diff --git a/src/test/compile-fail/const-eval-overflow2b.rs b/src/test/compile-fail/const-eval-overflow2b.rs index 08128f90e532f..d827e680c5bbb 100644 --- a/src/test/compile-fail/const-eval-overflow2b.rs +++ b/src/test/compile-fail/const-eval-overflow2b.rs @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize}; use std::{u8, u16, u32, u64, usize}; const VALS_I8: (i8,) = + //~^ ERROR this constant cannot be used ( i8::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_I16: (i16,) = + //~^ ERROR this constant cannot be used ( i16::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_I32: (i32,) = + //~^ ERROR this constant cannot be used ( i32::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_I64: (i64,) = + //~^ ERROR this constant cannot be used ( i64::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_U8: (u8,) = + //~^ ERROR this constant cannot be used ( u8::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_U16: (u16,) = ( + //~^ ERROR this constant cannot be used u16::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_U32: (u32,) = ( + //~^ ERROR this constant cannot be used u32::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); const VALS_U64: (u64,) = + //~^ ERROR this constant cannot be used ( u64::MAX + 1, - //~^ ERROR constant evaluation error - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow ); fn main() { diff --git a/src/test/compile-fail/const-eval-overflow2c.rs b/src/test/compile-fail/const-eval-overflow2c.rs index 31a1638cade17..2fd46b038ef28 100644 --- a/src/test/compile-fail/const-eval-overflow2c.rs +++ b/src/test/compile-fail/const-eval-overflow2c.rs @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize}; use std::{u8, u16, u32, u64, usize}; const VALS_I8: (i8,) = + //~^ ERROR this constant cannot be used ( i8::MIN * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_I16: (i16,) = + //~^ ERROR this constant cannot be used ( i16::MIN * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_I32: (i32,) = + //~^ ERROR this constant cannot be used ( i32::MIN * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_I64: (i64,) = + //~^ ERROR this constant cannot be used ( i64::MIN * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_U8: (u8,) = + //~^ ERROR this constant cannot be used ( u8::MAX * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_U16: (u16,) = ( + //~^ ERROR this constant cannot be used u16::MAX * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_U32: (u32,) = ( + //~^ ERROR this constant cannot be used u32::MAX * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); const VALS_U64: (u64,) = + //~^ ERROR this constant cannot be used ( u64::MAX * 2, - //~^ ERROR constant evaluation error - //~| ERROR attempt to multiply with overflow + //~^ ERROR attempt to multiply with overflow ); fn main() { diff --git a/src/test/compile-fail/const-slice-oob.rs b/src/test/compile-fail/const-slice-oob.rs index 179ea9e853f3a..7da5a2f17eaf9 100644 --- a/src/test/compile-fail/const-slice-oob.rs +++ b/src/test/compile-fail/const-slice-oob.rs @@ -14,6 +14,7 @@ const FOO: &'static[u32] = &[1, 2, 3]; const BAR: u32 = FOO[5]; //~^ ERROR constant evaluation error [E0080] //~| index out of bounds: the len is 3 but the index is 5 +//~| WARN this constant cannot be used fn main() { let _ = BAR; diff --git a/src/test/compile-fail/defaulted-never-note.rs b/src/test/compile-fail/defaulted-never-note.rs index 798544f164932..ac8ac85824edc 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 b9741e0add61c..d11aacec19631 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 5ef46bb27fd60..938f7fba2a032 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 e18c7d77ce366..8777ef2ffe33c 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 4e987d1ddce57..0fb75b535c6bc 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 8c2de7d68d3de..c0dd2cab749f4 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 72b0afa6bd3ee..05a97b855e703 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 e130df5c845b5..2cf4b78bdffe4 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 dca79bdfb87f7..cfd829e416e5b 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 0caf7d5123491..df340095bb433 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 7a4b5e59eeb75..da68dc39f85d7 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 56454586bb957..95101e70db951 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 0155332c51d1b..8f7b0c40538f9 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 d9b8461a1d07c..fdd21e08c20f9 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 0fe10d43910bf..826ca3a08c0e1 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 a96f98b9efda9..723a98bcdfa0d 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 87db440192984..86cf9b5ec4783 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 cf54e1c3bd598..794f5969bff50 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 a5a0a5a579447..5cbd3446d9b6f 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 ffdd99ebf6e5c..39053769b24b5 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 dda7a46f32585..9641ed282936f 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 8aa2a13ed8c8d..5c0af392f44df 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 = Ok(123); match x { diff --git a/src/test/run-pass/type-sizes.rs b/src/test/run-pass/type-sizes.rs index 2f50e63153ea4..2992ce53efb52 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 052575de4c267..75b60aa8d10b7 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 { fn ice(a: A) { let r = loop {}; r = r + a; - //~^ ERROR the trait bound `!: Add` is not satisfied + //~^ ERROR the trait bound `(): Add` 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 c22a645385ade..7924ab7444406 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` is not satisfied +error[E0277]: the trait bound `(): Add` is not satisfied --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11 | LL | r = r + a; - | ^ the trait `Add` is not implemented for `!` + | ^ the trait `Add` is not implemented for `()` error: aborting due to previous error diff --git a/src/test/ui/const-eval/conditional_array_execution.rs b/src/test/ui/const-eval/conditional_array_execution.rs index 324bcf60e8ff6..9df2693d69140 100644 --- a/src/test/ui/const-eval/conditional_array_execution.rs +++ b/src/test/ui/const-eval/conditional_array_execution.rs @@ -8,11 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// must-compile-successfully + const X: u32 = 5; const Y: u32 = 6; const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; //~^ WARN attempt to subtract with overflow +//~| WARN this constant cannot be used fn main() { - println!("{}", FOO); //~ E0080 + println!("{}", FOO); + //~^ WARN constant evaluation error } diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr index 9270dafbe651a..713b1b36c08b1 100644 --- a/src/test/ui/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.stderr @@ -1,17 +1,20 @@ warning: attempt to subtract with overflow - --> $DIR/conditional_array_execution.rs:13:19 + --> $DIR/conditional_array_execution.rs:15:19 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | ^^^^^ | = note: #[warn(const_err)] on by default -error[E0080]: constant evaluation error - --> $DIR/conditional_array_execution.rs:17:20 +warning: this constant cannot be used + --> $DIR/conditional_array_execution.rs:15:1 | -LL | println!("{}", FOO); //~ E0080 - | ^^^ referenced constant has errors +LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow -error: aborting due to previous error +warning: constant evaluation error + --> $DIR/conditional_array_execution.rs:20:20 + | +LL | println!("{}", FOO); + | ^^^ referenced constant has errors -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs index d5c4796d0b497..c732300e43da7 100644 --- a/src/test/ui/const-eval/issue-43197.rs +++ b/src/test/ui/const-eval/issue-43197.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// must-compile-successfully + #![feature(const_fn)] const fn foo(x: u32) -> u32 { @@ -17,9 +19,11 @@ const fn foo(x: u32) -> u32 { fn main() { const X: u32 = 0-1; //~^ WARN attempt to subtract with overflow + //~| WARN this constant cannot be used const Y: u32 = foo(0-1); //~^ WARN attempt to subtract with overflow + //~| WARN this constant cannot be used println!("{} {}", X, Y); - //~^ ERROR constant evaluation error - //~| ERROR constant evaluation error + //~^ WARN constant evaluation error + //~| WARN constant evaluation error } diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index 2d51e6603b59b..a22e8016296c4 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -1,29 +1,38 @@ warning: attempt to subtract with overflow - --> $DIR/issue-43197.rs:18:20 + --> $DIR/issue-43197.rs:20:20 | LL | const X: u32 = 0-1; | ^^^ | = note: #[warn(const_err)] on by default -error[E0080]: constant evaluation error - --> $DIR/issue-43197.rs:22:23 +warning: this constant cannot be used + --> $DIR/issue-43197.rs:20:5 | -LL | println!("{} {}", X, Y); - | ^ referenced constant has errors +LL | const X: u32 = 0-1; + | ^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow warning: attempt to subtract with overflow - --> $DIR/issue-43197.rs:20:24 + --> $DIR/issue-43197.rs:23:24 | LL | const Y: u32 = foo(0-1); | ^^^ -error[E0080]: constant evaluation error - --> $DIR/issue-43197.rs:22:26 +warning: this constant cannot be used + --> $DIR/issue-43197.rs:23:5 + | +LL | const Y: u32 = foo(0-1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + +warning: constant evaluation error + --> $DIR/issue-43197.rs:26:23 | LL | println!("{} {}", X, Y); - | ^ referenced constant has errors + | ^ referenced constant has errors -error: aborting due to 2 previous errors +warning: constant evaluation error + --> $DIR/issue-43197.rs:26:26 + | +LL | println!("{} {}", X, Y); + | ^ referenced constant has errors -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/compile-fail/issue-44578.rs b/src/test/ui/const-eval/issue-44578.rs similarity index 86% rename from src/test/compile-fail/issue-44578.rs rename to src/test/ui/const-eval/issue-44578.rs index 18cfb35113dc6..be6a2ed5f8841 100644 --- a/src/test/compile-fail/issue-44578.rs +++ b/src/test/ui/const-eval/issue-44578.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// must-compile-successfully + trait Foo { const AMT: usize; } @@ -30,5 +32,6 @@ impl Foo for u16 { } fn main() { - println!("{}", as Foo>::AMT); //~ E0080 + println!("{}", as Foo>::AMT); //~ WARN const_err + //~^ WARN const_err } diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr new file mode 100644 index 0000000000000..01c6fa3623f8d --- /dev/null +++ b/src/test/ui/const-eval/issue-44578.stderr @@ -0,0 +1,14 @@ +warning: constant evaluation error + --> $DIR/issue-44578.rs:35:20 + | +LL | println!("{}", as Foo>::AMT); //~ WARN const_err + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | + = note: #[warn(const_err)] on by default + +warning: constant evaluation error + --> $DIR/issue-44578.rs:35:20 + | +LL | println!("{}", as Foo>::AMT); //~ WARN const_err + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + diff --git a/src/test/ui/const-eval/promoted_errors.rs b/src/test/ui/const-eval/promoted_errors.rs new file mode 100644 index 0000000000000..dea84be37e1a7 --- /dev/null +++ b/src/test/ui/const-eval/promoted_errors.rs @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully +// compile-flags: -O +fn main() { + println!("{}", 0u32 - 1); + //~^ WARN const_err + //~| WARN const_err + let _x = 0u32 - 1; + //~^ WARN const_err + println!("{}", 1/(1-1)); + //~^ WARN const_err + //~| WARN const_err + let _x = 1/(1-1); + //~^ WARN const_err + //~| WARN const_err + println!("{}", 1/(false as u32)); + //~^ WARN const_err + let _x = 1/(false as u32); +} diff --git a/src/test/ui/const-eval/promoted_errors.stderr b/src/test/ui/const-eval/promoted_errors.stderr new file mode 100644 index 0000000000000..a5db8cc908331 --- /dev/null +++ b/src/test/ui/const-eval/promoted_errors.stderr @@ -0,0 +1,50 @@ +warning: constant evaluation error + --> $DIR/promoted_errors.rs:14:20 + | +LL | println!("{}", 0u32 - 1); + | ^^^^^^^^ attempted to do overflowing math + | + = note: #[warn(const_err)] on by default + +warning: constant evaluation error + --> $DIR/promoted_errors.rs:14:20 + | +LL | println!("{}", 0u32 - 1); + | ^^^^^^^^ attempted to do overflowing math + +warning: constant evaluation error + --> $DIR/promoted_errors.rs:17:14 + | +LL | let _x = 0u32 - 1; + | ^^^^^^^^ attempted to do overflowing math + +warning: attempt to divide by zero + --> $DIR/promoted_errors.rs:19:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ + +warning: constant evaluation error + --> $DIR/promoted_errors.rs:19:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ attempted to do overflowing math + +warning: attempt to divide by zero + --> $DIR/promoted_errors.rs:22:14 + | +LL | let _x = 1/(1-1); + | ^^^^^^^ + +warning: constant evaluation error + --> $DIR/promoted_errors.rs:22:14 + | +LL | let _x = 1/(1-1); + | ^^^^^^^ attempted to do overflowing math + +warning: constant evaluation error + --> $DIR/promoted_errors.rs:25:20 + | +LL | println!("{}", 1/(false as u32)); + | ^^^^^^^^^^^^^^^^ attempted to do overflowing math + diff --git a/src/test/ui/const-eval/pub_const_err.rs b/src/test/ui/const-eval/pub_const_err.rs index bdb9f5b19a885..5c0666ba71e8b 100644 --- a/src/test/ui/const-eval/pub_const_err.rs +++ b/src/test/ui/const-eval/pub_const_err.rs @@ -8,9 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(const_err)] +// must-compile-successfully #![crate_type = "lib"] pub const Z: u32 = 0 - 1; -//~^ ERROR attempt to subtract with overflow +//~^ WARN attempt to subtract with overflow +//~| WARN this constant cannot be used + +pub type Foo = [i32; 0 - 1]; +//~^ WARN attempt to subtract with overflow +//~| WARN this array length cannot be used diff --git a/src/test/ui/const-eval/pub_const_err.stderr b/src/test/ui/const-eval/pub_const_err.stderr index b77ec38ca1679..2981ac20cd981 100644 --- a/src/test/ui/const-eval/pub_const_err.stderr +++ b/src/test/ui/const-eval/pub_const_err.stderr @@ -1,14 +1,26 @@ -error: attempt to subtract with overflow +warning: attempt to subtract with overflow --> $DIR/pub_const_err.rs:15:20 | LL | pub const Z: u32 = 0 - 1; | ^^^^^ | -note: lint level defined here - --> $DIR/pub_const_err.rs:11:9 + = note: #[warn(const_err)] on by default + +warning: this constant cannot be used + --> $DIR/pub_const_err.rs:15:1 | -LL | #![deny(const_err)] - | ^^^^^^^^^ +LL | pub const Z: u32 = 0 - 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow -error: aborting due to previous error +warning: attempt to subtract with overflow + --> $DIR/pub_const_err.rs:19:22 + | +LL | pub type Foo = [i32; 0 - 1]; + | ^^^^^ + +warning: this array length cannot be used + --> $DIR/pub_const_err.rs:19:22 + | +LL | pub type Foo = [i32; 0 - 1]; + | ^^^^^ attempt to subtract with overflow diff --git a/src/test/ui/const-eval/pub_const_err_bin.rs b/src/test/ui/const-eval/pub_const_err_bin.rs new file mode 100644 index 0000000000000..4000e8768d6f7 --- /dev/null +++ b/src/test/ui/const-eval/pub_const_err_bin.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + +pub const Z: u32 = 0 - 1; +//~^ WARN attempt to subtract with overflow +//~| WARN this constant cannot be used + +pub type Foo = [i32; 0 - 1]; +//~^ WARN attempt to subtract with overflow +//~| WARN this array length cannot be used + +fn main() {} diff --git a/src/test/ui/const-eval/pub_const_err_bin.stderr b/src/test/ui/const-eval/pub_const_err_bin.stderr new file mode 100644 index 0000000000000..3e8966d854bf0 --- /dev/null +++ b/src/test/ui/const-eval/pub_const_err_bin.stderr @@ -0,0 +1,26 @@ +warning: attempt to subtract with overflow + --> $DIR/pub_const_err_bin.rs:13:20 + | +LL | pub const Z: u32 = 0 - 1; + | ^^^^^ + | + = note: #[warn(const_err)] on by default + +warning: this constant cannot be used + --> $DIR/pub_const_err_bin.rs:13:1 + | +LL | pub const Z: u32 = 0 - 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + +warning: attempt to subtract with overflow + --> $DIR/pub_const_err_bin.rs:17:22 + | +LL | pub type Foo = [i32; 0 - 1]; + | ^^^^^ + +warning: this array length cannot be used + --> $DIR/pub_const_err_bin.rs:17:22 + | +LL | pub type Foo = [i32; 0 - 1]; + | ^^^^^ attempt to subtract with overflow + diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs index a9f747d09ec2d..ed9033ad53d56 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 417ff1de3f817..e8b2c84c0df0b 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` for type `std::boxed::Box`: - --> $DIR/conflict-with-std.rs:15:1 + --> $DIR/conflict-with-std.rs:17:1 | LL | impl AsRef for Box { //~ ERROR conflicting implementations | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | impl AsRef for Box { //~ ERROR conflicting implementations where T: ?Sized; error[E0119]: conflicting implementations of trait `std::convert::From` for type `S`: - --> $DIR/conflict-with-std.rs:22:1 + --> $DIR/conflict-with-std.rs:24:1 | LL | impl From for S { //~ ERROR conflicting implementations | ^^^^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | impl From for S { //~ ERROR conflicting implementations - impl std::convert::From for T; error[E0119]: conflicting implementations of trait `std::convert::TryFrom` for type `X`: - --> $DIR/conflict-with-std.rs:29:1 + --> $DIR/conflict-with-std.rs:31:1 | LL | impl TryFrom 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 477dd1b38eb0d..c83d9b56bc39f 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.rs +++ b/src/test/ui/feature-gate-exhaustive-patterns.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - +#![feature(never_type)] fn foo() -> Result { 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 0000000000000..ebbe17a821f02 --- /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 or the MIT license +// , 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 0000000000000..187be6d829137 --- /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 7e8eff02c20a1..4d0396903e555 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 // must-compile-successfully +#![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 3e39b75d8c0f3..26760cfea4478 100644 --- a/src/test/ui/reachable/expr_add.rs +++ b/src/test/ui/reachable/expr_add.rs @@ -7,7 +7,7 @@ // , 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 73083af34d97d..308f2483be50a 100644 --- a/src/test/ui/reachable/expr_assign.rs +++ b/src/test/ui/reachable/expr_assign.rs @@ -7,7 +7,7 @@ // , 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 2772dd429d184..9696bdadf87e8 100644 --- a/src/test/ui/reachable/expr_call.rs +++ b/src/test/ui/reachable/expr_call.rs @@ -7,7 +7,7 @@ // , 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 88846b638416a..fc0041daf7c7c 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 7dabb30709762..c91646cfa1ef1 100644 --- a/src/test/ui/reachable/expr_method.rs +++ b/src/test/ui/reachable/expr_method.rs @@ -7,7 +7,7 @@ // , 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 2381ea2ac7a1b..ce12412ba7438 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 4096865f4c670..5b7ea57b1661a 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -7,7 +7,7 @@ // , 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)]