From 59688e119e1b9c2506fa9173728ae88eb196bf5e 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 | 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`.