@@ -191,45 +191,45 @@ impl ExprValidator {
191
191
let pattern_arena = Arena :: new ( ) ;
192
192
let mut m_arms = Vec :: with_capacity ( arms. len ( ) ) ;
193
193
let mut has_lowering_errors = false ;
194
+ // Note: Skipping the entire diagnostic rather than just not including a faulty match arm is
195
+ // preferred to avoid the chance of false positives.
194
196
for arm in arms {
195
- if let Some ( pat_ty) = self . infer . type_of_pat . get ( arm. pat ) {
196
- // We only include patterns whose type matches the type
197
- // of the scrutinee expression. If we had an InvalidMatchArmPattern
198
- // diagnostic or similar we could raise that in an else
199
- // block here.
200
- //
201
- // When comparing the types, we also have to consider that rustc
202
- // will automatically de-reference the scrutinee expression type if
203
- // necessary.
204
- //
205
- // FIXME we should use the type checker for this.
206
- if ( pat_ty == scrut_ty
207
- || scrut_ty
208
- . as_reference ( )
209
- . map ( |( match_expr_ty, ..) | match_expr_ty == pat_ty)
210
- . unwrap_or ( false ) )
211
- && types_of_subpatterns_do_match ( arm. pat , & self . body , & self . infer )
212
- {
213
- // If we had a NotUsefulMatchArm diagnostic, we could
214
- // check the usefulness of each pattern as we added it
215
- // to the matrix here.
216
- let pat = self . lower_pattern ( & cx, arm. pat , db, & mut has_lowering_errors) ;
217
- let m_arm = pat_analysis:: MatchArm {
218
- pat : pattern_arena. alloc ( pat) ,
219
- has_guard : arm. guard . is_some ( ) ,
220
- arm_data : ( ) ,
221
- } ;
222
- m_arms. push ( m_arm) ;
223
- if !has_lowering_errors {
224
- continue ;
225
- }
197
+ let Some ( pat_ty) = self . infer . type_of_pat . get ( arm. pat ) else {
198
+ return ;
199
+ } ;
200
+
201
+ // We only include patterns whose type matches the type
202
+ // of the scrutinee expression. If we had an InvalidMatchArmPattern
203
+ // diagnostic or similar we could raise that in an else
204
+ // block here.
205
+ //
206
+ // When comparing the types, we also have to consider that rustc
207
+ // will automatically de-reference the scrutinee expression type if
208
+ // necessary.
209
+ //
210
+ // FIXME we should use the type checker for this.
211
+ if ( pat_ty == scrut_ty
212
+ || scrut_ty
213
+ . as_reference ( )
214
+ . map ( |( match_expr_ty, ..) | match_expr_ty == pat_ty)
215
+ . unwrap_or ( false ) )
216
+ && types_of_subpatterns_do_match ( arm. pat , & self . body , & self . infer )
217
+ {
218
+ // If we had a NotUsefulMatchArm diagnostic, we could
219
+ // check the usefulness of each pattern as we added it
220
+ // to the matrix here.
221
+ let pat = self . lower_pattern ( & cx, arm. pat , db, & mut has_lowering_errors) ;
222
+ let m_arm = pat_analysis:: MatchArm {
223
+ pat : pattern_arena. alloc ( pat) ,
224
+ has_guard : arm. guard . is_some ( ) ,
225
+ arm_data : ( ) ,
226
+ } ;
227
+ m_arms. push ( m_arm) ;
228
+ if !has_lowering_errors {
229
+ continue ;
226
230
}
227
231
}
228
-
229
- // If we can't resolve the type of a pattern, or the pattern type doesn't
230
- // fit the match expression, we skip this diagnostic. Skipping the entire
231
- // diagnostic rather than just not including this match arm is preferred
232
- // to avoid the chance of false positives.
232
+ // If the pattern type doesn't fit the match expression, we skip this diagnostic.
233
233
cov_mark:: hit!( validate_match_bailed_out) ;
234
234
return ;
235
235
}
@@ -534,8 +534,16 @@ fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResul
534
534
fn walk ( pat : PatId , body : & Body , infer : & InferenceResult , has_type_mismatches : & mut bool ) {
535
535
match infer. type_mismatch_for_pat ( pat) {
536
536
Some ( _) => * has_type_mismatches = true ,
537
+ None if * has_type_mismatches => ( ) ,
537
538
None => {
538
- body[ pat] . walk_child_pats ( |subpat| walk ( subpat, body, infer, has_type_mismatches) )
539
+ let pat = & body[ pat] ;
540
+ if let Pat :: ConstBlock ( expr) | Pat :: Lit ( expr) = * pat {
541
+ * has_type_mismatches |= infer. type_mismatch_for_expr ( expr) . is_some ( ) ;
542
+ if * has_type_mismatches {
543
+ return ;
544
+ }
545
+ }
546
+ pat. walk_child_pats ( |subpat| walk ( subpat, body, infer, has_type_mismatches) )
539
547
}
540
548
}
541
549
}
0 commit comments