@@ -344,6 +344,12 @@ pub(super) struct PatCtxt<'a, 'p, 'tcx> {
344344 pub ( super ) is_top_level : bool ,
345345}
346346
347+ impl < ' a , ' p , ' tcx > fmt:: Debug for PatCtxt < ' a , ' p , ' tcx > {
348+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
349+ f. debug_struct ( "PatCtxt" ) . field ( "ty" , & self . ty ) . finish ( )
350+ }
351+ }
352+
347353crate fn expand_pattern < ' tcx > ( pat : Pat < ' tcx > ) -> Pat < ' tcx > {
348354 LiteralExpander . fold_pattern ( & pat)
349355}
@@ -383,7 +389,7 @@ impl<'tcx> Pat<'tcx> {
383389
384390/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
385391/// works well.
386- #[ derive( Debug , Clone ) ]
392+ #[ derive( Clone ) ]
387393struct PatStack < ' p , ' tcx > {
388394 pats : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ,
389395 /// Cache for the constructor of the head
@@ -475,6 +481,17 @@ impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> {
475481 }
476482}
477483
484+ /// Pretty-printing for matrix row.
485+ impl < ' p , ' tcx > fmt:: Debug for PatStack < ' p , ' tcx > {
486+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
487+ write ! ( f, "+" ) ?;
488+ for pat in self . iter ( ) {
489+ write ! ( f, " {} +" , pat) ?;
490+ }
491+ Ok ( ( ) )
492+ }
493+ }
494+
478495/// A 2D matrix.
479496#[ derive( Clone , PartialEq ) ]
480497pub ( super ) struct Matrix < ' p , ' tcx > {
@@ -543,35 +560,26 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
543560/// Pretty-printer for matrices of patterns, example:
544561///
545562/// ```text
546- /// +++++++++++++++++++++++++++++
547563/// + _ + [] +
548- /// +++++++++++++++++++++++++++++
549564/// + true + [First] +
550- /// +++++++++++++++++++++++++++++
551565/// + true + [Second(true)] +
552- /// +++++++++++++++++++++++++++++
553566/// + false + [_] +
554- /// +++++++++++++++++++++++++++++
555567/// + _ + [_, _, tail @ ..] +
556- /// +++++++++++++++++++++++++++++
557568/// ```
558569impl < ' p , ' tcx > fmt:: Debug for Matrix < ' p , ' tcx > {
559570 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
560571 write ! ( f, "\n " ) ?;
561572
562573 let Matrix { patterns : m, .. } = self ;
563574 let pretty_printed_matrix: Vec < Vec < String > > =
564- m. iter ( ) . map ( |row| row. iter ( ) . map ( |pat| format ! ( "{:? }" , pat) ) . collect ( ) ) . collect ( ) ;
575+ m. iter ( ) . map ( |row| row. iter ( ) . map ( |pat| format ! ( "{}" , pat) ) . collect ( ) ) . collect ( ) ;
565576
566- let column_count = m. iter ( ) . map ( |row| row. len ( ) ) . max ( ) . unwrap_or ( 0 ) ;
577+ let column_count = m. iter ( ) . map ( |row| row. len ( ) ) . next ( ) . unwrap_or ( 0 ) ;
567578 assert ! ( m. iter( ) . all( |row| row. len( ) == column_count) ) ;
568579 let column_widths: Vec < usize > = ( 0 ..column_count)
569580 . map ( |col| pretty_printed_matrix. iter ( ) . map ( |row| row[ col] . len ( ) ) . max ( ) . unwrap_or ( 0 ) )
570581 . collect ( ) ;
571582
572- let total_width = column_widths. iter ( ) . cloned ( ) . sum :: < usize > ( ) + column_count * 3 + 1 ;
573- let br = "+" . repeat ( total_width) ;
574- write ! ( f, "{}\n " , br) ?;
575583 for row in pretty_printed_matrix {
576584 write ! ( f, "+" ) ?;
577585 for ( column, pat_str) in row. into_iter ( ) . enumerate ( ) {
@@ -580,7 +588,6 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
580588 write ! ( f, " +" ) ?;
581589 }
582590 write ! ( f, "\n " ) ?;
583- write ! ( f, "{}\n " , br) ?;
584591 }
585592 Ok ( ( ) )
586593 }
@@ -924,6 +931,7 @@ impl<'tcx> Witness<'tcx> {
924931/// `is_under_guard` is used to inform if the pattern has a guard. If it
925932/// has one it must not be inserted into the matrix. This shouldn't be
926933/// relied on for soundness.
934+ #[ instrument( skip( cx, matrix, witness_preference, hir_id, is_under_guard, is_top_level) ) ]
927935fn is_useful < ' p , ' tcx > (
928936 cx : & MatchCheckCtxt < ' p , ' tcx > ,
929937 matrix : & Matrix < ' p , ' tcx > ,
@@ -933,32 +941,30 @@ fn is_useful<'p, 'tcx>(
933941 is_under_guard : bool ,
934942 is_top_level : bool ,
935943) -> Usefulness < ' tcx > {
944+ debug ! ( "matrix,v={:?}{:?}" , matrix, v) ;
936945 let Matrix { patterns : rows, .. } = matrix;
937- debug ! ( "is_useful({:#?}, {:#?})" , matrix, v) ;
938946
939947 // The base case. We are pattern-matching on () and the return value is
940948 // based on whether our matrix has a row or not.
941949 // NOTE: This could potentially be optimized by checking rows.is_empty()
942950 // first and then, if v is non-empty, the return value is based on whether
943951 // the type of the tuple we're checking is inhabited or not.
944952 if v. is_empty ( ) {
945- return if rows. is_empty ( ) {
946- Usefulness :: new_useful ( witness_preference)
947- } else {
948- NotUseful
949- } ;
950- } ;
953+ let ret =
954+ if rows. is_empty ( ) { Usefulness :: new_useful ( witness_preference) } else { NotUseful } ;
955+ debug ! ( ?ret) ;
956+ return ret;
957+ }
951958
952959 assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
953960
954961 // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
955962 let ty = matrix. heads ( ) . next ( ) . map_or ( v. head ( ) . ty , |r| r. ty ) ;
956963 let pcx = PatCtxt { cx, ty, span : v. head ( ) . span , is_top_level } ;
957964
958- debug ! ( "is_useful_expand_first_col: ty={:#?}, expanding {:#?}" , pcx. ty, v. head( ) ) ;
959-
960965 // If the first pattern is an or-pattern, expand it.
961966 let ret = if let Some ( vs) = v. expand_or_pat ( ) {
967+ debug ! ( "expanding or-pattern" ) ;
962968 let subspans: Vec < _ > = vs. iter ( ) . map ( |v| v. head ( ) . span ) . collect ( ) ;
963969 // We expand the or pattern, trying each of its branches in turn and keeping careful track
964970 // of possible unreachable sub-branches.
@@ -993,6 +999,7 @@ fn is_useful<'p, 'tcx>(
993999 // witness the usefulness of `v`.
9941000 let start_matrix = & matrix;
9951001 let usefulnesses = split_ctors. into_iter ( ) . map ( |ctor| {
1002+ debug ! ( "specialize({:?})" , ctor) ;
9961003 // We cache the result of `Fields::wildcards` because it is used a lot.
9971004 let ctor_wild_subpatterns = Fields :: wildcards ( pcx, & ctor) ;
9981005 let spec_matrix =
@@ -1004,7 +1011,7 @@ fn is_useful<'p, 'tcx>(
10041011 } ) ;
10051012 Usefulness :: merge ( usefulnesses)
10061013 } ;
1007- debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix , v , ret) ;
1014+ debug ! ( ? ret) ;
10081015 ret
10091016}
10101017
0 commit comments