Auto merge of #82738 - estebank:tail-expr-check-is-too-slow, r=oli-obk
Move check only relevant in error case out of critical path Move the check for potentially forgotten `return` in a tail expression of arbitrary expressions into the coercion error branch to avoid computing unncessary coercion checks on successful code. Follow up to #81458.
This commit is contained in:
commit
dfe519b344
1 changed files with 11 additions and 11 deletions
|
@ -207,17 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let cause = self.cause(span, code);
|
let cause = self.cause(span, code);
|
||||||
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
|
|
||||||
Some(ret_coercion) if self.in_tail_expr => {
|
|
||||||
let ret_ty = ret_coercion.borrow().expected_ty();
|
|
||||||
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
|
|
||||||
self.can_coerce(arm_ty, ret_ty)
|
|
||||||
&& prior_arm_ty.map_or(true, |t| self.can_coerce(t, ret_ty))
|
|
||||||
// The match arms need to unify for the case of `impl Trait`.
|
|
||||||
&& !matches!(ret_ty.kind(), ty::Opaque(..))
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is the moral equivalent of `coercion.coerce(self, cause, arm.body, arm_ty)`.
|
// This is the moral equivalent of `coercion.coerce(self, cause, arm.body, arm_ty)`.
|
||||||
// We use it this way to be able to expand on the potential error and detect when a
|
// We use it this way to be able to expand on the potential error and detect when a
|
||||||
|
@ -229,6 +218,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Some(&arm.body),
|
Some(&arm.body),
|
||||||
arm_ty,
|
arm_ty,
|
||||||
Some(&mut |err: &mut DiagnosticBuilder<'_>| {
|
Some(&mut |err: &mut DiagnosticBuilder<'_>| {
|
||||||
|
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
|
||||||
|
Some(ret_coercion) if self.in_tail_expr => {
|
||||||
|
let ret_ty = ret_coercion.borrow().expected_ty();
|
||||||
|
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
|
||||||
|
self.can_coerce(arm_ty, ret_ty)
|
||||||
|
&& prior_arm_ty.map_or(true, |t| self.can_coerce(t, ret_ty))
|
||||||
|
// The match arms need to unify for the case of `impl Trait`.
|
||||||
|
&& !matches!(ret_ty.kind(), ty::Opaque(..))
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
if let (Expectation::IsLast(stmt), Some(ret), true) =
|
if let (Expectation::IsLast(stmt), Some(ret), true) =
|
||||||
(orig_expected, self.ret_type_span, can_coerce_to_return_ty)
|
(orig_expected, self.ret_type_span, can_coerce_to_return_ty)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue