Make coerce_never lint an error
Remove the coerce_never lint and make the behaviour an error.
This commit is contained in:
parent
32ddb30715
commit
59688e119e
@ -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,
|
||||
|
@ -270,11 +270,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
|
||||
epoch: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(COERCE_NEVER),
|
||||
reference: "issue #46325 <https://github.com/rust-lang/rust/issues/46325>",
|
||||
epoch: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
|
||||
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) =>
|
||||
|
@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
-> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx>>) {
|
||||
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
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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::<f64, [u8; 8]>(panic!())
|
||||
//~^ ERROR cannot coerce `[u8; 8]` to !
|
||||
//~| hard error
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[allow(coerce_never)]
|
||||
fn assert_sizeof() -> ! {
|
||||
unsafe {
|
||||
::std::mem::transmute::<f64, [u8; 8]>(panic!())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -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 `!`
|
||||
}
|
||||
|
||||
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
Loading…
Reference in New Issue
Block a user