@@ -791,124 +791,6 @@ impl<'tcx> Constructor<'tcx> {
791
791
}
792
792
}
793
793
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
-
912
794
/// A wildcard constructor that we split relative to the constructors in the matrix, as explained
913
795
/// at the top of the file.
914
796
/// For splitting wildcards, there are two groups of constructors: there are the constructors
@@ -926,9 +808,121 @@ pub(super) struct SplitWildcard<'tcx> {
926
808
927
809
impl < ' tcx > SplitWildcard < ' tcx > {
928
810
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 }
932
926
}
933
927
934
928
/// Pass a set of constructors relative to which to split this one. Don't call twice, it won't
0 commit comments