@@ -561,19 +561,25 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
561561/// (1) all_constructors will only return constructors that are statically
562562/// possible. eg. it will only return Ok for Result<T, !>
563563///
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.
567573///
568574/// This is used both for reachability checking (if a pattern isn't useful in
569575/// relation to preceding patterns, it is not reachable) and exhaustiveness
570576/// checking (if a wildcard pattern is useful in relation to a matrix, the
571577/// matrix isn't exhaustive).
572578pub 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 > {
577583 let & Matrix ( ref rows) = matrix;
578584 debug ! ( "is_useful({:?}, {:?})" , matrix, v) ;
579585
@@ -596,6 +602,9 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
596602 assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
597603
598604 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).
599608 ty : rows. iter ( ) . map ( |r| r[ 0 ] . ty ) . find ( |ty| !ty. references_error ( ) )
600609 . unwrap_or ( v[ 0 ] . ty ) ,
601610 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>,
861870 if is_visible {
862871 field. ty ( cx. tcx , substs)
863872 } else {
864- // Treat all non-visible fields as nil . They
873+ // Treat all non-visible fields as TyErr . They
865874 // can't appear in any other pattern from
866875 // this match (because they are private),
867876 // so their type does not matter - but
868877 // we don't want to know they are
869878 // uninhabited.
870- cx. tcx . mk_nil ( )
879+ cx. tcx . types . err
871880 }
872881 } ) . collect ( )
873882 }
0 commit comments