From c3beef6dbe13d59e2c1549624d46027984237ab6 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Feb 2018 15:23:04 +0800 Subject: [PATCH] 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 | 4 --- 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 | 34 ++++++------------- 12 files changed, 21 insertions(+), 101 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 e9d4099aada26..08e254b29721c 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -221,12 +221,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, @@ -287,7 +281,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 14019f264702b..21cd316d514a1 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -243,10 +243,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS), reference: "issue #46205 ", }, - FutureIncompatibleInfo { - id: LintId::of(COERCE_NEVER), - reference: "issue #46325 ", - }, 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 c2c113f2da9fa..e4bad8349ea2b 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 d0280bf0b30be..6bc7a58aaeb6c 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}; use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts}; @@ -736,27 +735,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))?; @@ -1106,7 +1089,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 d2702d0810ed9..634a7ee569917 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 8cc6ef8cc2189..b7b7e9f5675c1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3948,7 +3948,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() { @@ -3956,7 +3955,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 8b3a9ed092d9a..5efb4dadc64bd 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 3f20040329024..15049232a4d3f 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 beacuse 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 a91c000bbf712..9ef5159cb771c 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 dfd99bcc9fb47..0000000000000 --- 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 524784934c7e4..4096865f4c670 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 478dcd68f6089..5dcc174b75c3a 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,8 +1,14 @@ +error[E0600]: cannot apply unary operator `!` to type `!` + --> $DIR/expr_unary.rs:17:16 + | +17 | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ + error: unreachable expression - --> $DIR/expr_unary.rs:18:28 + --> $DIR/expr_unary.rs:17:16 | -18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ +17 | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/expr_unary.rs:14:9 @@ -10,25 +16,5 @@ note: lint level defined here 14 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ -error: cannot coerce `{integer}` to ! - --> $DIR/expr_unary.rs:18:28 - | -18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ - | -note: lint level defined here - --> $DIR/expr_unary.rs:15:9 - | -15 | #![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 - | -18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors