@@ -2,7 +2,7 @@ use crate::callee::{self, DeferredCallResolution};
2
2
use crate :: errors:: CtorIsPrivate ;
3
3
use crate :: method:: { self , MethodCallee , SelfSource } ;
4
4
use crate :: rvalue_scopes;
5
- use crate :: { BreakableCtxt , Diverges , Expectation , FnCtxt , LoweredTy } ;
5
+ use crate :: { BreakableCtxt , DivergeReason , Diverges , Expectation , FnCtxt , LoweredTy } ;
6
6
use rustc_data_structures:: captures:: Captures ;
7
7
use rustc_data_structures:: fx:: FxHashSet ;
8
8
use rustc_errors:: { Applicability , Diag , ErrorGuaranteed , MultiSpan , StashKey } ;
@@ -48,36 +48,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48
48
/// Produces warning on the given node, if the current point in the
49
49
/// function is unreachable, and there hasn't been another warning.
50
50
pub ( in super :: super ) fn warn_if_unreachable ( & self , id : hir:: HirId , span : Span , kind : & str ) {
51
- // FIXME: Combine these two 'if' expressions into one once
52
- // let chains are implemented
53
- if let Diverges :: Always { span : orig_span, custom_note } = self . diverges . get ( ) {
54
- // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
55
- // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
56
- // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
57
- if !span. is_desugaring ( DesugaringKind :: CondTemporary )
58
- && !span. is_desugaring ( DesugaringKind :: Async )
59
- && !orig_span. is_desugaring ( DesugaringKind :: Await )
60
- {
61
- self . diverges . set ( Diverges :: WarnedAlways ) ;
62
-
63
- debug ! ( "warn_if_unreachable: id={:?} span={:?} kind={}" , id, span, kind) ;
64
-
65
- let msg = format ! ( "unreachable {kind}" ) ;
66
- self . tcx ( ) . node_span_lint (
67
- lint:: builtin:: UNREACHABLE_CODE ,
68
- id,
69
- span,
70
- msg. clone ( ) ,
71
- |lint| {
72
- lint. span_label ( span, msg) . span_label (
73
- orig_span,
74
- custom_note
75
- . unwrap_or ( "any code following this expression is unreachable" ) ,
76
- ) ;
77
- } ,
78
- )
79
- }
51
+ let Diverges :: Always ( reason, orig_span) = self . diverges . get ( ) else {
52
+ return ;
53
+ } ;
54
+ // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
55
+ // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
56
+ // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
57
+ if matches ! (
58
+ span. desugaring_kind( ) ,
59
+ Some ( DesugaringKind :: Async | DesugaringKind :: Await | DesugaringKind :: CondTemporary )
60
+ ) {
61
+ return ;
80
62
}
63
+
64
+ self . diverges . set ( Diverges :: WarnedAlways ) ;
65
+
66
+ debug ! ( "warn_if_unreachable: id={:?} span={:?} kind={}" , id, span, kind) ;
67
+
68
+ let msg = format ! ( "unreachable {kind}" ) ;
69
+ self . tcx ( ) . node_span_lint ( lint:: builtin:: UNREACHABLE_CODE , id, span, msg. clone ( ) , |lint| {
70
+ let label = match reason {
71
+ DivergeReason :: AllArmsDiverge => {
72
+ "any code following this `match` expression is unreachable, as all arms diverge"
73
+ }
74
+ DivergeReason :: NeverPattern => "any code following a never pattern is unreachable" ,
75
+ DivergeReason :: Other => "any code following this expression is unreachable" ,
76
+ } ;
77
+ lint. span_label ( span, msg) . span_label ( orig_span, label) ;
78
+ } )
81
79
}
82
80
83
81
/// Resolves type and const variables in `ty` if possible. Unlike the infcx
0 commit comments