macros: add diagnostic derive for lints

`SessionDiagnostic` isn't suitable for use on lints as whether or not it
creates an error or a warning is decided at compile-time by the macro,
whereas lints decide this at runtime based on the location of the lint
being reported (as it will depend on the user's `allow`/`deny`
attributes, etc). Re-using most of the machinery for
`SessionDiagnostic`, this macro introduces a `LintDiagnostic` derive
which implements a `DecorateLint` trait, taking a
`LintDiagnosticBuilder` and adding to the lint according to the
diagnostic struct.
This commit is contained in:
David Wood 2022-06-30 08:57:45 +01:00
parent 7f9d8480d6
commit 9d864c8d56
12 changed files with 847 additions and 614 deletions

View file

@ -5,6 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{fluent, Applicability, DiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_macros::LintDiagnostic;
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
@ -1553,13 +1554,20 @@ impl InvalidAtomicOrdering {
let Some(fail_ordering) = Self::match_ordering(cx, fail_order_arg) else { return };
if matches!(fail_ordering, sym::Release | sym::AcqRel) {
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg.span, |diag| {
diag.build(fluent::lint::atomic_ordering_invalid)
.set_arg("method", method)
.span_label(fail_order_arg.span, fluent::lint::label)
.help(fluent::lint::help)
.emit();
});
#[derive(LintDiagnostic)]
#[lint(lint::atomic_ordering_invalid)]
#[help]
struct InvalidAtomicOrderingDiag {
method: Symbol,
#[label]
fail_order_arg_span: Span,
}
cx.emit_spanned_lint(
INVALID_ATOMIC_ORDERING,
fail_order_arg.span,
InvalidAtomicOrderingDiag { method, fail_order_arg_span: fail_order_arg.span },
);
}
let Some(success_ordering) = Self::match_ordering(cx, success_order_arg) else { return };