Rollup merge of #45880 - arielb1:never-coerce, r=nikomatsakis
make coercions to `!` in unreachable code a hard error This was added to cover up a lazy extra semicolon in #35849, but does not actually make sense. This is removed as a part of the stabilization of `never_type`.
This commit is contained in:
commit
95f465d535
@ -222,6 +222,12 @@ declare_lint! {
|
||||
"detect mut variables which don't need to be mutable"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub COERCE_NEVER,
|
||||
Deny,
|
||||
"detect coercion to !"
|
||||
}
|
||||
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// which are used by other parts of the compiler.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -263,7 +269,8 @@ impl LintPass for HardwiredLints {
|
||||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
DEPRECATED,
|
||||
UNUSED_UNSAFE,
|
||||
UNUSED_MUT
|
||||
UNUSED_MUT,
|
||||
COERCE_NEVER
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +247,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
id: LintId::of(SAFE_PACKED_BORROWS),
|
||||
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(COERCE_NEVER),
|
||||
reference: "issue #46325 <https://github.com/rust-lang/rust/issues/46325>",
|
||||
},
|
||||
|
||||
]);
|
||||
|
||||
|
@ -66,6 +66,7 @@ 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, LvaluePreference, TypeAndMut,
|
||||
@ -754,7 +755,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// type, but only if the source expression diverges.
|
||||
if target.is_never() && expr_diverges.always() {
|
||||
debug!("permit coercion to `!` because expr diverges");
|
||||
return Ok(target);
|
||||
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);
|
||||
|
@ -12,8 +12,11 @@
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fn cast_b() {
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(never_type)]
|
||||
#![deny(coerce_never)]
|
||||
|
||||
fn foo(x: usize, y: !, z: usize) { }
|
||||
|
||||
@ -17,6 +18,8 @@ fn call_foo_a() {
|
||||
// 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
|
||||
}
|
||||
|
||||
fn call_foo_b() {
|
||||
@ -36,6 +39,8 @@ 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
|
||||
}
|
||||
|
||||
fn call_foo_e() {
|
||||
@ -75,6 +80,8 @@ 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
|
||||
}
|
||||
|
||||
fn tuple_c() {
|
||||
|
@ -8,9 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn _converge() -> ! {
|
||||
42 //~ ERROR mismatched types
|
||||
#[deny(coerce_never)]
|
||||
fn assert_sizeof() -> ! {
|
||||
unsafe {
|
||||
::std::mem::transmute::<f64, [u8; 8]>(panic!())
|
||||
//~^ ERROR cannot coerce `[u8; 8]` to !
|
||||
//~| hard error
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
// 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!())
|
||||
@ -15,4 +16,3 @@ fn assert_sizeof() -> ! {
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
||||
|
@ -12,11 +12,14 @@
|
||||
#![allow(unused_assignments)]
|
||||
#![allow(dead_code)]
|
||||
#![deny(unreachable_code)]
|
||||
#![deny(coerce_never)]
|
||||
#![feature(never_type)]
|
||||
|
||||
fn foo() {
|
||||
let x: ! = ! { return; 22 }; //~ ERROR unreachable
|
||||
//~^ ERROR cannot apply unary operator `!` to type `!`
|
||||
//~^ ERROR cannot coerce
|
||||
//~| hard error
|
||||
//~| ERROR cannot apply unary operator `!` to type `!`
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
@ -1,7 +1,7 @@
|
||||
error: unreachable expression
|
||||
--> $DIR/expr_unary.rs:18:28
|
||||
--> $DIR/expr_unary.rs:19:28
|
||||
|
|
||||
18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
|
||||
19 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
|
||||
| ^^
|
||||
|
|
||||
note: lint level defined here
|
||||
@ -10,11 +10,25 @@ note: lint level defined here
|
||||
14 | #![deny(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0600]: cannot apply unary operator `!` to type `!`
|
||||
--> $DIR/expr_unary.rs:18:16
|
||||
error: cannot coerce `{integer}` to !
|
||||
--> $DIR/expr_unary.rs:19:28
|
||||
|
|
||||
18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
|
||||
19 | 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 <https://github.com/rust-lang/rust/issues/46325>
|
||||
|
||||
error[E0600]: cannot apply unary operator `!` to type `!`
|
||||
--> $DIR/expr_unary.rs:19:16
|
||||
|
|
||||
19 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user