@@ -180,23 +180,26 @@ impl<'tcx> ConstToPat<'tcx> {
180180
181181 if let Some ( non_sm_ty) = structural {
182182 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 ( ) {
184184 if def. is_union ( ) {
185185 let err = UnionPattern { span : self . span } ;
186- self . tcx ( ) . sess . emit_err ( err) ;
186+ self . tcx ( ) . sess . emit_err ( err)
187187 } else {
188188 // fatal avoids ICE from resolution of nonexistent method (rare case).
189189 self . tcx ( )
190190 . sess
191- . emit_fatal ( TypeNotStructural { span : self . span , non_sm_ty } ) ;
191+ . emit_fatal ( TypeNotStructural { span : self . span , non_sm_ty } )
192192 }
193193 } else {
194194 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+ } ;
197197 // All branches above emitted an error. Don't print any more lints.
198- // The pattern we return is irrelevant since we errored.
199- return Box :: new ( Pat { span : self . span , ty : cv. ty ( ) , kind : PatKind :: Wild } ) ;
198+ // We errored. Signal that in the pattern, so that follow up errors can be silenced.
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 } ) ;
200203 } else if !self . saw_const_match_lint . get ( ) {
201204 if let Some ( mir_structural_match_violation) = mir_structural_match_violation {
202205 match non_sm_ty. kind ( ) {
@@ -346,17 +349,17 @@ impl<'tcx> ConstToPat<'tcx> {
346349 }
347350 ty:: FnDef ( ..) => {
348351 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 ) ) }
352355 }
353356 ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
354357 debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
355358 self . saw_const_match_error . set ( true ) ;
356359 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 ) ) }
360363 }
361364 ty:: Adt ( adt_def, args) if adt_def. is_enum ( ) => {
362365 let ( & variant_index, fields) = cv. unwrap_branch ( ) . split_first ( ) . unwrap ( ) ;
@@ -427,14 +430,20 @@ impl<'tcx> ConstToPat<'tcx> {
427430 }
428431 return Err ( FallbackToOpaqueConst ) ;
429432 } 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 {
431439 self . saw_const_match_error . set ( true ) ;
432440 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+ }
434446 }
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
438447 }
439448 }
440449 // All other references are converted into deref patterns and then recursively
@@ -443,11 +452,11 @@ impl<'tcx> ConstToPat<'tcx> {
443452 _ => {
444453 if !pointee_ty. is_sized ( tcx, param_env) && !pointee_ty. is_slice ( ) {
445454 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+ }
451460 } else {
452461 let old = self . behind_reference . replace ( true ) ;
453462 // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
@@ -476,9 +485,9 @@ impl<'tcx> ConstToPat<'tcx> {
476485 _ => {
477486 self . saw_const_match_error . set ( true ) ;
478487 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 ) ) }
482491 }
483492 } ;
484493
0 commit comments