1+ use crate :: thir:: pattern:: deconstruct_pat:: DeconstructedPat ;
12use crate :: thir:: pattern:: MatchCheckCtxt ;
23use rustc_errors:: Handler ;
34use rustc_errors:: {
4- error_code, Applicability , DiagnosticBuilder , ErrorGuaranteed , IntoDiagnostic , MultiSpan ,
5+ error_code, AddToDiagnostic , Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed ,
6+ IntoDiagnostic , MultiSpan , SubdiagnosticMessage ,
57} ;
8+ use rustc_hir:: def:: Res ;
69use rustc_macros:: { Diagnostic , LintDiagnostic , Subdiagnostic } ;
710use rustc_middle:: thir:: Pat ;
811use rustc_middle:: ty:: { self , Ty } ;
@@ -677,7 +680,6 @@ pub struct OverlappingRangeEndpoints<'tcx> {
677680 pub overlap : Overlap < ' tcx > ,
678681}
679682
680- #[ derive( Debug ) ]
681683#[ derive( Subdiagnostic ) ]
682684#[ label( mir_build_overlapping_range) ]
683685pub struct Overlap < ' tcx > {
@@ -692,10 +694,158 @@ pub struct Overlap<'tcx> {
692694#[ note]
693695pub ( crate ) struct NonExhaustiveOmittedPattern < ' tcx > {
694696 pub scrut_ty : Ty < ' tcx > ,
695- #[ label]
696- pub uncovered : Span ,
697+ #[ subdiagnostic]
698+ pub uncovered : Uncovered < ' tcx > ,
699+ }
700+
701+ #[ derive( Subdiagnostic ) ]
702+ #[ label( mir_build_uncovered) ]
703+ pub ( crate ) struct Uncovered < ' tcx > {
704+ #[ primary_span]
705+ span : Span ,
706+ count : usize ,
707+ witness_1 : Pat < ' tcx > ,
708+ witness_2 : Pat < ' tcx > ,
709+ witness_3 : Pat < ' tcx > ,
710+ remainder : usize ,
711+ }
712+
713+ impl < ' tcx > Uncovered < ' tcx > {
714+ pub fn new < ' p > (
715+ span : Span ,
716+ cx : & MatchCheckCtxt < ' p , ' tcx > ,
717+ witnesses : Vec < DeconstructedPat < ' p , ' tcx > > ,
718+ ) -> Self {
719+ let witness_1 = witnesses. get ( 0 ) . unwrap ( ) . to_pat ( cx) ;
720+ Self {
721+ span,
722+ count : witnesses. len ( ) ,
723+ // Substitute dummy values if witnesses is smaller than 3. These will never be read.
724+ witness_2 : witnesses. get ( 1 ) . map ( |w| w. to_pat ( cx) ) . unwrap_or_else ( || witness_1. clone ( ) ) ,
725+ witness_3 : witnesses. get ( 2 ) . map ( |w| w. to_pat ( cx) ) . unwrap_or_else ( || witness_1. clone ( ) ) ,
726+ witness_1,
727+ remainder : witnesses. len ( ) . saturating_sub ( 3 ) ,
728+ }
729+ }
730+ }
731+
732+ #[ derive( Diagnostic ) ]
733+ #[ diag( mir_build_pattern_not_covered, code = "E0005" ) ]
734+ pub ( crate ) struct PatternNotCovered < ' s , ' tcx > {
735+ #[ primary_span]
736+ pub span : Span ,
737+ pub origin : & ' s str ,
738+ #[ subdiagnostic]
739+ pub uncovered : Uncovered < ' tcx > ,
740+ #[ subdiagnostic]
741+ pub inform : Option < Inform > ,
742+ #[ subdiagnostic]
743+ pub interpreted_as_const : Option < InterpretedAsConst > ,
744+ #[ subdiagnostic]
745+ pub adt_defined_here : Option < AdtDefinedHere < ' tcx > > ,
746+ #[ note( pattern_ty) ]
747+ pub _p : ( ) ,
748+ pub pattern_ty : Ty < ' tcx > ,
749+ #[ subdiagnostic]
750+ pub if_let_suggestion : Option < SuggestIfLet > ,
751+ #[ subdiagnostic]
752+ pub let_else_suggestion : Option < SuggestLetElse > ,
753+ #[ subdiagnostic]
754+ pub res_defined_here : Option < ResDefinedHere > ,
755+ }
756+
757+ #[ derive( Subdiagnostic ) ]
758+ #[ note( mir_build_inform_irrefutable) ]
759+ #[ note( mir_build_more_information) ]
760+ pub struct Inform ;
761+
762+ pub struct AdtDefinedHere < ' tcx > {
763+ pub adt_def_span : Span ,
764+ pub ty : Ty < ' tcx > ,
765+ pub variants : Vec < Variant > ,
766+ }
767+
768+ pub struct Variant {
769+ pub span : Span ,
770+ }
771+
772+ impl < ' tcx > AddToDiagnostic for AdtDefinedHere < ' tcx > {
773+ fn add_to_diagnostic_with < F > ( self , diag : & mut Diagnostic , _: F )
774+ where
775+ F : Fn ( & mut Diagnostic , SubdiagnosticMessage ) -> SubdiagnosticMessage ,
776+ {
777+ diag. set_arg ( "ty" , self . ty ) ;
778+ let mut spans = MultiSpan :: from ( self . adt_def_span ) ;
779+
780+ for Variant { span } in self . variants {
781+ spans. push_span_label ( span, rustc_errors:: fluent:: mir_build_variant_defined_here) ;
782+ }
783+
784+ diag. span_note ( spans, rustc_errors:: fluent:: mir_build_adt_defined_here) ;
785+ }
786+ }
787+
788+ #[ derive( Subdiagnostic ) ]
789+ #[ label( mir_build_res_defined_here) ]
790+ pub struct ResDefinedHere {
791+ #[ primary_span]
792+ pub def_span : Span ,
793+ pub res : Res ,
794+ }
795+
796+ #[ derive( Subdiagnostic ) ]
797+ #[ suggestion(
798+ mir_build_interpreted_as_const,
799+ code = "{variable}_var" ,
800+ applicability = "maybe-incorrect"
801+ ) ]
802+ #[ label( mir_build_confused) ]
803+ pub struct InterpretedAsConst {
804+ #[ primary_span]
805+ pub span : Span ,
806+ pub article : & ' static str ,
807+ pub variable : String ,
808+ pub res : Res ,
809+ }
810+
811+ #[ derive( Subdiagnostic ) ]
812+ pub enum SuggestIfLet {
813+ #[ multipart_suggestion( mir_build_suggest_if_let, applicability = "has-placeholders" ) ]
814+ None {
815+ #[ suggestion_part( code = "if " ) ]
816+ start_span : Span ,
817+ #[ suggestion_part( code = " {{ todo!() }}" ) ]
818+ semi_span : Span ,
819+ count : usize ,
820+ } ,
821+ #[ multipart_suggestion( mir_build_suggest_if_let, applicability = "has-placeholders" ) ]
822+ One {
823+ #[ suggestion_part( code = "let {binding} = if " ) ]
824+ start_span : Span ,
825+ #[ suggestion_part( code = " {{ {binding} }} else {{ todo!() }}" ) ]
826+ end_span : Span ,
827+ binding : Ident ,
828+ count : usize ,
829+ } ,
830+ #[ multipart_suggestion( mir_build_suggest_if_let, applicability = "has-placeholders" ) ]
831+ More {
832+ #[ suggestion_part( code = "let ({bindings}) = if " ) ]
833+ start_span : Span ,
834+ #[ suggestion_part( code = " {{ ({bindings}) }} else {{ todo!() }}" ) ]
835+ end_span : Span ,
836+ bindings : String ,
837+ count : usize ,
838+ } ,
839+ }
840+
841+ #[ derive( Subdiagnostic ) ]
842+ #[ suggestion(
843+ mir_build_suggest_let_else,
844+ code = " else {{ todo!() }}" ,
845+ applicability = "has-placeholders"
846+ ) ]
847+ pub struct SuggestLetElse {
848+ #[ primary_span]
849+ pub end_span : Span ,
697850 pub count : usize ,
698- pub witness_1 : Pat < ' tcx > ,
699- pub witness_2 : Pat < ' tcx > ,
700- pub witness_3 : Pat < ' tcx > ,
701851}
0 commit comments