@@ -344,6 +344,12 @@ pub(super) struct PatCtxt<'a, 'p, 'tcx> {
344
344
pub ( super ) is_top_level : bool ,
345
345
}
346
346
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
+
347
353
crate fn expand_pattern < ' tcx > ( pat : Pat < ' tcx > ) -> Pat < ' tcx > {
348
354
LiteralExpander . fold_pattern ( & pat)
349
355
}
@@ -383,7 +389,7 @@ impl<'tcx> Pat<'tcx> {
383
389
384
390
/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
385
391
/// works well.
386
- #[ derive( Debug , Clone ) ]
392
+ #[ derive( Clone ) ]
387
393
struct PatStack < ' p , ' tcx > {
388
394
pats : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ,
389
395
/// Cache for the constructor of the head
@@ -475,6 +481,17 @@ impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> {
475
481
}
476
482
}
477
483
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
+
478
495
/// A 2D matrix.
479
496
#[ derive( Clone , PartialEq ) ]
480
497
pub ( super ) struct Matrix < ' p , ' tcx > {
@@ -543,35 +560,26 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
543
560
/// Pretty-printer for matrices of patterns, example:
544
561
///
545
562
/// ```text
546
- /// +++++++++++++++++++++++++++++
547
563
/// + _ + [] +
548
- /// +++++++++++++++++++++++++++++
549
564
/// + true + [First] +
550
- /// +++++++++++++++++++++++++++++
551
565
/// + true + [Second(true)] +
552
- /// +++++++++++++++++++++++++++++
553
566
/// + false + [_] +
554
- /// +++++++++++++++++++++++++++++
555
567
/// + _ + [_, _, tail @ ..] +
556
- /// +++++++++++++++++++++++++++++
557
568
/// ```
558
569
impl < ' p , ' tcx > fmt:: Debug for Matrix < ' p , ' tcx > {
559
570
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
560
571
write ! ( f, "\n " ) ?;
561
572
562
573
let Matrix { patterns : m, .. } = self ;
563
574
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 ( ) ;
565
576
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 ) ;
567
578
assert ! ( m. iter( ) . all( |row| row. len( ) == column_count) ) ;
568
579
let column_widths: Vec < usize > = ( 0 ..column_count)
569
580
. map ( |col| pretty_printed_matrix. iter ( ) . map ( |row| row[ col] . len ( ) ) . max ( ) . unwrap_or ( 0 ) )
570
581
. collect ( ) ;
571
582
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) ?;
575
583
for row in pretty_printed_matrix {
576
584
write ! ( f, "+" ) ?;
577
585
for ( column, pat_str) in row. into_iter ( ) . enumerate ( ) {
@@ -580,7 +588,6 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
580
588
write ! ( f, " +" ) ?;
581
589
}
582
590
write ! ( f, "\n " ) ?;
583
- write ! ( f, "{}\n " , br) ?;
584
591
}
585
592
Ok ( ( ) )
586
593
}
@@ -924,6 +931,7 @@ impl<'tcx> Witness<'tcx> {
924
931
/// `is_under_guard` is used to inform if the pattern has a guard. If it
925
932
/// has one it must not be inserted into the matrix. This shouldn't be
926
933
/// relied on for soundness.
934
+ #[ instrument( skip( cx, matrix, witness_preference, hir_id, is_under_guard, is_top_level) ) ]
927
935
fn is_useful < ' p , ' tcx > (
928
936
cx : & MatchCheckCtxt < ' p , ' tcx > ,
929
937
matrix : & Matrix < ' p , ' tcx > ,
@@ -933,32 +941,30 @@ fn is_useful<'p, 'tcx>(
933
941
is_under_guard : bool ,
934
942
is_top_level : bool ,
935
943
) -> Usefulness < ' tcx > {
944
+ debug ! ( "matrix,v={:?}{:?}" , matrix, v) ;
936
945
let Matrix { patterns : rows, .. } = matrix;
937
- debug ! ( "is_useful({:#?}, {:#?})" , matrix, v) ;
938
946
939
947
// The base case. We are pattern-matching on () and the return value is
940
948
// based on whether our matrix has a row or not.
941
949
// NOTE: This could potentially be optimized by checking rows.is_empty()
942
950
// first and then, if v is non-empty, the return value is based on whether
943
951
// the type of the tuple we're checking is inhabited or not.
944
952
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
+ }
951
958
952
959
assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
953
960
954
961
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
955
962
let ty = matrix. heads ( ) . next ( ) . map_or ( v. head ( ) . ty , |r| r. ty ) ;
956
963
let pcx = PatCtxt { cx, ty, span : v. head ( ) . span , is_top_level } ;
957
964
958
- debug ! ( "is_useful_expand_first_col: ty={:#?}, expanding {:#?}" , pcx. ty, v. head( ) ) ;
959
-
960
965
// If the first pattern is an or-pattern, expand it.
961
966
let ret = if let Some ( vs) = v. expand_or_pat ( ) {
967
+ debug ! ( "expanding or-pattern" ) ;
962
968
let subspans: Vec < _ > = vs. iter ( ) . map ( |v| v. head ( ) . span ) . collect ( ) ;
963
969
// We expand the or pattern, trying each of its branches in turn and keeping careful track
964
970
// of possible unreachable sub-branches.
@@ -993,6 +999,7 @@ fn is_useful<'p, 'tcx>(
993
999
// witness the usefulness of `v`.
994
1000
let start_matrix = & matrix;
995
1001
let usefulnesses = split_ctors. into_iter ( ) . map ( |ctor| {
1002
+ debug ! ( "specialize({:?})" , ctor) ;
996
1003
// We cache the result of `Fields::wildcards` because it is used a lot.
997
1004
let ctor_wild_subpatterns = Fields :: wildcards ( pcx, & ctor) ;
998
1005
let spec_matrix =
@@ -1004,7 +1011,7 @@ fn is_useful<'p, 'tcx>(
1004
1011
} ) ;
1005
1012
Usefulness :: merge ( usefulnesses)
1006
1013
} ;
1007
- debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix , v , ret) ;
1014
+ debug ! ( ? ret) ;
1008
1015
ret
1009
1016
}
1010
1017
0 commit comments