@@ -13,7 +13,6 @@ use std::fmt;
1313use std:: ops:: Index ;
1414
1515use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
16- use rustc_errors:: { DiagArgValue , IntoDiagArg } ;
1716use rustc_hir as hir;
1817use rustc_hir:: def_id:: DefId ;
1918use rustc_hir:: { BindingMode , ByRef , HirId , MatchSource , RangeEnd } ;
@@ -702,12 +701,6 @@ impl<'tcx> Pat<'tcx> {
702701 }
703702}
704703
705- impl < ' tcx > IntoDiagArg for Pat < ' tcx > {
706- fn into_diag_arg ( self ) -> DiagArgValue {
707- format ! ( "{self}" ) . into_diag_arg ( )
708- }
709- }
710-
711704#[ derive( Clone , Debug , HashStable , TypeVisitable ) ]
712705pub struct Ascription < ' tcx > {
713706 pub annotation : CanonicalUserTypeAnnotation < ' tcx > ,
@@ -1080,8 +1073,33 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10801073 }
10811074}
10821075
1083- impl < ' tcx > fmt:: Display for Pat < ' tcx > {
1076+ impl < ' tcx > Pat < ' tcx > {
1077+ /// Prints a [`Pat`] to an owned string, for user-facing diagnostics.
1078+ ///
1079+ /// If we ever switch over to storing subpatterns as `PatId`, this will also
1080+ /// need to take a context that can resolve IDs to subpatterns.
1081+ pub fn to_string ( & self ) -> String {
1082+ format ! ( "{}" , self . display( ) )
1083+ }
1084+
1085+ /// Used internally by [`fmt::Display`] for [`PatDisplay`].
1086+ fn display ( & self ) -> PatDisplay < ' _ , ' tcx > {
1087+ PatDisplay { pat : self }
1088+ }
1089+ }
1090+
1091+ /// Wrapper around [`&Pat<'tcx>`][`Pat`] that implements [`fmt::Display`].
1092+ ///
1093+ /// If we ever switch over to storing subpatterns as `PatId`, this will also
1094+ /// need to hold a context that can resolve IDs to subpatterns.
1095+ struct PatDisplay < ' pat , ' tcx > {
1096+ pat : & ' pat Pat < ' tcx > ,
1097+ }
1098+
1099+ impl < ' pat , ' tcx > fmt:: Display for PatDisplay < ' pat , ' tcx > {
10841100 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1101+ let & Self { pat } = self ;
1102+
10851103 // Printing lists is a chore.
10861104 let mut first = true ;
10871105 let mut start_or_continue = |s| {
@@ -1094,20 +1112,22 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
10941112 } ;
10951113 let mut start_or_comma = || start_or_continue ( ", " ) ;
10961114
1097- match self . kind {
1115+ match pat . kind {
10981116 PatKind :: Wild => write ! ( f, "_" ) ,
10991117 PatKind :: Never => write ! ( f, "!" ) ,
1100- PatKind :: AscribeUserType { ref subpattern, .. } => write ! ( f, "{subpattern}: _" ) ,
1118+ PatKind :: AscribeUserType { ref subpattern, .. } => {
1119+ write ! ( f, "{}: _" , subpattern. display( ) )
1120+ }
11011121 PatKind :: Binding { name, mode, ref subpattern, .. } => {
11021122 f. write_str ( mode. prefix_str ( ) ) ?;
11031123 write ! ( f, "{name}" ) ?;
11041124 if let Some ( ref subpattern) = * subpattern {
1105- write ! ( f, " @ {subpattern}" ) ?;
1125+ write ! ( f, " @ {}" , subpattern . display ( ) ) ?;
11061126 }
11071127 Ok ( ( ) )
11081128 }
11091129 PatKind :: Variant { ref subpatterns, .. } | PatKind :: Leaf { ref subpatterns } => {
1110- let variant_and_name = match self . kind {
1130+ let variant_and_name = match pat . kind {
11111131 PatKind :: Variant { adt_def, variant_index, .. } => ty:: tls:: with ( |tcx| {
11121132 let variant = adt_def. variant ( variant_index) ;
11131133 let adt_did = adt_def. did ( ) ;
@@ -1120,7 +1140,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
11201140 } ;
11211141 Some ( ( variant, name) )
11221142 } ) ,
1123- _ => self . ty . ty_adt_def ( ) . and_then ( |adt_def| {
1143+ _ => pat . ty . ty_adt_def ( ) . and_then ( |adt_def| {
11241144 if !adt_def. is_enum ( ) {
11251145 ty:: tls:: with ( |tcx| {
11261146 Some ( ( adt_def. non_enum_variant ( ) , tcx. def_path_str ( adt_def. did ( ) ) ) )
@@ -1145,11 +1165,11 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
11451165 continue ;
11461166 }
11471167 let name = variant. fields [ p. field ] . name ;
1148- write ! ( f, "{}{}: {}" , start_or_comma( ) , name, p. pattern) ?;
1168+ write ! ( f, "{}{}: {}" , start_or_comma( ) , name, p. pattern. display ( ) ) ?;
11491169 printed += 1 ;
11501170 }
11511171
1152- let is_union = self . ty . ty_adt_def ( ) . is_some_and ( |adt| adt. is_union ( ) ) ;
1172+ let is_union = pat . ty . ty_adt_def ( ) . is_some_and ( |adt| adt. is_union ( ) ) ;
11531173 if printed < variant. fields . len ( ) && ( !is_union || printed == 0 ) {
11541174 write ! ( f, "{}.." , start_or_comma( ) ) ?;
11551175 }
@@ -1168,14 +1188,14 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
11681188 // Common case: the field is where we expect it.
11691189 if let Some ( p) = subpatterns. get ( i) {
11701190 if p. field . index ( ) == i {
1171- write ! ( f, "{}" , p. pattern) ?;
1191+ write ! ( f, "{}" , p. pattern. display ( ) ) ?;
11721192 continue ;
11731193 }
11741194 }
11751195
11761196 // Otherwise, we have to go looking for it.
11771197 if let Some ( p) = subpatterns. iter ( ) . find ( |p| p. field . index ( ) == i) {
1178- write ! ( f, "{}" , p. pattern) ?;
1198+ write ! ( f, "{}" , p. pattern. display ( ) ) ?;
11791199 } else {
11801200 write ! ( f, "_" ) ?;
11811201 }
@@ -1186,45 +1206,45 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
11861206 Ok ( ( ) )
11871207 }
11881208 PatKind :: Deref { ref subpattern } => {
1189- match self . ty . kind ( ) {
1209+ match pat . ty . kind ( ) {
11901210 ty:: Adt ( def, _) if def. is_box ( ) => write ! ( f, "box " ) ?,
11911211 ty:: Ref ( _, _, mutbl) => {
11921212 write ! ( f, "&{}" , mutbl. prefix_str( ) ) ?;
11931213 }
1194- _ => bug ! ( "{} is a bad Deref pattern type" , self . ty) ,
1214+ _ => bug ! ( "{} is a bad Deref pattern type" , pat . ty) ,
11951215 }
1196- write ! ( f, "{subpattern}" )
1216+ write ! ( f, "{}" , subpattern . display ( ) )
11971217 }
11981218 PatKind :: DerefPattern { ref subpattern, .. } => {
1199- write ! ( f, "deref!({subpattern })" )
1219+ write ! ( f, "deref!({})" , subpattern . display ( ) )
12001220 }
12011221 PatKind :: Constant { value } => write ! ( f, "{value}" ) ,
12021222 PatKind :: InlineConstant { def : _, ref subpattern } => {
1203- write ! ( f, "{} (from inline const)" , subpattern)
1223+ write ! ( f, "{} (from inline const)" , subpattern. display ( ) )
12041224 }
12051225 PatKind :: Range ( ref range) => write ! ( f, "{range}" ) ,
12061226 PatKind :: Slice { ref prefix, ref slice, ref suffix }
12071227 | PatKind :: Array { ref prefix, ref slice, ref suffix } => {
12081228 write ! ( f, "[" ) ?;
12091229 for p in prefix. iter ( ) {
1210- write ! ( f, "{}{}" , start_or_comma( ) , p) ?;
1230+ write ! ( f, "{}{}" , start_or_comma( ) , p. display ( ) ) ?;
12111231 }
12121232 if let Some ( ref slice) = * slice {
12131233 write ! ( f, "{}" , start_or_comma( ) ) ?;
12141234 match slice. kind {
12151235 PatKind :: Wild => { }
1216- _ => write ! ( f, "{slice}" ) ?,
1236+ _ => write ! ( f, "{}" , slice . display ( ) ) ?,
12171237 }
12181238 write ! ( f, ".." ) ?;
12191239 }
12201240 for p in suffix. iter ( ) {
1221- write ! ( f, "{}{}" , start_or_comma( ) , p) ?;
1241+ write ! ( f, "{}{}" , start_or_comma( ) , p. display ( ) ) ?;
12221242 }
12231243 write ! ( f, "]" )
12241244 }
12251245 PatKind :: Or { ref pats } => {
12261246 for pat in pats. iter ( ) {
1227- write ! ( f, "{}{}" , start_or_continue( " | " ) , pat) ?;
1247+ write ! ( f, "{}{}" , start_or_continue( " | " ) , pat. display ( ) ) ?;
12281248 }
12291249 Ok ( ( ) )
12301250 }
0 commit comments