@@ -50,30 +50,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5050
5151 self . warn_arms_when_scrutinee_diverges ( arms, match_src) ;
5252
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 ) ;
5755
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+ }
7760
7861 // Now typecheck the blocks.
7962 //
@@ -104,19 +87,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10487 CoerceMany :: with_coercion_sites ( coerce_first, arms)
10588 } ;
10689
107- let mut other_arms = vec ! [ ] ; // used only for diagnostics
90+ let mut other_arms = vec ! [ ] ; // Used only for diagnostics.
10891 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 ( ) {
11093 if let Some ( g) = & arm. guard {
111- self . diverges . set ( pats_diverge ) ;
94+ self . diverges . set ( Diverges :: Maybe ) ;
11295 match g {
11396 hir:: Guard :: If ( e) => {
11497 self . check_expr_has_type_or_error ( e, tcx. types . bool , |_| { } )
11598 }
11699 } ;
117100 }
118101
119- self . diverges . set ( pats_diverge ) ;
102+ self . diverges . set ( Diverges :: Maybe ) ;
120103 let arm_ty = if source_if
121104 && if_no_else
122105 && i != 0
@@ -200,16 +183,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
200183 arms : & ' tcx [ hir:: Arm < ' tcx > ] ,
201184 source : hir:: MatchSource ,
202185 ) {
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) ;
213194 }
214195 }
215196
0 commit comments