40
40
//! - That have no non-trivial intersection with any of the constructors in the column (i.e. they're
41
41
//! each either disjoint with or covered by any given column constructor).
42
42
//!
43
- //! We compute this in two steps: first [`crate::cx::MatchCheckCtxt ::ctors_for_ty`] determines the
43
+ //! We compute this in two steps: first [`MatchCx ::ctors_for_ty`] determines the
44
44
//! set of all possible constructors for the type. Then [`ConstructorSet::split`] looks at the
45
45
//! column of constructors and splits the set into groups accordingly. The precise invariants of
46
46
//! [`ConstructorSet::split`] is described in [`SplitConstructorSet`].
136
136
//! the algorithm can't distinguish them from a nonempty constructor. The only known case where this
137
137
//! could happen is the `[..]` pattern on `[!; N]` with `N > 0` so we must take care to not emit it.
138
138
//!
139
- //! This is all handled by [`crate::cx::MatchCheckCtxt ::ctors_for_ty`] and
139
+ //! This is all handled by [`MatchCx ::ctors_for_ty`] and
140
140
//! [`ConstructorSet::split`]. The invariants of [`SplitConstructorSet`] are also of interest.
141
141
//!
142
142
//!
@@ -158,14 +158,13 @@ use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS};
158
158
use rustc_data_structures:: fx:: FxHashSet ;
159
159
use rustc_hir:: RangeEnd ;
160
160
use rustc_index:: IndexVec ;
161
- use rustc_middle:: mir:: Const ;
162
- use rustc_target:: abi:: VariantIdx ;
163
161
164
162
use self :: Constructor :: * ;
165
163
use self :: MaybeInfiniteInt :: * ;
166
164
use self :: SliceKind :: * ;
167
165
168
166
use crate :: usefulness:: PatCtxt ;
167
+ use crate :: MatchCx ;
169
168
170
169
/// Whether we have seen a constructor in the column or not.
171
170
#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
@@ -630,11 +629,11 @@ impl OpaqueId {
630
629
/// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
631
630
/// `Fields`.
632
631
#[ derive( Clone , Debug , PartialEq ) ]
633
- pub enum Constructor < ' tcx > {
632
+ pub enum Constructor < Cx : MatchCx > {
634
633
/// Tuples and structs.
635
634
Struct ,
636
635
/// Enum variants.
637
- Variant ( VariantIdx ) ,
636
+ Variant ( Cx :: VariantIdx ) ,
638
637
/// References
639
638
Ref ,
640
639
/// Array and slice patterns.
@@ -649,7 +648,7 @@ pub enum Constructor<'tcx> {
649
648
F32Range ( IeeeFloat < SingleS > , IeeeFloat < SingleS > , RangeEnd ) ,
650
649
F64Range ( IeeeFloat < DoubleS > , IeeeFloat < DoubleS > , RangeEnd ) ,
651
650
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
652
- Str ( Const < ' tcx > ) ,
651
+ Str ( Cx :: StrLit ) ,
653
652
/// Constants that must not be matched structurally. They are treated as black boxes for the
654
653
/// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
655
654
/// match exhaustive.
@@ -672,12 +671,12 @@ pub enum Constructor<'tcx> {
672
671
Missing ,
673
672
}
674
673
675
- impl < ' tcx > Constructor < ' tcx > {
674
+ impl < Cx : MatchCx > Constructor < Cx > {
676
675
pub ( crate ) fn is_non_exhaustive ( & self ) -> bool {
677
676
matches ! ( self , NonExhaustive )
678
677
}
679
678
680
- pub ( crate ) fn as_variant ( & self ) -> Option < VariantIdx > {
679
+ pub ( crate ) fn as_variant ( & self ) -> Option < Cx :: VariantIdx > {
681
680
match self {
682
681
Variant ( i) => Some ( * i) ,
683
682
_ => None ,
@@ -704,7 +703,7 @@ impl<'tcx> Constructor<'tcx> {
704
703
705
704
/// The number of fields for this constructor. This must be kept in sync with
706
705
/// `Fields::wildcards`.
707
- pub ( crate ) fn arity ( & self , pcx : & PatCtxt < ' _ , ' _ , ' tcx > ) -> usize {
706
+ pub ( crate ) fn arity ( & self , pcx : & PatCtxt < ' _ , ' _ , Cx > ) -> usize {
708
707
pcx. cx . ctor_arity ( self , pcx. ty )
709
708
}
710
709
@@ -713,14 +712,11 @@ impl<'tcx> Constructor<'tcx> {
713
712
/// this checks for inclusion.
714
713
// We inline because this has a single call site in `Matrix::specialize_constructor`.
715
714
#[ inline]
716
- pub ( crate ) fn is_covered_by < ' p > ( & self , pcx : & PatCtxt < ' _ , ' p , ' tcx > , other : & Self ) -> bool {
715
+ pub ( crate ) fn is_covered_by < ' p > ( & self , pcx : & PatCtxt < ' _ , ' p , Cx > , other : & Self ) -> bool {
717
716
match ( self , other) {
718
- ( Wildcard , _) => {
719
- span_bug ! (
720
- pcx. cx. scrut_span,
721
- "Constructor splitting should not have returned `Wildcard`"
722
- )
723
- }
717
+ ( Wildcard , _) => pcx
718
+ . cx
719
+ . bug ( format_args ! ( "Constructor splitting should not have returned `Wildcard`" ) ) ,
724
720
// Wildcards cover anything
725
721
( _, Wildcard ) => true ,
726
722
// Only a wildcard pattern can match these special constructors.
@@ -761,12 +757,9 @@ impl<'tcx> Constructor<'tcx> {
761
757
( Opaque ( self_id) , Opaque ( other_id) ) => self_id == other_id,
762
758
( Opaque ( ..) , _) | ( _, Opaque ( ..) ) => false ,
763
759
764
- _ => span_bug ! (
765
- pcx. cx. scrut_span,
766
- "trying to compare incompatible constructors {:?} and {:?}" ,
767
- self ,
768
- other
769
- ) ,
760
+ _ => pcx. cx . bug ( format_args ! (
761
+ "trying to compare incompatible constructors {self:?} and {other:?}"
762
+ ) ) ,
770
763
}
771
764
}
772
765
}
@@ -790,12 +783,12 @@ pub enum VariantVisibility {
790
783
/// In terms of division of responsibility, [`ConstructorSet::split`] handles all of the
791
784
/// `exhaustive_patterns` feature.
792
785
#[ derive( Debug ) ]
793
- pub enum ConstructorSet {
786
+ pub enum ConstructorSet < Cx : MatchCx > {
794
787
/// The type is a tuple or struct. `empty` tracks whether the type is empty.
795
788
Struct { empty : bool } ,
796
789
/// This type has the following list of constructors. If `variants` is empty and
797
790
/// `non_exhaustive` is false, don't use this; use `NoConstructors` instead.
798
- Variants { variants : IndexVec < VariantIdx , VariantVisibility > , non_exhaustive : bool } ,
791
+ Variants { variants : IndexVec < Cx :: VariantIdx , VariantVisibility > , non_exhaustive : bool } ,
799
792
/// The type is `&T`.
800
793
Ref ,
801
794
/// The type is a union.
@@ -838,25 +831,25 @@ pub enum ConstructorSet {
838
831
/// of the `ConstructorSet` for the type, yet if we forgot to include them in `present` we would be
839
832
/// ignoring any row with `Opaque`s in the algorithm. Hence the importance of point 4.
840
833
#[ derive( Debug ) ]
841
- pub ( crate ) struct SplitConstructorSet < ' tcx > {
842
- pub ( crate ) present : SmallVec < [ Constructor < ' tcx > ; 1 ] > ,
843
- pub ( crate ) missing : Vec < Constructor < ' tcx > > ,
844
- pub ( crate ) missing_empty : Vec < Constructor < ' tcx > > ,
834
+ pub ( crate ) struct SplitConstructorSet < Cx : MatchCx > {
835
+ pub ( crate ) present : SmallVec < [ Constructor < Cx > ; 1 ] > ,
836
+ pub ( crate ) missing : Vec < Constructor < Cx > > ,
837
+ pub ( crate ) missing_empty : Vec < Constructor < Cx > > ,
845
838
}
846
839
847
- impl ConstructorSet {
840
+ impl < Cx : MatchCx > ConstructorSet < Cx > {
848
841
/// This analyzes a column of constructors to 1/ determine which constructors of the type (if
849
842
/// any) are missing; 2/ split constructors to handle non-trivial intersections e.g. on ranges
850
843
/// or slices. This can get subtle; see [`SplitConstructorSet`] for details of this operation
851
844
/// and its invariants.
852
845
#[ instrument( level = "debug" , skip( self , pcx, ctors) , ret) ]
853
- pub ( crate ) fn split < ' a , ' tcx > (
846
+ pub ( crate ) fn split < ' a > (
854
847
& self ,
855
- pcx : & PatCtxt < ' _ , ' _ , ' tcx > ,
856
- ctors : impl Iterator < Item = & ' a Constructor < ' tcx > > + Clone ,
857
- ) -> SplitConstructorSet < ' tcx >
848
+ pcx : & PatCtxt < ' _ , ' _ , Cx > ,
849
+ ctors : impl Iterator < Item = & ' a Constructor < Cx > > + Clone ,
850
+ ) -> SplitConstructorSet < Cx >
858
851
where
859
- ' tcx : ' a ,
852
+ Cx : ' a ,
860
853
{
861
854
let mut present: SmallVec < [ _ ; 1 ] > = SmallVec :: new ( ) ;
862
855
// Empty constructors found missing.
@@ -997,7 +990,7 @@ impl ConstructorSet {
997
990
// We have now grouped all the constructors into 3 buckets: present, missing, missing_empty.
998
991
// In the absence of the `exhaustive_patterns` feature however, we don't count nested empty
999
992
// types as empty. Only non-nested `!` or `enum Foo {}` are considered empty.
1000
- if !pcx. cx . tcx . features ( ) . exhaustive_patterns
993
+ if !pcx. cx . is_exhaustive_patterns_feature_on ( )
1001
994
&& !( pcx. is_top_level && matches ! ( self , Self :: NoConstructors ) )
1002
995
{
1003
996
// Treat all missing constructors as nonempty.
0 commit comments