@@ -774,17 +774,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
774
774
}
775
775
}
776
776
777
- /// Convert to a [`print::Pat`] for diagnostic purposes.
778
- fn hoist_pat_range ( & self , range : & IntRange , ty : RevealedTy < ' tcx > ) -> print:: Pat < ' tcx > {
779
- use print:: { Pat , PatKind } ;
777
+ /// Prints an [`IntRange`] to a string for diagnostic purposes.
778
+ fn print_pat_range ( & self , range : & IntRange , ty : RevealedTy < ' tcx > ) -> String {
780
779
use MaybeInfiniteInt :: * ;
781
780
let cx = self ;
782
- let kind = if matches ! ( ( range. lo, range. hi) , ( NegInfinity , PosInfinity ) ) {
783
- PatKind :: Wild
781
+ if matches ! ( ( range. lo, range. hi) , ( NegInfinity , PosInfinity ) ) {
782
+ "_" . to_string ( )
784
783
} else if range. is_singleton ( ) {
785
784
let lo = cx. hoist_pat_range_bdy ( range. lo , ty) ;
786
785
let value = lo. as_finite ( ) . unwrap ( ) ;
787
- PatKind :: Constant { value }
786
+ value. to_string ( )
788
787
} else {
789
788
// We convert to an inclusive range for diagnostics.
790
789
let mut end = rustc_hir:: RangeEnd :: Included ;
@@ -807,32 +806,24 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
807
806
range. hi
808
807
} ;
809
808
let hi = cx. hoist_pat_range_bdy ( hi, ty) ;
810
- PatKind :: Range ( Box :: new ( PatRange { lo, hi, end, ty : ty. inner ( ) } ) )
811
- } ;
812
-
813
- Pat { ty : ty. inner ( ) , kind }
809
+ PatRange { lo, hi, end, ty : ty. inner ( ) } . to_string ( )
810
+ }
814
811
}
815
812
816
813
/// Prints a [`WitnessPat`] to an owned string, for diagnostic purposes.
814
+ ///
815
+ /// This panics for patterns that don't appear in diagnostics, like float ranges.
817
816
pub fn print_witness_pat ( & self , pat : & WitnessPat < ' p , ' tcx > ) -> String {
818
- // This works by converting the witness pattern to a `print::Pat`
819
- // and then printing that, but callers don't need to know that.
820
- self . hoist_witness_pat ( pat) . to_string ( )
821
- }
822
-
823
- /// Convert to a [`print::Pat`] for diagnostic purposes. This panics for patterns that don't
824
- /// appear in diagnostics, like float ranges.
825
- fn hoist_witness_pat ( & self , pat : & WitnessPat < ' p , ' tcx > ) -> print:: Pat < ' tcx > {
826
- use print:: { FieldPat , Pat , PatKind } ;
827
817
let cx = self ;
828
- let hoist = |p| Box :: new ( cx. hoist_witness_pat ( p) ) ;
829
- let kind = match pat. ctor ( ) {
830
- Bool ( b) => PatKind :: Constant { value : mir:: Const :: from_bool ( cx. tcx , * b) } ,
831
- IntRange ( range) => return self . hoist_pat_range ( range, * pat. ty ( ) ) ,
818
+ let print = |p| cx. print_witness_pat ( p) ;
819
+ match pat. ctor ( ) {
820
+ Bool ( b) => b. to_string ( ) ,
821
+ Str ( s) => s. to_string ( ) ,
822
+ IntRange ( range) => return self . print_pat_range ( range, * pat. ty ( ) ) ,
832
823
Struct if pat. ty ( ) . is_box ( ) => {
833
824
// Outside of the `alloc` crate, the only way to create a struct pattern
834
825
// of type `Box` is to use a `box` pattern via #[feature(box_patterns)].
835
- PatKind :: Box { subpattern : hoist ( & pat. fields [ 0 ] ) }
826
+ format ! ( "box {}" , print ( & pat. fields[ 0 ] ) )
836
827
}
837
828
Struct | Variant ( _) | UnionField => {
838
829
let enum_info = match * pat. ty ( ) . kind ( ) {
@@ -847,12 +838,29 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
847
838
let subpatterns = pat
848
839
. iter_fields ( )
849
840
. enumerate ( )
850
- . map ( |( i, pat) | FieldPat { field : FieldIdx :: new ( i) , pattern : hoist ( pat) } )
841
+ . map ( |( i, pat) | print:: FieldPat {
842
+ field : FieldIdx :: new ( i) ,
843
+ pattern : print ( pat) ,
844
+ is_wildcard : would_print_as_wildcard ( cx. tcx , pat) ,
845
+ } )
851
846
. collect :: < Vec < _ > > ( ) ;
852
847
853
- PatKind :: StructLike { enum_info, subpatterns }
848
+ let mut s = String :: new ( ) ;
849
+ print:: write_struct_like (
850
+ & mut s,
851
+ self . tcx ,
852
+ pat. ty ( ) . inner ( ) ,
853
+ & enum_info,
854
+ & subpatterns,
855
+ )
856
+ . unwrap ( ) ;
857
+ s
858
+ }
859
+ Ref => {
860
+ let mut s = String :: new ( ) ;
861
+ print:: write_ref_like ( & mut s, pat. ty ( ) . inner ( ) , & print ( & pat. fields [ 0 ] ) ) . unwrap ( ) ;
862
+ s
854
863
}
855
- Ref => PatKind :: Deref { subpattern : hoist ( & pat. fields [ 0 ] ) } ,
856
864
Slice ( slice) => {
857
865
let ( prefix_len, has_dot_dot) = match slice. kind {
858
866
SliceKind :: FixedLen ( len) => ( len, false ) ,
@@ -879,24 +887,23 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
879
887
}
880
888
}
881
889
882
- let prefix = prefix. iter ( ) . map ( hoist ) . collect ( ) ;
883
- let suffix = suffix. iter ( ) . map ( hoist ) . collect ( ) ;
890
+ let prefix = prefix. iter ( ) . map ( print ) . collect :: < Vec < _ > > ( ) ;
891
+ let suffix = suffix. iter ( ) . map ( print ) . collect :: < Vec < _ > > ( ) ;
884
892
885
- PatKind :: Slice { prefix, has_dot_dot, suffix }
893
+ let mut s = String :: new ( ) ;
894
+ print:: write_slice_like ( & mut s, & prefix, has_dot_dot, & suffix) . unwrap ( ) ;
895
+ s
886
896
}
887
- & Str ( value) => PatKind :: Constant { value } ,
888
- Never if self . tcx . features ( ) . never_patterns => PatKind :: Never ,
889
- Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind :: Wild ,
897
+ Never if self . tcx . features ( ) . never_patterns => "!" . to_string ( ) ,
898
+ Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => "_" . to_string ( ) ,
890
899
Missing { .. } => bug ! (
891
900
"trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
892
901
`Missing` should have been processed in `apply_constructors`"
893
902
) ,
894
903
F16Range ( ..) | F32Range ( ..) | F64Range ( ..) | F128Range ( ..) | Opaque ( ..) | Or => {
895
904
bug ! ( "can't convert to pattern: {:?}" , pat)
896
905
}
897
- } ;
898
-
899
- Pat { ty : pat. ty ( ) . inner ( ) , kind }
906
+ }
900
907
}
901
908
}
902
909
@@ -972,7 +979,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
972
979
overlaps_on : IntRange ,
973
980
overlaps_with : & [ & crate :: pat:: DeconstructedPat < Self > ] ,
974
981
) {
975
- let overlap_as_pat = self . hoist_pat_range ( & overlaps_on, * pat. ty ( ) ) ;
982
+ let overlap_as_pat = self . print_pat_range ( & overlaps_on, * pat. ty ( ) ) ;
976
983
let overlaps: Vec < _ > = overlaps_with
977
984
. iter ( )
978
985
. map ( |pat| pat. data ( ) . span )
@@ -1012,7 +1019,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
1012
1019
suggested_range. end = rustc_hir:: RangeEnd :: Included ;
1013
1020
suggested_range. to_string ( )
1014
1021
} ;
1015
- let gap_as_pat = self . hoist_pat_range ( & gap, * pat. ty ( ) ) ;
1022
+ let gap_as_pat = self . print_pat_range ( & gap, * pat. ty ( ) ) ;
1016
1023
if gapped_with. is_empty ( ) {
1017
1024
// If `gapped_with` is empty, `gap == T::MAX`.
1018
1025
self . tcx . emit_node_span_lint (
0 commit comments