@@ -774,17 +774,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
774774 }
775775 }
776776
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 {
780779 use MaybeInfiniteInt :: * ;
781780 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 ( )
784783 } else if range. is_singleton ( ) {
785784 let lo = cx. hoist_pat_range_bdy ( range. lo , ty) ;
786785 let value = lo. as_finite ( ) . unwrap ( ) ;
787- PatKind :: Constant { value }
786+ value. to_string ( )
788787 } else {
789788 // We convert to an inclusive range for diagnostics.
790789 let mut end = rustc_hir:: RangeEnd :: Included ;
@@ -807,32 +806,24 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
807806 range. hi
808807 } ;
809808 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+ }
814811 }
815812
816813 /// 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.
817816 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 } ;
827817 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 ( ) ) ,
832823 Struct if pat. ty ( ) . is_box ( ) => {
833824 // Outside of the `alloc` crate, the only way to create a struct pattern
834825 // 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 ] ) )
836827 }
837828 Struct | Variant ( _) | UnionField => {
838829 let enum_info = match * pat. ty ( ) . kind ( ) {
@@ -847,12 +838,29 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
847838 let subpatterns = pat
848839 . iter_fields ( )
849840 . 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+ } )
851846 . collect :: < Vec < _ > > ( ) ;
852847
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
854863 }
855- Ref => PatKind :: Deref { subpattern : hoist ( & pat. fields [ 0 ] ) } ,
856864 Slice ( slice) => {
857865 let ( prefix_len, has_dot_dot) = match slice. kind {
858866 SliceKind :: FixedLen ( len) => ( len, false ) ,
@@ -879,24 +887,23 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
879887 }
880888 }
881889
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 < _ > > ( ) ;
884892
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
886896 }
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 ( ) ,
890899 Missing { .. } => bug ! (
891900 "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug,
892901 `Missing` should have been processed in `apply_constructors`"
893902 ) ,
894903 F16Range ( ..) | F32Range ( ..) | F64Range ( ..) | F128Range ( ..) | Opaque ( ..) | Or => {
895904 bug ! ( "can't convert to pattern: {:?}" , pat)
896905 }
897- } ;
898-
899- Pat { ty : pat. ty ( ) . inner ( ) , kind }
906+ }
900907 }
901908}
902909
@@ -972,7 +979,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
972979 overlaps_on : IntRange ,
973980 overlaps_with : & [ & crate :: pat:: DeconstructedPat < Self > ] ,
974981 ) {
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 ( ) ) ;
976983 let overlaps: Vec < _ > = overlaps_with
977984 . iter ( )
978985 . map ( |pat| pat. data ( ) . span )
@@ -1012,7 +1019,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
10121019 suggested_range. end = rustc_hir:: RangeEnd :: Included ;
10131020 suggested_range. to_string ( )
10141021 } ;
1015- let gap_as_pat = self . hoist_pat_range ( & gap, * pat. ty ( ) ) ;
1022+ let gap_as_pat = self . print_pat_range ( & gap, * pat. ty ( ) ) ;
10161023 if gapped_with. is_empty ( ) {
10171024 // If `gapped_with` is empty, `gap == T::MAX`.
10181025 self . tcx . emit_node_span_lint (
0 commit comments