Skip to content

Commit c3beef6

Browse files
canndrewnikomatsakis
authored andcommitted
Make coerce_never lint an error
Remove the coerce_never lint and make the behaviour an error.
1 parent 32601f6 commit c3beef6

File tree

12 files changed

+21
-101
lines changed

12 files changed

+21
-101
lines changed

Diff for: src/librustc/lint/builtin.rs

-7
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,6 @@ declare_lint! {
221221
"detect mut variables which don't need to be mutable"
222222
}
223223

224-
declare_lint! {
225-
pub COERCE_NEVER,
226-
Deny,
227-
"detect coercion to !"
228-
}
229-
230224
declare_lint! {
231225
pub SINGLE_USE_LIFETIME,
232226
Allow,
@@ -287,7 +281,6 @@ impl LintPass for HardwiredLints {
287281
DEPRECATED,
288282
UNUSED_UNSAFE,
289283
UNUSED_MUT,
290-
COERCE_NEVER,
291284
SINGLE_USE_LIFETIME,
292285
TYVAR_BEHIND_RAW_POINTER,
293286
ELIDED_LIFETIME_IN_PATH

Diff for: src/librustc_lint/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
243243
id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
244244
reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
245245
},
246-
FutureIncompatibleInfo {
247-
id: LintId::of(COERCE_NEVER),
248-
reference: "issue #46325 <https://github.com/rust-lang/rust/issues/46325>",
249-
},
250246
FutureIncompatibleInfo {
251247
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
252248
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",

Diff for: src/librustc_typeck/check/cast.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
3939
//! `U1` coerces to `U2`).
4040
41-
use super::{Diverges, FnCtxt};
41+
use super::FnCtxt;
4242

4343
use errors::DiagnosticBuilder;
4444
use hir::def_id::DefId;
@@ -59,7 +59,6 @@ use util::common::ErrorReported;
5959
pub struct CastCheck<'tcx> {
6060
expr: &'tcx hir::Expr,
6161
expr_ty: Ty<'tcx>,
62-
expr_diverges: Diverges,
6362
cast_ty: Ty<'tcx>,
6463
cast_span: Span,
6564
span: Span,
@@ -183,15 +182,13 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
183182
pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>,
184183
expr: &'tcx hir::Expr,
185184
expr_ty: Ty<'tcx>,
186-
expr_diverges: Diverges,
187185
cast_ty: Ty<'tcx>,
188186
cast_span: Span,
189187
span: Span)
190188
-> Result<CastCheck<'tcx>, ErrorReported> {
191189
let check = CastCheck {
192190
expr,
193191
expr_ty,
194-
expr_diverges,
195192
cast_ty,
196193
cast_span,
197194
span,
@@ -437,7 +434,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
437434
let f = self.expr_ty.fn_sig(fcx.tcx);
438435
let res = fcx.try_coerce(self.expr,
439436
self.expr_ty,
440-
self.expr_diverges,
441437
fcx.tcx.mk_fn_ptr(f));
442438
if !res.is_ok() {
443439
return Err(CastError::NonScalar);
@@ -620,7 +616,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
620616
}
621617

622618
fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool {
623-
fcx.try_coerce(self.expr, self.expr_ty, self.expr_diverges, self.cast_ty).is_ok()
619+
fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok()
624620
}
625621
}
626622

Diff for: src/librustc_typeck/check/coercion.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ use rustc::hir;
6666
use rustc::hir::def_id::DefId;
6767
use rustc::infer::{Coercion, InferResult, InferOk};
6868
use rustc::infer::type_variable::TypeVariableOrigin;
69-
use rustc::lint;
7069
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
7170
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
7271
use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts};
@@ -736,27 +735,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
736735
pub fn try_coerce(&self,
737736
expr: &hir::Expr,
738737
expr_ty: Ty<'tcx>,
739-
expr_diverges: Diverges,
740738
target: Ty<'tcx>)
741739
-> RelateResult<'tcx, Ty<'tcx>> {
742740
let source = self.resolve_type_vars_with_obligations(expr_ty);
743741
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
744742

745-
// Special-ish case: we can coerce any type `T` into the `!`
746-
// type, but only if the source expression diverges.
747-
if target.is_never() && expr_diverges.always() {
748-
debug!("permit coercion to `!` because expr diverges");
749-
if self.can_eq(self.param_env, source, target).is_err() {
750-
self.tcx.lint_node(
751-
lint::builtin::COERCE_NEVER,
752-
expr.id,
753-
expr.span,
754-
&format!("cannot coerce `{}` to !", source)
755-
);
756-
return Ok(target);
757-
}
758-
}
759-
760743
let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable);
761744
let coerce = Coerce::new(self, cause);
762745
let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?;
@@ -1106,7 +1089,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
11061089
if self.pushed == 0 {
11071090
// Special-case the first expression we are coercing.
11081091
// To be honest, I'm not entirely sure why we do this.
1109-
fcx.try_coerce(expression, expression_ty, expression_diverges, self.expected_ty)
1092+
fcx.try_coerce(expression, expression_ty, self.expected_ty)
11101093
} else {
11111094
match self.expressions {
11121095
Expressions::Dynamic(ref exprs) =>

Diff for: src/librustc_typeck/check/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
100100
-> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx>>) {
101101
let expected = self.resolve_type_vars_with_obligations(expected);
102102

103-
let e = match self.try_coerce(expr, checked_ty, self.diverges.get(), expected) {
103+
let e = match self.try_coerce(expr, checked_ty, expected) {
104104
Ok(ty) => return (ty, None),
105105
Err(e) => e
106106
};

Diff for: src/librustc_typeck/check/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3948,15 +3948,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
39483948
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
39493949
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
39503950
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3951-
let diverges = self.diverges.get();
39523951

39533952
// Eagerly check for some obvious errors.
39543953
if t_expr.references_error() || t_cast.references_error() {
39553954
tcx.types.err
39563955
} else {
39573956
// Defer other checks until we're done type checking.
39583957
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3959-
match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
3958+
match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
39603959
Ok(cast_check) => {
39613960
deferred_cast_checks.push(cast_check);
39623961
t_cast

Diff for: src/test/compile-fail/coerce-to-bang-cast.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010

1111
fn foo(x: usize, y: !, z: usize) { }
1212

13-
#[deny(coerce_never)]
1413
fn cast_a() {
1514
let y = {return; 22} as !;
16-
//~^ ERROR cannot coerce `i32` to !
17-
//~| hard error
15+
//~^ ERROR non-primitive cast
1816
}
1917

2018
fn cast_b() {

Diff for: src/test/compile-fail/coerce-to-bang.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![deny(coerce_never)]
12-
1311
fn foo(x: usize, y: !, z: usize) { }
1412

1513
fn call_foo_a() {
16-
// FIXME(#40800) -- accepted beacuse divergence happens **before**
17-
// the coercion to `!`, but within same expression. Not clear that
18-
// these are the rules we want.
1914
foo(return, 22, 44);
20-
//~^ ERROR cannot coerce `{integer}` to !
21-
//~| hard error
15+
//~^ ERROR mismatched types
2216
}
2317

2418
fn call_foo_b() {
@@ -38,8 +32,7 @@ fn call_foo_d() {
3832
let b = 22;
3933
let c = 44;
4034
foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
41-
//~^ ERROR cannot coerce `{integer}` to !
42-
//~| hard error
35+
//~^ ERROR mismatched types
4336
}
4437

4538
fn call_foo_e() {
@@ -79,8 +72,7 @@ fn tuple_a() {
7972
fn tuple_b() {
8073
// Divergence happens before coercion: OK
8174
let x: (usize, !, usize) = (return, 44, 66);
82-
//~^ ERROR cannot coerce `{integer}` to !
83-
//~| hard error
75+
//~^ ERROR mismatched types
8476
}
8577

8678
fn tuple_c() {

Diff for: src/test/compile-fail/diverging-fn-tail-35849.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[deny(coerce_never)]
1211
fn assert_sizeof() -> ! {
1312
unsafe {
1413
::std::mem::transmute::<f64, [u8; 8]>(panic!())
15-
//~^ ERROR cannot coerce `[u8; 8]` to !
16-
//~| hard error
14+
//~^ ERROR mismatched types
1715
}
1816
}
1917

Diff for: src/test/run-pass/diverging-fn-tail-35849.rs

-18
This file was deleted.

Diff for: src/test/ui/reachable/expr_unary.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
#![allow(unused_assignments)]
1313
#![allow(dead_code)]
1414
#![deny(unreachable_code)]
15-
#![deny(coerce_never)]
1615

1716
fn foo() {
18-
let x: ! = ! { return; 22 }; //~ ERROR unreachable
19-
//~^ ERROR cannot coerce
20-
//~| hard error
17+
let x: ! = ! { return; }; //~ ERROR unreachable
2118
//~| ERROR cannot apply unary operator `!` to type `!`
2219
}
2320

Diff for: src/test/ui/reachable/expr_unary.stderr

+10-24
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
1+
error[E0600]: cannot apply unary operator `!` to type `!`
2+
--> $DIR/expr_unary.rs:17:16
3+
|
4+
17 | let x: ! = ! { return; }; //~ ERROR unreachable
5+
| ^^^^^^^^^^^^^
6+
17
error: unreachable expression
2-
--> $DIR/expr_unary.rs:18:28
8+
--> $DIR/expr_unary.rs:17:16
39
|
4-
18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
5-
| ^^
10+
17 | let x: ! = ! { return; }; //~ ERROR unreachable
11+
| ^^^^^^^^^^^^^
612
|
713
note: lint level defined here
814
--> $DIR/expr_unary.rs:14:9
915
|
1016
14 | #![deny(unreachable_code)]
1117
| ^^^^^^^^^^^^^^^^
1218

13-
error: cannot coerce `{integer}` to !
14-
--> $DIR/expr_unary.rs:18:28
15-
|
16-
18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
17-
| ^^
18-
|
19-
note: lint level defined here
20-
--> $DIR/expr_unary.rs:15:9
21-
|
22-
15 | #![deny(coerce_never)]
23-
| ^^^^^^^^^^^^
24-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
25-
= note: for more information, see issue #46325 <https://github.com/rust-lang/rust/issues/46325>
26-
27-
error[E0600]: cannot apply unary operator `!` to type `!`
28-
--> $DIR/expr_unary.rs:18:16
29-
|
30-
18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable
31-
| ^^^^^^^^^^^^^^^^
32-
33-
error: aborting due to 3 previous errors
19+
error: aborting due to 2 previous errors
3420

0 commit comments

Comments
 (0)