@@ -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` - this is defined as there being a set of
566
+ /// inputs 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,25 @@ 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
+ // TyErr is used to represent the type of wildcard patterns matching
606
+ // against inaccessible (private) fields of structs, so that we won't
607
+ // be able to observe whether the types of the struct's fields are
608
+ // inhabited.
609
+ //
610
+ // If the field is truely inaccessible, then all the patterns
611
+ // matching against it must be wildcard patterns, so its type
612
+ // does not matter.
613
+ //
614
+ // However, if we are matching against non-wildcard patterns, we
615
+ // need to know the real type of the field so we can specialize
616
+ // against it. This primarily occurs through constants - they
617
+ // can include contents for fields that are inaccessible at the
618
+ // location of the match. In that case, the field's type is
619
+ // inhabited - by the constant - so we can just use it.
620
+ //
621
+ // FIXME: this might lead to "unstable" behavior with macro hygiene
622
+ // introducing uninhabited patterns for inaccessible fields. We
623
+ // need to figure out how to model that.
599
624
ty : rows. iter ( ) . map ( |r| r[ 0 ] . ty ) . find ( |ty| !ty. references_error ( ) )
600
625
. unwrap_or ( v[ 0 ] . ty ) ,
601
626
max_slice_length : max_slice_length ( cx, rows. iter ( ) . map ( |r| r[ 0 ] ) . chain ( Some ( v[ 0 ] ) ) )
@@ -861,13 +886,13 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
861
886
if is_visible {
862
887
field. ty ( cx. tcx , substs)
863
888
} else {
864
- // Treat all non-visible fields as nil . They
889
+ // Treat all non-visible fields as TyErr . They
865
890
// can't appear in any other pattern from
866
891
// this match (because they are private),
867
892
// so their type does not matter - but
868
893
// we don't want to know they are
869
894
// uninhabited.
870
- cx. tcx . mk_nil ( )
895
+ cx. tcx . types . err
871
896
}
872
897
} ) . collect ( )
873
898
}
0 commit comments