Rollup merge of #106097 - mejrs:mir_build2, r=oli-obk
Migrate mir_build diagnostics 2 of 3 The first three commits are fairly boring, however I've made some changes to the output of the match checking diagnostics.
This commit is contained in:
commit
83d3b76ac2
39 changed files with 568 additions and 488 deletions
|
@ -1,9 +1,13 @@
|
|||
use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
|
||||
use crate::thir::pattern::MatchCheckCtxt;
|
||||
use rustc_errors::Handler;
|
||||
use rustc_errors::{
|
||||
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
|
||||
error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
|
||||
};
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::thir::Pat;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{symbol::Ident, Span};
|
||||
|
||||
|
@ -624,3 +628,223 @@ pub enum MultipleMutBorrowOccurence {
|
|||
name_moved: Ident,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_union_pattern)]
|
||||
pub struct UnionPattern {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_type_not_structural)]
|
||||
pub struct TypeNotStructural<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_invalid_pattern)]
|
||||
pub struct InvalidPattern<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_unsized_pattern)]
|
||||
pub struct UnsizedPattern<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_float_pattern)]
|
||||
pub struct FloatPattern;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_pointer_pattern)]
|
||||
pub struct PointerPattern;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_indirect_structural_match)]
|
||||
pub struct IndirectStructuralMatch<'tcx> {
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_nontrivial_structural_match)]
|
||||
pub struct NontrivialStructuralMatch<'tcx> {
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_overlapping_range_endpoints)]
|
||||
#[note]
|
||||
pub struct OverlappingRangeEndpoints<'tcx> {
|
||||
#[label(range)]
|
||||
pub range: Span,
|
||||
#[subdiagnostic]
|
||||
pub overlap: Vec<Overlap<'tcx>>,
|
||||
}
|
||||
|
||||
pub struct Overlap<'tcx> {
|
||||
pub span: Span,
|
||||
pub range: Pat<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
let Overlap { span, range } = self;
|
||||
|
||||
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
||||
// does not support `#[subdiagnostic(eager)]`...
|
||||
let message = format!("this range overlaps on `{range}`...");
|
||||
diag.span_label(span, message);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_non_exhaustive_omitted_pattern)]
|
||||
#[help]
|
||||
#[note]
|
||||
pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
|
||||
pub scrut_ty: Ty<'tcx>,
|
||||
#[subdiagnostic]
|
||||
pub uncovered: Uncovered<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(mir_build_uncovered)]
|
||||
pub(crate) struct Uncovered<'tcx> {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
count: usize,
|
||||
witness_1: Pat<'tcx>,
|
||||
witness_2: Pat<'tcx>,
|
||||
witness_3: Pat<'tcx>,
|
||||
remainder: usize,
|
||||
}
|
||||
|
||||
impl<'tcx> Uncovered<'tcx> {
|
||||
pub fn new<'p>(
|
||||
span: Span,
|
||||
cx: &MatchCheckCtxt<'p, 'tcx>,
|
||||
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
|
||||
) -> Self {
|
||||
let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
|
||||
Self {
|
||||
span,
|
||||
count: witnesses.len(),
|
||||
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
|
||||
witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
|
||||
witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
|
||||
witness_1,
|
||||
remainder: witnesses.len().saturating_sub(3),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_pattern_not_covered, code = "E0005")]
|
||||
pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub origin: &'s str,
|
||||
#[subdiagnostic]
|
||||
pub uncovered: Uncovered<'tcx>,
|
||||
#[subdiagnostic]
|
||||
pub inform: Option<Inform>,
|
||||
#[subdiagnostic]
|
||||
pub interpreted_as_const: Option<InterpretedAsConst>,
|
||||
#[subdiagnostic]
|
||||
pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
|
||||
#[note(pattern_ty)]
|
||||
pub _p: (),
|
||||
pub pattern_ty: Ty<'tcx>,
|
||||
#[subdiagnostic]
|
||||
pub let_suggestion: Option<SuggestLet>,
|
||||
#[subdiagnostic]
|
||||
pub res_defined_here: Option<ResDefinedHere>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(mir_build_inform_irrefutable)]
|
||||
#[note(mir_build_more_information)]
|
||||
pub struct Inform;
|
||||
|
||||
pub struct AdtDefinedHere<'tcx> {
|
||||
pub adt_def_span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub variants: Vec<Variant>,
|
||||
}
|
||||
|
||||
pub struct Variant {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
diag.set_arg("ty", self.ty);
|
||||
let mut spans = MultiSpan::from(self.adt_def_span);
|
||||
|
||||
for Variant { span } in self.variants {
|
||||
spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
|
||||
}
|
||||
|
||||
diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(mir_build_res_defined_here)]
|
||||
pub struct ResDefinedHere {
|
||||
#[primary_span]
|
||||
pub def_span: Span,
|
||||
pub res: Res,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
mir_build_interpreted_as_const,
|
||||
code = "{variable}_var",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
#[label(mir_build_confused)]
|
||||
pub struct InterpretedAsConst {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub article: &'static str,
|
||||
pub variable: String,
|
||||
pub res: Res,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum SuggestLet {
|
||||
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
|
||||
If {
|
||||
#[suggestion_part(code = "if ")]
|
||||
start_span: Span,
|
||||
#[suggestion_part(code = " {{ todo!() }}")]
|
||||
semi_span: Span,
|
||||
count: usize,
|
||||
},
|
||||
#[suggestion(
|
||||
mir_build_suggest_let_else,
|
||||
code = " else {{ todo!() }}",
|
||||
applicability = "has-placeholders"
|
||||
)]
|
||||
Else {
|
||||
#[primary_span]
|
||||
end_span: Span,
|
||||
count: usize,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue