about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-04 14:36:24 +0000
committerbors <bors@rust-lang.org>2024-08-04 14:36:24 +0000
commitab1527f1d6560168f9fd36fa8cd7ba677c1d36ad (patch)
tree24f0032a8dd7d61ce9b20ebc94c53f93982a2bb0 /compiler
parentebd08d8ed5c8904de8700def78adc1dbd5727684 (diff)
parentf850e37119eac6489ae6d9983631f2c702a4887f (diff)
downloadrust-ab1527f1d6560168f9fd36fa8cd7ba677c1d36ad.tar.gz
rust-ab1527f1d6560168f9fd36fa8cd7ba677c1d36ad.zip
Auto merge of #128544 - compiler-errors:perf-warn_if_unreachable, r=fmease
Check divergence value first before doing span operations in `warn_if_unreachable`

It's more expensive to extract the span's desugaring first rather than check the value of the divergence enum. For some reason I inverted these checks, probably for readability, but as a consequence I regressed perf:

https://github.com/rust-lang/rust/pull/128443#issuecomment-2265425016

r? fmease
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs36
1 files changed, 18 insertions, 18 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 40d9a2985da..8c1aa66332f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -48,28 +48,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Produces warning on the given node, if the current point in the
     /// function is unreachable, and there hasn't been another warning.
     pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) {
-        // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
-        // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
-        // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
-        if span.is_desugaring(DesugaringKind::CondTemporary) {
+        let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() else {
             return;
-        }
+        };
 
-        // Don't lint if the result of an async block or async function is `!`.
-        // This does not affect the unreachable lints *within* the body.
-        if span.is_desugaring(DesugaringKind::Async) {
-            return;
-        }
+        match span.desugaring_kind() {
+            // If span arose from a desugaring of `if` or `while`, then it is the condition
+            // itself, which diverges, that we are about to lint on. This gives suboptimal
+            // diagnostics. Instead, stop here so that the `if`- or `while`-expression's
+            // block is linted instead.
+            Some(DesugaringKind::CondTemporary) => return,
 
-        // Don't lint *within* the `.await` operator, since that's all just desugaring junk.
-        // We only want to lint if there is a subsequent expression after the `.await`.
-        if span.is_desugaring(DesugaringKind::Await) {
-            return;
-        }
+            // Don't lint if the result of an async block or async function is `!`.
+            // This does not affect the unreachable lints *within* the body.
+            Some(DesugaringKind::Async) => return,
 
-        let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() else {
-            return;
-        };
+            // Don't lint *within* the `.await` operator, since that's all just desugaring
+            // junk. We only want to lint if there is a subsequent expression after the
+            // `.await` operator.
+            Some(DesugaringKind::Await) => return,
+
+            _ => {}
+        }
 
         // Don't warn twice.
         self.diverges.set(Diverges::WarnedAlways);