@@ -24,6 +24,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
2424 /// Converts an evaluated constant to a pattern (if possible).
2525 /// This means aggregate values (like structs and enums) are converted
2626 /// to a pattern that matches the value (as if you'd compared via structural equality).
27+ ///
28+ /// `cv` must be a valtree or a `mir::ConstValue`.
2729 #[ instrument( level = "debug" , skip( self ) , ret) ]
2830 pub ( super ) fn const_to_pat (
2931 & self ,
@@ -64,12 +66,8 @@ struct ConstToPat<'tcx> {
6466}
6567
6668/// This error type signals that we encountered a non-struct-eq situation.
67- /// We bubble this up in order to get back to the reference destructuring and make that emit
68- /// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
69- /// on such patterns (since that function takes a reference) and not have to jump through any
70- /// hoops to get a reference to the value.
7169#[ derive( Debug ) ]
72- struct FallbackToConstRef ;
70+ struct FallbackToOpaqueConst ;
7371
7472impl < ' tcx > ConstToPat < ' tcx > {
7573 fn new (
@@ -136,7 +134,7 @@ impl<'tcx> ConstToPat<'tcx> {
136134 }
137135 ty:: ConstKind :: Value ( valtree) => self
138136 . recur ( valtree, cv. ty ( ) , mir_structural_match_violation. unwrap_or ( false ) )
139- . unwrap_or_else ( |_| {
137+ . unwrap_or_else ( |_: FallbackToOpaqueConst | {
140138 Box :: new ( Pat {
141139 span : self . span ,
142140 ty : cv. ty ( ) ,
@@ -266,7 +264,7 @@ impl<'tcx> ConstToPat<'tcx> {
266264 fn field_pats (
267265 & self ,
268266 vals : impl Iterator < Item = ( ValTree < ' tcx > , Ty < ' tcx > ) > ,
269- ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToConstRef > {
267+ ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToOpaqueConst > {
270268 vals. enumerate ( )
271269 . map ( |( idx, ( val, ty) ) | {
272270 let field = FieldIdx :: new ( idx) ;
@@ -284,7 +282,7 @@ impl<'tcx> ConstToPat<'tcx> {
284282 cv : ValTree < ' tcx > ,
285283 ty : Ty < ' tcx > ,
286284 mir_structural_match_violation : bool ,
287- ) -> Result < Box < Pat < ' tcx > > , FallbackToConstRef > {
285+ ) -> Result < Box < Pat < ' tcx > > , FallbackToOpaqueConst > {
288286 let id = self . id ;
289287 let span = self . span ;
290288 let tcx = self . tcx ( ) ;
@@ -299,7 +297,7 @@ impl<'tcx> ConstToPat<'tcx> {
299297 span,
300298 FloatPattern ,
301299 ) ;
302- return Err ( FallbackToConstRef ) ;
300+ return Err ( FallbackToOpaqueConst ) ;
303301 }
304302 // If the type is not structurally comparable, just emit the constant directly,
305303 // causing the pattern match code to treat it opaquely.
@@ -323,18 +321,20 @@ impl<'tcx> ConstToPat<'tcx> {
323321 // Since we are behind a reference, we can just bubble the error up so we get a
324322 // constant at reference type, making it easy to let the fallback call
325323 // `PartialEq::eq` on it.
326- return Err ( FallbackToConstRef ) ;
324+ return Err ( FallbackToOpaqueConst ) ;
327325 }
328326 ty:: FnDef ( ..) => {
329327 self . saw_const_match_error . set ( true ) ;
330328 tcx. sess . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
329+ // We errored, so the pattern we generate is irrelevant.
331330 PatKind :: Wild
332331 }
333332 ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
334333 debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
335334 self . saw_const_match_error . set ( true ) ;
336335 let err = TypeNotStructural { span, non_sm_ty : ty } ;
337336 tcx. sess . emit_err ( err) ;
337+ // We errored, so the pattern we generate is irrelevant.
338338 PatKind :: Wild
339339 }
340340 ty:: Adt ( adt_def, args) if adt_def. is_enum ( ) => {
@@ -404,13 +404,14 @@ impl<'tcx> ConstToPat<'tcx> {
404404 IndirectStructuralMatch { non_sm_ty : * pointee_ty } ,
405405 ) ;
406406 }
407- return Err ( FallbackToConstRef ) ;
407+ return Err ( FallbackToOpaqueConst ) ;
408408 } else {
409409 if !self . saw_const_match_error . get ( ) {
410410 self . saw_const_match_error . set ( true ) ;
411411 let err = TypeNotStructural { span, non_sm_ty : * pointee_ty } ;
412412 tcx. sess . emit_err ( err) ;
413413 }
414+ // We errored, so the pattern we generate is irrelevant.
414415 PatKind :: Wild
415416 }
416417 }
@@ -423,6 +424,7 @@ impl<'tcx> ConstToPat<'tcx> {
423424 tcx. sess . emit_err ( err) ;
424425
425426 // FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
427+ // We errored, so the pattern we generate is irrelevant.
426428 PatKind :: Wild
427429 } else {
428430 let old = self . behind_reference . replace ( true ) ;
@@ -453,6 +455,7 @@ impl<'tcx> ConstToPat<'tcx> {
453455 self . saw_const_match_error . set ( true ) ;
454456 let err = InvalidPattern { span, non_sm_ty : ty } ;
455457 tcx. sess . emit_err ( err) ;
458+ // We errored, so the pattern we generate is irrelevant.
456459 PatKind :: Wild
457460 }
458461 } ;
0 commit comments