@@ -750,12 +750,15 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
750750 LocalFor => "`for` loop"
751751 } ;
752752
753- let mut spans = vec ! [ ] ;
754- find_refutable ( cx, & * loc. pat , & mut spans) ;
755-
756- for span in spans. iter ( ) {
757- cx. tcx . sess . span_err ( * span,
758- format ! ( "refutable pattern in {} binding" , name) . as_slice ( ) ) ;
753+ match is_refutable ( cx, loc. pat ) {
754+ Some ( pat) => {
755+ let msg = format ! (
756+ "refutable pattern in {} binding: {} not covered" ,
757+ name, pat_to_str( & * pat)
758+ ) ;
759+ cx. tcx . sess . span_err ( loc. pat . span , msg. as_slice ( ) ) ;
760+ } ,
761+ None => ( )
759762 }
760763
761764 // Check legality of move bindings.
@@ -769,67 +772,27 @@ fn check_fn(cx: &mut MatchCheckCtxt,
769772 sp : Span ) {
770773 visit:: walk_fn ( cx, kind, decl, body, sp, ( ) ) ;
771774 for input in decl. inputs . iter ( ) {
772- let mut spans = vec ! [ ] ;
773- find_refutable ( cx, & * input. pat , & mut spans) ;
774-
775- for span in spans. iter ( ) {
776- cx. tcx . sess . span_err ( * span,
777- "refutable pattern in function argument" ) ;
775+ match is_refutable ( cx, input. pat ) {
776+ Some ( pat) => {
777+ let msg = format ! (
778+ "refutable pattern in function argument: {} not covered" ,
779+ pat_to_str( & * pat)
780+ ) ;
781+ cx. tcx . sess . span_err ( input. pat . span , msg. as_slice ( ) ) ;
782+ } ,
783+ None => ( )
778784 }
779785 }
780786}
781787
782- fn find_refutable ( cx : & MatchCheckCtxt , pat : & Pat , spans : & mut Vec < Span > ) {
783- macro_rules! this_pattern {
784- ( ) => {
785- {
786- spans. push( pat. span) ;
787- return
788- }
789- }
790- }
791- let opt_def = cx. tcx . def_map . borrow ( ) . find_copy ( & pat. id ) ;
792- match opt_def {
793- Some ( DefVariant ( enum_id, _, _) ) => {
794- if ty:: enum_variants ( cx. tcx , enum_id) . len ( ) != 1 u {
795- this_pattern ! ( )
796- }
797- }
798- Some ( DefStatic ( ..) ) => this_pattern ! ( ) ,
799- _ => ( )
800- }
801-
802- match pat. node {
803- PatBox ( ref sub) | PatRegion ( ref sub) | PatIdent ( _, _, Some ( ref sub) ) => {
804- find_refutable ( cx, & * * sub, spans)
805- }
806- PatWild | PatWildMulti | PatIdent ( _, _, None ) => { }
807- PatLit ( lit) => {
808- match lit. node {
809- ExprLit ( lit) => {
810- match lit. node {
811- LitNil => { } // `()`
812- _ => this_pattern ! ( ) ,
813- }
814- }
815- _ => this_pattern ! ( ) ,
816- }
817- }
818- PatRange ( _, _) => { this_pattern ! ( ) }
819- PatStruct ( _, ref fields, _) => {
820- for f in fields. iter ( ) {
821- find_refutable ( cx, & * f. pat , spans) ;
822- }
823- }
824- PatTup ( ref elts) | PatEnum ( _, Some ( ref elts) ) => {
825- for elt in elts. iter ( ) {
826- find_refutable ( cx, & * * elt, spans)
827- }
828- }
829- PatEnum ( _, _) => { }
830- PatVec ( ..) => { this_pattern ! ( ) }
831- PatMac ( _) => cx. tcx . sess . bug ( "unexpanded macro" ) ,
832- }
788+ fn is_refutable ( cx : & MatchCheckCtxt , pat : Gc < Pat > ) -> Option < Gc < Pat > > {
789+ let pats = vec ! ( vec!( pat) ) ;
790+ is_useful ( cx, & pats, [ wild ( ) ] )
791+ . useful ( )
792+ . map ( |pats| {
793+ assert_eq ! ( pats. len( ) , 1 ) ;
794+ pats. get ( 0 ) . clone ( )
795+ } )
833796}
834797
835798// Legality of move bindings checking
0 commit comments