@@ -562,8 +562,8 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
562562/// possible. eg. it will only return Ok for Result<T, !>
563563///
564564/// 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`.
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`.
567567///
568568/// All the patterns at each column of the `matrix ++ v` matrix must
569569/// have the same type, except that wildcard (PatternKind::Wild) patterns
@@ -602,9 +602,25 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
602602 assert ! ( rows. iter( ) . all( |r| r. len( ) == v. len( ) ) ) ;
603603
604604 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).
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.
608624 ty : rows. iter ( ) . map ( |r| r[ 0 ] . ty ) . find ( |ty| !ty. references_error ( ) )
609625 . unwrap_or ( v[ 0 ] . ty ) ,
610626 max_slice_length : max_slice_length ( cx, rows. iter ( ) . map ( |r| r[ 0 ] ) . chain ( Some ( v[ 0 ] ) ) )
0 commit comments