1- use super :: _match:: { MatchCheckCtxt , Matrix , Witness , expand_pattern, is_useful} ;
1+ use super :: _match:: { MatchCheckCtxt , Matrix , expand_pattern, is_useful} ;
22use super :: _match:: Usefulness :: * ;
33use super :: _match:: WitnessPreference :: * ;
44
@@ -276,26 +276,26 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
276276 expand_pattern( cx, pattern)
277277 ] ] . into_iter ( ) . collect ( ) ;
278278
279- let witness = match check_not_useful ( cx, pattern_ty, & pats) {
279+ let witnesses = match check_not_useful ( cx, pattern_ty, & pats) {
280280 Ok ( _) => return ,
281- Err ( ( witness , _ ) ) => witness ,
281+ Err ( err ) => err ,
282282 } ;
283283
284- let pattern_string = witness [ 0 ] . single_pattern ( ) . to_string ( ) ;
284+ let joined_patterns = joined_uncovered_patterns ( & witnesses ) ;
285285 let mut err = struct_span_err ! (
286286 self . tcx. sess, pat. span, E0005 ,
287- "refutable pattern in {}: `{}` not covered" ,
288- origin, pattern_string
287+ "refutable pattern in {}: {} not covered" ,
288+ origin, joined_patterns
289289 ) ;
290- err. span_label ( pat. span , match pat. node {
291- PatKind :: Path ( hir:: QPath :: Resolved ( None , ref path) )
292- if path. segments . len ( ) == 1 && path. segments [ 0 ] . args . is_none ( ) => {
290+ err. span_label ( pat. span , match & pat. node {
291+ PatKind :: Path ( hir:: QPath :: Resolved ( None , path) )
292+ if path. segments . len ( ) == 1 && path. segments [ 0 ] . args . is_none ( ) => {
293293 format ! ( "interpreted as {} {} pattern, not new variable" ,
294294 path. res. article( ) , path. res. descr( ) )
295295 }
296- _ => format ! ( "pattern `{}` not covered" , pattern_string ) ,
296+ _ => pattern_not_convered_label ( & witnesses , & joined_patterns ) ,
297297 } ) ;
298- adt_defined_here ( cx, pattern_ty . peel_refs ( ) , & mut err) ;
298+ adt_defined_here ( cx, & mut err, pattern_ty , & witnesses ) ;
299299 err. emit ( ) ;
300300 } ) ;
301301 }
@@ -437,11 +437,15 @@ fn check_not_useful(
437437 cx : & mut MatchCheckCtxt < ' _ , ' tcx > ,
438438 ty : Ty < ' tcx > ,
439439 matrix : & Matrix < ' _ , ' tcx > ,
440- ) -> Result < ( ) , ( Vec < Witness < ' tcx > > , Pattern < ' tcx > ) > {
440+ ) -> Result < ( ) , Vec < Pattern < ' tcx > > > {
441441 let wild_pattern = Pattern { ty, span : DUMMY_SP , kind : box PatternKind :: Wild } ;
442442 match is_useful ( cx, matrix, & [ & wild_pattern] , ConstructWitness ) {
443443 NotUseful => Ok ( ( ) ) , // This is good, wildcard pattern isn't reachable.
444- UsefulWithWitness ( pats) => Err ( ( pats, wild_pattern) ) ,
444+ UsefulWithWitness ( pats) => Err ( if pats. is_empty ( ) {
445+ vec ! [ wild_pattern]
446+ } else {
447+ pats. into_iter ( ) . map ( |w| w. single_pattern ( ) ) . collect ( )
448+ } ) ,
445449 Useful => bug ! ( ) ,
446450 }
447451}
@@ -452,42 +456,26 @@ fn check_exhaustive<'tcx>(
452456 sp : Span ,
453457 matrix : & Matrix < ' _ , ' tcx > ,
454458) {
455- let ( pats , wild_pattern ) = match check_not_useful ( cx, scrut_ty, matrix) {
459+ let witnesses = match check_not_useful ( cx, scrut_ty, matrix) {
456460 Ok ( _) => return ,
457461 Err ( err) => err,
458462 } ;
459463
460- let witnesses = if pats. is_empty ( ) {
461- vec ! [ & wild_pattern]
462- } else {
463- pats. iter ( ) . map ( |w| w. single_pattern ( ) ) . collect ( )
464- } ;
465-
466464 let joined_patterns = joined_uncovered_patterns ( & witnesses) ;
467-
468- let mut err = create_e0004 ( cx. tcx . sess , sp, format ! (
469- "non-exhaustive patterns: {} not covered" ,
470- joined_patterns,
471- ) ) ;
472- err. span_label ( sp, match witnesses. len ( ) {
473- 1 => format ! ( "pattern {} not covered" , joined_patterns) ,
474- _ => format ! ( "patterns {} not covered" , joined_patterns) ,
475- } ) ;
476- // point at the definition of non-covered enum variants
477- let scrut_ty = scrut_ty. peel_refs ( ) ;
478- adt_defined_here ( cx, scrut_ty, & mut err) ;
479- let patterns = witnesses. iter ( ) . map ( |p| ( * * p) . clone ( ) ) . collect :: < Vec < Pattern < ' _ > > > ( ) ;
480- if patterns. len ( ) < 4 {
481- for sp in maybe_point_at_variant ( scrut_ty, & patterns) {
482- err. span_label ( sp, "not covered" ) ;
483- }
484- }
485- err. help ( "ensure that all possible cases are being handled, \
486- possibly by adding wildcards or more match arms") ;
487- err. emit ( ) ;
465+ let mut err = create_e0004 (
466+ cx. tcx . sess , sp,
467+ format ! ( "non-exhaustive patterns: {} not covered" , joined_patterns) ,
468+ ) ;
469+ err. span_label ( sp, pattern_not_convered_label ( & witnesses, & joined_patterns) ) ;
470+ adt_defined_here ( cx, & mut err, scrut_ty, & witnesses) ;
471+ err. help (
472+ "ensure that all possible cases are being handled, \
473+ possibly by adding wildcards or more match arms"
474+ )
475+ . emit ( ) ;
488476}
489477
490- fn joined_uncovered_patterns ( witnesses : & [ & Pattern < ' _ > ] ) -> String {
478+ fn joined_uncovered_patterns ( witnesses : & [ Pattern < ' _ > ] ) -> String {
491479 const LIMIT : usize = 3 ;
492480 match witnesses {
493481 [ ] => bug ! ( ) ,
@@ -504,11 +492,31 @@ fn joined_uncovered_patterns(witnesses: &[&Pattern<'_>]) -> String {
504492 }
505493}
506494
507- fn adt_defined_here ( cx : & mut MatchCheckCtxt < ' _ , ' _ > , ty : Ty < ' _ > , err : & mut DiagnosticBuilder < ' _ > ) {
495+ fn pattern_not_convered_label ( witnesses : & [ Pattern < ' _ > ] , joined_patterns : & str ) -> String {
496+ match witnesses. len ( ) {
497+ 1 => format ! ( "pattern {} not covered" , joined_patterns) ,
498+ _ => format ! ( "patterns {} not covered" , joined_patterns) ,
499+ }
500+ }
501+
502+ /// Point at the definition of non-covered `enum` variants.
503+ fn adt_defined_here (
504+ cx : & MatchCheckCtxt < ' _ , ' _ > ,
505+ err : & mut DiagnosticBuilder < ' _ > ,
506+ ty : Ty < ' _ > ,
507+ witnesses : & [ Pattern < ' _ > ] ,
508+ ) {
509+ let ty = ty. peel_refs ( ) ;
508510 if let ty:: Adt ( def, _) = ty. sty {
509511 if let Some ( sp) = cx. tcx . hir ( ) . span_if_local ( def. did ) {
510512 err. span_label ( sp, format ! ( "`{}` defined here" , ty) ) ;
511513 }
514+
515+ if witnesses. len ( ) < 4 {
516+ for sp in maybe_point_at_variant ( ty, & witnesses) {
517+ err. span_label ( sp, "not covered" ) ;
518+ }
519+ }
512520 }
513521}
514522
0 commit comments