@@ -91,7 +91,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
9191 fn visit_local ( & mut self , loc : & ' tcx hir:: Local ) {
9292 intravisit:: walk_local ( self , loc) ;
9393
94- self . check_irrefutable ( & loc. pat , false ) ;
94+ self . check_irrefutable ( & loc. pat , match loc. source {
95+ hir:: LocalSource :: Normal => "local binding" ,
96+ hir:: LocalSource :: ForLoopDesugar => "`for` loop binding" ,
97+ } ) ;
9598
9699 // Check legality of move bindings and `@` patterns.
97100 self . check_patterns ( false , slice:: ref_slice ( & loc. pat ) ) ;
@@ -101,7 +104,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
101104 intravisit:: walk_body ( self , body) ;
102105
103106 for arg in & body. arguments {
104- self . check_irrefutable ( & arg. pat , true ) ;
107+ self . check_irrefutable ( & arg. pat , "function argument" ) ;
105108 self . check_patterns ( false , slice:: ref_slice ( & arg. pat ) ) ;
106109 }
107110 }
@@ -210,7 +213,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
210213 . map ( |pat| vec ! [ pat. 0 ] )
211214 . collect ( ) ;
212215 let scrut_ty = self . tables . node_id_to_type ( scrut. id ) ;
213- check_exhaustive ( cx, scrut_ty, scrut. span , & matrix, source ) ;
216+ check_exhaustive ( cx, scrut_ty, scrut. span , & matrix) ;
214217 } )
215218 }
216219
@@ -223,13 +226,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
223226 }
224227 }
225228
226- fn check_irrefutable ( & self , pat : & Pat , is_fn_arg : bool ) {
227- let origin = if is_fn_arg {
228- "function argument"
229- } else {
230- "local binding"
231- } ;
232-
229+ fn check_irrefutable ( & self , pat : & Pat , origin : & str ) {
233230 let module = self . tcx . hir . get_module_parent ( pat. id ) ;
234231 MatchCheckCtxt :: create_and_enter ( self . tcx , module, |ref mut cx| {
235232 let mut patcx = PatternContext :: new ( self . tcx , self . tables ) ;
@@ -395,8 +392,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
395392fn check_exhaustive < ' a , ' tcx > ( cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
396393 scrut_ty : Ty < ' tcx > ,
397394 sp : Span ,
398- matrix : & Matrix < ' a , ' tcx > ,
399- source : hir:: MatchSource ) {
395+ matrix : & Matrix < ' a , ' tcx > ) {
400396 let wild_pattern = Pattern {
401397 ty : scrut_ty,
402398 span : DUMMY_SP ,
@@ -409,52 +405,32 @@ fn check_exhaustive<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
409405 } else {
410406 pats. iter ( ) . map ( |w| w. single_pattern ( ) ) . collect ( )
411407 } ;
412- match source {
413- hir:: MatchSource :: ForLoopDesugar => {
414- // `witnesses[0]` has the form `Some(<head>)`, peel off the `Some`
415- let witness = match * witnesses[ 0 ] . kind {
416- PatternKind :: Variant { ref subpatterns, .. } => match & subpatterns[ ..] {
417- & [ ref pat] => & pat. pattern ,
418- _ => bug ! ( ) ,
419- } ,
420- _ => bug ! ( ) ,
421- } ;
422- let pattern_string = witness. to_string ( ) ;
423- struct_span_err ! ( cx. tcx. sess, sp, E0297 ,
424- "refutable pattern in `for` loop binding: \
425- `{}` not covered",
426- pattern_string)
427- . span_label ( sp, format ! ( "pattern `{}` not covered" , pattern_string) )
428- . emit ( ) ;
408+
409+ const LIMIT : usize = 3 ;
410+ let joined_patterns = match witnesses. len ( ) {
411+ 0 => bug ! ( ) ,
412+ 1 => format ! ( "`{}`" , witnesses[ 0 ] ) ,
413+ 2 ...LIMIT => {
414+ let ( tail, head) = witnesses. split_last ( ) . unwrap ( ) ;
415+ let head: Vec < _ > = head. iter ( ) . map ( |w| w. to_string ( ) ) . collect ( ) ;
416+ format ! ( "`{}` and `{}`" , head. join( "`, `" ) , tail)
429417 } ,
430418 _ => {
431- const LIMIT : usize = 3 ;
432- let joined_patterns = match witnesses. len ( ) {
433- 0 => bug ! ( ) ,
434- 1 => format ! ( "`{}`" , witnesses[ 0 ] ) ,
435- 2 ...LIMIT => {
436- let ( tail, head) = witnesses. split_last ( ) . unwrap ( ) ;
437- let head: Vec < _ > = head. iter ( ) . map ( |w| w. to_string ( ) ) . collect ( ) ;
438- format ! ( "`{}` and `{}`" , head. join( "`, `" ) , tail)
439- } ,
440- _ => {
441- let ( head, tail) = witnesses. split_at ( LIMIT ) ;
442- let head: Vec < _ > = head. iter ( ) . map ( |w| w. to_string ( ) ) . collect ( ) ;
443- format ! ( "`{}` and {} more" , head. join( "`, `" ) , tail. len( ) )
444- }
445- } ;
446-
447- let label_text = match witnesses. len ( ) {
448- 1 => format ! ( "pattern {} not covered" , joined_patterns) ,
449- _ => format ! ( "patterns {} not covered" , joined_patterns)
450- } ;
451- create_e0004 ( cx. tcx . sess , sp,
452- format ! ( "non-exhaustive patterns: {} not covered" ,
453- joined_patterns) )
454- . span_label ( sp, label_text)
455- . emit ( ) ;
456- } ,
457- }
419+ let ( head, tail) = witnesses. split_at ( LIMIT ) ;
420+ let head: Vec < _ > = head. iter ( ) . map ( |w| w. to_string ( ) ) . collect ( ) ;
421+ format ! ( "`{}` and {} more" , head. join( "`, `" ) , tail. len( ) )
422+ }
423+ } ;
424+
425+ let label_text = match witnesses. len ( ) {
426+ 1 => format ! ( "pattern {} not covered" , joined_patterns) ,
427+ _ => format ! ( "patterns {} not covered" , joined_patterns)
428+ } ;
429+ create_e0004 ( cx. tcx . sess , sp,
430+ format ! ( "non-exhaustive patterns: {} not covered" ,
431+ joined_patterns) )
432+ . span_label ( sp, label_text)
433+ . emit ( ) ;
458434 }
459435 NotUseful => {
460436 // This is good, wildcard pattern isn't reachable
0 commit comments