45
45
use self :: Constructor :: * ;
46
46
use self :: SliceKind :: * ;
47
47
48
- use super :: number_type_size;
49
48
use super :: usefulness:: { MatchCheckCtxt , PatCtxt } ;
50
49
51
50
use rustc_apfloat:: ieee:: { DoubleS , IeeeFloat , SingleS } ;
52
51
use rustc_data_structures:: captures:: Captures ;
53
52
use rustc_index:: vec:: Idx ;
54
53
55
54
use rustc_hir:: { HirId , RangeEnd } ;
56
- use rustc_middle:: middle:: stability:: EvalResult ;
57
- use rustc_middle:: mir:: Field ;
58
55
use rustc_middle:: ty:: subst:: GenericArg ;
59
- use rustc_middle:: ty:: { self , Ty , VariantDef } ;
56
+ use rustc_middle:: ty:: { self , Ty } ;
60
57
use rustc_span:: { Span , DUMMY_SP } ;
61
58
use rustc_target:: abi:: VariantIdx ;
62
59
@@ -619,7 +616,7 @@ impl<'tcx> Constructor<'tcx> {
619
616
Single | Variant ( _) => match pcx. ty . kind ( ) {
620
617
ty:: Adt ( adt, ..) => {
621
618
let variant = & adt. variants [ self . variant_index_for_adt ( adt) ] ;
622
- Fields :: list_variant_nonhidden_fields ( pcx. cx , pcx. ty , variant) . count ( )
619
+ pcx. cx . list_variant_nonhidden_fields ( pcx. ty , variant) . count ( )
623
620
}
624
621
_ => bug ! ( "Unexpected type for `Single` constructor: {:?}" , pcx. ty) ,
625
622
} ,
@@ -806,138 +803,7 @@ pub(super) struct SplitWildcard<'tcx> {
806
803
807
804
impl < ' tcx > SplitWildcard < ' tcx > {
808
805
pub ( super ) fn new < ' p > ( pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> Self {
809
- debug ! ( "SplitWildcard::new({:?})" , pcx. ty) ;
810
- let cx = pcx. cx ;
811
- let ty = pcx. ty ;
812
- let make_range = |size, start, end| {
813
- IntRange ( IntRange :: from_bits ( ty, size, start, end, & RangeEnd :: Included ) )
814
- } ;
815
- // This determines the set of all possible constructors for the type `ty`. For numbers,
816
- // arrays and slices we use ranges and variable-length slices when appropriate.
817
- //
818
- // If the `exhaustive_patterns` feature is enabled, we make sure to omit constructors that
819
- // are statically impossible. E.g., for `Option<!>`, we do not include `Some(_)` in the
820
- // returned list of constructors.
821
- // Invariant: this is empty if and only if the type is uninhabited (as determined by
822
- // `cx.is_uninhabited()`).
823
- let all_ctors = match ty. kind ( ) {
824
- _ if cx. is_uninhabited ( ty) => smallvec ! [ ] ,
825
- ty:: Bool => smallvec ! [ Bool ( false ) , Bool ( true ) ] ,
826
- ty:: Char => {
827
- let size = number_type_size ( cx. tcx , ty) ;
828
- smallvec ! [
829
- // The valid Unicode Scalar Value ranges.
830
- make_range( size, '\u{0000}' as u128 , '\u{D7FF}' as u128 ) ,
831
- make_range( size, '\u{E000}' as u128 , '\u{10FFFF}' as u128 ) ,
832
- ]
833
- }
834
- ty:: Int ( _) | ty:: Uint ( _)
835
- if ty. is_ptr_sized_integral ( )
836
- && !cx. tcx . features ( ) . precise_pointer_size_matching =>
837
- {
838
- // `usize`/`isize` are not allowed to be matched exhaustively unless the
839
- // `precise_pointer_size_matching` feature is enabled. So we treat those types like
840
- // `#[non_exhaustive]` enums by returning a special unmatcheable constructor.
841
- smallvec ! [ NonExhaustive ]
842
- }
843
- & ty:: Int ( _) => {
844
- let size = number_type_size ( cx. tcx , ty) ;
845
- let bits = size. bits ( ) as u128 ;
846
- let min = 1u128 << ( bits - 1 ) ;
847
- let max = min - 1 ;
848
- smallvec ! [ make_range( size, min, max) ]
849
- }
850
- & ty:: Uint ( _) => {
851
- let size = number_type_size ( cx. tcx , ty) ;
852
- let max = size. truncate ( u128:: MAX ) ;
853
- smallvec ! [ make_range( size, 0 , max) ]
854
- }
855
- ty:: Adt ( def, substs) if def. is_enum ( ) => {
856
- // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
857
- // additional "unknown" constructor.
858
- // There is no point in enumerating all possible variants, because the user can't
859
- // actually match against them all themselves. So we always return only the fictitious
860
- // constructor.
861
- // E.g., in an example like:
862
- //
863
- // ```
864
- // let err: io::ErrorKind = ...;
865
- // match err {
866
- // io::ErrorKind::NotFound => {},
867
- // }
868
- // ```
869
- //
870
- // we don't want to show every possible IO error, but instead have only `_` as the
871
- // witness.
872
- let is_declared_nonexhaustive = cx. is_foreign_non_exhaustive_enum ( ty) ;
873
-
874
- let is_exhaustive_pat_feature = cx. tcx . features ( ) . exhaustive_patterns ;
875
-
876
- // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
877
- // as though it had an "unknown" constructor to avoid exposing its emptiness. The
878
- // exception is if the pattern is at the top level, because we want empty matches to be
879
- // considered exhaustive.
880
- let is_secretly_empty =
881
- def. variants . is_empty ( ) && !is_exhaustive_pat_feature && !pcx. is_top_level ;
882
-
883
- let mut ctors: SmallVec < [ _ ; 1 ] > = def
884
- . variants
885
- . iter_enumerated ( )
886
- . filter ( |( _, v) | {
887
- // Filter variants that depend on a disabled unstalbe feature.
888
- let is_enabled = !matches ! (
889
- cx. tcx. eval_stability( v. def_id, None , DUMMY_SP , None ) ,
890
- EvalResult :: Deny { .. }
891
- ) ;
892
- // If `exhaustive_patterns` is enabled, we exclude variants known to be
893
- // uninhabited.
894
- let is_uninhabited = is_exhaustive_pat_feature
895
- && v. uninhabited_from ( cx. tcx , substs, def. adt_kind ( ) , cx. param_env )
896
- . contains ( cx. tcx , cx. module ) ;
897
- is_enabled && !is_uninhabited
898
- } )
899
- . map ( |( idx, _) | Variant ( idx) )
900
- . collect ( ) ;
901
-
902
- if is_secretly_empty || is_declared_nonexhaustive {
903
- ctors. push ( NonExhaustive ) ;
904
- }
905
- ctors
906
- }
907
- // The only legal non-wildcard patterns of type `Box` are box patterns, so we emit
908
- // that.
909
- ty:: Adt ( def, substs) if def. is_box ( ) => smallvec ! [ BoxPat ( substs. type_at( 0 ) ) ] ,
910
- ty:: Adt ( ..) => smallvec ! [ Single ] ,
911
- ty:: Ref ( _, ty, _) => smallvec ! [ Ref ( * ty) ] ,
912
- ty:: Tuple ( fs) => smallvec ! [ Tuple ( * fs) ] ,
913
- ty:: Array ( sub_ty, len) => {
914
- match len. try_eval_usize ( cx. tcx , cx. param_env ) {
915
- Some ( len) => {
916
- // The uninhabited case is already handled.
917
- smallvec ! [ Slice ( Slice :: new( Some ( len as usize ) , VarLen ( 0 , 0 ) ) ) ]
918
- }
919
- None => {
920
- // Treat arrays of a constant but unknown length like slices.
921
- let kind =
922
- if cx. is_uninhabited ( sub_ty) { FixedLen ( 0 ) } else { VarLen ( 0 , 0 ) } ;
923
- smallvec ! [ Slice ( Slice :: new( None , kind) ) ]
924
- }
925
- }
926
- }
927
- ty:: Slice ( sub_ty) => {
928
- let kind = if cx. is_uninhabited ( sub_ty) { FixedLen ( 0 ) } else { VarLen ( 0 , 0 ) } ;
929
- smallvec ! [ Slice ( Slice :: new( None , kind) ) ]
930
- }
931
- // If `exhaustive_patterns` is disabled and our scrutinee is the never type, we don't
932
- // expose its emptiness and return `NonExhaustive` below. The exception is if the
933
- // pattern is at the top level, because we want empty matches to be considered
934
- // exhaustive.
935
- ty:: Never if pcx. is_top_level => smallvec ! [ ] ,
936
- // This type is one for which we cannot list constructors, like `str` or `f64`, or is
937
- // uninhabited but `exhaustive_patterns` is disabled.
938
- _ => smallvec ! [ NonExhaustive ] ,
939
- } ;
940
-
806
+ let all_ctors = pcx. cx . list_constructors_for_type ( pcx. ty , pcx. is_top_level ) ;
941
807
SplitWildcard { matrix_ctors : Vec :: new ( ) , all_ctors }
942
808
}
943
809
@@ -1079,36 +945,6 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1079
945
Fields :: from_iter ( cx, tys. into_iter ( ) . map ( DeconstructedPat :: wildcard) )
1080
946
}
1081
947
1082
- // In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
1083
- // uninhabited fields in order not to reveal the uninhabitedness of the whole variant.
1084
- // This lists the fields we keep along with their types.
1085
- pub ( super ) fn list_variant_nonhidden_fields < ' a > (
1086
- cx : & ' a MatchCheckCtxt < ' p , ' tcx > ,
1087
- ty : Ty < ' tcx > ,
1088
- variant : & ' a VariantDef ,
1089
- ) -> impl Iterator < Item = ( Field , Ty < ' tcx > ) > + Captures < ' a > + Captures < ' p > {
1090
- let ( adt, substs) = match ty. kind ( ) {
1091
- ty:: Adt ( adt, substs) => ( adt, substs) ,
1092
- _ => bug ! ( ) ,
1093
- } ;
1094
- // Whether we must not match the fields of this variant exhaustively.
1095
- let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) && !adt. did . is_local ( ) ;
1096
-
1097
- variant. fields . iter ( ) . enumerate ( ) . filter_map ( move |( i, field) | {
1098
- let ty = field. ty ( cx. tcx , substs) ;
1099
- // `field.ty()` doesn't normalize after substituting.
1100
- let ty = cx. tcx . normalize_erasing_regions ( cx. param_env , ty) ;
1101
- let is_visible = adt. is_enum ( ) || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
1102
- let is_uninhabited = cx. is_uninhabited ( ty) ;
1103
-
1104
- if is_uninhabited && ( !is_visible || is_non_exhaustive) {
1105
- None
1106
- } else {
1107
- Some ( ( Field :: new ( i) , ty) )
1108
- }
1109
- } )
1110
- }
1111
-
1112
948
/// Creates a new list of wildcard fields for a given constructor. The result must have a
1113
949
/// length of `constructor.arity()`.
1114
950
pub ( super ) fn wildcards (
@@ -1120,8 +956,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1120
956
Single | Variant ( _) => match ty. kind ( ) {
1121
957
ty:: Adt ( adt, _) => {
1122
958
let variant = & adt. variants [ constructor. variant_index_for_adt ( adt) ] ;
1123
- let tys =
1124
- Fields :: list_variant_nonhidden_fields ( cx, ty, variant) . map ( |( _, ty) | ty) ;
959
+ let tys = cx. list_variant_nonhidden_fields ( ty, variant) . map ( |( _, ty) | ty) ;
1125
960
Fields :: wildcards_from_tys ( cx, tys)
1126
961
}
1127
962
_ => bug ! ( "Unexpected type for `Single` constructor: {:?}" , ty) ,
0 commit comments