@@ -561,19 +561,25 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
561
561
/// (1) all_constructors will only return constructors that are statically
562
562
/// possible. eg. it will only return Ok for Result<T, !>
563
563
///
564
- /// Whether a vector `v` of patterns is 'useful' in relation to a set of such
565
- /// vectors `m` is defined as there being a set of inputs that will match `v`
566
- /// but not any of the sets in `m`.
564
+ /// This finds whether a (row) vector `v` of patterns is 'useful' in relation
565
+ /// to a set of such vectors `m` is defined as there being a set of inputs
566
+ /// that will match `v` but not any of the sets in `m`.
567
+ ///
568
+ /// All the patterns at each column of the `matrix ++ v` matrix must
569
+ /// have the same type, except that wildcard (PatternKind::Wild) patterns
570
+ /// with type TyErr are also allowed, even if the "type of the column"
571
+ /// is not TyErr. That is used to represent private fields, as using their
572
+ /// real type would assert that they are inhabited.
567
573
///
568
574
/// This is used both for reachability checking (if a pattern isn't useful in
569
575
/// relation to preceding patterns, it is not reachable) and exhaustiveness
570
576
/// checking (if a wildcard pattern is useful in relation to a matrix, the
571
577
/// matrix isn't exhaustive).
572
578
pub fn is_useful < ' p , ' a : ' p , ' tcx : ' a > ( cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
573
- matrix : & Matrix < ' p , ' tcx > ,
574
- v : & [ & ' p Pattern < ' tcx > ] ,
575
- witness : WitnessPreference )
576
- -> Usefulness < ' tcx > {
579
+ matrix : & Matrix < ' p , ' tcx > ,
580
+ v : & [ & ' p Pattern < ' tcx > ] ,
581
+ witness : WitnessPreference )
582
+ -> Usefulness < ' tcx > {
577
583
let & Matrix ( ref rows) = matrix;
578
584
debug ! ( "is_useful({:?}, {:?})" , matrix, v) ;
579
585
@@ -596,6 +602,9 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
596
602
assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
597
603
598
604
let pcx = PatternContext {
605
+ // () is used to represent an unknown type in this context. If
606
+ // one of the fields has a known type, use it instead (other
607
+ // than that, all types should be equal modulo normalization).
599
608
ty : rows. iter ( ) . map ( |r| r[ 0 ] . ty ) . find ( |ty| !ty. references_error ( ) )
600
609
. unwrap_or ( v[ 0 ] . ty ) ,
601
610
max_slice_length : max_slice_length ( cx, rows. iter ( ) . map ( |r| r[ 0 ] ) . chain ( Some ( v[ 0 ] ) ) )
@@ -861,13 +870,13 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
861
870
if is_visible {
862
871
field. ty ( cx. tcx , substs)
863
872
} else {
864
- // Treat all non-visible fields as nil . They
873
+ // Treat all non-visible fields as TyErr . They
865
874
// can't appear in any other pattern from
866
875
// this match (because they are private),
867
876
// so their type does not matter - but
868
877
// we don't want to know they are
869
878
// uninhabited.
870
- cx. tcx . mk_nil ( )
879
+ cx. tcx . types . err
871
880
}
872
881
} ) . collect ( )
873
882
}
0 commit comments