Skip to content

Commit eca0da5

Browse files
committed
Auto merge of #50351 - varkor:vestigial-never-conversion, r=nikomatsakis
Remove vestigial diverging !-coercion Such conversions are no longer permitted. Fixes #50350. r? @nikomatsakis
2 parents 0b17da2 + 5489969 commit eca0da5

File tree

4 files changed

+18
-45
lines changed

4 files changed

+18
-45
lines changed

src/librustc_typeck/check/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
688688
arm_span: arm.body.span,
689689
source: match_src
690690
});
691-
coercion.coerce(self, &cause, &arm.body, arm_ty, self.diverges.get());
691+
coercion.coerce(self, &cause, &arm.body, arm_ty);
692692
}
693693
}
694694

src/librustc_typeck/check/coercion.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
//! sort of a minor point so I've opted to leave it for later---after all
6161
//! we may want to adjust precisely when coercions occur.
6262
63-
use check::{Diverges, FnCtxt, Needs};
63+
use check::{FnCtxt, Needs};
6464

6565
use rustc::hir;
6666
use rustc::hir::def_id::DefId;
@@ -800,22 +800,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
800800
exprs: &[E],
801801
prev_ty: Ty<'tcx>,
802802
new: &hir::Expr,
803-
new_ty: Ty<'tcx>,
804-
new_diverges: Diverges)
803+
new_ty: Ty<'tcx>)
805804
-> RelateResult<'tcx, Ty<'tcx>>
806805
where E: AsCoercionSite
807806
{
808807
let prev_ty = self.resolve_type_vars_with_obligations(prev_ty);
809808
let new_ty = self.resolve_type_vars_with_obligations(new_ty);
810809
debug!("coercion::try_find_coercion_lub({:?}, {:?})", prev_ty, new_ty);
811810

812-
// Special-ish case: we can coerce any type `T` into the `!`
813-
// type, but only if the source expression diverges.
814-
if prev_ty.is_never() && new_diverges.always() {
815-
debug!("permit coercion to `!` because expr diverges");
816-
return Ok(prev_ty);
817-
}
818-
819811
// Special-case that coercion alone cannot handle:
820812
// Two function item types of differing IDs or Substs.
821813
if let (&ty::TyFnDef(..), &ty::TyFnDef(..)) = (&prev_ty.sty, &new_ty.sty) {
@@ -1054,14 +1046,12 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
10541046
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
10551047
cause: &ObligationCause<'tcx>,
10561048
expression: &'gcx hir::Expr,
1057-
expression_ty: Ty<'tcx>,
1058-
expression_diverges: Diverges)
1049+
expression_ty: Ty<'tcx>)
10591050
{
10601051
self.coerce_inner(fcx,
10611052
cause,
10621053
Some(expression),
10631054
expression_ty,
1064-
expression_diverges,
10651055
None, false)
10661056
}
10671057

@@ -1087,7 +1077,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
10871077
cause,
10881078
None,
10891079
fcx.tcx.mk_nil(),
1090-
Diverges::Maybe,
10911080
Some(augment_error),
10921081
label_unit_as_expected)
10931082
}
@@ -1100,7 +1089,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
11001089
cause: &ObligationCause<'tcx>,
11011090
expression: Option<&'gcx hir::Expr>,
11021091
mut expression_ty: Ty<'tcx>,
1103-
expression_diverges: Diverges,
11041092
augment_error: Option<&mut FnMut(&mut DiagnosticBuilder)>,
11051093
label_expression_as_expected: bool)
11061094
{
@@ -1134,15 +1122,13 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
11341122
exprs,
11351123
self.merged_ty(),
11361124
expression,
1137-
expression_ty,
1138-
expression_diverges),
1125+
expression_ty),
11391126
Expressions::UpFront(ref coercion_sites) =>
11401127
fcx.try_find_coercion_lub(cause,
11411128
&coercion_sites[0..self.pushed],
11421129
self.merged_ty(),
11431130
expression,
1144-
expression_ty,
1145-
expression_diverges),
1131+
expression_ty),
11461132
}
11471133
}
11481134
} else {

src/librustc_typeck/check/mod.rs

+10-22
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
542542
/// you get indicates whether any subexpression that was
543543
/// evaluating up to and including `X` diverged.
544544
///
545-
/// We use this flag for two purposes:
545+
/// We currently use this flag only for diagnostic purposes:
546546
///
547547
/// - To warn about unreachable code: if, after processing a
548548
/// sub-expression but before we have applied the effects of the
@@ -556,16 +556,8 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
556556
/// foo();}` or `{return; 22}`, where we would warn on the
557557
/// `foo()` or `22`.
558558
///
559-
/// - To permit assignment into a local variable or other place
560-
/// (including the "return slot") of type `!`. This is allowed
561-
/// if **either** the type of value being assigned is `!`, which
562-
/// means the current code is dead, **or** the expression's
563-
/// diverging flag is true, which means that a diverging value was
564-
/// wrapped (e.g., `let x: ! = foo(return)`).
565-
///
566-
/// To repeat the last point: an expression represents dead-code
567-
/// if, after checking it, **either** its type is `!` OR the
568-
/// diverges flag is set to something other than `Maybe`.
559+
/// An expression represents dead-code if, after checking it,
560+
/// the diverges flag is set to something other than `Maybe`.
569561
diverges: Cell<Diverges>,
570562

571563
/// Whether any child nodes have any type errors.
@@ -3002,8 +2994,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30022994
&self.cause(return_expr.span,
30032995
ObligationCauseCode::ReturnType(return_expr.id)),
30042996
return_expr,
3005-
return_expr_ty,
3006-
self.diverges.get());
2997+
return_expr_ty);
30072998
}
30082999

