| use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic}; |
| use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; |
| use rustc_middle::mir::AssertKind; |
| use rustc_middle::ty::TyCtxt; |
| use rustc_session::lint::{self, Lint}; |
| use rustc_span::def_id::DefId; |
| use rustc_span::Span; |
| |
| use crate::fluent_generated as fluent; |
| |
| #[derive(LintDiagnostic)] |
| pub(crate) enum ConstMutate { |
| #[diag(mir_transform_const_modify)] |
| #[note] |
| Modify { |
| #[note(mir_transform_const_defined_here)] |
| konst: Span, |
| }, |
| #[diag(mir_transform_const_mut_borrow)] |
| #[note] |
| #[note(mir_transform_note2)] |
| MutBorrow { |
| #[note(mir_transform_note3)] |
| method_call: Option<Span>, |
| #[note(mir_transform_const_defined_here)] |
| konst: Span, |
| }, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(mir_transform_unaligned_packed_ref, code = E0793)] |
| #[note] |
| #[note(mir_transform_note_ub)] |
| #[help] |
| pub(crate) struct UnalignedPackedRef { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| pub(crate) struct AssertLint<P> { |
| pub span: Span, |
| pub assert_kind: AssertKind<P>, |
| pub lint_kind: AssertLintKind, |
| } |
| |
| pub(crate) enum AssertLintKind { |
| ArithmeticOverflow, |
| UnconditionalPanic, |
| } |
| |
| impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> { |
| fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { |
| let message = self.assert_kind.diagnostic_message(); |
| self.assert_kind.add_args(&mut |name, value| { |
| diag.arg(name, value); |
| }); |
| diag.span_label(self.span, message); |
| } |
| |
| fn msg(&self) -> DiagMessage { |
| match self.lint_kind { |
| AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, |
| AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, |
| } |
| } |
| } |
| |
| impl AssertLintKind { |
| pub fn lint(&self) -> &'static Lint { |
| match self { |
| AssertLintKind::ArithmeticOverflow => lint::builtin::ARITHMETIC_OVERFLOW, |
| AssertLintKind::UnconditionalPanic => lint::builtin::UNCONDITIONAL_PANIC, |
| } |
| } |
| } |
| |
| #[derive(LintDiagnostic)] |
| #[diag(mir_transform_ffi_unwind_call)] |
| pub(crate) struct FfiUnwindCall { |
| #[label(mir_transform_ffi_unwind_call)] |
| pub span: Span, |
| pub foreign: bool, |
| } |
| |
| #[derive(LintDiagnostic)] |
| #[diag(mir_transform_fn_item_ref)] |
| pub(crate) struct FnItemRef { |
| #[suggestion(code = "{sugg}", applicability = "unspecified")] |
| pub span: Span, |
| pub sugg: String, |
| pub ident: String, |
| } |
| |
| pub(crate) struct MustNotSupend<'tcx, 'a> { |
| pub tcx: TyCtxt<'tcx>, |
| pub yield_sp: Span, |
| pub reason: Option<MustNotSuspendReason>, |
| pub src_sp: Span, |
| pub pre: &'a str, |
| pub def_id: DefId, |
| pub post: &'a str, |
| } |
| |
| // Needed for def_path_str |
| impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { |
| fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { |
| diag.span_label(self.yield_sp, fluent::_subdiag::label); |
| if let Some(reason) = self.reason { |
| diag.subdiagnostic(diag.dcx, reason); |
| } |
| diag.span_help(self.src_sp, fluent::_subdiag::help); |
| diag.arg("pre", self.pre); |
| diag.arg("def_path", self.tcx.def_path_str(self.def_id)); |
| diag.arg("post", self.post); |
| } |
| |
| fn msg(&self) -> rustc_errors::DiagMessage { |
| fluent::mir_transform_must_not_suspend |
| } |
| } |
| |
| #[derive(Subdiagnostic)] |
| #[note(mir_transform_note)] |
| pub(crate) struct MustNotSuspendReason { |
| #[primary_span] |
| pub span: Span, |
| pub reason: String, |
| } |