1
+ use crate :: thir:: pattern:: deconstruct_pat:: DeconstructedPat ;
1
2
use crate :: thir:: pattern:: MatchCheckCtxt ;
2
3
use rustc_errors:: Handler ;
3
4
use rustc_errors:: {
4
- error_code, Applicability , DiagnosticBuilder , ErrorGuaranteed , IntoDiagnostic , MultiSpan ,
5
+ error_code, AddToDiagnostic , Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed ,
6
+ IntoDiagnostic , MultiSpan , SubdiagnosticMessage ,
5
7
} ;
8
+ use rustc_hir:: def:: Res ;
6
9
use rustc_macros:: { Diagnostic , LintDiagnostic , Subdiagnostic } ;
7
10
use rustc_middle:: thir:: Pat ;
8
11
use rustc_middle:: ty:: { self , Ty } ;
@@ -677,7 +680,6 @@ pub struct OverlappingRangeEndpoints<'tcx> {
677
680
pub overlap : Overlap < ' tcx > ,
678
681
}
679
682
680
- #[ derive( Debug ) ]
681
683
#[ derive( Subdiagnostic ) ]
682
684
#[ label( mir_build_overlapping_range) ]
683
685
pub struct Overlap < ' tcx > {
@@ -692,10 +694,158 @@ pub struct Overlap<'tcx> {
692
694
#[ note]
693
695
pub ( crate ) struct NonExhaustiveOmittedPattern < ' tcx > {
694
696
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 ,
697
850
pub count : usize ,
698
- pub witness_1 : Pat < ' tcx > ,
699
- pub witness_2 : Pat < ' tcx > ,
700
- pub witness_3 : Pat < ' tcx > ,
701
851
}
0 commit comments