about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2021-03-03 18:28:53 -0800
committerEsteban Küber <esteban@kuber.com.ar>2021-03-03 18:28:53 -0800
commitc6c243ae1e569eb0967e2ebfb0c82f997ee353c6 (patch)
tree15c23c884e696b4257f356c6f6ec3072c746f582
parent1c77a1fa3ca574f2a40056f64d498db8efe0d8a8 (diff)
downloadrust-c6c243ae1e569eb0967e2ebfb0c82f997ee353c6.tar.gz
rust-c6c243ae1e569eb0967e2ebfb0c82f997ee353c6.zip
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.
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs22
1 files changed, 11 insertions, 11 deletions
diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index cfd4e0830ef..d056f2c90f9 100644
--- a/compiler/rustc_typeck/src/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
@@ -207,17 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ),
                 };
                 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)`.
                 // 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),
                     arm_ty,
                     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) =
                             (orig_expected, self.ret_type_span, can_coerce_to_return_ty)
                         {