30093000

@@ -3034,13 +3025,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30343025
let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
30353026

30363027
let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
3037-
coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
3028+
coerce.coerce(self, &if_cause, then_expr, then_ty);
30383029

30393030
if let Some(else_expr) = opt_else_expr {
30403031
let else_ty = self.check_expr_with_expectation(else_expr, expected);
30413032
let else_diverges = self.diverges.get();
30423033

3043-
coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
3034+
coerce.coerce(self, &if_cause, else_expr, else_ty);
30443035

30453036
// We won't diverge unless both branches do (or the condition does).
30463037
self.diverges.set(cond_diverges | then_diverges & else_diverges);
@@ -3733,7 +3724,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37333724
}
37343725
hir::ExprBreak(destination, ref expr_opt) => {
37353726
if let Some(target_id) = destination.target_id.opt_id() {
3736-
let (e_ty, e_diverges, cause);
3727+
let (e_ty, cause);
37373728
if let Some(ref e) = *expr_opt {
37383729
// If this is a break with a value, we need to type-check
37393730
// the expression. Get an expected type from the loop context.
@@ -3752,13 +3743,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37523743

37533744
// Recurse without `enclosing_breakables` borrowed.
37543745
e_ty = self.check_expr_with_hint(e, coerce_to);
3755-
e_diverges = self.diverges.get();
37563746
cause = self.misc(e.span);
37573747
} else {
37583748
// Otherwise, this is a break *without* a value. That's
37593749
// always legal, and is equivalent to `break ()`.
37603750
e_ty = tcx.mk_nil();
3761-
e_diverges = Diverges::Maybe;
37623751
cause = self.misc(expr.span);
37633752
}
37643753

@@ -3769,7 +3758,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37693758
let ctxt = enclosing_breakables.find_breakable(target_id);
37703759
if let Some(ref mut coerce) = ctxt.coerce {
37713760
if let Some(ref e) = *expr_opt {
3772-
coerce.coerce(self, &cause, e, e_ty, e_diverges);
3761+
coerce.coerce(self, &cause, e, e_ty);
37733762
} else {
37743763
assert!(e_ty.is_nil());
37753764
coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
@@ -3975,7 +3964,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
39753964
for e in args {
39763965
let e_ty = self.check_expr_with_hint(e, coerce_to);
39773966
let cause = self.misc(e.span);
3978-
coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
3967+
coerce.coerce(self, &cause, e, e_ty);
39793968
}
39803969
coerce.complete(self)
39813970
} else {
@@ -4386,8 +4375,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
43864375
coerce.coerce(self,
43874376
&cause,
43884377
tail_expr,
4389-
tail_expr_ty,
4390-
self.diverges.get());
4378+
tail_expr_ty);
43914379
} else {
43924380
// Subtle: if there is no explicit tail expression,
43934381
// that is typically equivalent to a tail expression

src/test/compile-fail/coerce-to-bang.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ fn call_foo_f() {
5656
}
5757

5858
fn array_a() {
59-
// Accepted: return is coerced to `!` just fine, and then `22` can be
60-
// because we already diverged.
61-
let x: [!; 2] = [return, 22];
59+
// Return is coerced to `!` just fine, but `22` cannot be.
60+
let x: [!; 2] = [return, 22]; //~ ERROR mismatched types
6261
}
6362

6463
fn array_b() {

0 commit comments

Comments
 (0)