@@ -112,36 +112,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
112
112
}
113
113
114
114
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 {
116
129
let then_expr = & arms[ 0 ] . body ;
117
130
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).
133
133
( _, _) => {
134
- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
135
- all_arms_diverge &= self . diverges . get ( ) ;
136
134
let then_ty = prior_arm_ty. unwrap ( ) ;
137
135
let cause = self . if_cause ( expr. span , then_expr, & arm. body , then_ty, arm_ty) ;
138
136
coercion. coerce ( self , & cause, & arm. body , arm_ty) ;
139
- arm_ty
140
137
}
141
138
}
142
139
} else {
143
- let arm_ty = self . check_expr_with_expectation ( & arm. body , expected) ;
144
- all_arms_diverge &= self . diverges . get ( ) ;
145
140
let arm_span = if let hir:: ExprKind :: Block ( blk, _) = & arm. body . node {
146
141
// Point at the block expr instead of the entire block
147
142
blk. expr . as_ref ( ) . map ( |e| e. span ) . unwrap_or ( arm. body . span )
@@ -166,8 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166
161
if other_arms. len ( ) > 5 {
167
162
other_arms. remove ( 0 ) ;
168
163
}
169
- arm_ty
170
- } ;
164
+ }
171
165
prior_arm_ty = Some ( arm_ty) ;
172
166
}
173
167
0 commit comments