@@ -112,36 +112,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
112112 }
113113
114114 self . diverges . set ( pats_diverge) ;
115- let arm_ty = if source_if {
115+ let arm_ty = if source_if && if_no_else && i != 0 && self . if_fallback_coercion (
116+ expr. span ,
117+ & arms[ 0 ] . body ,
118+ & mut coercion,
119+ ) {
120+ tcx. types . err
121+ } else {
122+ // Only call this if this is not an `if` expr with an expected type and no `else`
123+ // clause to avoid duplicated type errors. (#60254)
124+ let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
125+ all_arms_diverge &= self . diverges . get ( ) ;
126+ arm_ty
127+ } ;
128+ if source_if {
116129 let then_expr = & arms[ 0 ] . body ;
117130 match ( i, if_no_else) {
118- ( 0 , _) => {
119- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
120- all_arms_diverge &= self . diverges . get ( ) ;
121- coercion. coerce ( self , & self . misc ( expr. span ) , & arm. body , arm_ty) ;
122- arm_ty
123- }
124- ( _, true ) => {
125- if self . if_fallback_coercion ( expr. span , then_expr, & mut coercion) {
126- tcx. types . err
127- } else {
128- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
129- all_arms_diverge &= self . diverges . get ( ) ;
130- arm_ty
131- }
132- }
131+ ( 0 , _) => coercion. coerce ( self , & self . misc ( expr. span ) , & arm. body , arm_ty) ,
132+ ( _, true ) => { } // Handled above to avoid duplicated type errors (#60254).
133133 ( _, _) => {
134- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
135- all_arms_diverge &= self . diverges . get ( ) ;
136134 let then_ty = prior_arm_ty. unwrap ( ) ;
137135 let cause = self . if_cause ( expr. span , then_expr, & arm. body , then_ty, arm_ty) ;
138136 coercion. coerce ( self , & cause, & arm. body , arm_ty) ;
139- arm_ty
140137 }
141138 }
142139 } else {
143- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
144- all_arms_diverge &= self . diverges . get ( ) ;
145140 let arm_span = if let hir:: ExprKind :: Block ( blk, _) = & arm. body . node {
146141 // Point at the block expr instead of the entire block
147142 blk. expr . as_ref ( ) . map ( |e| e. span ) . unwrap_or ( arm. body . span )
@@ -166,8 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166161 if other_arms. len ( ) > 5 {
167162 other_arms. remove ( 0 ) ;
168163 }
169- arm_ty
170- } ;
164+ }
171165 prior_arm_ty = Some ( arm_ty) ;
172166 }
173167
0 commit comments