From 9b15ddb29e5acb15b074913d1e70b5b26bd89ee6 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 13:33:21 +0800 Subject: [PATCH 01/14] remove defaulting to unit Types will no longer default to `()`, instead always defaulting to `!`. This disables the associated warning and removes the flag from TyTuple --- src/librustc/ich/impls_ty.rs | 3 +- src/librustc/infer/resolve.rs | 6 -- src/librustc/lint/builtin.rs | 8 --- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/mir/tcx.rs | 7 +-- src/librustc/traits/error_reporting.rs | 10 ++-- src/librustc/traits/fulfill.rs | 6 +- src/librustc/traits/select.rs | 55 ++----------------- src/librustc/traits/util.rs | 2 +- src/librustc/ty/context.rs | 21 ++----- src/librustc/ty/error.rs | 2 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 5 +- src/librustc/ty/inhabitedness/mod.rs | 2 +- src/librustc/ty/item_path.rs | 6 +- src/librustc/ty/layout.rs | 4 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/relate.rs | 5 +- src/librustc/ty/structural_impls.rs | 4 +- src/librustc/ty/sty.rs | 17 +----- src/librustc/ty/util.rs | 13 ++--- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 4 +- src/librustc_driver/test.rs | 10 ++-- src/librustc_lint/lib.rs | 5 -- src/librustc_lint/unused.rs | 2 +- .../borrow_check/error_reporting.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 2 +- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/build/expr/as_rvalue.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 4 +- src/librustc_mir/hair/pattern/mod.rs | 4 +- src/librustc_mir/interpret/terminator/mod.rs | 2 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 8 +-- src/librustc_trans/debuginfo/mod.rs | 4 +- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/mir/block.rs | 2 +- src/librustc_trans/mir/mod.rs | 2 +- src/librustc_trans/mir/rvalue.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/_match.rs | 4 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/intrinsic.rs | 8 +-- src/librustc_typeck/check/mod.rs | 19 +++---- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 8 +-- .../compile-fail/defaulted-unit-warning.rs | 38 ------------- ...ed-types-ICE-when-projecting-out-of-err.rs | 2 +- ...ypes-ICE-when-projecting-out-of-err.stderr | 4 +- 57 files changed, 107 insertions(+), 243 deletions(-) delete mode 100644 src/test/compile-fail/defaulted-unit-warning.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 4eb4f0edafe..bb3051b546e 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -886,9 +886,8 @@ for ty::TypeVariants<'gcx> TyGeneratorWitness(types) => { types.hash_stable(hcx, hasher) } - TyTuple(inner_tys, from_diverging_type_var) => { + TyTuple(inner_tys) => { inner_tys.hash_stable(hcx, hasher); - from_diverging_type_var.hash_stable(hcx, hasher); } TyProjection(ref projection_ty) => { projection_ty.hash_stable(hcx, hasher); diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 5e70c0ce368..77b722c5695 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -173,12 +173,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> ty::TyInfer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); } - ty::TyTuple(tys, true) => { - // Un-default defaulted tuples - we are going to a - // different infcx, and the default will just cause - // pollution. - self.tcx().intern_tup(tys, false) - } _ => { t.super_fold_with(self) } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8e1f76c5018..1795866e103 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -151,13 +151,6 @@ declare_lint! { "lints that have been renamed or removed" } -declare_lint! { - pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT, - Deny, - "attempt to resolve a trait on an expression whose type cannot be inferred but which \ - currently defaults to ()" -} - declare_lint! { pub SAFE_EXTERN_STATICS, Deny, @@ -304,7 +297,6 @@ impl LintPass for HardwiredLints { INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, - RESOLVE_TRAIT_ON_DEFAULTED_UNIT, SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 30d63b8443e..6bf0c5d1ba3 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1298,7 +1298,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::Tuple(ref subpats, ddpos) => { // (p1, ..., pN) let expected_len = match self.pat_ty(&pat)?.sty { - ty::TyTuple(ref tys, _) => tys.len(), + ty::TyTuple(ref tys) => tys.len(), ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index d779ccd1736..20902d91110 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -155,7 +155,7 @@ impl<'tcx> Rvalue<'tcx> { let lhs_ty = lhs.ty(local_decls, tcx); let rhs_ty = rhs.ty(local_decls, tcx); let ty = op.ty(tcx, lhs_ty, rhs_ty); - tcx.intern_tup(&[ty, tcx.types.bool], false) + tcx.intern_tup(&[ty, tcx.types.bool]) } Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => { @@ -178,10 +178,7 @@ impl<'tcx> Rvalue<'tcx> { tcx.mk_array(ty, ops.len() as u64) } AggregateKind::Tuple => { - tcx.mk_tup( - ops.iter().map(|op| op.ty(local_decls, tcx)), - false - ) + tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))) } AggregateKind::Adt(def, _, substs, _) => { tcx.type_of(def.did).subst(tcx, substs) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b8455b97fa4..5d994a0e444 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -729,14 +729,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def let found = match found_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => tys.iter() + ty::TyTuple(ref tys) => tys.iter() .map(|_| ArgKind::empty()).collect::>(), _ => vec![ArgKind::empty()], }; let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => tys.iter() + ty::TyTuple(ref tys) => tys.iter() .map(|t| match t.sty { - ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple( + ty::TypeVariants::TyTuple(ref tys) => ArgKind::Tuple( Some(span), tys.iter() .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) @@ -986,7 +986,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> String { let inputs = trait_ref.substs.type_at(1); - let sig = if let ty::TyTuple(inputs, _) = inputs.sty { + let sig = if let ty::TyTuple(inputs) = inputs.sty { tcx.mk_fn_sig( inputs.iter().map(|&x| x), tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })), @@ -1422,7 +1422,7 @@ impl ArgKind { /// argument. This has no name (`_`) and no source spans.. pub fn from_expected_ty(t: Ty<'_>) -> ArgKind { match t.sty { - ty::TyTuple(ref tys, _) => ArgKind::Tuple( + ty::TyTuple(ref tys) => ArgKind::Tuple( None, tys.iter() .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index bb2c7977f26..150a2ead9e9 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -330,11 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( if data.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. - if - // make defaulted unit go through the slow path for better warnings, - // please remove this when the warnings are removed. - !trait_obligation.predicate.skip_binder().self_ty().is_defaulted_unit() && - selcx.evaluate_obligation_conservatively(&obligation) { + if selcx.evaluate_obligation_conservatively(&obligation) { debug!("selecting trait `{:?}` at depth {} evaluated to holds", data, obligation.recursion_depth); return Ok(Some(vec![])) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index f2f54dcedfd..4db81cf1dec 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -53,7 +53,6 @@ use std::mem; use std::rc::Rc; use syntax::abi::Abi; use hir; -use lint; use util::nodemap::{FxHashMap, FxHashSet}; @@ -526,54 +525,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("select({:?})", obligation); assert!(!obligation.predicate.has_escaping_regions()); - let tcx = self.tcx(); - let stack = self.push_stack(TraitObligationStackList::empty(), obligation); let ret = match self.candidate_from_obligation(&stack)? { None => None, Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?) }; - // Test whether this is a `()` which was produced by defaulting a - // diverging type variable with `!` disabled. If so, we may need - // to raise a warning. - if obligation.predicate.skip_binder().self_ty().is_defaulted_unit() { - let mut raise_warning = true; - // Don't raise a warning if the trait is implemented for ! and only - // permits a trivial implementation for !. This stops us warning - // about (for example) `(): Clone` becoming `!: Clone` because such - // a switch can't cause code to stop compiling or execute - // differently. - let mut never_obligation = obligation.clone(); - let def_id = never_obligation.predicate.skip_binder().trait_ref.def_id; - never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| { - // Swap out () with ! so we can check if the trait is impld for ! - { - let trait_ref = &mut trait_pred.trait_ref; - let unit_substs = trait_ref.substs; - let mut never_substs = Vec::with_capacity(unit_substs.len()); - never_substs.push(tcx.types.never.into()); - never_substs.extend(&unit_substs[1..]); - trait_ref.substs = tcx.intern_substs(&never_substs); - } - trait_pred - }); - if let Ok(Some(..)) = self.select(&never_obligation) { - if !tcx.trait_relevant_for_never(def_id) { - // The trait is also implemented for ! and the resulting - // implementation cannot actually be invoked in any way. - raise_warning = false; - } - } - - if raise_warning { - tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT, - obligation.cause.body_id, - obligation.cause.span, - &format!("code relies on type inference rules which are likely \ - to change")); - } - } Ok(ret) } @@ -1929,7 +1886,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } // (.., T) -> (.., U). - (&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { + (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => { tys_a.len() == tys_b.len() } @@ -2068,7 +2025,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never, - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { Where(ty::Binder(tys.last().into_iter().cloned().collect())) } @@ -2122,7 +2079,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(vec![element_ty])) } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { // (*) binder moved here Where(ty::Binder(tys.to_vec())) } @@ -2215,7 +2172,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { vec![element_ty] } - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet tys.to_vec() } @@ -3004,7 +2961,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } // (.., T) -> (.., U). - (&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { + (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => { assert_eq!(tys_a.len(), tys_b.len()); // The last field of the tuple has to exist. @@ -3017,7 +2974,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Check that the source tuple with the target's // last element is equal to the target. - let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)), false); + let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last))); let InferOk { obligations, .. } = self.infcx.at(&obligation.cause, obligation.param_env) .eq(target, new_tuple) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index c562f2cd48d..8f7a2405747 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -503,7 +503,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => - self.intern_tup(sig.skip_binder().inputs(), false), + self.intern_tup(sig.skip_binder().inputs()), }; let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 9a687028b58..fd3465f59eb 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2014,7 +2014,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { let converted_sig = sig.map_bound(|s| { let params_iter = match s.inputs()[0].sty { - ty::TyTuple(params, _) => { + ty::TyTuple(params) => { params.into_iter().cloned() } _ => bug!(), @@ -2134,25 +2134,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.mk_ty(TySlice(ty)) } - pub fn intern_tup(self, ts: &[Ty<'tcx>], defaulted: bool) -> Ty<'tcx> { - self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted)) + pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { + self.mk_ty(TyTuple(self.intern_type_list(ts))) } - pub fn mk_tup], Ty<'tcx>>>(self, iter: I, - defaulted: bool) -> I::Output { - iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted))) + pub fn mk_tup], Ty<'tcx>>>(self, iter: I) -> I::Output { + iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts)))) } pub fn mk_nil(self) -> Ty<'tcx> { - self.intern_tup(&[], false) - } - - pub fn mk_diverging_default(self) -> Ty<'tcx> { - if self.features().never_type { - self.types.never - } else { - self.intern_tup(&[], true) - } + self.intern_tup(&[]) } pub fn mk_bool(self) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 8a0253ed2f1..eb392418647 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -177,7 +177,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { match self.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(), - ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(), + ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), ty::TyForeign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 93d8a4d979d..6533a7440ac 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -97,7 +97,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())) } ty::TyNever => Some(NeverSimplifiedType), - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { Some(TupleSimplifiedType(tys.len())) } ty::TyFnPtr(ref f) => { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index cae64fd4c95..086fc66c70f 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -179,10 +179,7 @@ impl FlagComputation { self.add_ty(m.ty); } - &ty::TyTuple(ref ts, is_default) => { - if is_default { - self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX); - } + &ty::TyTuple(ref ts) => { self.add_tys(&ts[..]); } diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 3e653cf126a..325f8575fd0 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -256,7 +256,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { }, TyNever => DefIdForest::full(tcx), - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { DefIdForest::union(tcx, tys.iter().map(|ty| { ty.uninhabited_from(visited, tcx) })) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index fefd11eecf4..1f23b0a27e3 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -355,9 +355,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyRawPtr(mt) | ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), - ty::TyTuple(ref tys, _) => tys.iter() - .filter_map(|ty| characteristic_def_id_of_type(ty)) - .next(), + ty::TyTuple(ref tys) => tys.iter() + .filter_map(|ty| characteristic_def_id_of_type(ty)) + .next(), ty::TyFnDef(def_id, _) | ty::TyClosure(def_id, _) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 04353d2ece1..3a3f10cb87d 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1318,7 +1318,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { StructKind::AlwaysSized)? } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { let kind = if tys.len() == 0 { StructKind::AlwaysSized } else { @@ -2243,7 +2243,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { substs.field_tys(def_id, tcx).nth(i).unwrap() } - ty::TyTuple(tys, _) => tys[i], + ty::TyTuple(tys) => tys[i], // SIMD vector types. ty::TyAdt(def, ..) if def.repr.simd() => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fc1d26b0e09..09b11a36352 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2046,7 +2046,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { vec![ty] } - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { match tys.last() { None => vec![], Some(ty) => self.sized_constraint_for_ty(tcx, ty) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 72e7d16b64d..36eb3e3f94c 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -529,11 +529,10 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, Ok(tcx.mk_slice(t)) } - (&ty::TyTuple(as_, a_defaulted), &ty::TyTuple(bs, b_defaulted)) => + (&ty::TyTuple(as_), &ty::TyTuple(bs)) => { if as_.len() == bs.len() { - let defaulted = a_defaulted || b_defaulted; - Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)), defaulted)?) + Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?) } else if !(as_.is_empty() || bs.is_empty()) { Err(TypeError::TupleSize( expected_found(relation, &as_.len(), &bs.len()))) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0627bcdfb0e..c9a69d5405c 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -869,7 +869,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)), ty::TyDynamic(ref trait_ty, ref region) => ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)), - ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted), + ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)), ty::TyFnDef(def_id, substs) => { ty::TyFnDef(def_id, substs.fold_with(folder)) } @@ -908,7 +908,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAdt(_, substs) => substs.visit_with(visitor), ty::TyDynamic(ref trait_ty, ref reg) => trait_ty.visit_with(visitor) || reg.visit_with(visitor), - ty::TyTuple(ts, _) => ts.visit_with(visitor), + ty::TyTuple(ts) => ts.visit_with(visitor), ty::TyFnDef(_, substs) => substs.visit_with(visitor), ty::TyFnPtr(ref f) => f.visit_with(visitor), ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 109422564c8..ae053d7f4f5 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -148,11 +148,7 @@ pub enum TypeVariants<'tcx> { TyNever, /// A tuple type. For example, `(i32, bool)`. - /// The bool indicates whether this is a unit tuple and was created by - /// defaulting a diverging type variable with feature(never_type) disabled. - /// It's only purpose is for raising future-compatibility warnings for when - /// diverging type variables start defaulting to ! instead of (). - TyTuple(&'tcx Slice>, bool), + TyTuple(&'tcx Slice>), /// The projection of an associated type. For example, /// `>::N`. @@ -1274,7 +1270,7 @@ impl RegionKind { impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_nil(&self) -> bool { match self.sty { - TyTuple(ref tys, _) => tys.is_empty(), + TyTuple(ref tys) => tys.is_empty(), _ => false, } } @@ -1286,15 +1282,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - /// Test whether this is a `()` which was produced by defaulting a - /// diverging type variable with feature(never_type) disabled. - pub fn is_defaulted_unit(&self) -> bool { - match self.sty { - TyTuple(_, true) => true, - _ => false, - } - } - pub fn is_primitive(&self) -> bool { match self.sty { TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 753f89d8cd2..91d460a96f7 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -269,7 +269,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Don't use `non_enum_variant`, this may be a univariant enum. adt.variants[0].fields.get(i).map(|f| f.ty(self, substs)) } - (&TyTuple(ref v, _), None) => v.get(i).cloned(), + (&TyTuple(ref v), None) => v.get(i).cloned(), _ => None, } } @@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { if let Some((&last_ty, _)) = tys.split_last() { ty = last_ty; } else { @@ -344,7 +344,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { break; } }, - (&TyTuple(a_tys, _), &TyTuple(b_tys, _)) + (&TyTuple(a_tys), &TyTuple(b_tys)) if a_tys.len() == b_tys.len() => { if let Some(a_last) = a_tys.last() { a = a_last; @@ -709,9 +709,8 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyGeneratorWitness(tys) => { self.hash(tys.skip_binder().len()); } - TyTuple(tys, defaulted) => { + TyTuple(tys) => { self.hash(tys.len()); - self.hash(defaulted); } TyParam(p) => { self.hash(p.idx); @@ -838,7 +837,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { -> Representability { match ty.sty { - TyTuple(ref ts, _) => { + TyTuple(ref ts) => { // Find non representable fold_repr(ts.iter().map(|ty| { is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty) @@ -1106,7 +1105,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // state transformation pass ty::TyGenerator(..) => true, - ty::TyTuple(ref tys, _) => tys.iter().cloned().any(needs_drop), + ty::TyTuple(ref tys) => tys.iter().cloned().any(needs_drop), // unions don't have destructors regardless of the child types ty::TyAdt(def, _) if def.is_union() => false, diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 722fdfe773a..46c048e839b 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -125,7 +125,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyGeneratorWitness(ts) => { stack.extend(ts.skip_binder().iter().cloned().rev()); } - ty::TyTuple(ts, _) => { + ty::TyTuple(ts) => { stack.extend(ts.iter().cloned().rev()); } ty::TyFnDef(_, substs) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 49ae79ae9c9..f05d56c9d83 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -275,7 +275,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { self.compute_const(len); } - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { if let Some((_last, rest)) = tys.split_last() { for elem in rest { self.require_sized(elem, traits::TupleElem); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index efa53c775ae..2c3ee1ec285 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -340,7 +340,7 @@ impl PrintContext { if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { let projection_ty = projections[0].ty; - if let TyTuple(ref args, _) = substs.type_at(1).sty { + if let TyTuple(ref args) = substs.type_at(1).sty { return self.fn_sig(f, args, false, projection_ty); } } @@ -1013,7 +1013,7 @@ define_print! { tm.print(f, cx) } TyNever => write!(f, "!"), - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { write!(f, "(")?; let mut tys = tys.iter(); if let Some(&ty) = tys.next() { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 06610609ebd..f7cd1c99a79 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -287,7 +287,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> { - self.infcx.tcx.intern_tup(&[ty1, ty2], false) + self.infcx.tcx.intern_tup(&[ty1, ty2]) } pub fn t_param(&self, index: u32) -> Ty<'tcx> { @@ -593,8 +593,8 @@ fn walk_ty() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let usize_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]); let walked: Vec<_> = tup2_ty.walk().collect(); assert_eq!(walked, [tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty, @@ -608,8 +608,8 @@ fn walk_ty_skip_subtree() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let usize_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 779aa3a9037..235d733b253 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -234,11 +234,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #39207 ", epoch: None, }, - FutureIncompatibleInfo { - id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT), - reference: "issue #39216 ", - epoch: None, - }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 6ab3172c4fe..d777f6f19b0 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let t = cx.tables.expr_ty(&expr); let ty_warned = match t.sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => return, + ty::TyTuple(ref tys) if tys.is_empty() => return, ty::TyNever => return, ty::TyAdt(def, _) => { if def.variants.is_empty() { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 84ba1367450..56371d809b2 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -789,7 +789,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } else { format!("{}", def.non_enum_variant().fields[field.index()].name) }, - ty::TyTuple(_, _) => format!("{}", field.index()), + ty::TyTuple(_) => format!("{}", field.index()), ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => { self.describe_field_from_ty(&tnm.ty, field) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 06e6be5cd56..022831b5a92 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -542,7 +542,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { }), }; } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { return match tys.get(field.index()) { Some(&ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 668172749fe..afd33858139 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -635,7 +635,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); let inputs = match tuplized_inputs[0].sty { - ty::TyTuple(inputs, _) => inputs, + ty::TyTuple(inputs) => inputs, _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), }; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 1a9064aab1b..b7f402f61a9 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -298,7 +298,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_info = self.source_info(span); let bool_ty = self.hir.bool_ty(); if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() { - let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty], false); + let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]); let result_value = self.temp(result_tup, span); self.cfg.push_assign(block, source_info, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index da25969bf11..62d1b43d625 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -227,7 +227,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let tupled_args = Expr { - ty: cx.tcx.mk_tup(arg_tys, false), + ty: cx.tcx.mk_tup(arg_tys), temp_lifetime, span: expr.span, kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() }, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index a3295aac801..58aa9b06c64 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -877,7 +877,7 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt, fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { debug!("constructor_arity({:#?}, {:?})", ctor, ty); match ty.sty { - ty::TyTuple(ref fs, _) => fs.len() as u64, + ty::TyTuple(ref fs) => fs.len() as u64, ty::TySlice(..) | ty::TyArray(..) => match *ctor { Slice(length) => length, ConstantValue(_) => 0, @@ -901,7 +901,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, { debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty); match ty.sty { - ty::TyTuple(ref fs, _) => fs.into_iter().map(|t| *t).collect(), + ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(), ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { Slice(length) => (0..length).map(|_| ty).collect(), ConstantValue(_) => vec![], diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 1774c95af0f..eb87d5b044b 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -449,7 +449,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatKind::Tuple(ref subpatterns, ddpos) => { let ty = self.tables.node_id_to_type(pat.hir_id); match ty.sty { - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { let subpatterns = subpatterns.iter() .enumerate_and_adjust(tys.len(), ddpos) @@ -879,7 +879,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { subpatterns: adt_subpatterns(struct_var.fields.len(), None), } } - ty::TyTuple(fields, _) => { + ty::TyTuple(fields) => { PatternKind::Leaf { subpatterns: adt_subpatterns(fields.len(), None), } diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index be34b8705eb..851fac532e3 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -234,7 +234,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { // Second argument must be a tuple matching the argument list of sig let snd_ty = real_sig.inputs_and_output[1]; match snd_ty.sty { - ty::TyTuple(tys, _) if sig.inputs().len() == tys.len() => + ty::TyTuple(tys) if sig.inputs().len() == tys.len() => if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) { return Ok(true) }, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 10e2a84038d..c2f4359c008 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -281,7 +281,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { self.push_def_path(adt_def.did, output); self.push_type_params(substs, iter::empty(), output); }, - ty::TyTuple(component_types, _) => { + ty::TyTuple(component_types) => { output.push('('); for &component_type in component_types { self.push_type_name(component_type, output); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 62af09cc491..6a0f42c6dbb 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -312,7 +312,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, substs.upvar_tys(def_id, tcx) ) } - ty::TyTuple(tys, _) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), + ty::TyTuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), _ => { bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty) } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 6380d2a5c15..2dd805ccf9b 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { assert!(args.next().is_none()); let tuple = Place::Local(tuple); - let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { + let tuple_tys = if let ty::TyTuple(s) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { s } else { bug!("Closure arguments are not passed as a tuple"); diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 3f5208dd2d4..e95126c8a1a 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -788,7 +788,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); self.open_drop_for_tuple(&tys) } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { self.open_drop_for_tuple(tys) } ty::TyAdt(def, _) if def.is_box() => { diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index c1dc8c6684a..4a98fff6af7 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -722,7 +722,7 @@ impl<'a, 'tcx> FnType<'tcx> { assert!(!sig.variadic && extra_args.is_empty()); match sig.inputs().last().unwrap().sty { - ty::TyTuple(ref tupled_arguments, _) => { + ty::TyTuple(ref tupled_arguments) => { inputs = &sig.inputs()[0..sig.inputs().len() - 1]; tupled_arguments } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 20cc57522b5..f3d95cf794b 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -362,7 +362,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // return type signature_metadata.push(match signature.output().sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), + ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), _ => type_metadata(cx, signature.output(), span) }); @@ -533,7 +533,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyFloat(_) => { MetadataCreationResult::new(basic_type_metadata(cx, t), false) } - ty::TyTuple(ref elements, _) if elements.is_empty() => { + ty::TyTuple(ref elements) if elements.is_empty() => { MetadataCreationResult::new(basic_type_metadata(cx, t), false) } ty::TyArray(typ, _) | @@ -621,7 +621,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, usage_site_span).finalize(cx) } }, - ty::TyTuple(ref elements, _) => { + ty::TyTuple(ref elements) => { prepare_tuple_metadata(cx, t, &elements[..], @@ -731,7 +731,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let (name, encoding) = match t.sty { ty::TyNever => ("!", DW_ATE_unsigned), - ty::TyTuple(ref elements, _) if elements.is_empty() => + ty::TyTuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned), ty::TyBool => ("bool", DW_ATE_boolean), ty::TyChar => ("char", DW_ATE_unsigned_char), diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index c13b91eb3b6..7664c88679e 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -312,7 +312,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 signature.push(match sig.output().sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), + ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), _ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP) }); @@ -351,7 +351,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } if sig.abi == Abi::RustCall && !sig.inputs().is_empty() { - if let ty::TyTuple(args, _) = sig.inputs()[sig.inputs().len() - 1].sty { + if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty { for &argument_type in args { signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)); } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 211de95c96e..96ed4e88471 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -53,7 +53,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, push_item_name(cx, def.did, qualified, output); push_type_params(cx, substs, output); }, - ty::TyTuple(component_types, _) => { + ty::TyTuple(component_types) => { output.push('('); for &component_type in component_types { push_debuginfo_type_name(cx, component_type, true, output); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 96c5bb3b91d..93bc89f0914 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let layout = cx.layout_of(cx.tcx.intern_tup(&[ cx.tcx.mk_mut_ptr(cx.tcx.types.u8), cx.tcx.types.i32 - ], false)); + ])); let slot = PlaceRef::alloca(bx, layout, "personalityslot"); self.personality_slot = Some(slot); slot diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 0533b04a0c1..11dabbeae74 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -448,7 +448,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, let arg_ty = fx.monomorphize(&arg_decl.ty); let tupled_arg_tys = match arg_ty.sty { - ty::TyTuple(ref tys, _) => tys, + ty::TyTuple(ref tys) => tys, _ => bug!("spread argument isn't a tuple?!") }; diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index fa0514952d2..93702bfbbf3 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { lhs.immediate(), rhs.immediate(), lhs.layout.ty); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); - let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool], false); + let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]); let operand = OperandRef { val: result, layout: bx.cx.layout_of(operand_ty) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0df1225cf26..827ca79334c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1050,7 +1050,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.types.never }, hir::TyTup(ref fields) => { - tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false) + tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t))) } hir::TyBareFn(ref bf) => { require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index eb02c05fd39..379fd93ba2b 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -319,7 +319,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut expected_len = elements.len(); if ddpos.is_some() { // Require known type only when `..` is present - if let ty::TyTuple(ref tys, _) = + if let ty::TyTuple(ref tys) = self.structurally_resolved_type(pat.span, expected).sty { expected_len = tys.len(); } @@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::UniverseIndex::ROOT, TypeVariableOrigin::TypeInference(pat.span))); let element_tys = tcx.mk_type_list(element_tys_iter); - let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false)); + let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys)); self.demand_eqtype(pat.span, expected, pat_ty); for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { self.check_pat_walk(elem, &element_tys[i], def_bm, true); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 48bd7b14fc9..c2c113f2da9 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - ty::TyTuple(fields, _) => match fields.last() { + ty::TyTuple(fields) => match fields.last() { None => Some(PointerKind::Thin), Some(f) => self.pointer_kind(f, span)? }, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 72e4b726a22..562c0cb1b8d 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -140,7 +140,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - iter::once(self.tcx.intern_tup(sig.inputs(), false)), + iter::once(self.tcx.intern_tup(sig.inputs())), sig.output(), sig.variadic, sig.unsafety, @@ -312,7 +312,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); let input_tys = match arg_param_ty.sty { - ty::TyTuple(tys, _) => tys.into_iter(), + ty::TyTuple(tys) => tys.into_iter(), _ => { return None; } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2e00040d99a..59cf8a0358e 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -87,7 +87,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)], - tcx.intern_tup(&[param(0), tcx.types.bool], false)), + tcx.intern_tup(&[param(0), tcx.types.bool])), "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)), "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], @@ -281,7 +281,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => (1, vec![param(0), param(0)], - tcx.intern_tup(&[param(0), tcx.types.bool], false)), + tcx.intern_tup(&[param(0), tcx.types.bool])), "unchecked_div" | "unchecked_rem" => (1, vec![param(0), param(0)], param(0)), @@ -441,7 +441,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>( match *expected { Void => match t.sty { - ty::TyTuple(ref v, _) if v.is_empty() => {}, + ty::TyTuple(ref v) if v.is_empty() => {}, _ => simple_error(&format!("`{}`", t), "()"), }, // (The width we pass to LLVM doesn't concern the type checker.) @@ -515,7 +515,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>( } Aggregate(_flatten, ref expected_contents) => { match t.sty { - ty::TyTuple(contents, _) => { + ty::TyTuple(contents) => { if contents.len() != expected_contents.len() { simple_error(&format!("tuple with length {}", contents.len()), &format!("tuple with length {}", expected_contents.len())); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 48591998a1f..ec6383bf9a5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2160,8 +2160,7 @@ 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 ! or () (depending on whether - // feature(never_type) is enabled), unconstrained ints with i32, + // Non-numerics get replaced with !, 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. @@ -2174,7 +2173,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.mk_diverging_default(), + Neither if self.type_var_diverges(ty) => self.tcx.types.never, Neither => return }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); @@ -2438,7 +2437,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, - TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)], + TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])], }; self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr, @@ -2531,16 +2530,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let formal_tys = if tuple_arguments == TupleArguments { let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]); match tuple_type.sty { - ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => { + ty::TyTuple(arg_types) if arg_types.len() != args.len() => { parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(), "E0057", false, def_span, false); expected_arg_tys = &[]; self.err_args(args.len()) } - ty::TyTuple(arg_types, _) => { + ty::TyTuple(arg_types) => { expected_arg_tys = match expected_arg_tys.get(0) { Some(&ty) => match ty.sty { - ty::TyTuple(ref tys, _) => &tys, + ty::TyTuple(ref tys) => &tys, _ => &[] }, None => &[] @@ -3193,7 +3192,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None } } - ty::TyTuple(ref v, _) => { + ty::TyTuple(ref v) => { tuple_like = true; v.get(idx.node).cloned() } @@ -4060,7 +4059,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let flds = expected.only_has_type(self).and_then(|ty| { let ty = self.resolve_type_vars_with_obligations(ty); match ty.sty { - ty::TyTuple(ref flds, _) => Some(&flds[..]), + ty::TyTuple(ref flds) => Some(&flds[..]), _ => None } }); @@ -4078,7 +4077,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; t }); - let tuple = tcx.mk_tup(elt_ts_iter, false); + let tuple = tcx.mk_tup(elt_ts_iter); if tuple.references_error() { tcx.types.err } else { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 2a4e92034de..a24e501aba9 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_mt(current, mt, variance); } - ty::TyTuple(subtys, _) => { + ty::TyTuple(subtys) => { for &subty in subtys { self.add_constraints_from_ty(current, subty, variance); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ff281a53ab7..904c24815cb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1322,7 +1322,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option, has_self: boo Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => { assert_eq!(types.len(), 1); let inputs = match types[0].sty { - ty::TyTuple(ref tys, _) => tys.iter().map(|t| t.clean(cx)).collect(), + ty::TyTuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(), _ => { return PathParameters::AngleBracketed { lifetimes, @@ -1334,7 +1334,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option, has_self: boo let output = None; // FIXME(#20299) return type comes from a projection now // match types[1].sty { - // ty::TyTuple(ref v, _) if v.is_empty() => None, // -> () + // ty::TyTuple(ref v) if v.is_empty() => None, // -> () // _ => Some(types[1].clean(cx)) // }; PathParameters::Parenthesized { @@ -1377,7 +1377,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { // collect any late bound regions let mut late_bounds = vec![]; for ty_s in self.input_types().skip(1) { - if let ty::TyTuple(ts, _) = ty_s.sty { + if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { if let &ty::RegionKind::ReLateBound(..) = *reg { @@ -2731,7 +2731,7 @@ impl<'tcx> Clean for Ty<'tcx> { Never } } - ty::TyTuple(ref t, _) => Tuple(t.clean(cx)), + ty::TyTuple(ref t) => Tuple(t.clean(cx)), ty::TyProjection(ref data) => data.clean(cx), diff --git a/src/test/compile-fail/defaulted-unit-warning.rs b/src/test/compile-fail/defaulted-unit-warning.rs deleted file mode 100644 index 3f4e1cce548..00000000000 --- a/src/test/compile-fail/defaulted-unit-warning.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2016 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. - -#![allow(unused)] - -trait Deserialize: Sized { - fn deserialize() -> Result; -} - -impl Deserialize for () { - fn deserialize() -> Result<(), String> { - Ok(()) - } -} - -trait ImplementedForUnitButNotNever {} - -impl ImplementedForUnitButNotNever for () {} - -fn foo(_t: T) {} - -fn smeg() { - let _x = return; - foo(_x); - //~^ ERROR code relies on type - //~| WARNING previously accepted -} - -fn main() { - smeg(); -} 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 75b60aa8d10..052575de4c2 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 7924ab74444..c22a645385a 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 From a9fc3901b07d0494bd3eb9c37b10e63b429714b0 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 16:44:41 +0800 Subject: [PATCH 02/14] stabilise feature(never_type) Replace feature(never_type) with feature(exhaustive_patterns). feature(exhaustive_patterns) only covers the pattern-exhaustives checks that used to be covered by feature(never_type) --- src/libcore/cmp.rs | 8 +++--- src/libcore/fmt/mod.rs | 4 +-- src/libcore/lib.rs | 3 +- src/librustc/lib.rs | 2 +- src/librustc_lint/lib.rs | 1 + src/librustc_mir/build/matches/simplify.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 6 ++-- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_mir/lib.rs | 3 +- src/librustc_typeck/lib.rs | 3 +- src/libstd/error.rs | 2 +- src/libstd/lib.rs | 3 +- src/libstd/primitive_docs.rs | 11 ++++---- src/libsyntax/feature_gate.rs | 8 ++---- .../call-fn-never-arg-wrong-type.rs | 2 -- src/test/compile-fail/coerce-to-bang-cast.rs | 2 -- src/test/compile-fail/coerce-to-bang.rs | 1 - .../inhabitedness-infinite-loop.rs | 2 +- src/test/compile-fail/loop-break-value.rs | 2 -- .../compile-fail/match-privately-empty.rs | 2 +- .../compile-fail/never-assign-dead-code.rs | 2 +- .../compile-fail/never-assign-wrong-type.rs | 1 - .../recursive-types-are-not-uninhabited.rs | 2 -- .../compile-fail/uninhabited-irrefutable.rs | 2 +- src/test/compile-fail/uninhabited-patterns.rs | 2 +- .../compile-fail/unreachable-loop-patterns.rs | 2 +- .../compile-fail/unreachable-try-pattern.rs | 2 +- src/test/run-fail/adjust_never.rs | 2 -- src/test/run-fail/call-fn-never-arg.rs | 1 - src/test/run-fail/cast-never.rs | 2 -- src/test/run-fail/never-associated-type.rs | 2 -- src/test/run-fail/never-type-arg.rs | 2 -- .../diverging-fallback-control-flow.rs | 2 -- src/test/run-pass/empty-types-in-patterns.rs | 2 +- src/test/run-pass/impl-for-never.rs | 2 -- src/test/run-pass/issue-44402.rs | 2 +- src/test/run-pass/loop-break-value.rs | 2 -- src/test/run-pass/mir_calls_to_shims.rs | 1 - src/test/run-pass/never-result.rs | 2 -- .../feature-gate-exhaustive-patterns.rs} | 23 ++++++--------- .../feature-gate-exhaustive-patterns.stderr | 8 ++++++ src/test/ui/feature-gate-never_type.rs | 28 ------------------- src/test/ui/print_type_sizes/uninhabited.rs | 1 - src/test/ui/reachable/expr_add.rs | 1 - src/test/ui/reachable/expr_add.stderr | 4 +-- src/test/ui/reachable/expr_array.rs | 3 +- src/test/ui/reachable/expr_array.stderr | 4 +-- src/test/ui/reachable/expr_assign.rs | 1 - src/test/ui/reachable/expr_assign.stderr | 6 ++-- src/test/ui/reachable/expr_block.rs | 1 - src/test/ui/reachable/expr_block.stderr | 4 +-- src/test/ui/reachable/expr_call.rs | 1 - src/test/ui/reachable/expr_call.stderr | 4 +-- src/test/ui/reachable/expr_cast.rs | 1 - src/test/ui/reachable/expr_cast.stderr | 2 +- src/test/ui/reachable/expr_if.rs | 1 - src/test/ui/reachable/expr_if.stderr | 2 +- src/test/ui/reachable/expr_loop.rs | 1 - src/test/ui/reachable/expr_loop.stderr | 6 ++-- src/test/ui/reachable/expr_match.rs | 1 - src/test/ui/reachable/expr_match.stderr | 6 ++-- src/test/ui/reachable/expr_method.rs | 1 - src/test/ui/reachable/expr_method.stderr | 4 +-- src/test/ui/reachable/expr_repeat.rs | 1 - src/test/ui/reachable/expr_repeat.stderr | 2 +- src/test/ui/reachable/expr_return.rs | 1 - src/test/ui/reachable/expr_return.stderr | 2 +- src/test/ui/reachable/expr_struct.rs | 1 - src/test/ui/reachable/expr_struct.stderr | 8 +++--- src/test/ui/reachable/expr_tup.rs | 1 - src/test/ui/reachable/expr_tup.stderr | 4 +-- src/test/ui/reachable/expr_type.rs | 1 - src/test/ui/reachable/expr_type.stderr | 2 +- src/test/ui/reachable/expr_unary.rs | 1 - src/test/ui/reachable/expr_unary.stderr | 6 ++-- src/test/ui/reachable/expr_while.rs | 1 - src/test/ui/reachable/expr_while.stderr | 6 ++-- 77 files changed, 91 insertions(+), 164 deletions(-) rename src/test/{run-pass/issue-38972.rs => ui/feature-gate-exhaustive-patterns.rs} (54%) create mode 100644 src/test/ui/feature-gate-exhaustive-patterns.stderr delete mode 100644 src/test/ui/feature-gate-never_type.rs diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 6602643dc51..fdb9946469b 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 } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl Eq for ! {} - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 213b317f632..3706da7c521 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index cefcc5ff03f..a947c9f0b7c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -85,7 +85,7 @@ #![feature(iterator_repeat_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(no_core)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] @@ -103,6 +103,7 @@ #![feature(unwind_attributes)] #![cfg_attr(stage0, allow(unused_attributes))] +#![cfg_attr(stage0, feature(never_type))] #[prelude_import] #[allow(unused)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 77b3a87c0ed..51882385b2e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -60,7 +60,7 @@ #![feature(match_default_bindings)] #![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(non_exhaustive)] #![feature(nonzero)] #![feature(proc_macro_internals)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 235d733b253..cbc1d7c38d6 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -32,6 +32,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] +#![cfg_attr(stage0, feature(never_type))] #[macro_use] extern crate syntax; diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index abea5583546..4e95ee6444d 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -113,7 +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/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 58aa9b06c64..6f8b1f8e799 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -219,7 +219,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { - if self.tcx.features().never_type { + if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(self.module, ty) } else { false @@ -245,7 +245,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { substs: &'tcx ty::subst::Substs<'tcx>) -> bool { - if self.tcx.features().never_type { + if self.tcx.features().exhaustive_patterns { self.tcx.is_enum_variant_uninhabited_from(self.module, variant, substs) } else { false @@ -694,7 +694,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, // test for details. // // FIXME: currently the only way I know of something can - // be a privately-empty enum is when the never_type + // be a privately-empty enum is when the exhaustive_patterns // feature flag is not present, so this is only // needed for that case. diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 69ed4e6064f..d924baaf005 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -222,7 +222,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { let pat_ty = self.tables.node_id_to_type(scrut.hir_id); let module = self.tcx.hir.get_module_parent(scrut.id); if inlined_arms.is_empty() { - let scrutinee_is_uninhabited = if self.tcx.features().never_type { + let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(module, pat_ty) } else { self.conservative_is_uninhabited(pat_ty) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index c31e95fd826..5510e219780 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -32,13 +32,14 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(inclusive_range)] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(placement_in_syntax)] #![feature(collection_placement)] #![feature(nonzero)] #![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(never_type))] extern crate arena; #[macro_use] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ea90c35cb8f..a97c6e84eab 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -80,13 +80,14 @@ This API is completely unstable and subject to change. #![feature(crate_visibility_modifier)] #![feature(from_ref)] #![feature(match_default_bindings)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(option_filter)] #![feature(quote)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] #![feature(i128_type)] +#![cfg_attr(stage0, 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 eb5022ad577..347b8224410 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Error for ! { fn description(&self) -> &str { *self } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index da15941374d..eea0e6b6752 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -282,7 +282,7 @@ #![feature(macro_reexport)] #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] @@ -324,6 +324,7 @@ #![feature(doc_spotlight)] #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(used))] +#![cfg_attr(stage0, feature(never_type))] #![default_lib_allocator] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 358aa2c37df..e6e6be2e453 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -79,7 +79,6 @@ mod prim_bool { } /// write: /// /// ``` -/// #![feature(never_type)] /// # fn foo() -> u32 { /// let x: ! = { /// return 123 @@ -131,13 +130,15 @@ mod prim_bool { } /// [`Result`] which we can unpack like this: /// /// ```ignore (string-from-str-error-type-is-not-never-yet) +/// #[feature(exhaustive_patterns)] /// // NOTE: This does not work today! /// let Ok(s) = String::from_str("hello"); /// ``` /// -/// Since the [`Err`] variant contains a `!`, it can never occur. So we can exhaustively match on -/// [`Result`] by just taking the [`Ok`] variant. This illustrates another behaviour of `!` - -/// it can be used to "delete" certain enum variants from generic types like `Result`. +/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` +/// feature is present this means we can exhaustively match on [`Result`] by just taking the +/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain +/// enum variants from generic types like `Result`. /// /// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str /// [`Result`]: result/enum.Result.html @@ -154,7 +155,6 @@ mod prim_bool { } /// for example: /// /// ``` -/// # #![feature(never_type)] /// # use std::fmt; /// # trait Debug { /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; @@ -192,7 +192,6 @@ mod prim_bool { } /// [`Default`]: default/trait.Default.html /// [`default()`]: default/trait.Default.html#tymethod.default /// -#[unstable(feature = "never_type", issue = "35121")] mod prim_never { } #[doc(primitive = "char")] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ec9a15d9f2b..91364fe6ed4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -286,8 +286,8 @@ declare_features! ( // Allows `impl Trait` in function arguments. (active, universal_impl_trait, "1.23.0", Some(34511), None), - // The `!` type - (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), // Allows all literals in attribute lists and values of key-value pairs. (active, attr_literals, "1.13.0", Some(34981), None), @@ -1566,10 +1566,6 @@ 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 583befed1e8..c2f157cd35c 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,8 +10,6 @@ // 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 0d5bf6cd68c..8b3a9ed092d 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -8,8 +8,6 @@ // 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) { } #[deny(coerce_never)] diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index b804bb2981b..b365f142a9b 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] #![deny(coerce_never)] fn foo(x: usize, y: !, z: usize) { } diff --git a/src/test/compile-fail/inhabitedness-infinite-loop.rs b/src/test/compile-fail/inhabitedness-infinite-loop.rs index 91b85d7510a..b9741e0add6 100644 --- a/src/test/compile-fail/inhabitedness-infinite-loop.rs +++ b/src/test/compile-fail/inhabitedness-infinite-loop.rs @@ -10,7 +10,7 @@ // error-pattern:reached recursion limit -#![feature(never_type)] +#![feature(exhaustive_patterns)] struct Foo<'a, T: 'a> { ph: std::marker::PhantomData, diff --git a/src/test/compile-fail/loop-break-value.rs b/src/test/compile-fail/loop-break-value.rs index 938f7fba2a0..5ef46bb27fd 100644 --- a/src/test/compile-fail/loop-break-value.rs +++ b/src/test/compile-fail/loop-break-value.rs @@ -8,8 +8,6 @@ // 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 3affb1c03e9..e18c7d77ce3 100644 --- a/src/test/compile-fail/match-privately-empty.rs +++ b/src/test/compile-fail/match-privately-empty.rs @@ -8,7 +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 { pub struct Private { diff --git a/src/test/compile-fail/never-assign-dead-code.rs b/src/test/compile-fail/never-assign-dead-code.rs index 1e0cc0f5357..4e987d1ddce 100644 --- a/src/test/compile-fail/never-assign-dead-code.rs +++ b/src/test/compile-fail/never-assign-dead-code.rs @@ -10,7 +10,7 @@ // Test that an assignment of type ! makes the rest of the block dead code. -#![feature(never_type, rustc_attrs)] +#![feature(rustc_attrs)] #![warn(unused)] #[rustc_error] diff --git a/src/test/compile-fail/never-assign-wrong-type.rs b/src/test/compile-fail/never-assign-wrong-type.rs index c0dd2cab749..8c2de7d68d3 100644 --- a/src/test/compile-fail/never-assign-wrong-type.rs +++ b/src/test/compile-fail/never-assign-wrong-type.rs @@ -10,7 +10,6 @@ // 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/recursive-types-are-not-uninhabited.rs b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs index f8d6c3de2ab..fa936697072 100644 --- a/src/test/compile-fail/recursive-types-are-not-uninhabited.rs +++ b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//#![feature(never_type)] - struct R<'a> { r: &'a R<'a>, } diff --git a/src/test/compile-fail/uninhabited-irrefutable.rs b/src/test/compile-fail/uninhabited-irrefutable.rs index 4755fdd4fd5..72b0afa6bd3 100644 --- a/src/test/compile-fail/uninhabited-irrefutable.rs +++ b/src/test/compile-fail/uninhabited-irrefutable.rs @@ -8,7 +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 { pub struct SecretlyEmpty { diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs index 4c894b0bdd3..9f943f08232 100644 --- a/src/test/compile-fail/uninhabited-patterns.rs +++ b/src/test/compile-fail/uninhabited-patterns.rs @@ -11,7 +11,7 @@ #![feature(box_patterns)] #![feature(slice_patterns)] #![feature(box_syntax)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![deny(unreachable_patterns)] mod foo { diff --git a/src/test/compile-fail/unreachable-loop-patterns.rs b/src/test/compile-fail/unreachable-loop-patterns.rs index 6147692658f..dca79bdfb87 100644 --- a/src/test/compile-fail/unreachable-loop-patterns.rs +++ b/src/test/compile-fail/unreachable-loop-patterns.rs @@ -8,7 +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)] fn main() { diff --git a/src/test/compile-fail/unreachable-try-pattern.rs b/src/test/compile-fail/unreachable-try-pattern.rs index 46ea4a06a3b..0caf7d51234 100644 --- a/src/test/compile-fail/unreachable-try-pattern.rs +++ b/src/test/compile-fail/unreachable-try-pattern.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type, rustc_attrs)] +#![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 ccdb1ca15bb..7a4b5e59eeb 100644 --- a/src/test/run-fail/adjust_never.rs +++ b/src/test/run-fail/adjust_never.rs @@ -10,8 +10,6 @@ // Test that a variable of type ! can coerce to another type. -#![feature(never_type)] - // error-pattern:explicit fn main() { let x: ! = panic!(); diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs index 95101e70db9..56454586bb9 100644 --- a/src/test/run-fail/call-fn-never-arg.rs +++ b/src/test/run-fail/call-fn-never-arg.rs @@ -12,7 +12,6 @@ // 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 acd002494f4..0155332c51d 100644 --- a/src/test/run-fail/cast-never.rs +++ b/src/test/run-fail/cast-never.rs @@ -10,8 +10,6 @@ // Test that we can explicitly cast ! to another type -#![feature(never_type)] - // error-pattern:explicit fn main() { let x: ! = panic!(); diff --git a/src/test/run-fail/never-associated-type.rs b/src/test/run-fail/never-associated-type.rs index 345674f3f52..d9b8461a1d0 100644 --- a/src/test/run-fail/never-associated-type.rs +++ b/src/test/run-fail/never-associated-type.rs @@ -10,8 +10,6 @@ // Test that we can use ! as an associated type. -#![feature(never_type)] - // error-pattern:kapow! trait Foo { diff --git a/src/test/run-fail/never-type-arg.rs b/src/test/run-fail/never-type-arg.rs index 826ca3a08c0..0fe10d43910 100644 --- a/src/test/run-fail/never-type-arg.rs +++ b/src/test/run-fail/never-type-arg.rs @@ -12,8 +12,6 @@ // 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 723a98bcdfa..a96f98b9efd 100644 --- a/src/test/run-pass/diverging-fallback-control-flow.rs +++ b/src/test/run-pass/diverging-fallback-control-flow.rs @@ -14,8 +14,6 @@ // 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 033b185a0ef..87db4401929 100644 --- a/src/test/run-pass/empty-types-in-patterns.rs +++ b/src/test/run-pass/empty-types-in-patterns.rs @@ -8,7 +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)] #![allow(unreachable_code)] diff --git a/src/test/run-pass/impl-for-never.rs b/src/test/run-pass/impl-for-never.rs index 794f5969bff..cf54e1c3bd5 100644 --- a/src/test/run-pass/impl-for-never.rs +++ b/src/test/run-pass/impl-for-never.rs @@ -10,8 +10,6 @@ // 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 244aa65a3d5..a5a0a5a5794 100644 --- a/src/test/run-pass/issue-44402.rs +++ b/src/test/run-pass/issue-44402.rs @@ -8,7 +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 // cache used to cause us to incorrectly decide diff --git a/src/test/run-pass/loop-break-value.rs b/src/test/run-pass/loop-break-value.rs index 39053769b24..ffdd99ebf6e 100644 --- a/src/test/run-pass/loop-break-value.rs +++ b/src/test/run-pass/loop-break-value.rs @@ -8,8 +8,6 @@ // 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 9641ed28293..dda7a46f325 100644 --- a/src/test/run-pass/mir_calls_to_shims.rs +++ b/src/test/run-pass/mir_calls_to_shims.rs @@ -11,7 +11,6 @@ // 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 5c0af392f44..8aa2a13ed8c 100644 --- a/src/test/run-pass/never-result.rs +++ b/src/test/run-pass/never-result.rs @@ -10,8 +10,6 @@ // 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/issue-38972.rs b/src/test/ui/feature-gate-exhaustive-patterns.rs similarity index 54% rename from src/test/run-pass/issue-38972.rs rename to src/test/ui/feature-gate-exhaustive-patterns.rs index d5df84e0fb0..477dd1b38eb 100644 --- a/src/test/run-pass/issue-38972.rs +++ b/src/test/ui/feature-gate-exhaustive-patterns.rs @@ -1,4 +1,4 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,18 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// This issue tracks a regression (a new warning) without -// feature(never_type). When we make that the default, please -// remove this test. - -enum Foo { } - -fn make_foo() -> Option { None } - -#[deny(warnings)] -fn main() { - match make_foo() { - None => {}, - Some(_) => {} - } +fn foo() -> Result { + Ok(123) } + +fn main() { + let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding +} + diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr new file mode 100644 index 00000000000..43a4adf9373 --- /dev/null +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -0,0 +1,8 @@ +error[E0005]: refutable pattern in local binding: `Err(_)` not covered + --> $DIR/feature-gate-exhaustive-patterns.rs:16:9 + | +16 | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding + | ^^^^^^ pattern `Err(_)` not covered + +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-never_type.rs b/src/test/ui/feature-gate-never_type.rs deleted file mode 100644 index 11b9f412957..00000000000 --- a/src/test/ui/feature-gate-never_type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index 4d0396903e5..7e8eff02c20 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -11,7 +11,6 @@ // 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 dd43c58de6d..3e39b75d8c0 100644 --- a/src/test/ui/reachable/expr_add.rs +++ b/src/test/ui/reachable/expr_add.rs @@ -8,7 +8,6 @@ // 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_add.stderr b/src/test/ui/reachable/expr_add.stderr index d3e1da0e718..f49a781ce33 100644 --- a/src/test/ui/reachable/expr_add.stderr +++ b/src/test/ui/reachable/expr_add.stderr @@ -1,11 +1,11 @@ error: unreachable expression - --> $DIR/expr_add.rs:27:13 + --> $DIR/expr_add.rs:26:13 | LL | let x = Foo + return; //~ ERROR unreachable | ^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/expr_add.rs:13:9 + --> $DIR/expr_add.rs:12:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs index 31229668796..323a5752e22 100644 --- a/src/test/ui/reachable/expr_array.rs +++ b/src/test/ui/reachable/expr_array.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { @@ -21,7 +20,7 @@ fn a() { } fn b() { - // the `array is unreachable: + // the array is unreachable: let x: [usize; 2] = [22, return]; //~ ERROR unreachable } diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr index 3257514ea50..78ac76a6137 100644 --- a/src/test/ui/reachable/expr_array.stderr +++ b/src/test/ui/reachable/expr_array.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_array.rs:20:34 + --> $DIR/expr_array.rs:19:34 | LL | let x: [usize; 2] = [return, 22]; //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_array.rs:25:25 + --> $DIR/expr_array.rs:24:25 | LL | let x: [usize; 2] = [22, return]; //~ ERROR unreachable | ^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs index e6fb46a5bac..73083af34d9 100644 --- a/src/test/ui/reachable/expr_assign.rs +++ b/src/test/ui/reachable/expr_assign.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { // No error here. diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr index 15dcf2c2401..628bfbf6217 100644 --- a/src/test/ui/reachable/expr_assign.stderr +++ b/src/test/ui/reachable/expr_assign.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_assign.rs:20:5 + --> $DIR/expr_assign.rs:19:5 | LL | x = return; //~ ERROR unreachable | ^^^^^^^^^^ @@ -11,13 +11,13 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_assign.rs:30:14 + --> $DIR/expr_assign.rs:29:14 | LL | *p = return; //~ ERROR unreachable | ^^^^^^ error: unreachable expression - --> $DIR/expr_assign.rs:36:15 + --> $DIR/expr_assign.rs:35:15 | LL | *{return; &mut i} = 22; //~ ERROR unreachable | ^^^^^^ diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs index 57b5d3cabce..93bce43f76d 100644 --- a/src/test/ui/reachable/expr_block.rs +++ b/src/test/ui/reachable/expr_block.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { // Here the tail expression is considered unreachable: diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index a0cef6449f7..5f5696aadb3 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_block.rs:21:9 + --> $DIR/expr_block.rs:20:9 | LL | 22 //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable statement - --> $DIR/expr_block.rs:36:9 + --> $DIR/expr_block.rs:35:9 | LL | println!("foo"); | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs index 86b95aad9c2..2772dd429d1 100644 --- a/src/test/ui/reachable/expr_call.rs +++ b/src/test/ui/reachable/expr_call.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo(x: !, y: usize) { } diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr index 455e5ab3653..414d29ec2a7 100644 --- a/src/test/ui/reachable/expr_call.stderr +++ b/src/test/ui/reachable/expr_call.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_call.rs:23:17 + --> $DIR/expr_call.rs:22:17 | LL | foo(return, 22); //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_call.rs:28:5 + --> $DIR/expr_call.rs:27:5 | LL | bar(return); //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs index 76b00c00ad9..88846b63841 100644 --- a/src/test/ui/reachable/expr_cast.rs +++ b/src/test/ui/reachable/expr_cast.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr index 8c37759aa46..458334e2af9 100644 --- a/src/test/ui/reachable/expr_cast.stderr +++ b/src/test/ui/reachable/expr_cast.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_cast.rs:20:13 + --> $DIR/expr_cast.rs:19:13 | LL | let x = {return} as !; //~ ERROR unreachable | ^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs index 2a265e772f3..d2fb1044e48 100644 --- a/src/test/ui/reachable/expr_if.rs +++ b/src/test/ui/reachable/expr_if.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { if {return} { diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index c14cdbfc2bc..6e8afd1c5be 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_if.rs:38:5 + --> $DIR/expr_if.rs:37:5 | LL | println!("But I am."); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs index 3ed4b2dcf0c..533cdac0968 100644 --- a/src/test/ui/reachable/expr_loop.rs +++ b/src/test/ui/reachable/expr_loop.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { loop { return; } diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index 7f834567de3..a51ef293acf 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_loop.rs:19:5 + --> $DIR/expr_loop.rs:18:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)] = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_loop.rs:31:5 + --> $DIR/expr_loop.rs:30:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | println!("I am dead."); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_loop.rs:41:5 + --> $DIR/expr_loop.rs:40:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs index d2b96e51a95..193edd77435 100644 --- a/src/test/ui/reachable/expr_match.rs +++ b/src/test/ui/reachable/expr_match.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { // The match is considered unreachable here, because the `return` diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index d4cf21cef28..dfc1417f3d2 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_match.rs:20:5 + --> $DIR/expr_match.rs:19:5 | LL | match {return} { } //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable statement - --> $DIR/expr_match.rs:25:5 + --> $DIR/expr_match.rs:24:5 | LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | println!("I am dead"); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_match.rs:35:5 + --> $DIR/expr_match.rs:34:5 | LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs index 8be71e464b2..7dabb307097 100644 --- a/src/test/ui/reachable/expr_method.rs +++ b/src/test/ui/reachable/expr_method.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] struct Foo; diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr index b9348b5d481..6d67bfcd54a 100644 --- a/src/test/ui/reachable/expr_method.stderr +++ b/src/test/ui/reachable/expr_method.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_method.rs:26:21 + --> $DIR/expr_method.rs:25:21 | LL | Foo.foo(return, 22); //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_method.rs:31:5 + --> $DIR/expr_method.rs:30:5 | LL | Foo.bar(return); //~ ERROR unreachable | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs index 47ee2ba62b8..fd9fca413a7 100644 --- a/src/test/ui/reachable/expr_repeat.rs +++ b/src/test/ui/reachable/expr_repeat.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr index 90cc3183c72..36393de90b7 100644 --- a/src/test/ui/reachable/expr_repeat.stderr +++ b/src/test/ui/reachable/expr_repeat.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_repeat.rs:20:25 + --> $DIR/expr_repeat.rs:19:25 | LL | let x: [usize; 2] = [return; 2]; //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_return.rs b/src/test/ui/reachable/expr_return.rs index fac1116dc68..9bbbe6f9099 100644 --- a/src/test/ui/reachable/expr_return.rs +++ b/src/test/ui/reachable/expr_return.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr index 3876da6541d..2dcc50944c5 100644 --- a/src/test/ui/reachable/expr_return.stderr +++ b/src/test/ui/reachable/expr_return.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_return.rs:21:22 + --> $DIR/expr_return.rs:20:22 | LL | let x = {return {return {return;}}}; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_struct.rs b/src/test/ui/reachable/expr_struct.rs index b5acd395be6..66414f6084b 100644 --- a/src/test/ui/reachable/expr_struct.rs +++ b/src/test/ui/reachable/expr_struct.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] struct Foo { diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr index 43985bbbb5c..3f0ecb20479 100644 --- a/src/test/ui/reachable/expr_struct.stderr +++ b/src/test/ui/reachable/expr_struct.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_struct.rs:25:13 + --> $DIR/expr_struct.rs:24:13 | LL | let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,19 +11,19 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_struct.rs:30:33 + --> $DIR/expr_struct.rs:29:33 | LL | let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable | ^^ error: unreachable expression - --> $DIR/expr_struct.rs:35:39 + --> $DIR/expr_struct.rs:34:39 | LL | let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable | ^^^^^^ error: unreachable expression - --> $DIR/expr_struct.rs:40:13 + --> $DIR/expr_struct.rs:39:13 | LL | let x = Foo { a: 22, b: return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_tup.rs b/src/test/ui/reachable/expr_tup.rs index 089020bf385..e2c10090248 100644 --- a/src/test/ui/reachable/expr_tup.rs +++ b/src/test/ui/reachable/expr_tup.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr index ff9aa666d8e..d372373ced0 100644 --- a/src/test/ui/reachable/expr_tup.stderr +++ b/src/test/ui/reachable/expr_tup.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_tup.rs:20:38 + --> $DIR/expr_tup.rs:19:38 | LL | let x: (usize, usize) = (return, 2); //~ ERROR unreachable | ^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_tup.rs:25:29 + --> $DIR/expr_tup.rs:24:29 | LL | let x: (usize, usize) = (2, return); //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs index 29c59d5304f..2381ea2ac7a 100644 --- a/src/test/ui/reachable/expr_type.rs +++ b/src/test/ui/reachable/expr_type.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr index d6b9f75edf1..9b165d6b3ee 100644 --- a/src/test/ui/reachable/expr_type.stderr +++ b/src/test/ui/reachable/expr_type.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_type.rs:20:13 + --> $DIR/expr_type.rs:19:13 | LL | let x = {return}: !; //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index ad12cb876fe..524784934c7 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -13,7 +13,6 @@ #![allow(dead_code)] #![deny(unreachable_code)] #![deny(coerce_never)] -#![feature(never_type)] fn foo() { let x: ! = ! { return; 22 }; //~ ERROR unreachable diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index b09721e5957..1239701cabd 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_unary.rs:19:28 + --> $DIR/expr_unary.rs:18:28 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: cannot coerce `{integer}` to ! - --> $DIR/expr_unary.rs:19:28 + --> $DIR/expr_unary.rs:18:28 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ @@ -25,7 +25,7 @@ LL | #![deny(coerce_never)] = note: for more information, see issue #46325 error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:19:16 + --> $DIR/expr_unary.rs:18:16 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs index 7dcd609fbc8..79fa69a9289 100644 --- a/src/test/ui/reachable/expr_while.rs +++ b/src/test/ui/reachable/expr_while.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { while {return} { diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr index cd093906615..90c35bfaa7a 100644 --- a/src/test/ui/reachable/expr_while.stderr +++ b/src/test/ui/reachable/expr_while.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_while.rs:19:9 + --> $DIR/expr_while.rs:18:9 | LL | println!("Hello, world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)] = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_while.rs:33:9 + --> $DIR/expr_while.rs:32:9 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | println!("I am dead."); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_while.rs:35:5 + --> $DIR/expr_while.rs:34:5 | LL | println!("I am, too."); | ^^^^^^^^^^^^^^^^^^^^^^^ From 32ddb30715f73498477262c992d1152cf10ca631 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 18:30:04 +0800 Subject: [PATCH 03/14] Fix version number --- src/libcore/cmp.rs | 8 ++++---- src/libcore/fmt/mod.rs | 4 ++-- src/libstd/error.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index fdb9946469b..3923b652afc 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.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl Eq for ! {} - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3706da7c521..40b88ded27d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 347b8224410..1743dfbfb7b 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Error for ! { fn description(&self) -> &str { *self } } From 59688e119e1b9c2506fa9173728ae88eb196bf5e Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Feb 2018 15:23:04 +0800 Subject: [PATCH 04/14] Make coerce_never lint an error Remove the coerce_never lint and make the behaviour an error. --- src/librustc/lint/builtin.rs | 7 ---- src/librustc_lint/lib.rs | 5 --- src/librustc_typeck/check/cast.rs | 8 ++--- src/librustc_typeck/check/coercion.rs | 19 +--------- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/mod.rs | 3 +- src/test/compile-fail/coerce-to-bang-cast.rs | 4 +-- src/test/compile-fail/coerce-to-bang.rs | 14 ++------ .../compile-fail/diverging-fn-tail-35849.rs | 4 +-- src/test/run-pass/diverging-fn-tail-35849.rs | 18 ---------- src/test/ui/reachable/expr_unary.rs | 5 +-- src/test/ui/reachable/expr_unary.stderr | 36 ++++++------------- 12 files changed, 22 insertions(+), 103 deletions(-) delete mode 100644 src/test/run-pass/diverging-fn-tail-35849.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1795866e103..b4ed9c269bd 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -230,12 +230,6 @@ declare_lint! { "detect mut variables which don't need to be mutable" } -declare_lint! { - pub COERCE_NEVER, - Deny, - "detect coercion to !" -} - declare_lint! { pub SINGLE_USE_LIFETIME, Allow, @@ -310,7 +304,6 @@ impl LintPass for HardwiredLints { DEPRECATED, UNUSED_UNSAFE, UNUSED_MUT, - COERCE_NEVER, SINGLE_USE_LIFETIME, TYVAR_BEHIND_RAW_POINTER, ELIDED_LIFETIME_IN_PATH, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index cbc1d7c38d6..010678ecfb5 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -270,11 +270,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #46205 ", epoch: None, }, - FutureIncompatibleInfo { - id: LintId::of(COERCE_NEVER), - reference: "issue #46325 ", - epoch: None, - }, FutureIncompatibleInfo { id: LintId::of(TYVAR_BEHIND_RAW_POINTER), reference: "issue #46906 ", diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index c2c113f2da9..e4bad8349ea 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -38,7 +38,7 @@ //! expression, `e as U2` is not necessarily so (in fact it will only be valid if //! `U1` coerces to `U2`). -use super::{Diverges, FnCtxt}; +use super::FnCtxt; use errors::DiagnosticBuilder; use hir::def_id::DefId; @@ -59,7 +59,6 @@ use util::common::ErrorReported; pub struct CastCheck<'tcx> { expr: &'tcx hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, cast_ty: Ty<'tcx>, cast_span: Span, span: Span, @@ -183,7 +182,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, cast_ty: Ty<'tcx>, cast_span: Span, span: Span) @@ -191,7 +189,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let check = CastCheck { expr, expr_ty, - expr_diverges, cast_ty, cast_span, span, @@ -437,7 +434,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let f = self.expr_ty.fn_sig(fcx.tcx); let res = fcx.try_coerce(self.expr, self.expr_ty, - self.expr_diverges, fcx.tcx.mk_fn_ptr(f)); if !res.is_ok() { return Err(CastError::NonScalar); @@ -620,7 +616,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.expr_diverges, self.cast_ty).is_ok() + fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok() } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index abb0acd699c..144ca37f2c6 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -66,7 +66,6 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer::{Coercion, InferResult, InferOk}; use rustc::infer::type_variable::TypeVariableOrigin; -use rustc::lint; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability}; use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts}; @@ -752,27 +751,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn try_coerce(&self, expr: &hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, target: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { let source = self.resolve_type_vars_with_obligations(expr_ty); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); - // Special-ish case: we can coerce any type `T` into the `!` - // type, but only if the source expression diverges. - if target.is_never() && expr_diverges.always() { - debug!("permit coercion to `!` because expr diverges"); - if self.can_eq(self.param_env, source, target).is_err() { - self.tcx.lint_node( - lint::builtin::COERCE_NEVER, - expr.id, - expr.span, - &format!("cannot coerce `{}` to !", source) - ); - return Ok(target); - } - } - let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable); let coerce = Coerce::new(self, cause); let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?; @@ -1123,7 +1106,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> if self.pushed == 0 { // Special-case the first expression we are coercing. // To be honest, I'm not entirely sure why we do this. - fcx.try_coerce(expression, expression_ty, expression_diverges, self.expected_ty) + fcx.try_coerce(expression, expression_ty, self.expected_ty) } else { match self.expressions { Expressions::Dynamic(ref exprs) => diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index d2702d0810e..634a7ee5699 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { -> (Ty<'tcx>, Option>) { let expected = self.resolve_type_vars_with_obligations(expected); - let e = match self.try_coerce(expr, checked_ty, self.diverges.get(), expected) { + let e = match self.try_coerce(expr, checked_ty, expected) { Ok(ty) => return (ty, None), Err(e) => e }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ec6383bf9a5..80d95ea86e4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3944,7 +3944,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let t_cast = self.resolve_type_vars_if_possible(&t_cast); let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast)); let t_cast = self.resolve_type_vars_if_possible(&t_cast); - let diverges = self.diverges.get(); // Eagerly check for some obvious errors. if t_expr.references_error() || t_cast.references_error() { @@ -3952,7 +3951,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); - match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) { + match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) { Ok(cast_check) => { deferred_cast_checks.push(cast_check); t_cast diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs index 8b3a9ed092d..5efb4dadc64 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -10,11 +10,9 @@ fn foo(x: usize, y: !, z: usize) { } -#[deny(coerce_never)] fn cast_a() { let y = {return; 22} as !; - //~^ ERROR cannot coerce `i32` to ! - //~| hard error + //~^ ERROR non-primitive cast } fn cast_b() { diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index b365f142a9b..15049232a4d 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -8,17 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(coerce_never)] - fn foo(x: usize, y: !, z: usize) { } fn call_foo_a() { - // FIXME(#40800) -- accepted because divergence happens **before** - // the coercion to `!`, but within same expression. Not clear that - // these are the rules we want. foo(return, 22, 44); - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn call_foo_b() { @@ -38,8 +32,7 @@ fn call_foo_d() { let b = 22; let c = 44; foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn call_foo_e() { @@ -79,8 +72,7 @@ fn tuple_a() { fn tuple_b() { // Divergence happens before coercion: OK let x: (usize, !, usize) = (return, 44, 66); - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn tuple_c() { diff --git a/src/test/compile-fail/diverging-fn-tail-35849.rs b/src/test/compile-fail/diverging-fn-tail-35849.rs index a91c000bbf7..9ef5159cb77 100644 --- a/src/test/compile-fail/diverging-fn-tail-35849.rs +++ b/src/test/compile-fail/diverging-fn-tail-35849.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deny(coerce_never)] fn assert_sizeof() -> ! { unsafe { ::std::mem::transmute::(panic!()) - //~^ ERROR cannot coerce `[u8; 8]` to ! - //~| hard error + //~^ ERROR mismatched types } } diff --git a/src/test/run-pass/diverging-fn-tail-35849.rs b/src/test/run-pass/diverging-fn-tail-35849.rs deleted file mode 100644 index dfd99bcc9fb..00000000000 --- a/src/test/run-pass/diverging-fn-tail-35849.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 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. - -#[allow(coerce_never)] -fn assert_sizeof() -> ! { - unsafe { - ::std::mem::transmute::(panic!()) - } -} - -fn main() { } diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index 524784934c7..4096865f4c6 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -12,12 +12,9 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![deny(coerce_never)] fn foo() { - let x: ! = ! { return; 22 }; //~ ERROR unreachable - //~^ ERROR cannot coerce - //~| hard error + let x: ! = ! { return; }; //~ ERROR unreachable //~| ERROR cannot apply unary operator `!` to type `!` } diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index 1239701cabd..e39909eee7f 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,8 +1,14 @@ -error: unreachable expression - --> $DIR/expr_unary.rs:18:28 +error[E0600]: cannot apply unary operator `!` to type `!` + --> $DIR/expr_unary.rs:17:16 | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ +17 | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_unary.rs:17:16 + | +LL | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/expr_unary.rs:14:9 @@ -10,26 +16,6 @@ note: lint level defined here LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ -error: cannot coerce `{integer}` to ! - --> $DIR/expr_unary.rs:18:28 - | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ - | -note: lint level defined here - --> $DIR/expr_unary.rs:15:9 - | -LL | #![deny(coerce_never)] - | ^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #46325 - -error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:18:16 - | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0600`. From edb9d2b20dd907903d0cf70194c4c28c8d40c063 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 01:26:51 +0800 Subject: [PATCH 05/14] Fix ui test errors --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 2 +- src/test/ui/reachable/expr_unary.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 43a4adf9373..c11c9da3963 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -1,7 +1,7 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered --> $DIR/feature-gate-exhaustive-patterns.rs:16:9 | -16 | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding +LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index e39909eee7f..165eccd4239 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,7 +1,7 @@ error[E0600]: cannot apply unary operator `!` to type `!` --> $DIR/expr_unary.rs:17:16 | -17 | let x: ! = ! { return; }; //~ ERROR unreachable +LL | let x: ! = ! { return; }; //~ ERROR unreachable | ^^^^^^^^^^^^^ error: unreachable expression From a704624ef5830541acb9912146fa28305b9a920c Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 01:41:10 +0800 Subject: [PATCH 06/14] change never_type stabilisation version --- src/libcore/cmp.rs | 8 ++++---- src/libcore/fmt/mod.rs | 4 ++-- src/libstd/error.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 3923b652afc..67445daa436 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.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl Eq for ! {} - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 40b88ded27d..2456b5b6654 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 1743dfbfb7b..f8dbe193fed 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Error for ! { fn description(&self) -> &str { *self } } From 04cad569159006492f8d3c82bf2a07ced75363db Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 11:41:38 +0800 Subject: [PATCH 07/14] really fix ui test errors --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index c11c9da3963..864c57e033f 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -4,5 +4,4 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered -error: aborting due to previous error From b4f1081af1fa0ef9b579f8a9e469aa9803057c68 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 13:54:20 +0800 Subject: [PATCH 08/14] really fix ui test errors for real --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 864c57e033f..8bf8641ab68 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -4,4 +4,7 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0005" From 5a6b7812665f26e2483075ce2cbde92af822b2e4 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sat, 3 Mar 2018 13:12:50 +0800 Subject: [PATCH 09/14] really actually fix ui test error for real --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 8bf8641ab68..51fdac064ce 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -7,4 +7,3 @@ LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding error: aborting due to previous error If you want more information on this error, try using "rustc --explain E0005" - From 5b32211e620a47b2c14dd313f0c3aa91e78f7361 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Mon, 12 Mar 2018 12:15:06 +0800 Subject: [PATCH 10/14] Add note about fallback to `!: !Trait` error --- src/librustc/infer/outlives/bounds.rs | 2 +- src/librustc/traits/error_reporting.rs | 45 ++++++++++++++++--- src/librustc/traits/mod.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 27 ++++++----- src/librustc_typeck/check/op.rs | 2 +- src/librustc_typeck/coherence/builtin.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/test/compile-fail/defaulted-never-note.rs | 41 +++++++++++++++++ 12 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 src/test/compile-fail/defaulted-never-note.rs diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs index abb35d24d79..8bb3f4158ff 100644 --- a/src/librustc/infer/outlives/bounds.rs +++ b/src/librustc/infer/outlives/bounds.rs @@ -151,7 +151,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { // get solved *here*. match fulfill_cx.select_all_or_error(self) { Ok(()) => (), - Err(errors) => self.report_fulfillment_errors(&errors, None), + Err(errors) => self.report_fulfillment_errors(&errors, None, false), } implied_bounds diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5d994a0e444..b19935b8c4f 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -47,7 +47,8 @@ use syntax_pos::{DUMMY_SP, Span}; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_fulfillment_errors(&self, errors: &Vec>, - body_id: Option) { + body_id: Option, + fallback_has_occurred: bool) { #[derive(Debug)] struct ErrorDescriptor<'tcx> { predicate: ty::Predicate<'tcx>, @@ -107,7 +108,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { for (error, suppressed) in errors.iter().zip(is_suppressed) { if !suppressed { - self.report_fulfillment_error(error, body_id); + self.report_fulfillment_error(error, body_id, fallback_has_occurred); } } } @@ -151,11 +152,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>, - body_id: Option) { + body_id: Option, + fallback_has_occurred: bool) { debug!("report_fulfillment_errors({:?})", error); match error.code { FulfillmentErrorCode::CodeSelectionError(ref e) => { - self.report_selection_error(&error.obligation, e); + self.report_selection_error(&error.obligation, e, fallback_has_occurred); } FulfillmentErrorCode::CodeProjectionError(ref e) => { self.report_projection_error(&error.obligation, e); @@ -533,9 +535,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_selection_error(&self, obligation: &PredicateObligation<'tcx>, - error: &SelectionError<'tcx>) + error: &SelectionError<'tcx>, + fallback_has_occurred: bool) { let span = obligation.cause.span; + let _ = fallback_has_occurred; let mut err = match *error { SelectionError::Unimplemented => { @@ -619,6 +623,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_similar_impl_candidates(impl_candidates, &mut err); } + // If this error is due to `!: !Trait` but `(): Trait` then add a note + // about the fallback behaviour change. + if trait_predicate.skip_binder().self_ty().is_never() { + let predicate = trait_predicate.map_bound(|mut trait_pred| { + { + let trait_ref = &mut trait_pred.trait_ref; + let never_substs = trait_ref.substs; + let mut unit_substs = Vec::with_capacity(never_substs.len()); + unit_substs.push(self.tcx.mk_nil().into()); + unit_substs.extend(&never_substs[1..]); + trait_ref.substs = self.tcx.intern_substs(&unit_substs); + } + trait_pred + }); + let unit_obligation = Obligation { + cause: obligation.cause.clone(), + param_env: obligation.param_env, + recursion_depth: obligation.recursion_depth, + predicate, + }; + let mut selcx = SelectionContext::new(self); + if let Ok(Some(..)) = selcx.select(&unit_obligation) { + err.note("the trait is implemented for `()`. \ + Possibly this error has been caused by changes to \ + Rust's type-inference algorithm \ + (see: https://github.com/rust-lang/rust/issues/48950 \ + for more info). Consider whether you meant to use the \ + type `()` here instead."); + } + } + err } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index a2a5aa246cf..bd8f99780f9 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -580,7 +580,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ) { Ok(predicates) => predicates, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); // An unnormalized env is better than nothing. return elaborated_env; } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 94446a98e63..59a872a23b0 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1246,7 +1246,7 @@ impl MirPass for QualifyAndPromoteConstants { tcx.require_lang_item(lang_items::SyncTraitLangItem), cause); if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&err, None); + infcx.report_fulfillment_errors(&err, None, false); } }); } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 144ca37f2c6..269ee49f38e 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -571,7 +571,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // Object safety violations or miscellaneous. Err(err) => { - self.report_selection_error(&obligation, &err); + self.report_selection_error(&obligation, &err, false); // Treat this like an obligation and follow through // with the unsizing - the lack of a coercion should // be silent, as it causes a type mismatch later. diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index b6459b62410..60ac31ac8eb 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -334,7 +334,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all obligations are satisfied by the implementation's // version. if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return Err(ErrorReported); } @@ -839,7 +839,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all obligations are satisfied by the implementation's // version. if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return; } diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 67c9832cbf9..596381d7ea6 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -112,7 +112,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) { // this could be reached when we get lazy normalization - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return Err(ErrorReported); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 80d95ea86e4..18de8d1bee7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -873,11 +873,12 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; // All type checking constraints were added, try to fallback unsolved variables. - fcx.select_obligations_where_possible(); + fcx.select_obligations_where_possible(false); + let mut fallback_has_occurred = false; for ty in &fcx.unsolved_variables() { - fcx.fallback_if_possible(ty); + fallback_has_occurred |= fcx.fallback_if_possible(ty); } - fcx.select_obligations_where_possible(); + fcx.select_obligations_where_possible(fallback_has_occurred); // Even though coercion casts provide type hints, we check casts after fallback for // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. @@ -1837,7 +1838,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // possible. This can help substantially when there are // indirect dependencies that don't seem worth tracking // precisely. - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); ty = self.resolve_type_vars_if_possible(&ty); debug!("resolve_type_vars_with_obligations: ty={:?}", ty); @@ -2154,7 +2155,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn resolve_generator_interiors(&self, def_id: DefId) { let mut generators = self.deferred_generator_interiors.borrow_mut(); for (body_id, interior) in generators.drain(..) { - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); generator_interior::resolve_interior(self, def_id, body_id, interior); } } @@ -2164,7 +2165,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // unconstrained floats with f64. // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to TyError. - fn fallback_if_possible(&self, ty: Ty<'tcx>) { + // The return value indicates whether fallback has occured. + fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool { use rustc::ty::error::UnconstrainedNumeric::Neither; use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; @@ -2174,24 +2176,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, Neither if self.type_var_diverges(ty) => self.tcx.types.never, - Neither => return + Neither => return false, }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback); + true } fn select_all_obligations_or_error(&self) { debug!("select_all_obligations_or_error"); if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) { - self.report_fulfillment_errors(&errors, self.inh.body_id); + self.report_fulfillment_errors(&errors, self.inh.body_id, false); } } /// Select as many obligations as we can at present. - fn select_obligations_where_possible(&self) { + fn select_obligations_where_possible(&self, fallback_has_occurred: bool) { match self.fulfillment_cx.borrow_mut().select_where_possible(self) { Ok(()) => { } - Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); } + Err(errors) => { + self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred); + }, } } @@ -2595,7 +2600,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // an "opportunistic" vtable resolution of any trait bounds on // the call. This helps coercions. if check_closures { - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); } // For variadic functions, we don't have a declared type for all of diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 47a229cbd3b..eae692f4cda 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -479,7 +479,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match method { Some(ok) => { let method = self.register_infer_ok_obligations(ok); - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); Ok(method) } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 2f1c42bbef8..9493c36fe95 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -386,7 +386,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all transitive obligations are satisfied. if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); } // Finally, resolve all regions. diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index a97c6e84eab..964c0021133 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -174,7 +174,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match fulfill_cx.select_all_or_error(infcx) { Ok(()) => true, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); false } } diff --git a/src/test/compile-fail/defaulted-never-note.rs b/src/test/compile-fail/defaulted-never-note.rs new file mode 100644 index 00000000000..798544f1649 --- /dev/null +++ b/src/test/compile-fail/defaulted-never-note.rs @@ -0,0 +1,41 @@ +// Copyright 2016 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. + +#![allow(unused)] + +trait Deserialize: Sized { + fn deserialize() -> Result; +} + +impl Deserialize for () { + fn deserialize() -> Result<(), String> { + Ok(()) + } +} + +trait ImplementedForUnitButNotNever {} + +impl ImplementedForUnitButNotNever for () {} + +fn foo(_t: T) {} +//~^ NOTE required by `foo` + +fn smeg() { + let _x = return; + foo(_x); + //~^ ERROR the trait bound + //~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented + //~| NOTE the trait is implemented for `()` +} + +fn main() { + smeg(); +} + From 00a52a2be36fd80e8430a524e8c0dad7b249af41 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:03:33 +0800 Subject: [PATCH 11/14] Fix fallback note --- src/librustc/traits/error_reporting.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b19935b8c4f..206a4bf6689 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -539,7 +539,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fallback_has_occurred: bool) { let span = obligation.cause.span; - let _ = fallback_has_occurred; let mut err = match *error { SelectionError::Unimplemented => { @@ -623,9 +622,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_similar_impl_candidates(impl_candidates, &mut err); } - // If this error is due to `!: !Trait` but `(): Trait` then add a note - // about the fallback behaviour change. - if trait_predicate.skip_binder().self_ty().is_never() { + // If this error is due to `!: Trait` not implemented but `(): Trait` is + // implemented, and fallback has occured, then it could be due to a + // variable that used to fallback to `()` now falling back to `!`. Issue a + // note informing about the change in behaviour. + if trait_predicate.skip_binder().self_ty().is_never() + && fallback_has_occurred + { let predicate = trait_predicate.map_bound(|mut trait_pred| { { let trait_ref = &mut trait_pred.trait_ref; @@ -638,13 +641,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_pred }); let unit_obligation = Obligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env, - recursion_depth: obligation.recursion_depth, - predicate, + predicate: ty::Predicate::Trait(predicate), + .. obligation.clone() }; let mut selcx = SelectionContext::new(self); - if let Ok(Some(..)) = selcx.select(&unit_obligation) { + if selcx.evaluate_obligation(&unit_obligation) { err.note("the trait is implemented for `()`. \ Possibly this error has been caused by changes to \ Rust's type-inference algorithm \ From 81ae93e3390aa686c09c5ae3a2e25274ad1fdab2 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:04:29 +0800 Subject: [PATCH 12/14] register removed lints --- src/librustc_lint/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 010678ecfb5..8b86c905489 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -306,4 +306,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/36892"); store.register_removed("extra_requirement_in_impl", "converted into hard error, see https://github.com/rust-lang/rust/issues/37166"); + store.register_removed("coerce_never", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); + store.register_removed("resolve_trait_on_defaulted_unit", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); } From b1526ca384028bb1ca52dc58eb4d47f930afae62 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:36:58 +0800 Subject: [PATCH 13/14] Fixes after rebase --- src/librustc/infer/canonical.rs | 8 +--- src/librustc/traits/query/dropck_outlives.rs | 2 +- src/librustc_traits/dropck_outlives.rs | 2 +- src/test/ui/feature-gate-never_type.stderr | 43 -------------------- 4 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/feature-gate-never_type.stderr diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 9519baa3ff7..4e0cf59e8a7 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -609,12 +609,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> bug!("encountered a canonical type during canonicalization") } - // Replace a `()` that "would've fallen back" to `!` with just `()`. - ty::TyTuple(ref tys, true) => { - assert!(tys.is_empty()); - self.tcx().mk_nil() - } - ty::TyClosure(..) | ty::TyGenerator(..) | ty::TyGeneratorWitness(..) @@ -634,7 +628,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::TyFnPtr(_) | ty::TyDynamic(..) | ty::TyNever - | ty::TyTuple(_, false) + | ty::TyTuple(..) | ty::TyProjection(..) | ty::TyForeign(..) | ty::TyParam(..) diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 0fe4daa36ed..1caab6fd89e 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -236,7 +236,7 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>) // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. - ty::TyTuple(ref tys, _) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)), + ty::TyTuple(ref tys) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)), ty::TyClosure(def_id, ref substs) => substs .upvar_tys(def_id, tcx) .all(|t| trivial_dropck_outlives(tcx, t)), diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2274f3942bd..2a8cfe5cc06 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -184,7 +184,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ety) } - ty::TyTuple(tys, _) => tys.iter() + ty::TyTuple(tys) => tys.iter() .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) .collect(), diff --git a/src/test/ui/feature-gate-never_type.stderr b/src/test/ui/feature-gate-never_type.stderr deleted file mode 100644 index 187be6d8291..00000000000 --- a/src/test/ui/feature-gate-never_type.stderr +++ /dev/null @@ -1,43 +0,0 @@ -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`. From a8a0c691914b72d1ca54057914b4cee2bd097ae3 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 13:31:02 +0800 Subject: [PATCH 14/14] fix ui test error again --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 51fdac064ce..4afe5b5d5e0 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -6,4 +6,4 @@ LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0005" +For more information about this error, try `rustc --explain E0005`.