@@ -50,30 +50,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
50
50
51
51
self . warn_arms_when_scrutinee_diverges ( arms, match_src) ;
52
52
53
- // Otherwise, we have to union together the types that the
54
- // arms produce and so forth.
55
- let scrut_diverges = self . diverges . get ( ) ;
56
- self . diverges . set ( Diverges :: Maybe ) ;
53
+ // Otherwise, we have to union together the types that the arms produce and so forth.
54
+ let scrut_diverges = self . diverges . replace ( Diverges :: Maybe ) ;
57
55
58
- // rust-lang/rust#55810: Typecheck patterns first (via eager
59
- // collection into `Vec`), so we get types for all bindings.
60
- let all_arm_pats_diverge: Vec < _ > = arms
61
- . iter ( )
62
- . map ( |arm| {
63
- let mut all_pats_diverge = Diverges :: WarnedAlways ;
64
- self . diverges . set ( Diverges :: Maybe ) ;
65
- self . check_pat_top ( & arm. pat , scrut_ty, Some ( scrut. span ) , true ) ;
66
- all_pats_diverge &= self . diverges . get ( ) ;
67
-
68
- // As discussed with @eddyb, this is for disabling unreachable_code
69
- // warnings on patterns (they're now subsumed by unreachable_patterns
70
- // warnings).
71
- match all_pats_diverge {
72
- Diverges :: Maybe => Diverges :: Maybe ,
73
- Diverges :: Always { .. } | Diverges :: WarnedAlways => Diverges :: WarnedAlways ,
74
- }
75
- } )
76
- . collect ( ) ;
56
+ // #55810: Type check patterns first so we get types for all bindings.
57
+ for arm in arms {
58
+ self . check_pat_top ( & arm. pat , scrut_ty, Some ( scrut. span ) , true ) ;
59
+ }
77
60
78
61
// Now typecheck the blocks.
79
62
//
@@ -104,19 +87,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
104
87
CoerceMany :: with_coercion_sites ( coerce_first, arms)
105
88
} ;
106
89
107
- let mut other_arms = vec ! [ ] ; // used only for diagnostics
90
+ let mut other_arms = vec ! [ ] ; // Used only for diagnostics.
108
91
let mut prior_arm_ty = None ;
109
- for ( i, ( arm, pats_diverge ) ) in arms. iter ( ) . zip ( all_arm_pats_diverge ) . enumerate ( ) {
92
+ for ( i, arm) in arms. iter ( ) . enumerate ( ) {
110
93
if let Some ( g) = & arm. guard {
111
- self . diverges . set ( pats_diverge ) ;
94
+ self . diverges . set ( Diverges :: Maybe ) ;
112
95
match g {
113
96
hir:: Guard :: If ( e) => {
114
97
self . check_expr_has_type_or_error ( e, tcx. types . bool , |_| { } )
115
98
}
116
99
} ;
117
100
}
118
101
119
- self . diverges . set ( pats_diverge ) ;
102
+ self . diverges . set ( Diverges :: Maybe ) ;
120
103
let arm_ty = if source_if
121
104
&& if_no_else
122
105
&& i != 0
@@ -200,16 +183,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
200
183
arms : & ' tcx [ hir:: Arm < ' tcx > ] ,
201
184
source : hir:: MatchSource ,
202
185
) {
203
- if self . diverges . get ( ) . is_always ( ) {
204
- use hir:: MatchSource :: * ;
205
- let msg = match source {
206
- IfDesugar { .. } | IfLetDesugar { .. } => "block in `if` expression" ,
207
- WhileDesugar { .. } | WhileLetDesugar { .. } => "block in `while` expression" ,
208
- _ => "arm" ,
209
- } ;
210
- for arm in arms {
211
- self . warn_if_unreachable ( arm. body . hir_id , arm. body . span , msg) ;
212
- }
186
+ use hir:: MatchSource :: * ;
187
+ let msg = match source {
188
+ IfDesugar { .. } | IfLetDesugar { .. } => "block in `if` expression" ,
189
+ WhileDesugar { .. } | WhileLetDesugar { .. } => "block in `while` expression" ,
190
+ _ => "arm" ,
191
+ } ;
192
+ for arm in arms {
193
+ self . warn_if_unreachable ( arm. body . hir_id , arm. body . span , msg) ;
213
194
}
214
195
}
215
196
0 commit comments