@@ -180,23 +180,26 @@ impl<'tcx> ConstToPat<'tcx> {
180
180
181
181
if let Some ( non_sm_ty) = structural {
182
182
if !self . type_has_partial_eq_impl ( cv. ty ( ) ) {
183
- if let ty:: Adt ( def, ..) = non_sm_ty. kind ( ) {
183
+ let e = if let ty:: Adt ( def, ..) = non_sm_ty. kind ( ) {
184
184
if def. is_union ( ) {
185
185
let err = UnionPattern { span : self . span } ;
186
- self . tcx ( ) . sess . emit_err ( err) ;
186
+ self . tcx ( ) . sess . emit_err ( err)
187
187
} else {
188
188
// fatal avoids ICE from resolution of nonexistent method (rare case).
189
189
self . tcx ( )
190
190
. sess
191
- . emit_fatal ( TypeNotStructural { span : self . span , non_sm_ty } ) ;
191
+ . emit_fatal ( TypeNotStructural { span : self . span , non_sm_ty } )
192
192
}
193
193
} else {
194
194
let err = InvalidPattern { span : self . span , non_sm_ty } ;
195
- self . tcx ( ) . sess . emit_err ( err) ;
196
- }
195
+ self . tcx ( ) . sess . emit_err ( err)
196
+ } ;
197
197
// All branches above emitted an error. Don't print any more lints.
198
198
// The pattern we return is irrelevant since we errored.
199
- return Box :: new ( Pat { span : self . span , ty : cv. ty ( ) , kind : PatKind :: Wild } ) ;
199
+ let kind = PatKind :: Constant {
200
+ value : mir:: Const :: Ty ( ty:: Const :: new_error ( self . tcx ( ) , e, cv. ty ( ) ) ) ,
201
+ } ;
202
+ return Box :: new ( Pat { span : self . span , ty : cv. ty ( ) , kind } ) ;
200
203
} else if !self . saw_const_match_lint . get ( ) {
201
204
if let Some ( mir_structural_match_violation) = mir_structural_match_violation {
202
205
match non_sm_ty. kind ( ) {
@@ -346,17 +349,17 @@ impl<'tcx> ConstToPat<'tcx> {
346
349
}
347
350
ty:: FnDef ( ..) => {
348
351
self . saw_const_match_error . set ( true ) ;
349
- tcx. sess . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
350
- // We errored, so the pattern we generate is irrelevant .
351
- PatKind :: Wild
352
+ let e = tcx. sess . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
353
+ // We errored. Signal that in the pattern, so that follow up errors can be silenced .
354
+ PatKind :: Constant { value : mir :: Const :: Ty ( ty :: Const :: new_error ( tcx , e , ty ) ) }
352
355
}
353
356
ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
354
357
debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
355
358
self . saw_const_match_error . set ( true ) ;
356
359
let err = TypeNotStructural { span, non_sm_ty : ty } ;
357
- tcx. sess . emit_err ( err) ;
358
- // We errored, so the pattern we generate is irrelevant .
359
- PatKind :: Wild
360
+ let e = tcx. sess . emit_err ( err) ;
361
+ // We errored. Signal that in the pattern, so that follow up errors can be silenced .
362
+ PatKind :: Constant { value : mir :: Const :: Ty ( ty :: Const :: new_error ( tcx , e , ty ) ) }
360
363
}
361
364
ty:: Adt ( adt_def, args) if adt_def. is_enum ( ) => {
362
365
let ( & variant_index, fields) = cv. unwrap_branch ( ) . split_first ( ) . unwrap ( ) ;
@@ -427,14 +430,20 @@ impl<'tcx> ConstToPat<'tcx> {
427
430
}
428
431
return Err ( FallbackToOpaqueConst ) ;
429
432
} else {
430
- if !self . saw_const_match_error . get ( ) {
433
+ if self . saw_const_match_error . get ( ) {
434
+ // We already errored. Signal that in the pattern, so that follow up errors can be silenced.
435
+ PatKind :: Constant {
436
+ value : mir:: Const :: Ty ( ty:: Const :: new_misc_error ( tcx, ty) ) ,
437
+ }
438
+ } else {
431
439
self . saw_const_match_error . set ( true ) ;
432
440
let err = TypeNotStructural { span, non_sm_ty : * pointee_ty } ;
433
- tcx. sess . emit_err ( err) ;
441
+ let e = tcx. sess . emit_err ( err) ;
442
+ // We errored. Signal that in the pattern, so that follow up errors can be silenced.
443
+ PatKind :: Constant {
444
+ value : mir:: Const :: Ty ( ty:: Const :: new_error ( tcx, e, ty) ) ,
445
+ }
434
446
}
435
- tcx. sess . delay_span_bug ( span, "`saw_const_match_error` set but no error?" ) ;
436
- // We errored, so the pattern we generate is irrelevant.
437
- PatKind :: Wild
438
447
}
439
448
}
440
449
// All other references are converted into deref patterns and then recursively
@@ -443,11 +452,11 @@ impl<'tcx> ConstToPat<'tcx> {
443
452
_ => {
444
453
if !pointee_ty. is_sized ( tcx, param_env) && !pointee_ty. is_slice ( ) {
445
454
let err = UnsizedPattern { span, non_sm_ty : * pointee_ty } ;
446
- tcx. sess . emit_err ( err) ;
447
-
448
- // FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
449
- // We errored, so the pattern we generate is irrelevant.
450
- PatKind :: Wild
455
+ let e = tcx. sess . emit_err ( err) ;
456
+ // We errored. Signal that in the pattern, so that follow up errors can be silenced.
457
+ PatKind :: Constant {
458
+ value : mir :: Const :: Ty ( ty :: Const :: new_error ( tcx , e , ty ) ) ,
459
+ }
451
460
} else {
452
461
let old = self . behind_reference . replace ( true ) ;
453
462
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
@@ -476,9 +485,9 @@ impl<'tcx> ConstToPat<'tcx> {
476
485
_ => {
477
486
self . saw_const_match_error . set ( true ) ;
478
487
let err = InvalidPattern { span, non_sm_ty : ty } ;
479
- tcx. sess . emit_err ( err) ;
480
- // We errored, so the pattern we generate is irrelevant .
481
- PatKind :: Wild
488
+ let e = tcx. sess . emit_err ( err) ;
489
+ // We errored. Signal that in the pattern, so that follow up errors can be silenced .
490
+ PatKind :: Constant { value : mir :: Const :: Ty ( ty :: Const :: new_error ( tcx , e , ty ) ) }
482
491
}
483
492
} ;
484
493
0 commit comments