@@ -791,124 +791,6 @@ impl<'tcx> Constructor<'tcx> {
791791 }
792792}
793793
794- /// This determines the set of all possible constructors of a pattern matching
795- /// values of type `left_ty`. For vectors, this would normally be an infinite set
796- /// but is instead bounded by the maximum fixed length of slice patterns in
797- /// the column of patterns being analyzed.
798- ///
799- /// We make sure to omit constructors that are statically impossible. E.g., for
800- /// `Option<!>`, we do not include `Some(_)` in the returned list of constructors.
801- /// Invariant: this returns an empty `Vec` if and only if the type is uninhabited (as determined by
802- /// `cx.is_uninhabited()`).
803- fn all_constructors < ' p , ' tcx > ( pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
804- debug ! ( "all_constructors({:?})" , pcx. ty) ;
805- let cx = pcx. cx ;
806- let make_range = |start, end| {
807- IntRange (
808- // `unwrap()` is ok because we know the type is an integer.
809- IntRange :: from_range ( cx. tcx , start, end, pcx. ty , & RangeEnd :: Included ) . unwrap ( ) ,
810- )
811- } ;
812- match pcx. ty . kind ( ) {
813- ty:: Bool => smallvec ! [ make_range( 0 , 1 ) ] ,
814- ty:: Array ( sub_ty, len) if len. try_eval_usize ( cx. tcx , cx. param_env ) . is_some ( ) => {
815- let len = len. eval_usize ( cx. tcx , cx. param_env ) ;
816- if len != 0 && cx. is_uninhabited ( sub_ty) {
817- smallvec ! [ ]
818- } else {
819- smallvec ! [ Slice ( Slice :: new( Some ( len) , VarLen ( 0 , 0 ) ) ) ]
820- }
821- }
822- // Treat arrays of a constant but unknown length like slices.
823- ty:: Array ( sub_ty, _) | ty:: Slice ( sub_ty) => {
824- let kind = if cx. is_uninhabited ( sub_ty) { FixedLen ( 0 ) } else { VarLen ( 0 , 0 ) } ;
825- smallvec ! [ Slice ( Slice :: new( None , kind) ) ]
826- }
827- ty:: Adt ( def, substs) if def. is_enum ( ) => {
828- // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
829- // additional "unknown" constructor.
830- // There is no point in enumerating all possible variants, because the user can't
831- // actually match against them all themselves. So we always return only the fictitious
832- // constructor.
833- // E.g., in an example like:
834- //
835- // ```
836- // let err: io::ErrorKind = ...;
837- // match err {
838- // io::ErrorKind::NotFound => {},
839- // }
840- // ```
841- //
842- // we don't want to show every possible IO error, but instead have only `_` as the
843- // witness.
844- let is_declared_nonexhaustive = cx. is_foreign_non_exhaustive_enum ( pcx. ty ) ;
845-
846- // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
847- // as though it had an "unknown" constructor to avoid exposing its emptiness. The
848- // exception is if the pattern is at the top level, because we want empty matches to be
849- // considered exhaustive.
850- let is_secretly_empty = def. variants . is_empty ( )
851- && !cx. tcx . features ( ) . exhaustive_patterns
852- && !pcx. is_top_level ;
853-
854- if is_secretly_empty || is_declared_nonexhaustive {
855- smallvec ! [ NonExhaustive ]
856- } else if cx. tcx . features ( ) . exhaustive_patterns {
857- // If `exhaustive_patterns` is enabled, we exclude variants known to be
858- // uninhabited.
859- def. variants
860- . iter ( )
861- . filter ( |v| {
862- !v. uninhabited_from ( cx. tcx , substs, def. adt_kind ( ) , cx. param_env )
863- . contains ( cx. tcx , cx. module )
864- } )
865- . map ( |v| Variant ( v. def_id ) )
866- . collect ( )
867- } else {
868- def. variants . iter ( ) . map ( |v| Variant ( v. def_id ) ) . collect ( )
869- }
870- }
871- ty:: Char => {
872- smallvec ! [
873- // The valid Unicode Scalar Value ranges.
874- make_range( '\u{0000}' as u128 , '\u{D7FF}' as u128 ) ,
875- make_range( '\u{E000}' as u128 , '\u{10FFFF}' as u128 ) ,
876- ]
877- }
878- ty:: Int ( _) | ty:: Uint ( _)
879- if pcx. ty . is_ptr_sized_integral ( )
880- && !cx. tcx . features ( ) . precise_pointer_size_matching =>
881- {
882- // `usize`/`isize` are not allowed to be matched exhaustively unless the
883- // `precise_pointer_size_matching` feature is enabled. So we treat those types like
884- // `#[non_exhaustive]` enums by returning a special unmatcheable constructor.
885- smallvec ! [ NonExhaustive ]
886- }
887- & ty:: Int ( ity) => {
888- let bits = Integer :: from_attr ( & cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
889- let min = 1u128 << ( bits - 1 ) ;
890- let max = min - 1 ;
891- smallvec ! [ make_range( min, max) ]
892- }
893- & ty:: Uint ( uty) => {
894- let size = Integer :: from_attr ( & cx. tcx , UnsignedInt ( uty) ) . size ( ) ;
895- let max = size. truncate ( u128:: MAX ) ;
896- smallvec ! [ make_range( 0 , max) ]
897- }
898- // If `exhaustive_patterns` is disabled and our scrutinee is the never type, we cannot
899- // expose its emptiness. The exception is if the pattern is at the top level, because we
900- // want empty matches to be considered exhaustive.
901- ty:: Never if !cx. tcx . features ( ) . exhaustive_patterns && !pcx. is_top_level => {
902- smallvec ! [ NonExhaustive ]
903- }
904- ty:: Never => smallvec ! [ ] ,
905- _ if cx. is_uninhabited ( pcx. ty ) => smallvec ! [ ] ,
906- ty:: Adt ( ..) | ty:: Tuple ( ..) | ty:: Ref ( ..) => smallvec ! [ Single ] ,
907- // This type is one for which we cannot list constructors, like `str` or `f64`.
908- _ => smallvec ! [ NonExhaustive ] ,
909- }
910- }
911-
912794/// A wildcard constructor that we split relative to the constructors in the matrix, as explained
913795/// at the top of the file.
914796/// For splitting wildcards, there are two groups of constructors: there are the constructors
@@ -926,9 +808,121 @@ pub(super) struct SplitWildcard<'tcx> {
926808
927809impl < ' tcx > SplitWildcard < ' tcx > {
928810 pub ( super ) fn new < ' p > ( pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> Self {
929- let matrix_ctors = Vec :: new ( ) ;
930- let all_ctors = all_constructors ( pcx) ;
931- SplitWildcard { matrix_ctors, all_ctors }
811+ debug ! ( "SplitWildcard::new({:?})" , pcx. ty) ;
812+ let cx = pcx. cx ;
813+ let make_range = |start, end| {
814+ IntRange (
815+ // `unwrap()` is ok because we know the type is an integer.
816+ IntRange :: from_range ( cx. tcx , start, end, pcx. ty , & RangeEnd :: Included ) . unwrap ( ) ,
817+ )
818+ } ;
819+ // This determines the set of all possible constructors for the type `pcx.ty`. For numbers,
820+ // arrays and slices we use ranges and variable-length slices when appropriate.
821+ //
822+ // If the `exhaustive_patterns` feature is enabled, we make sure to omit constructors that
823+ // are statically impossible. E.g., for `Option<!>`, we do not include `Some(_)` in the
824+ // returned list of constructors.
825+ // Invariant: this is empty if and only if the type is uninhabited (as determined by
826+ // `cx.is_uninhabited()`).
827+ let all_ctors = match pcx. ty . kind ( ) {
828+ ty:: Bool => smallvec ! [ make_range( 0 , 1 ) ] ,
829+ ty:: Array ( sub_ty, len) if len. try_eval_usize ( cx. tcx , cx. param_env ) . is_some ( ) => {
830+ let len = len. eval_usize ( cx. tcx , cx. param_env ) ;
831+ if len != 0 && cx. is_uninhabited ( sub_ty) {
832+ smallvec ! [ ]
833+ } else {
834+ smallvec ! [ Slice ( Slice :: new( Some ( len) , VarLen ( 0 , 0 ) ) ) ]
835+ }
836+ }
837+ // Treat arrays of a constant but unknown length like slices.
838+ ty:: Array ( sub_ty, _) | ty:: Slice ( sub_ty) => {
839+ let kind = if cx. is_uninhabited ( sub_ty) { FixedLen ( 0 ) } else { VarLen ( 0 , 0 ) } ;
840+ smallvec ! [ Slice ( Slice :: new( None , kind) ) ]
841+ }
842+ ty:: Adt ( def, substs) if def. is_enum ( ) => {
843+ // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
844+ // additional "unknown" constructor.
845+ // There is no point in enumerating all possible variants, because the user can't
846+ // actually match against them all themselves. So we always return only the fictitious
847+ // constructor.
848+ // E.g., in an example like:
849+ //
850+ // ```
851+ // let err: io::ErrorKind = ...;
852+ // match err {
853+ // io::ErrorKind::NotFound => {},
854+ // }
855+ // ```
856+ //
857+ // we don't want to show every possible IO error, but instead have only `_` as the
858+ // witness.
859+ let is_declared_nonexhaustive = cx. is_foreign_non_exhaustive_enum ( pcx. ty ) ;
860+
861+ // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
862+ // as though it had an "unknown" constructor to avoid exposing its emptiness. The
863+ // exception is if the pattern is at the top level, because we want empty matches to be
864+ // considered exhaustive.
865+ let is_secretly_empty = def. variants . is_empty ( )
866+ && !cx. tcx . features ( ) . exhaustive_patterns
867+ && !pcx. is_top_level ;
868+
869+ if is_secretly_empty || is_declared_nonexhaustive {
870+ smallvec ! [ NonExhaustive ]
871+ } else if cx. tcx . features ( ) . exhaustive_patterns {
872+ // If `exhaustive_patterns` is enabled, we exclude variants known to be
873+ // uninhabited.
874+ def. variants
875+ . iter ( )
876+ . filter ( |v| {
877+ !v. uninhabited_from ( cx. tcx , substs, def. adt_kind ( ) , cx. param_env )
878+ . contains ( cx. tcx , cx. module )
879+ } )
880+ . map ( |v| Variant ( v. def_id ) )
881+ . collect ( )
882+ } else {
883+ def. variants . iter ( ) . map ( |v| Variant ( v. def_id ) ) . collect ( )
884+ }
885+ }
886+ ty:: Char => {
887+ smallvec ! [
888+ // The valid Unicode Scalar Value ranges.
889+ make_range( '\u{0000}' as u128 , '\u{D7FF}' as u128 ) ,
890+ make_range( '\u{E000}' as u128 , '\u{10FFFF}' as u128 ) ,
891+ ]
892+ }
893+ ty:: Int ( _) | ty:: Uint ( _)
894+ if pcx. ty . is_ptr_sized_integral ( )
895+ && !cx. tcx . features ( ) . precise_pointer_size_matching =>
896+ {
897+ // `usize`/`isize` are not allowed to be matched exhaustively unless the
898+ // `precise_pointer_size_matching` feature is enabled. So we treat those types like
899+ // `#[non_exhaustive]` enums by returning a special unmatcheable constructor.
900+ smallvec ! [ NonExhaustive ]
901+ }
902+ & ty:: Int ( ity) => {
903+ let bits = Integer :: from_attr ( & cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
904+ let min = 1u128 << ( bits - 1 ) ;
905+ let max = min - 1 ;
906+ smallvec ! [ make_range( min, max) ]
907+ }
908+ & ty:: Uint ( uty) => {
909+ let size = Integer :: from_attr ( & cx. tcx , UnsignedInt ( uty) ) . size ( ) ;
910+ let max = size. truncate ( u128:: MAX ) ;
911+ smallvec ! [ make_range( 0 , max) ]
912+ }
913+ // If `exhaustive_patterns` is disabled and our scrutinee is the never type, we cannot
914+ // expose its emptiness. The exception is if the pattern is at the top level, because we
915+ // want empty matches to be considered exhaustive.
916+ ty:: Never if !cx. tcx . features ( ) . exhaustive_patterns && !pcx. is_top_level => {
917+ smallvec ! [ NonExhaustive ]
918+ }
919+ ty:: Never => smallvec ! [ ] ,
920+ _ if cx. is_uninhabited ( pcx. ty ) => smallvec ! [ ] ,
921+ ty:: Adt ( ..) | ty:: Tuple ( ..) | ty:: Ref ( ..) => smallvec ! [ Single ] ,
922+ // This type is one for which we cannot list constructors, like `str` or `f64`.
923+ _ => smallvec ! [ NonExhaustive ] ,
924+ } ;
925+ SplitWildcard { matrix_ctors : Vec :: new ( ) , all_ctors }
932926 }
933927
934928 /// Pass a set of constructors relative to which to split this one. Don't call twice, it won't
0 commit comments