@@ -24,6 +24,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
24
24
/// Converts an evaluated constant to a pattern (if possible).
25
25
/// This means aggregate values (like structs and enums) are converted
26
26
/// 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`.
27
29
#[ instrument( level = "debug" , skip( self ) , ret) ]
28
30
pub ( super ) fn const_to_pat (
29
31
& self ,
@@ -64,12 +66,8 @@ struct ConstToPat<'tcx> {
64
66
}
65
67
66
68
/// 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.
71
69
#[ derive( Debug ) ]
72
- struct FallbackToConstRef ;
70
+ struct FallbackToOpaqueConst ;
73
71
74
72
impl < ' tcx > ConstToPat < ' tcx > {
75
73
fn new (
@@ -136,7 +134,7 @@ impl<'tcx> ConstToPat<'tcx> {
136
134
}
137
135
ty:: ConstKind :: Value ( valtree) => self
138
136
. recur ( valtree, cv. ty ( ) , mir_structural_match_violation. unwrap_or ( false ) )
139
- . unwrap_or_else ( |_| {
137
+ . unwrap_or_else ( |_: FallbackToOpaqueConst | {
140
138
Box :: new ( Pat {
141
139
span : self . span ,
142
140
ty : cv. ty ( ) ,
@@ -266,7 +264,7 @@ impl<'tcx> ConstToPat<'tcx> {
266
264
fn field_pats (
267
265
& self ,
268
266
vals : impl Iterator < Item = ( ValTree < ' tcx > , Ty < ' tcx > ) > ,
269
- ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToConstRef > {
267
+ ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToOpaqueConst > {
270
268
vals. enumerate ( )
271
269
. map ( |( idx, ( val, ty) ) | {
272
270
let field = FieldIdx :: new ( idx) ;
@@ -284,7 +282,7 @@ impl<'tcx> ConstToPat<'tcx> {
284
282
cv : ValTree < ' tcx > ,
285
283
ty : Ty < ' tcx > ,
286
284
mir_structural_match_violation : bool ,
287
- ) -> Result < Box < Pat < ' tcx > > , FallbackToConstRef > {
285
+ ) -> Result < Box < Pat < ' tcx > > , FallbackToOpaqueConst > {
288
286
let id = self . id ;
289
287
let span = self . span ;
290
288
let tcx = self . tcx ( ) ;
@@ -299,7 +297,7 @@ impl<'tcx> ConstToPat<'tcx> {
299
297
span,
300
298
FloatPattern ,
301
299
) ;
302
- return Err ( FallbackToConstRef ) ;
300
+ return Err ( FallbackToOpaqueConst ) ;
303
301
}
304
302
// If the type is not structurally comparable, just emit the constant directly,
305
303
// causing the pattern match code to treat it opaquely.
@@ -323,18 +321,20 @@ impl<'tcx> ConstToPat<'tcx> {
323
321
// Since we are behind a reference, we can just bubble the error up so we get a
324
322
// constant at reference type, making it easy to let the fallback call
325
323
// `PartialEq::eq` on it.
326
- return Err ( FallbackToConstRef ) ;
324
+ return Err ( FallbackToOpaqueConst ) ;
327
325
}
328
326
ty:: FnDef ( ..) => {
329
327
self . saw_const_match_error . set ( true ) ;
330
328
tcx. sess . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
329
+ // We errored, so the pattern we generate is irrelevant.
331
330
PatKind :: Wild
332
331
}
333
332
ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
334
333
debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
335
334
self . saw_const_match_error . set ( true ) ;
336
335
let err = TypeNotStructural { span, non_sm_ty : ty } ;
337
336
tcx. sess . emit_err ( err) ;
337
+ // We errored, so the pattern we generate is irrelevant.
338
338
PatKind :: Wild
339
339
}
340
340
ty:: Adt ( adt_def, args) if adt_def. is_enum ( ) => {
@@ -404,13 +404,14 @@ impl<'tcx> ConstToPat<'tcx> {
404
404
IndirectStructuralMatch { non_sm_ty : * pointee_ty } ,
405
405
) ;
406
406
}
407
- return Err ( FallbackToConstRef ) ;
407
+ return Err ( FallbackToOpaqueConst ) ;
408
408
} else {
409
409
if !self . saw_const_match_error . get ( ) {
410
410
self . saw_const_match_error . set ( true ) ;
411
411
let err = TypeNotStructural { span, non_sm_ty : * pointee_ty } ;
412
412
tcx. sess . emit_err ( err) ;
413
413
}
414
+ // We errored, so the pattern we generate is irrelevant.
414
415
PatKind :: Wild
415
416
}
416
417
}
@@ -423,6 +424,7 @@ impl<'tcx> ConstToPat<'tcx> {
423
424
tcx. sess . emit_err ( err) ;
424
425
425
426
// FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
427
+ // We errored, so the pattern we generate is irrelevant.
426
428
PatKind :: Wild
427
429
} else {
428
430
let old = self . behind_reference . replace ( true ) ;
@@ -453,6 +455,7 @@ impl<'tcx> ConstToPat<'tcx> {
453
455
self . saw_const_match_error . set ( true ) ;
454
456
let err = InvalidPattern { span, non_sm_ty : ty } ;
455
457
tcx. sess . emit_err ( err) ;
458
+ // We errored, so the pattern we generate is irrelevant.
456
459
PatKind :: Wild
457
460
}
458
461
} ;
0 commit comments