@@ -191,45 +191,45 @@ impl ExprValidator {
191191 let pattern_arena = Arena :: new ( ) ;
192192 let mut m_arms = Vec :: with_capacity ( arms. len ( ) ) ;
193193 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.
194196 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 ;
226230 }
227231 }
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.
233233 cov_mark:: hit!( validate_match_bailed_out) ;
234234 return ;
235235 }
@@ -534,8 +534,16 @@ fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResul
534534 fn walk ( pat : PatId , body : & Body , infer : & InferenceResult , has_type_mismatches : & mut bool ) {
535535 match infer. type_mismatch_for_pat ( pat) {
536536 Some ( _) => * has_type_mismatches = true ,
537+ None if * has_type_mismatches => ( ) ,
537538 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) )
539547 }
540548 }
541549 }
0 commit comments