Auto merge of #50351 - varkor:vestigial-never-conversion, r=nikomatsakis
Remove vestigial diverging !-coercion Such conversions are no longer permitted. Fixes #50350. r? @nikomatsakis
This commit is contained in:
commit
eca0da5985
@ -688,7 +688,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||
arm_span: arm.body.span,
|
||||
source: match_src
|
||||
});
|
||||
coercion.coerce(self, &cause, &arm.body, arm_ty, self.diverges.get());
|
||||
coercion.coerce(self, &cause, &arm.body, arm_ty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
//! sort of a minor point so I've opted to leave it for later---after all
|
||||
//! we may want to adjust precisely when coercions occur.
|
||||
|
||||
use check::{Diverges, FnCtxt, Needs};
|
||||
use check::{FnCtxt, Needs};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
@ -800,8 +800,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
exprs: &[E],
|
||||
prev_ty: Ty<'tcx>,
|
||||
new: &hir::Expr,
|
||||
new_ty: Ty<'tcx>,
|
||||
new_diverges: Diverges)
|
||||
new_ty: Ty<'tcx>)
|
||||
-> RelateResult<'tcx, Ty<'tcx>>
|
||||
where E: AsCoercionSite
|
||||
{
|
||||
@ -809,13 +808,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let new_ty = self.resolve_type_vars_with_obligations(new_ty);
|
||||
debug!("coercion::try_find_coercion_lub({:?}, {:?})", prev_ty, new_ty);
|
||||
|
||||
// Special-ish case: we can coerce any type `T` into the `!`
|
||||
// type, but only if the source expression diverges.
|
||||
if prev_ty.is_never() && new_diverges.always() {
|
||||
debug!("permit coercion to `!` because expr diverges");
|
||||
return Ok(prev_ty);
|
||||
}
|
||||
|
||||
// Special-case that coercion alone cannot handle:
|
||||
// Two function item types of differing IDs or Substs.
|
||||
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>
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expression: &'gcx hir::Expr,
|
||||
expression_ty: Ty<'tcx>,
|
||||
expression_diverges: Diverges)
|
||||
expression_ty: Ty<'tcx>)
|
||||
{
|
||||
self.coerce_inner(fcx,
|
||||
cause,
|
||||
Some(expression),
|
||||
expression_ty,
|
||||
expression_diverges,
|
||||
None, false)
|
||||
}
|
||||
|
||||
@ -1087,7 +1077,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||
cause,
|
||||
None,
|
||||
fcx.tcx.mk_nil(),
|
||||
Diverges::Maybe,
|
||||
Some(augment_error),
|
||||
label_unit_as_expected)
|
||||
}
|
||||
@ -1100,7 +1089,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expression: Option<&'gcx hir::Expr>,
|
||||
mut expression_ty: Ty<'tcx>,
|
||||
expression_diverges: Diverges,
|
||||
augment_error: Option<&mut FnMut(&mut DiagnosticBuilder)>,
|
||||
label_expression_as_expected: bool)
|
||||
{
|
||||
@ -1134,15 +1122,13 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
||||
exprs,
|
||||
self.merged_ty(),
|
||||
expression,
|
||||
expression_ty,
|
||||
expression_diverges),
|
||||
expression_ty),
|
||||
Expressions::UpFront(ref coercion_sites) =>
|
||||
fcx.try_find_coercion_lub(cause,
|
||||
&coercion_sites[0..self.pushed],
|
||||
self.merged_ty(),
|
||||
expression,
|
||||
expression_ty,
|
||||
expression_diverges),
|
||||
expression_ty),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -542,7 +542,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
/// you get indicates whether any subexpression that was
|
||||
/// evaluating up to and including `X` diverged.
|
||||
///
|
||||
/// We use this flag for two purposes:
|
||||
/// We currently use this flag only for diagnostic purposes:
|
||||
///
|
||||
/// - To warn about unreachable code: if, after processing a
|
||||
/// sub-expression but before we have applied the effects of the
|
||||
@ -556,16 +556,8 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
/// foo();}` or `{return; 22}`, where we would warn on the
|
||||
/// `foo()` or `22`.
|
||||
///
|
||||
/// - To permit assignment into a local variable or other place
|
||||
/// (including the "return slot") of type `!`. This is allowed
|
||||
/// if **either** the type of value being assigned is `!`, which
|
||||
/// means the current code is dead, **or** the expression's
|
||||
/// diverging flag is true, which means that a diverging value was
|
||||
/// wrapped (e.g., `let x: ! = foo(return)`).
|
||||
///
|
||||
/// To repeat the last point: an expression represents dead-code
|
||||
/// if, after checking it, **either** its type is `!` OR the
|
||||
/// diverges flag is set to something other than `Maybe`.
|
||||
/// An expression represents dead-code if, after checking it,
|
||||
/// the diverges flag is set to something other than `Maybe`.
|
||||
diverges: Cell<Diverges>,
|
||||
|
||||
/// Whether any child nodes have any type errors.
|
||||
@ -3002,8 +2994,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
&self.cause(return_expr.span,
|
||||
ObligationCauseCode::ReturnType(return_expr.id)),
|
||||
return_expr,
|
||||
return_expr_ty,
|
||||
self.diverges.get());
|
||||
return_expr_ty);
|
||||
}
|
||||
|
||||
|
||||
@ -3034,13 +3025,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
|
||||
|
||||
let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
|
||||
coerce.coerce(self, &if_cause, then_expr, then_ty, then_diverges);
|
||||
coerce.coerce(self, &if_cause, then_expr, then_ty);
|
||||
|
||||
if let Some(else_expr) = opt_else_expr {
|
||||
let else_ty = self.check_expr_with_expectation(else_expr, expected);
|
||||
let else_diverges = self.diverges.get();
|
||||
|
||||
coerce.coerce(self, &if_cause, else_expr, else_ty, else_diverges);
|
||||
coerce.coerce(self, &if_cause, else_expr, else_ty);
|
||||
|
||||
// We won't diverge unless both branches do (or the condition does).
|
||||
self.diverges.set(cond_diverges | then_diverges & else_diverges);
|
||||
@ -3733,7 +3724,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
hir::ExprBreak(destination, ref expr_opt) => {
|
||||
if let Some(target_id) = destination.target_id.opt_id() {
|
||||
let (e_ty, e_diverges, cause);
|
||||
let (e_ty, cause);
|
||||
if let Some(ref e) = *expr_opt {
|
||||
// If this is a break with a value, we need to type-check
|
||||
// the expression. Get an expected type from the loop context.
|
||||
@ -3752,13 +3743,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Recurse without `enclosing_breakables` borrowed.
|
||||
e_ty = self.check_expr_with_hint(e, coerce_to);
|
||||
e_diverges = self.diverges.get();
|
||||
cause = self.misc(e.span);
|
||||
} else {
|
||||
// Otherwise, this is a break *without* a value. That's
|
||||
// always legal, and is equivalent to `break ()`.
|
||||
e_ty = tcx.mk_nil();
|
||||
e_diverges = Diverges::Maybe;
|
||||
cause = self.misc(expr.span);
|
||||
}
|
||||
|
||||
@ -3769,7 +3758,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let ctxt = enclosing_breakables.find_breakable(target_id);
|
||||
if let Some(ref mut coerce) = ctxt.coerce {
|
||||
if let Some(ref e) = *expr_opt {
|
||||
coerce.coerce(self, &cause, e, e_ty, e_diverges);
|
||||
coerce.coerce(self, &cause, e, e_ty);
|
||||
} else {
|
||||
assert!(e_ty.is_nil());
|
||||
coerce.coerce_forced_unit(self, &cause, &mut |_| (), true);
|
||||
@ -3975,7 +3964,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
for e in args {
|
||||
let e_ty = self.check_expr_with_hint(e, coerce_to);
|
||||
let cause = self.misc(e.span);
|
||||
coerce.coerce(self, &cause, e, e_ty, self.diverges.get());
|
||||
coerce.coerce(self, &cause, e, e_ty);
|
||||
}
|
||||
coerce.complete(self)
|
||||
} else {
|
||||
@ -4386,8 +4375,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
coerce.coerce(self,
|
||||
&cause,
|
||||
tail_expr,
|
||||
tail_expr_ty,
|
||||
self.diverges.get());
|
||||
tail_expr_ty);
|
||||
} else {
|
||||
// Subtle: if there is no explicit tail expression,
|
||||
// that is typically equivalent to a tail expression
|
||||
|
@ -56,9 +56,8 @@ fn call_foo_f() {
|
||||
}
|
||||
|
||||
fn array_a() {
|
||||
// Accepted: return is coerced to `!` just fine, and then `22` can be
|
||||
// because we already diverged.
|
||||
let x: [!; 2] = [return, 22];
|
||||
// Return is coerced to `!` just fine, but `22` cannot be.
|
||||
let x: [!; 2] = [return, 22]; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn array_b() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user